├── .github ├── CODEOWNERS ├── dependabot.yml └── workflows │ ├── dist.yml │ ├── release-python.yml │ └── test.yml ├── .gitignore ├── CHANGELOG.rst ├── LICENSE ├── MANIFEST.in ├── README.rst ├── benchmark.py ├── bsonjs ├── bson │ ├── bcon.c │ ├── bcon.h │ ├── bson-atomic.c │ ├── bson-atomic.h │ ├── bson-clock.c │ ├── bson-clock.h │ ├── bson-cmp.h │ ├── bson-compat.h │ ├── bson-config.h │ ├── bson-context-private.h │ ├── bson-context.c │ ├── bson-context.h │ ├── bson-decimal128.c │ ├── bson-decimal128.h │ ├── bson-endian.h │ ├── bson-error.c │ ├── bson-error.h │ ├── bson-iso8601-private.h │ ├── bson-iso8601.c │ ├── bson-iter.c │ ├── bson-iter.h │ ├── bson-json-private.h │ ├── bson-json.c │ ├── bson-json.h │ ├── bson-keys.c │ ├── bson-keys.h │ ├── bson-macros.h │ ├── bson-md5.c │ ├── bson-md5.h │ ├── bson-memory.c │ ├── bson-memory.h │ ├── bson-oid.c │ ├── bson-oid.h │ ├── bson-prelude.h │ ├── bson-private.h │ ├── bson-reader.c │ ├── bson-reader.h │ ├── bson-string.c │ ├── bson-string.h │ ├── bson-timegm-private.h │ ├── bson-timegm.c │ ├── bson-types.h │ ├── bson-utf8.c │ ├── bson-utf8.h │ ├── bson-value.c │ ├── bson-value.h │ ├── bson-version-functions.c │ ├── bson-version-functions.h │ ├── bson-version.h │ ├── bson-writer.c │ ├── bson-writer.h │ ├── bson.c │ └── bson.h ├── bsonjs.c ├── bsonjs.h ├── common │ ├── bson-dsl.h │ ├── common-b64-private.h │ ├── common-b64.c │ ├── common-config.h │ ├── common-macros-private.h │ ├── common-md5-private.h │ ├── common-md5.c │ ├── common-prelude.h │ ├── common-thread-private.h │ └── common-thread.c └── jsonsl │ ├── LICENSE │ ├── jsonsl.c │ └── jsonsl.h ├── build-wheels.sh ├── docker-build.sh ├── pyproject.toml ├── setup.py ├── test ├── __init__.py └── test_bsonjs.py └── vendor.sh /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Global owner for repo 2 | * @mongodb-labs/dbx-python 3 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | # GitHub Actions 4 | - package-ecosystem: "github-actions" 5 | directory: "/" 6 | schedule: 7 | interval: "weekly" 8 | groups: 9 | actions: 10 | patterns: 11 | - "*" 12 | assignees: 13 | - "@mongodb/dbx-python" 14 | # Python 15 | - package-ecosystem: "pip" 16 | directory: "/bindings/python" 17 | schedule: 18 | interval: "weekly" 19 | assignees: 20 | - "@mongodb/dbx-python" -------------------------------------------------------------------------------- /.github/workflows/dist.yml: -------------------------------------------------------------------------------- 1 | name: Python Dist 2 | 3 | on: 4 | push: 5 | tags: 6 | - "[0-9]+.[0-9]+.[0-9]+" 7 | - "[0-9]+.[0-9]+.[0-9]+.post[0-9]+" 8 | - "[0-9]+.[0-9]+.[0-9]+[a-b][0-9]+" 9 | - "[0-9]+.[0-9]+.[0-9]+rc[0-9]+" 10 | workflow_dispatch: 11 | pull_request: 12 | workflow_call: 13 | inputs: 14 | ref: 15 | required: true 16 | type: string 17 | 18 | concurrency: 19 | group: dist-${{ github.ref }} 20 | cancel-in-progress: true 21 | 22 | defaults: 23 | run: 24 | shell: bash -eux {0} 25 | 26 | jobs: 27 | build_wheels: 28 | runs-on: ${{ matrix.os }} 29 | strategy: 30 | matrix: 31 | os: [macos-latest, windows-latest, ubuntu-latest] 32 | name: Build CPython-${{ matrix.os }} 33 | steps: 34 | - uses: actions/checkout@v4 35 | - uses: pypa/cibuildwheel@faf86a6ed7efa889faf6996aa23820831055001a # v2.23.3 36 | env: 37 | CIBW_ARCHS_MACOS: x86_64 universal2 38 | CIBW_TEST_SKIP: '*universal2:arm64' 39 | CIBW_BUILD: "cp39-macosx_universal2 cp39-win* cp39-manylinux_{x86_64,i686}" 40 | - uses: actions/upload-artifact@v4 41 | with: 42 | name: ${{ matrix.os }}-wheel 43 | path: ./wheelhouse/*.whl 44 | if-no-files-found: error 45 | test_non_linux_wheels: 46 | needs: build_wheels 47 | runs-on: ${{ matrix.os }} 48 | strategy: 49 | matrix: 50 | os: [macos-latest, windows-latest] 51 | python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] 52 | name: Test CPython ${{ matrix.python-version }}-${{ matrix.os }} 53 | steps: 54 | - name: Setup Python 55 | uses: actions/setup-python@v5 56 | with: 57 | python-version: ${{ matrix.python-version }} 58 | allow-prereleases: true 59 | - name: Download a previously created wheel 60 | uses: actions/download-artifact@v4 61 | with: 62 | name: ${{ matrix.os }}-wheel 63 | - name: Test wheel 64 | shell: bash 65 | run: | 66 | python -m pip install -U pip 67 | python -m pip install --no-index --find-links=./ python_bsonjs 68 | python -m pip list | grep python-bsonjs 69 | python -c "from bsonjs import dumps" 70 | # Linux 71 | test_manylinux_wheels: 72 | runs-on: ${{ matrix.os }} 73 | needs: build_wheels 74 | strategy: 75 | matrix: 76 | os: [ubuntu-latest] 77 | container: ['manylinux2014_i686', 'manylinux2014_x86_64'] 78 | python-version: ['cp39-cp39', 'cp310-cp310', 'cp311-cp311', 'cp312-cp312', 'cp313-cp313'] 79 | name: Test CPython ${{ matrix.python-version }}-${{ matrix.container }} 80 | steps: 81 | - name: Download a previously created wheel 82 | uses: actions/download-artifact@v4 83 | with: 84 | name: ${{ matrix.os }}-wheel 85 | - name: Test wheel 86 | run: | 87 | docker run --rm --volume `pwd`:/python quay.io/pypa/${{ matrix.container }} /bin/bash -c "/opt/python/${{ matrix.python-version }}/bin/python -m pip install -U pip && /opt/python/${{ matrix.python-version }}/bin/python -m pip install --find-links=/python/ --no-index python_bsonjs && /opt/python/${{ matrix.python-version }}/bin/python -m pip list | grep python-bsonjs && /opt/python/${{ matrix.python-version }}/bin/python -c 'from bsonjs import dumps'" 88 | make_sdist: 89 | name: Make SDist 90 | runs-on: ubuntu-latest 91 | steps: 92 | - uses: actions/checkout@v4 93 | - name: Setup Python 94 | uses: actions/setup-python@v5 95 | with: 96 | python-version: 3.9 97 | - name: Build SDist 98 | run: | 99 | python -m pip install build 100 | python -m build --sdist 101 | - uses: actions/upload-artifact@v4 102 | with: 103 | name: "sdist" 104 | path: dist/*.tar.gz 105 | collect_dist: 106 | runs-on: ubuntu-latest 107 | needs: [build_wheels, make_sdist] 108 | name: Download Wheels 109 | steps: 110 | - name: Download all workflow run artifacts 111 | uses: actions/download-artifact@v4 112 | - name: Flatten directory 113 | working-directory: . 114 | run: | 115 | find . -mindepth 2 -type f -exec mv {} . \; 116 | find . -type d -empty -delete 117 | - uses: actions/upload-artifact@v4 118 | with: 119 | name: all-dist-${{ github.run_id }} 120 | path: "./*" -------------------------------------------------------------------------------- /.github/workflows/release-python.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | following_version: 7 | description: "The post (dev) version to set" 8 | dry_run: 9 | description: "Dry Run?" 10 | default: false 11 | type: boolean 12 | schedule: 13 | - cron: '30 5 * * *' 14 | 15 | env: 16 | # Changes per repo 17 | PRODUCT_NAME: python-bsonjs 18 | # Constant 19 | # inputs will be empty on a scheduled run. so, we only set dry_run 20 | # to 'false' when the input is set to 'false'. 21 | DRY_RUN: ${{ ! contains(inputs.dry_run, 'false') }} 22 | FOLLOWING_VERSION: ${{ inputs.following_version || '' }} 23 | 24 | concurrency: 25 | group: wheels-${{ github.ref }} 26 | cancel-in-progress: true 27 | 28 | defaults: 29 | run: 30 | shell: bash -eux {0} 31 | 32 | jobs: 33 | pre-publish: 34 | environment: release 35 | runs-on: ubuntu-latest 36 | if: github.repository_owner == 'mongodb-labs' || github.event_name == 'workflow_dispatch' 37 | permissions: 38 | id-token: write 39 | contents: write 40 | outputs: 41 | version: ${{ steps.pre-publish.outputs.version }} 42 | steps: 43 | - uses: mongodb-labs/drivers-github-tools/secure-checkout@v2 44 | with: 45 | app_id: ${{ vars.APP_ID }} 46 | private_key: ${{ secrets.APP_PRIVATE_KEY }} 47 | - uses: mongodb-labs/drivers-github-tools/setup@v2 48 | with: 49 | aws_role_arn: ${{ secrets.AWS_ROLE_ARN }} 50 | aws_region_name: ${{ vars.AWS_REGION_NAME }} 51 | aws_secret_id: ${{ secrets.AWS_SECRET_ID }} 52 | artifactory_username: ${{ vars.ARTIFACTORY_USERNAME }} 53 | - uses: mongodb-labs/drivers-github-tools/python-labs/pre-publish@v2 54 | id: pre-publish 55 | with: 56 | dry_run: ${{ env.DRY_RUN }} 57 | 58 | build-dist: 59 | needs: [pre-publish] 60 | uses: ./.github/workflows/dist.yml 61 | with: 62 | ref: ${{ needs.pre-publish.outputs.version }} 63 | 64 | publish: 65 | # https://packaging.python.org/en/latest/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows/#publishing-the-distribution-to-pypi 66 | needs: [build-dist] 67 | if: (github.repository_owner == 'mongodb-labs' && github.event_name != 'pull_request') || github.event_name == 'workflow_dispatch' 68 | runs-on: ubuntu-latest 69 | environment: release 70 | permissions: 71 | id-token: write 72 | steps: 73 | - name: Download all the dists 74 | uses: actions/download-artifact@v4 75 | with: 76 | name: all-dist-${{ github.run_id }} 77 | path: dist/ 78 | - name: Publish package distributions to TestPyPI 79 | uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc # release/v1 80 | with: 81 | repository-url: https://test.pypi.org/legacy/ 82 | skip-existing: true 83 | attestations: ${{ env.DRY_RUN }} 84 | - name: Publish distribution 📦 to PyPI 85 | if: startsWith(env.DRY_RUN, 'false') 86 | uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc # release/v1 87 | 88 | post-publish: 89 | needs: [publish] 90 | runs-on: ubuntu-latest 91 | environment: release 92 | permissions: 93 | id-token: write 94 | contents: write 95 | attestations: write 96 | security-events: write 97 | steps: 98 | - uses: mongodb-labs/drivers-github-tools/secure-checkout@v2 99 | with: 100 | app_id: ${{ vars.APP_ID }} 101 | private_key: ${{ secrets.APP_PRIVATE_KEY }} 102 | - uses: mongodb-labs/drivers-github-tools/setup@v2 103 | with: 104 | aws_role_arn: ${{ secrets.AWS_ROLE_ARN }} 105 | aws_region_name: ${{ vars.AWS_REGION_NAME }} 106 | aws_secret_id: ${{ secrets.AWS_SECRET_ID }} 107 | artifactory_username: ${{ vars.ARTIFACTORY_USERNAME }} 108 | - uses: mongodb-labs/drivers-github-tools/python-labs/post-publish@v2 109 | with: 110 | following_version: ${{ env.FOLLOWING_VERSION }} 111 | product_name: ${{ env.PRODUCT_NAME }} 112 | token: ${{ github.token }} 113 | dry_run: ${{ env.DRY_RUN }} 114 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: python-bsonjs 2 | 3 | on: 4 | push: 5 | branches: ["master"] 6 | pull_request: 7 | workflow_dispatch: 8 | 9 | concurrency: 10 | group: test-${{ github.ref }} 11 | cancel-in-progress: true 12 | 13 | jobs: 14 | build: 15 | 16 | runs-on: ${{ matrix.os }} 17 | strategy: 18 | matrix: 19 | os: [macos-latest, ubuntu-latest, windows-2019] 20 | python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] 21 | 22 | steps: 23 | - uses: actions/checkout@v4 24 | - name: Set up Python ${{ matrix.python-version }} 25 | uses: actions/setup-python@v5 26 | with: 27 | python-version: ${{ matrix.python-version }} 28 | allow-prereleases: true 29 | - name: Test with python 30 | run: | 31 | python -m pip install -v -e ".[test]" 32 | pytest 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/python,c 3 | 4 | ### Python ### 5 | # Byte-compiled / optimized / DLL files 6 | __pycache__/ 7 | *.py[cod] 8 | *$py.class 9 | 10 | # C extensions 11 | *.so 12 | 13 | # Distribution / packaging 14 | .Python 15 | env/ 16 | build/ 17 | develop-eggs/ 18 | dist/ 19 | downloads/ 20 | eggs/ 21 | .eggs/ 22 | lib/ 23 | lib64/ 24 | parts/ 25 | sdist/ 26 | var/ 27 | *.egg-info/ 28 | .installed.cfg 29 | *.egg 30 | 31 | # PyInstaller 32 | # Usually these files are written by a python script from a template 33 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 34 | *.manifest 35 | *.spec 36 | 37 | # Installer logs 38 | pip-log.txt 39 | pip-delete-this-directory.txt 40 | 41 | # Unit test / coverage reports 42 | htmlcov/ 43 | .tox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *,cover 50 | .hypothesis/ 51 | 52 | # Translations 53 | *.mo 54 | *.pot 55 | 56 | # Django stuff: 57 | *.log 58 | local_settings.py 59 | 60 | # Flask stuff: 61 | instance/ 62 | .webassets-cache 63 | 64 | # Scrapy stuff: 65 | .scrapy 66 | 67 | # Sphinx documentation 68 | docs/_build/ 69 | 70 | # PyBuilder 71 | target/ 72 | 73 | # IPython Notebook 74 | .ipynb_checkpoints 75 | 76 | # pyenv 77 | .python-version 78 | 79 | # celery beat schedule file 80 | celerybeat-schedule 81 | 82 | # dotenv 83 | .env 84 | 85 | # virtualenv 86 | venv/ 87 | ENV/ 88 | 89 | # Spyder project settings 90 | .spyderproject 91 | 92 | # Rope project settings 93 | .ropeproject 94 | 95 | 96 | ### C ### 97 | # Object files 98 | *.o 99 | *.ko 100 | *.obj 101 | *.elf 102 | 103 | # Precompiled Headers 104 | *.gch 105 | *.pch 106 | 107 | # Libraries 108 | *.lib 109 | *.a 110 | *.la 111 | *.lo 112 | 113 | # Shared objects (inc. Windows DLLs) 114 | *.dll 115 | *.so 116 | *.so.* 117 | *.dylib 118 | 119 | # Executables 120 | *.exe 121 | *.out 122 | *.app 123 | *.i*86 124 | *.x86_64 125 | *.hex 126 | 127 | # Debug files 128 | *.dSYM/ 129 | *.su 130 | 131 | # .idea 132 | .idea/** 133 | 134 | # Local checkout of mongo-c-driver 135 | mongo-c-driver/ -------------------------------------------------------------------------------- /CHANGELOG.rst: -------------------------------------------------------------------------------- 1 | Changelog 2 | ========= 3 | 4 | 0.6.0 5 | ````` 6 | - Drop support for Python 3.8. 7 | - Fix memory leak in ``dump`` and ``dumps`` when an invalid ``mode`` is provided. 8 | 9 | 0.5.0 10 | ````` 11 | Version 0.5.0 updates python-bsonjs's vendored copy of libbson to 1.27.6. 12 | For a detailed breakdown of what changed in each version of libbson see its changelog: 13 | https://github.com/mongodb/mongo-c-driver/blob/1.27.6/src/libbson/NEWS 14 | http://mongoc.org/libbson/1.27.6/ 15 | 16 | This release also adds support for Python 3.13 and drops support for Python 3.7. 17 | 18 | 0.4.0 19 | ````` 20 | Version 0.4.0 updates python-bsonjs's vendored copy of libbson to 1.24.2. 21 | For a detailed breakdown of what changed in each version of libbson see its changelog: 22 | https://github.com/mongodb/mongo-c-driver/blob/1.24.2/src/libbson/NEWS 23 | http://mongoc.org/libbson/1.24.2/ 24 | 25 | This release also adds support for Python 3.11 and 3.12. 26 | 27 | 0.3.0 28 | ````` 29 | 30 | Version 0.3.0 updates python-bsonjs's vendored copy of libbson to 1.20.0. 31 | For a detailed breakdown of what changed in each version of libbson see its changelog: 32 | https://github.com/mongodb/mongo-c-driver/blob/1.20.0/src/libbson/NEWS 33 | http://mongoc.org/libbson/1.20.0/ 34 | 35 | This release also provides a number of improvements and features: 36 | 37 | - Added support for Python 3.7, 3.8, 3.9, and 3.10 38 | - Added a new keyword argument to the `dumps` and `dump` functions: `mode`. It 39 | can be one of: bsonjs.LEGACY, bsonjs.CANONICAL, or bsonjs.RELAXED. Which are: 40 | libbson's legacy extended JSON format, MongoDB Extended JSON 2.0 canonical 41 | mode, and MongoDB Extended JSON relaxed mode. 42 | - Dropped support for Python 2.7, 3.4, and 3.5. 43 | 44 | 45 | 0.2.0 46 | ````` 47 | 48 | Version 0.2.0 updates python-bsonjs's vendored copy of libbson to 1.6.5 49 | http://mongoc.org/libbson/1.6.2/. 50 | Updating libbson provides a number of improvements and features including: 51 | 52 | - Use jsonsl instead of libyajl as our JSON parsing library, parse JSON more 53 | strictly, fix minor parsing bugs. 54 | - Extended JSON documents like '{"$code": "...", "$scope": {}}' are now parsed 55 | into BSON "code" elements. 56 | - ISO8601 dates now allow years from 0000 to 9999 inclusive. Before, years 57 | before 1970 were prohibited. 58 | - BSON floats and ints are now distinguished in JSON output. 59 | - Support for the BSON decimal128 type encoded to json as 60 | '{ "$numberDecimal" : "1.62" }'. 61 | 62 | This release also fixes an error in our Linux builds. Previously published 63 | releases for Python 3.3 and 3.4 on Linux are broken due to the following 64 | error:: 65 | 66 | >>> import bsonjs 67 | Traceback (most recent call last): 68 | File "", line 1, in 69 | ImportError: /path/to/bsonjs.cpython-34m.so: undefined symbol: clock_gettime 70 | 71 | 0.1.1 72 | ````` 73 | 74 | Version 0.1.1 fixes a Windows build error. 75 | 76 | 0.1.0 77 | ````` 78 | 79 | Version 0.1.0 is the first release of python-bsonjs! 80 | This release uses libbson 1.3.5 http://mongoc.org/libbson/1.3.5/. 81 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include README.rst 2 | include CHANGELOG.rst 3 | include LICENSE 4 | recursive-include bsonjs LICENSE 5 | recursive-include bsonjs *.h 6 | recursive-include bsonjs *.py 7 | exclude benchmark.py 8 | exclude build-wheels.sh 9 | exclude docker-build.sh 10 | exclude vendor.sh 11 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | ============= 2 | python-bsonjs 3 | ============= 4 | 5 | :Info: See `github `_ for the latest source. 6 | :Author: Shane Harvey 7 | 8 | About 9 | ===== 10 | 11 | A fast BSON to MongoDB Extended JSON converter for Python that uses 12 | `libbson `_. 13 | 14 | Installation 15 | ============ 16 | 17 | python-bsonjs can be installed with `pip `_:: 18 | 19 | $ python -m pip install python-bsonjs 20 | 21 | Examples 22 | ======== 23 | 24 | .. code-block:: python 25 | 26 | >>> import bsonjs 27 | >>> bson_bytes = bsonjs.loads('{"hello": "world"}') 28 | >>> bson_bytes 29 | '\x16\x00\x00\x00\x02hello\x00\x06\x00\x00\x00world\x00\x00' 30 | >>> bsonjs.dumps(bson_bytes) 31 | '{ "hello" : "world" }' 32 | 33 | Using bsonjs with pymongo to insert a RawBSONDocument. 34 | 35 | .. code-block:: python 36 | 37 | >>> import bsonjs 38 | >>> from pymongo import MongoClient 39 | >>> from bson.raw_bson import RawBSONDocument 40 | >>> client = MongoClient("localhost", 27017, document_class=RawBSONDocument) 41 | >>> db = client.test 42 | >>> bson_bytes = bsonjs.loads('{"_id": 1, "x": 2}') 43 | >>> bson_bytes 44 | '\x15\x00\x00\x00\x10_id\x00\x01\x00\x00\x00\x10x\x00\x02\x00\x00\x00\x00' 45 | >>> result = db.test.insert_one(RawBSONDocument(bson_bytes)) 46 | >>> result.inserted_id # NOTE: inserted_id is None 47 | >>> result.acknowledged 48 | True 49 | >>> raw_doc = db.test.find_one({'x': 2}) 50 | >>> raw_doc.raw == bson_bytes 51 | True 52 | >>> bsonjs.dumps(raw_doc.raw) 53 | '{ "_id" : 1, "x" : 2 }' 54 | 55 | Speed 56 | ===== 57 | 58 | bsonjs is roughly 3-4x faster than PyMongo's json_util at decoding BSON to 59 | JSON and encoding JSON to BSON. See `benchmark.py`:: 60 | 61 | $ python benchmark.py 62 | Timing: bsonjs.dumps(b) 63 | 10000 loops, best of 3: 0.04682216700166464 64 | Timing: json_util.dumps(bson.decode(b)) 65 | 10000 loops, best of 3: 0.17319270805455744 66 | bsonjs is 3.70x faster than json_util 67 | 68 | Timing: bsonjs.loads(j) 69 | 10000 loops, best of 3: 0.053156834095716476 70 | Timing: bson.encode(json_util.loads(j)) 71 | 10000 loops, best of 3: 0.15982166700996459 72 | bsonjs is 3.01x faster than json_util 73 | 74 | 75 | Limitations 76 | =========== 77 | 78 | Top Level Arrays 79 | ```````````````` 80 | Because `libbson` does not distinguish between top level arrays and top 81 | level documents, neither does `python-bsonjs`. This means that if you give 82 | `dumps` or `dump` a top level array it will give you back a dictionary. 83 | Below are two examples of this behavior 84 | 85 | .. code-block:: python 86 | 87 | >>> import bson 88 | >>> from bson import json_util 89 | >>> import bsonjs 90 | >>> bson.decode(bsonjs.loads(json_util.dumps(["a", "b", "c"]))) 91 | {'0': 'a', '1': 'b', '2': 'c'} 92 | >>> bson.decode(bsonjs.loads(json_util.dumps([]))) 93 | {} 94 | 95 | One potential solution to this problem is to wrap your list in a dictionary, 96 | like so 97 | 98 | .. code-block:: python 99 | 100 | >>> list = ["a", "b", "c"] 101 | >>> dict = {"data": list} 102 | >>> wrapped = bson.decode(bsonjs.loads(json_util.dumps(dict))) 103 | {'data': ['a', 'b', 'c']} 104 | >>> wrapped["data"] 105 | ['a', 'b', 'c'] 106 | 107 | Installing From Source 108 | ====================== 109 | 110 | python-bsonjs supports CPython 3.9+. 111 | 112 | Compiler 113 | ```````` 114 | 115 | You must build python-bsonjs separately for each version of Python. On 116 | Windows this means you must use the same C compiler your Python version was 117 | built with. 118 | 119 | - Windows build requires Microsoft Visual Studio 2015 120 | 121 | Source 122 | `````` 123 | You can download the source using git:: 124 | 125 | $ git clone https://github.com/mongodb-labs/python-bsonjs.git 126 | 127 | 128 | Install 129 | ``````` 130 | 131 | Once you have the source properly downloaded, build and install the package:: 132 | 133 | $ pip install -v . 134 | 135 | Test 136 | ```` 137 | 138 | To run the test suite:: 139 | 140 | $ python -m pytest 141 | -------------------------------------------------------------------------------- /benchmark.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Copyright 2016 MongoDB, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Benchmark bsonjs vs bson.json_util""" 18 | 19 | import sys 20 | import timeit 21 | 22 | 23 | def time(stmt, iterations, setup): 24 | print('Timing: ' + stmt) 25 | times = timeit.repeat(stmt=stmt, number=iterations, setup=setup) 26 | best = min(times) 27 | print('{0} loops, best of 3: {1}'.format(iterations, best)) 28 | return best 29 | 30 | 31 | def compare(bsonjs_stmt, json_util_stmt, iterations, setup): 32 | bsonjs_secs = time(bsonjs_stmt, iterations, setup) 33 | json_util_secs = time(json_util_stmt, iterations, setup) 34 | print('bsonjs is {0:.2f}x faster than json_util\n'.format( 35 | json_util_secs/bsonjs_secs)) 36 | 37 | 38 | def main(iterations): 39 | setup = ("import datetime\n" 40 | "import bsonjs\n" 41 | "import bson\n" 42 | "from bson import json_util\n" 43 | "doc = {\n" 44 | " '_id': bson.ObjectId(),\n" 45 | " 'foo': [1, 2],\n" 46 | " 'bar': {'hello': 'world'},\n" 47 | " 'code': bson.Code('function x() { return 1; }'),\n" 48 | " 'bin': bson.Binary(b'\x01\x02\x03\x04'),\n" 49 | " 'min': bson.MinKey(),\n" 50 | " 'max': bson.MaxKey(),\n" 51 | " 'int64': bson.Int64(123),\n" 52 | " 'time': bson.Timestamp(4, 13),\n" 53 | " 'date': datetime.datetime(2009, 12, 9, 15),\n" 54 | " 'regex': bson.Regex('.*', 'i'),\n" 55 | "}\n" 56 | "b = bson.encode(doc)\n" 57 | "j = bsonjs.dumps(b)\n") 58 | 59 | # dumps 60 | compare("bsonjs.dumps(b)", 61 | "json_util.dumps(bson.decode(b))", 62 | iterations, 63 | setup) 64 | # loads 65 | compare("bsonjs.loads(j)", 66 | "bson.encode(json_util.loads(j))", 67 | iterations, 68 | setup) 69 | 70 | 71 | def get_iterations(): 72 | """Return number of iterations to perform""" 73 | if len(sys.argv) > 1: 74 | try: 75 | return int(sys.argv[1]) 76 | except ValueError: 77 | exit('usage: {0} [iterations]'.format(__file__)) 78 | return 10000 79 | 80 | 81 | if __name__ == "__main__": 82 | main(get_iterations()) 83 | -------------------------------------------------------------------------------- /bsonjs/bson/bcon.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @file bcon.h 3 | * @brief BCON (BSON C Object Notation) Declarations 4 | */ 5 | 6 | #include 7 | 8 | /* Copyright 2009-2013 MongoDB, Inc. 9 | * 10 | * Licensed under the Apache License, Version 2.0 (the "License"); 11 | * you may not use this file except in compliance with the License. 12 | * You may obtain a copy of the License at 13 | * 14 | * http://www.apache.org/licenses/LICENSE-2.0 15 | * 16 | * Unless required by applicable law or agreed to in writing, software 17 | * distributed under the License is distributed on an "AS IS" BASIS, 18 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | * See the License for the specific language governing permissions and 20 | * limitations under the License. 21 | */ 22 | 23 | #ifndef BCON_H_ 24 | #define BCON_H_ 25 | 26 | #include "bson.h" 27 | 28 | 29 | BSON_BEGIN_DECLS 30 | 31 | 32 | #define BCON_STACK_MAX 100 33 | 34 | #define BCON_ENSURE_DECLARE(fun, type) \ 35 | static BSON_INLINE type bcon_ensure_##fun (type _t) \ 36 | { \ 37 | return _t; \ 38 | } 39 | 40 | #define BCON_ENSURE(fun, val) bcon_ensure_##fun (val) 41 | 42 | #define BCON_ENSURE_STORAGE(fun, val) bcon_ensure_##fun (&(val)) 43 | 44 | BCON_ENSURE_DECLARE (const_char_ptr, const char *) 45 | BCON_ENSURE_DECLARE (const_char_ptr_ptr, const char **) 46 | BCON_ENSURE_DECLARE (double, double) 47 | BCON_ENSURE_DECLARE (double_ptr, double *) 48 | BCON_ENSURE_DECLARE (const_bson_ptr, const bson_t *) 49 | BCON_ENSURE_DECLARE (bson_ptr, bson_t *) 50 | BCON_ENSURE_DECLARE (subtype, bson_subtype_t) 51 | BCON_ENSURE_DECLARE (subtype_ptr, bson_subtype_t *) 52 | BCON_ENSURE_DECLARE (const_uint8_ptr, const uint8_t *) 53 | BCON_ENSURE_DECLARE (const_uint8_ptr_ptr, const uint8_t **) 54 | BCON_ENSURE_DECLARE (uint32, uint32_t) 55 | BCON_ENSURE_DECLARE (uint32_ptr, uint32_t *) 56 | BCON_ENSURE_DECLARE (const_oid_ptr, const bson_oid_t *) 57 | BCON_ENSURE_DECLARE (const_oid_ptr_ptr, const bson_oid_t **) 58 | BCON_ENSURE_DECLARE (int32, int32_t) 59 | BCON_ENSURE_DECLARE (int32_ptr, int32_t *) 60 | BCON_ENSURE_DECLARE (int64, int64_t) 61 | BCON_ENSURE_DECLARE (int64_ptr, int64_t *) 62 | BCON_ENSURE_DECLARE (const_decimal128_ptr, const bson_decimal128_t *) 63 | BCON_ENSURE_DECLARE (bool, bool) 64 | BCON_ENSURE_DECLARE (bool_ptr, bool *) 65 | BCON_ENSURE_DECLARE (bson_type, bson_type_t) 66 | BCON_ENSURE_DECLARE (bson_iter_ptr, bson_iter_t *) 67 | BCON_ENSURE_DECLARE (const_bson_iter_ptr, const bson_iter_t *) 68 | 69 | #define BCON_UTF8(_val) BCON_MAGIC, BCON_TYPE_UTF8, BCON_ENSURE (const_char_ptr, (_val)) 70 | #define BCON_DOUBLE(_val) BCON_MAGIC, BCON_TYPE_DOUBLE, BCON_ENSURE (double, (_val)) 71 | #define BCON_DOCUMENT(_val) BCON_MAGIC, BCON_TYPE_DOCUMENT, BCON_ENSURE (const_bson_ptr, (_val)) 72 | #define BCON_ARRAY(_val) BCON_MAGIC, BCON_TYPE_ARRAY, BCON_ENSURE (const_bson_ptr, (_val)) 73 | #define BCON_BIN(_subtype, _binary, _length) \ 74 | BCON_MAGIC, BCON_TYPE_BIN, BCON_ENSURE (subtype, (_subtype)), BCON_ENSURE (const_uint8_ptr, (_binary)), \ 75 | BCON_ENSURE (uint32, (_length)) 76 | #define BCON_UNDEFINED BCON_MAGIC, BCON_TYPE_UNDEFINED 77 | #define BCON_OID(_val) BCON_MAGIC, BCON_TYPE_OID, BCON_ENSURE (const_oid_ptr, (_val)) 78 | #define BCON_BOOL(_val) BCON_MAGIC, BCON_TYPE_BOOL, BCON_ENSURE (bool, (_val)) 79 | #define BCON_DATE_TIME(_val) BCON_MAGIC, BCON_TYPE_DATE_TIME, BCON_ENSURE (int64, (_val)) 80 | #define BCON_NULL BCON_MAGIC, BCON_TYPE_NULL 81 | #define BCON_REGEX(_regex, _flags) \ 82 | BCON_MAGIC, BCON_TYPE_REGEX, BCON_ENSURE (const_char_ptr, (_regex)), BCON_ENSURE (const_char_ptr, (_flags)) 83 | #define BCON_DBPOINTER(_collection, _oid) \ 84 | BCON_MAGIC, BCON_TYPE_DBPOINTER, BCON_ENSURE (const_char_ptr, (_collection)), BCON_ENSURE (const_oid_ptr, (_oid)) 85 | #define BCON_CODE(_val) BCON_MAGIC, BCON_TYPE_CODE, BCON_ENSURE (const_char_ptr, (_val)) 86 | #define BCON_SYMBOL(_val) BCON_MAGIC, BCON_TYPE_SYMBOL, BCON_ENSURE (const_char_ptr, (_val)) 87 | #define BCON_CODEWSCOPE(_js, _scope) \ 88 | BCON_MAGIC, BCON_TYPE_CODEWSCOPE, BCON_ENSURE (const_char_ptr, (_js)), BCON_ENSURE (const_bson_ptr, (_scope)) 89 | #define BCON_INT32(_val) BCON_MAGIC, BCON_TYPE_INT32, BCON_ENSURE (int32, (_val)) 90 | #define BCON_TIMESTAMP(_timestamp, _increment) \ 91 | BCON_MAGIC, BCON_TYPE_TIMESTAMP, BCON_ENSURE (int32, (_timestamp)), BCON_ENSURE (int32, (_increment)) 92 | #define BCON_INT64(_val) BCON_MAGIC, BCON_TYPE_INT64, BCON_ENSURE (int64, (_val)) 93 | #define BCON_DECIMAL128(_val) BCON_MAGIC, BCON_TYPE_DECIMAL128, BCON_ENSURE (const_decimal128_ptr, (_val)) 94 | #define BCON_MAXKEY BCON_MAGIC, BCON_TYPE_MAXKEY 95 | #define BCON_MINKEY BCON_MAGIC, BCON_TYPE_MINKEY 96 | #define BCON(_val) BCON_MAGIC, BCON_TYPE_BCON, BCON_ENSURE (const_bson_ptr, (_val)) 97 | #define BCON_ITER(_val) BCON_MAGIC, BCON_TYPE_ITER, BCON_ENSURE (const_bson_iter_ptr, (_val)) 98 | 99 | #define BCONE_UTF8(_val) BCONE_MAGIC, BCON_TYPE_UTF8, BCON_ENSURE_STORAGE (const_char_ptr_ptr, (_val)) 100 | #define BCONE_DOUBLE(_val) BCONE_MAGIC, BCON_TYPE_DOUBLE, BCON_ENSURE_STORAGE (double_ptr, (_val)) 101 | #define BCONE_DOCUMENT(_val) BCONE_MAGIC, BCON_TYPE_DOCUMENT, BCON_ENSURE_STORAGE (bson_ptr, (_val)) 102 | #define BCONE_ARRAY(_val) BCONE_MAGIC, BCON_TYPE_ARRAY, BCON_ENSURE_STORAGE (bson_ptr, (_val)) 103 | #define BCONE_BIN(subtype, binary, length) \ 104 | BCONE_MAGIC, BCON_TYPE_BIN, BCON_ENSURE_STORAGE (subtype_ptr, (subtype)), \ 105 | BCON_ENSURE_STORAGE (const_uint8_ptr_ptr, (binary)), BCON_ENSURE_STORAGE (uint32_ptr, (length)) 106 | #define BCONE_UNDEFINED BCONE_MAGIC, BCON_TYPE_UNDEFINED 107 | #define BCONE_OID(_val) BCONE_MAGIC, BCON_TYPE_OID, BCON_ENSURE_STORAGE (const_oid_ptr_ptr, (_val)) 108 | #define BCONE_BOOL(_val) BCONE_MAGIC, BCON_TYPE_BOOL, BCON_ENSURE_STORAGE (bool_ptr, (_val)) 109 | #define BCONE_DATE_TIME(_val) BCONE_MAGIC, BCON_TYPE_DATE_TIME, BCON_ENSURE_STORAGE (int64_ptr, (_val)) 110 | #define BCONE_NULL BCONE_MAGIC, BCON_TYPE_NULL 111 | #define BCONE_REGEX(_regex, _flags) \ 112 | BCONE_MAGIC, BCON_TYPE_REGEX, BCON_ENSURE_STORAGE (const_char_ptr_ptr, (_regex)), \ 113 | BCON_ENSURE_STORAGE (const_char_ptr_ptr, (_flags)) 114 | #define BCONE_DBPOINTER(_collection, _oid) \ 115 | BCONE_MAGIC, BCON_TYPE_DBPOINTER, BCON_ENSURE_STORAGE (const_char_ptr_ptr, (_collection)), \ 116 | BCON_ENSURE_STORAGE (const_oid_ptr_ptr, (_oid)) 117 | #define BCONE_CODE(_val) BCONE_MAGIC, BCON_TYPE_CODE, BCON_ENSURE_STORAGE (const_char_ptr_ptr, (_val)) 118 | #define BCONE_SYMBOL(_val) BCONE_MAGIC, BCON_TYPE_SYMBOL, BCON_ENSURE_STORAGE (const_char_ptr_ptr, (_val)) 119 | #define BCONE_CODEWSCOPE(_js, _scope) \ 120 | BCONE_MAGIC, BCON_TYPE_CODEWSCOPE, BCON_ENSURE_STORAGE (const_char_ptr_ptr, (_js)), \ 121 | BCON_ENSURE_STORAGE (bson_ptr, (_scope)) 122 | #define BCONE_INT32(_val) BCONE_MAGIC, BCON_TYPE_INT32, BCON_ENSURE_STORAGE (int32_ptr, (_val)) 123 | #define BCONE_TIMESTAMP(_timestamp, _increment) \ 124 | BCONE_MAGIC, BCON_TYPE_TIMESTAMP, BCON_ENSURE_STORAGE (int32_ptr, (_timestamp)), \ 125 | BCON_ENSURE_STORAGE (int32_ptr, (_increment)) 126 | #define BCONE_INT64(_val) BCONE_MAGIC, BCON_TYPE_INT64, BCON_ENSURE_STORAGE (int64_ptr, (_val)) 127 | #define BCONE_DECIMAL128(_val) BCONE_MAGIC, BCON_TYPE_DECIMAL128, BCON_ENSURE_STORAGE (const_decimal128_ptr, (_val)) 128 | #define BCONE_MAXKEY BCONE_MAGIC, BCON_TYPE_MAXKEY 129 | #define BCONE_MINKEY BCONE_MAGIC, BCON_TYPE_MINKEY 130 | #define BCONE_SKIP(_val) BCONE_MAGIC, BCON_TYPE_SKIP, BCON_ENSURE (bson_type, (_val)) 131 | #define BCONE_ITER(_val) BCONE_MAGIC, BCON_TYPE_ITER, BCON_ENSURE_STORAGE (bson_iter_ptr, (_val)) 132 | 133 | #define BCON_MAGIC bson_bcon_magic () 134 | #define BCONE_MAGIC bson_bcone_magic () 135 | 136 | typedef enum { 137 | BCON_TYPE_UTF8, 138 | BCON_TYPE_DOUBLE, 139 | BCON_TYPE_DOCUMENT, 140 | BCON_TYPE_ARRAY, 141 | BCON_TYPE_BIN, 142 | BCON_TYPE_UNDEFINED, 143 | BCON_TYPE_OID, 144 | BCON_TYPE_BOOL, 145 | BCON_TYPE_DATE_TIME, 146 | BCON_TYPE_NULL, 147 | BCON_TYPE_REGEX, 148 | BCON_TYPE_DBPOINTER, 149 | BCON_TYPE_CODE, 150 | BCON_TYPE_SYMBOL, 151 | BCON_TYPE_CODEWSCOPE, 152 | BCON_TYPE_INT32, 153 | BCON_TYPE_TIMESTAMP, 154 | BCON_TYPE_INT64, 155 | BCON_TYPE_DECIMAL128, 156 | BCON_TYPE_MAXKEY, 157 | BCON_TYPE_MINKEY, 158 | BCON_TYPE_BCON, 159 | BCON_TYPE_ARRAY_START, 160 | BCON_TYPE_ARRAY_END, 161 | BCON_TYPE_DOC_START, 162 | BCON_TYPE_DOC_END, 163 | BCON_TYPE_END, 164 | BCON_TYPE_RAW, 165 | BCON_TYPE_SKIP, 166 | BCON_TYPE_ITER, 167 | BCON_TYPE_ERROR, 168 | } bcon_type_t; 169 | 170 | typedef struct bcon_append_ctx_frame { 171 | int i; 172 | bool is_array; 173 | bson_t bson; 174 | } bcon_append_ctx_frame_t; 175 | 176 | typedef struct bcon_extract_ctx_frame { 177 | int i; 178 | bool is_array; 179 | bson_iter_t iter; 180 | } bcon_extract_ctx_frame_t; 181 | 182 | typedef struct _bcon_append_ctx_t { 183 | bcon_append_ctx_frame_t stack[BCON_STACK_MAX]; 184 | int n; 185 | } bcon_append_ctx_t; 186 | 187 | typedef struct _bcon_extract_ctx_t { 188 | bcon_extract_ctx_frame_t stack[BCON_STACK_MAX]; 189 | int n; 190 | } bcon_extract_ctx_t; 191 | 192 | BSON_EXPORT (void) 193 | bcon_append (bson_t *bson, ...) BSON_GNUC_NULL_TERMINATED; 194 | BSON_EXPORT (void) 195 | bcon_append_ctx (bson_t *bson, bcon_append_ctx_t *ctx, ...) BSON_GNUC_NULL_TERMINATED; 196 | BSON_EXPORT (void) 197 | bcon_append_ctx_va (bson_t *bson, bcon_append_ctx_t *ctx, va_list *va); 198 | BSON_EXPORT (void) 199 | bcon_append_ctx_init (bcon_append_ctx_t *ctx); 200 | 201 | BSON_EXPORT (void) 202 | bcon_extract_ctx_init (bcon_extract_ctx_t *ctx); 203 | 204 | BSON_EXPORT (void) 205 | bcon_extract_ctx (bson_t *bson, bcon_extract_ctx_t *ctx, ...) BSON_GNUC_NULL_TERMINATED; 206 | 207 | BSON_EXPORT (bool) 208 | bcon_extract_ctx_va (bson_t *bson, bcon_extract_ctx_t *ctx, va_list *ap); 209 | 210 | BSON_EXPORT (bool) 211 | bcon_extract (bson_t *bson, ...) BSON_GNUC_NULL_TERMINATED; 212 | 213 | BSON_EXPORT (bool) 214 | bcon_extract_va (bson_t *bson, bcon_extract_ctx_t *ctx, ...) BSON_GNUC_NULL_TERMINATED; 215 | 216 | BSON_EXPORT (bson_t *) 217 | bcon_new (void *unused, ...) BSON_GNUC_NULL_TERMINATED; 218 | 219 | /** 220 | * The bcon_..() functions are all declared with __attribute__((sentinel)). 221 | * 222 | * From GCC manual for "sentinel": "A valid NULL in this context is defined as 223 | * zero with any pointer type. If your system defines the NULL macro with an 224 | * integer type then you need to add an explicit cast." 225 | * Case in point: GCC on Solaris (at least) 226 | */ 227 | #define BCON_APPEND(_bson, ...) bcon_append ((_bson), __VA_ARGS__, (void *) NULL) 228 | #define BCON_APPEND_CTX(_bson, _ctx, ...) bcon_append_ctx ((_bson), (_ctx), __VA_ARGS__, (void *) NULL) 229 | 230 | #define BCON_EXTRACT(_bson, ...) bcon_extract ((_bson), __VA_ARGS__, (void *) NULL) 231 | 232 | #define BCON_EXTRACT_CTX(_bson, _ctx, ...) bcon_extract ((_bson), (_ctx), __VA_ARGS__, (void *) NULL) 233 | 234 | #define BCON_NEW(...) bcon_new (NULL, __VA_ARGS__, (void *) NULL) 235 | 236 | BSON_EXPORT (const char *) 237 | bson_bcon_magic (void) BSON_GNUC_PURE; 238 | BSON_EXPORT (const char *) 239 | bson_bcone_magic (void) BSON_GNUC_PURE; 240 | 241 | 242 | BSON_END_DECLS 243 | 244 | 245 | #endif 246 | -------------------------------------------------------------------------------- /bsonjs/bson/bson-atomic.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #include 19 | 20 | #ifdef BSON_OS_UNIX 21 | /* For sched_yield() */ 22 | #include 23 | #endif 24 | 25 | int32_t 26 | bson_atomic_int_add (volatile int32_t *p, int32_t n) 27 | { 28 | return n + bson_atomic_int32_fetch_add ((DECL_ATOMIC_INTEGRAL_INT32 *) p, n, bson_memory_order_seq_cst); 29 | } 30 | 31 | int64_t 32 | bson_atomic_int64_add (volatile int64_t *p, int64_t n) 33 | { 34 | return n + bson_atomic_int64_fetch_add (p, n, bson_memory_order_seq_cst); 35 | } 36 | 37 | void 38 | bson_thrd_yield (void) 39 | { 40 | BSON_IF_WINDOWS (SwitchToThread ();) 41 | BSON_IF_POSIX (sched_yield ();) 42 | } 43 | 44 | void 45 | bson_memory_barrier (void) 46 | { 47 | bson_atomic_thread_fence (); 48 | } 49 | 50 | /** 51 | * Some platforms do not support compiler intrinsics for atomic operations. 52 | * We emulate that here using a spin lock and regular arithmetic operations 53 | */ 54 | static int8_t gEmulAtomicLock = 0; 55 | 56 | static void 57 | _lock_emul_atomic (void) 58 | { 59 | int i; 60 | if (bson_atomic_int8_compare_exchange_weak (&gEmulAtomicLock, 0, 1, bson_memory_order_acquire) == 0) { 61 | /* Successfully took the spinlock */ 62 | return; 63 | } 64 | /* Failed. Try taking ten more times, then begin sleeping. */ 65 | for (i = 0; i < 10; ++i) { 66 | if (bson_atomic_int8_compare_exchange_weak (&gEmulAtomicLock, 0, 1, bson_memory_order_acquire) == 0) { 67 | /* Succeeded in taking the lock */ 68 | return; 69 | } 70 | } 71 | /* Still don't have the lock. Spin and yield */ 72 | while (bson_atomic_int8_compare_exchange_weak (&gEmulAtomicLock, 0, 1, bson_memory_order_acquire) != 0) { 73 | bson_thrd_yield (); 74 | } 75 | } 76 | 77 | static void 78 | _unlock_emul_atomic (void) 79 | { 80 | int64_t rv = bson_atomic_int8_exchange (&gEmulAtomicLock, 0, bson_memory_order_release); 81 | BSON_ASSERT (rv == 1 && "Released atomic lock while not holding it"); 82 | } 83 | 84 | int64_t 85 | _bson_emul_atomic_int64_fetch_add (volatile int64_t *p, int64_t n, enum bson_memory_order _unused) 86 | { 87 | int64_t ret; 88 | 89 | BSON_UNUSED (_unused); 90 | 91 | _lock_emul_atomic (); 92 | ret = *p; 93 | *p += n; 94 | _unlock_emul_atomic (); 95 | return ret; 96 | } 97 | 98 | int64_t 99 | _bson_emul_atomic_int64_exchange (volatile int64_t *p, int64_t n, enum bson_memory_order _unused) 100 | { 101 | int64_t ret; 102 | 103 | BSON_UNUSED (_unused); 104 | 105 | _lock_emul_atomic (); 106 | ret = *p; 107 | *p = n; 108 | _unlock_emul_atomic (); 109 | return ret; 110 | } 111 | 112 | int64_t 113 | _bson_emul_atomic_int64_compare_exchange_strong (volatile int64_t *p, 114 | int64_t expect_value, 115 | int64_t new_value, 116 | enum bson_memory_order _unused) 117 | { 118 | int64_t ret; 119 | 120 | BSON_UNUSED (_unused); 121 | 122 | _lock_emul_atomic (); 123 | ret = *p; 124 | if (ret == expect_value) { 125 | *p = new_value; 126 | } 127 | _unlock_emul_atomic (); 128 | return ret; 129 | } 130 | 131 | int64_t 132 | _bson_emul_atomic_int64_compare_exchange_weak (volatile int64_t *p, 133 | int64_t expect_value, 134 | int64_t new_value, 135 | enum bson_memory_order order) 136 | { 137 | /* We're emulating. We can't do a weak version. */ 138 | return _bson_emul_atomic_int64_compare_exchange_strong (p, expect_value, new_value, order); 139 | } 140 | 141 | 142 | int32_t 143 | _bson_emul_atomic_int32_fetch_add (volatile int32_t *p, int32_t n, enum bson_memory_order _unused) 144 | { 145 | int32_t ret; 146 | 147 | BSON_UNUSED (_unused); 148 | 149 | _lock_emul_atomic (); 150 | ret = *p; 151 | *p += n; 152 | _unlock_emul_atomic (); 153 | return ret; 154 | } 155 | 156 | int32_t 157 | _bson_emul_atomic_int32_exchange (volatile int32_t *p, int32_t n, enum bson_memory_order _unused) 158 | { 159 | int32_t ret; 160 | 161 | BSON_UNUSED (_unused); 162 | 163 | _lock_emul_atomic (); 164 | ret = *p; 165 | *p = n; 166 | _unlock_emul_atomic (); 167 | return ret; 168 | } 169 | 170 | int32_t 171 | _bson_emul_atomic_int32_compare_exchange_strong (volatile int32_t *p, 172 | int32_t expect_value, 173 | int32_t new_value, 174 | enum bson_memory_order _unused) 175 | { 176 | int32_t ret; 177 | 178 | BSON_UNUSED (_unused); 179 | 180 | _lock_emul_atomic (); 181 | ret = *p; 182 | if (ret == expect_value) { 183 | *p = new_value; 184 | } 185 | _unlock_emul_atomic (); 186 | return ret; 187 | } 188 | 189 | int32_t 190 | _bson_emul_atomic_int32_compare_exchange_weak (volatile int32_t *p, 191 | int32_t expect_value, 192 | int32_t new_value, 193 | enum bson_memory_order order) 194 | { 195 | /* We're emulating. We can't do a weak version. */ 196 | return _bson_emul_atomic_int32_compare_exchange_strong (p, expect_value, new_value, order); 197 | } 198 | 199 | 200 | int 201 | _bson_emul_atomic_int_fetch_add (volatile int *p, int n, enum bson_memory_order _unused) 202 | { 203 | int ret; 204 | 205 | BSON_UNUSED (_unused); 206 | 207 | _lock_emul_atomic (); 208 | ret = *p; 209 | *p += n; 210 | _unlock_emul_atomic (); 211 | return ret; 212 | } 213 | 214 | int 215 | _bson_emul_atomic_int_exchange (volatile int *p, int n, enum bson_memory_order _unused) 216 | { 217 | int ret; 218 | 219 | BSON_UNUSED (_unused); 220 | 221 | _lock_emul_atomic (); 222 | ret = *p; 223 | *p = n; 224 | _unlock_emul_atomic (); 225 | return ret; 226 | } 227 | 228 | int 229 | _bson_emul_atomic_int_compare_exchange_strong (volatile int *p, 230 | int expect_value, 231 | int new_value, 232 | enum bson_memory_order _unused) 233 | { 234 | int ret; 235 | 236 | BSON_UNUSED (_unused); 237 | 238 | _lock_emul_atomic (); 239 | ret = *p; 240 | if (ret == expect_value) { 241 | *p = new_value; 242 | } 243 | _unlock_emul_atomic (); 244 | return ret; 245 | } 246 | 247 | int 248 | _bson_emul_atomic_int_compare_exchange_weak (volatile int *p, 249 | int expect_value, 250 | int new_value, 251 | enum bson_memory_order order) 252 | { 253 | /* We're emulating. We can't do a weak version. */ 254 | return _bson_emul_atomic_int_compare_exchange_strong (p, expect_value, new_value, order); 255 | } 256 | 257 | void * 258 | _bson_emul_atomic_ptr_exchange (void *volatile *p, void *n, enum bson_memory_order _unused) 259 | { 260 | void *ret; 261 | 262 | BSON_UNUSED (_unused); 263 | 264 | _lock_emul_atomic (); 265 | ret = *p; 266 | *p = n; 267 | _unlock_emul_atomic (); 268 | return ret; 269 | } 270 | -------------------------------------------------------------------------------- /bsonjs/bson/bson-clock.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | 21 | #if defined(BSON_HAVE_CLOCK_GETTIME) 22 | #include 23 | #include 24 | #endif 25 | 26 | #include 27 | 28 | /* 29 | *-------------------------------------------------------------------------- 30 | * 31 | * bson_gettimeofday -- 32 | * 33 | * A wrapper around gettimeofday() with fallback support for Windows. 34 | * 35 | * Returns: 36 | * 0 if successful. 37 | * 38 | * Side effects: 39 | * @tv is set. 40 | * 41 | *-------------------------------------------------------------------------- 42 | */ 43 | 44 | int 45 | bson_gettimeofday (struct timeval *tv) /* OUT */ 46 | { 47 | #if defined(_WIN32) 48 | #if defined(_MSC_VER) 49 | #define DELTA_EPOCH_IN_MICROSEC 11644473600000000Ui64 50 | #else 51 | #define DELTA_EPOCH_IN_MICROSEC 11644473600000000ULL 52 | #endif 53 | FILETIME ft; 54 | uint64_t tmp = 0; 55 | 56 | /* 57 | * The const value is shamelessly stolen from 58 | * http://www.boost.org/doc/libs/1_55_0/boost/chrono/detail/inlined/win/chrono.hpp 59 | * 60 | * File times are the number of 100 nanosecond intervals elapsed since 61 | * 12:00 am Jan 1, 1601 UTC. I haven't check the math particularly hard 62 | * 63 | * ... good luck 64 | */ 65 | 66 | if (tv) { 67 | GetSystemTimeAsFileTime (&ft); 68 | 69 | /* pull out of the filetime into a 64 bit uint */ 70 | tmp |= ft.dwHighDateTime; 71 | tmp <<= 32; 72 | tmp |= ft.dwLowDateTime; 73 | 74 | /* convert from 100's of nanosecs to microsecs */ 75 | tmp /= 10; 76 | 77 | /* adjust to unix epoch */ 78 | tmp -= DELTA_EPOCH_IN_MICROSEC; 79 | 80 | tv->tv_sec = (long) (tmp / 1000000UL); 81 | tv->tv_usec = (long) (tmp % 1000000UL); 82 | } 83 | 84 | return 0; 85 | #else 86 | return gettimeofday (tv, NULL); 87 | #endif 88 | } 89 | 90 | 91 | /* 92 | *-------------------------------------------------------------------------- 93 | * 94 | * bson_get_monotonic_time -- 95 | * 96 | * Returns the monotonic system time, if available. A best effort is 97 | * made to use the monotonic clock. However, some systems may not 98 | * support such a feature. 99 | * 100 | * Returns: 101 | * The monotonic clock in microseconds. 102 | * 103 | * Side effects: 104 | * None. 105 | * 106 | *-------------------------------------------------------------------------- 107 | */ 108 | 109 | int64_t 110 | bson_get_monotonic_time (void) 111 | { 112 | #if defined(BSON_HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) 113 | struct timespec ts; 114 | /* ts.tv_sec may be a four-byte integer on 32 bit machines, so cast to 115 | * int64_t to avoid truncation. */ 116 | clock_gettime (CLOCK_MONOTONIC, &ts); 117 | return (((int64_t) ts.tv_sec * 1000000) + (ts.tv_nsec / 1000)); 118 | #elif defined(_WIN32) 119 | /* Despite it's name, this is in milliseconds! */ 120 | int64_t ticks = GetTickCount64 (); 121 | return (ticks * 1000); 122 | #elif defined(__hpux__) 123 | int64_t nanosec = gethrtime (); 124 | return (nanosec / 1000UL); 125 | #else 126 | #pragma message "Monotonic clock is not yet supported on your platform." 127 | struct timeval tv; 128 | 129 | bson_gettimeofday (&tv); 130 | return ((int64_t) tv.tv_sec * 1000000) + tv.tv_usec; 131 | #endif 132 | } 133 | -------------------------------------------------------------------------------- /bsonjs/bson/bson-clock.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | 20 | #ifndef BSON_CLOCK_H 21 | #define BSON_CLOCK_H 22 | 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | 29 | BSON_BEGIN_DECLS 30 | 31 | 32 | BSON_EXPORT (int64_t) 33 | bson_get_monotonic_time (void); 34 | BSON_EXPORT (int) 35 | bson_gettimeofday (struct timeval *tv); 36 | 37 | 38 | BSON_END_DECLS 39 | 40 | 41 | #endif /* BSON_CLOCK_H */ 42 | -------------------------------------------------------------------------------- /bsonjs/bson/bson-cmp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | 20 | #ifndef BSON_CMP_H 21 | #define BSON_CMP_H 22 | 23 | 24 | #include /* ssize_t */ 25 | #include /* BSON_CONCAT */ 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | 32 | BSON_BEGIN_DECLS 33 | 34 | 35 | /* Based on the "Safe Integral Comparisons" proposal merged in C++20: 36 | * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p0586r2.html 37 | * 38 | * Due to lack of type deduction in C, relational comparison functions (e.g. 39 | * `cmp_less`) are defined in sets of four "functions" according to the 40 | * signedness of each value argument, e.g.: 41 | * - bson_cmp_less_ss (signed-value, signed-value) 42 | * - bson_cmp_less_uu (unsigned-value, unsigned-value) 43 | * - bson_cmp_less_su (signed-value, unsigned-value) 44 | * - bson_cmp_less_us (unsigned-value, signed-value) 45 | * 46 | * Similarly, the `in_range` function is defined as a set of two "functions" 47 | * according to the signedness of the value argument: 48 | * - bson_in_range_signed (Type, signed-value) 49 | * - bson_in_range_unsigned (Type, unsigned-value) 50 | * 51 | * The user must take care to use the correct signedness for the provided 52 | * argument(s). Enabling compiler warnings for implicit sign conversions is 53 | * recommended. 54 | */ 55 | 56 | 57 | #define BSON_CMP_SET(op, ss, uu, su, us) \ 58 | static BSON_INLINE bool BSON_CONCAT3 (bson_cmp_, op, _ss) (int64_t t, int64_t u) \ 59 | { \ 60 | return (ss); \ 61 | } \ 62 | \ 63 | static BSON_INLINE bool BSON_CONCAT3 (bson_cmp_, op, _uu) (uint64_t t, uint64_t u) \ 64 | { \ 65 | return (uu); \ 66 | } \ 67 | \ 68 | static BSON_INLINE bool BSON_CONCAT3 (bson_cmp_, op, _su) (int64_t t, uint64_t u) \ 69 | { \ 70 | return (su); \ 71 | } \ 72 | \ 73 | static BSON_INLINE bool BSON_CONCAT3 (bson_cmp_, op, _us) (uint64_t t, int64_t u) \ 74 | { \ 75 | return (us); \ 76 | } 77 | 78 | BSON_CMP_SET (equal, t == u, t == u, t < 0 ? false : (uint64_t) (t) == u, u < 0 ? false : t == (uint64_t) (u)) 79 | 80 | BSON_CMP_SET (not_equal, 81 | !bson_cmp_equal_ss (t, u), 82 | !bson_cmp_equal_uu (t, u), 83 | !bson_cmp_equal_su (t, u), 84 | !bson_cmp_equal_us (t, u)) 85 | 86 | BSON_CMP_SET (less, t < u, t < u, t < 0 ? true : (uint64_t) (t) < u, u < 0 ? false : t < (uint64_t) (u)) 87 | 88 | BSON_CMP_SET ( 89 | greater, bson_cmp_less_ss (u, t), bson_cmp_less_uu (u, t), bson_cmp_less_us (u, t), bson_cmp_less_su (u, t)) 90 | 91 | BSON_CMP_SET (less_equal, 92 | !bson_cmp_greater_ss (t, u), 93 | !bson_cmp_greater_uu (t, u), 94 | !bson_cmp_greater_su (t, u), 95 | !bson_cmp_greater_us (t, u)) 96 | 97 | BSON_CMP_SET (greater_equal, 98 | !bson_cmp_less_ss (t, u), 99 | !bson_cmp_less_uu (t, u), 100 | !bson_cmp_less_su (t, u), 101 | !bson_cmp_less_us (t, u)) 102 | 103 | #undef BSON_CMP_SET 104 | 105 | 106 | /* Return true if the given value is within the range of the corresponding 107 | * signed type. The suffix must match the signedness of the given value. */ 108 | #define BSON_IN_RANGE_SET_SIGNED(Type, min, max) \ 109 | static BSON_INLINE bool BSON_CONCAT3 (bson_in_range, _##Type, _signed) (int64_t value) \ 110 | { \ 111 | return bson_cmp_greater_equal_ss (value, min) && bson_cmp_less_equal_ss (value, max); \ 112 | } \ 113 | \ 114 | static BSON_INLINE bool BSON_CONCAT3 (bson_in_range, _##Type, _unsigned) (uint64_t value) \ 115 | { \ 116 | return bson_cmp_greater_equal_us (value, min) && bson_cmp_less_equal_us (value, max); \ 117 | } 118 | 119 | /* Return true if the given value is within the range of the corresponding 120 | * unsigned type. The suffix must match the signedness of the given value. */ 121 | #define BSON_IN_RANGE_SET_UNSIGNED(Type, max) \ 122 | static BSON_INLINE bool BSON_CONCAT3 (bson_in_range, _##Type, _signed) (int64_t value) \ 123 | { \ 124 | return bson_cmp_greater_equal_su (value, 0u) && bson_cmp_less_equal_su (value, max); \ 125 | } \ 126 | \ 127 | static BSON_INLINE bool BSON_CONCAT3 (bson_in_range, _##Type, _unsigned) (uint64_t value) \ 128 | { \ 129 | return bson_cmp_less_equal_uu (value, max); \ 130 | } 131 | 132 | BSON_IN_RANGE_SET_SIGNED (signed_char, SCHAR_MIN, SCHAR_MAX) 133 | BSON_IN_RANGE_SET_SIGNED (short, SHRT_MIN, SHRT_MAX) 134 | BSON_IN_RANGE_SET_SIGNED (int, INT_MIN, INT_MAX) 135 | BSON_IN_RANGE_SET_SIGNED (long, LONG_MIN, LONG_MAX) 136 | BSON_IN_RANGE_SET_SIGNED (long_long, LLONG_MIN, LLONG_MAX) 137 | 138 | BSON_IN_RANGE_SET_UNSIGNED (unsigned_char, UCHAR_MAX) 139 | BSON_IN_RANGE_SET_UNSIGNED (unsigned_short, USHRT_MAX) 140 | BSON_IN_RANGE_SET_UNSIGNED (unsigned_int, UINT_MAX) 141 | BSON_IN_RANGE_SET_UNSIGNED (unsigned_long, ULONG_MAX) 142 | BSON_IN_RANGE_SET_UNSIGNED (unsigned_long_long, ULLONG_MAX) 143 | 144 | BSON_IN_RANGE_SET_SIGNED (int8_t, INT8_MIN, INT8_MAX) 145 | BSON_IN_RANGE_SET_SIGNED (int16_t, INT16_MIN, INT16_MAX) 146 | BSON_IN_RANGE_SET_SIGNED (int32_t, INT32_MIN, INT32_MAX) 147 | BSON_IN_RANGE_SET_SIGNED (int64_t, INT64_MIN, INT64_MAX) 148 | 149 | BSON_IN_RANGE_SET_UNSIGNED (uint8_t, UINT8_MAX) 150 | BSON_IN_RANGE_SET_UNSIGNED (uint16_t, UINT16_MAX) 151 | BSON_IN_RANGE_SET_UNSIGNED (uint32_t, UINT32_MAX) 152 | BSON_IN_RANGE_SET_UNSIGNED (uint64_t, UINT64_MAX) 153 | 154 | BSON_IN_RANGE_SET_SIGNED (ssize_t, SSIZE_MIN, SSIZE_MAX) 155 | BSON_IN_RANGE_SET_UNSIGNED (size_t, SIZE_MAX) 156 | 157 | #undef BSON_IN_RANGE_SET_SIGNED 158 | #undef BSON_IN_RANGE_SET_UNSIGNED 159 | 160 | 161 | /* Return true if the value with *signed* type is in the representable range of 162 | * Type and false otherwise. */ 163 | #define bson_in_range_signed(Type, value) BSON_CONCAT3 (bson_in_range, _##Type, _signed) (value) 164 | 165 | /* Return true if the value with *unsigned* type is in the representable range 166 | * of Type and false otherwise. */ 167 | #define bson_in_range_unsigned(Type, value) BSON_CONCAT3 (bson_in_range, _##Type, _unsigned) (value) 168 | 169 | 170 | BSON_END_DECLS 171 | 172 | 173 | #endif /* BSON_CMP_H */ 174 | -------------------------------------------------------------------------------- /bsonjs/bson/bson-compat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | 20 | #ifndef BSON_COMPAT_H 21 | #define BSON_COMPAT_H 22 | 23 | 24 | #if defined(__MINGW32__) 25 | #if defined(__USE_MINGW_ANSI_STDIO) 26 | #if __USE_MINGW_ANSI_STDIO < 1 27 | #error "__USE_MINGW_ANSI_STDIO > 0 is required for correct PRI* macros" 28 | #endif 29 | #else 30 | #define __USE_MINGW_ANSI_STDIO 1 31 | #endif 32 | #endif 33 | 34 | #include 35 | #include 36 | 37 | 38 | #ifdef BSON_OS_WIN32 39 | #if defined(_WIN32_WINNT) && (_WIN32_WINNT < 0x0600) 40 | #undef _WIN32_WINNT 41 | #endif 42 | #ifndef _WIN32_WINNT 43 | #define _WIN32_WINNT 0x0600 44 | #endif 45 | #ifndef NOMINMAX 46 | #define NOMINMAX 47 | #endif 48 | #include 49 | #ifndef WIN32_LEAN_AND_MEAN 50 | #define WIN32_LEAN_AND_MEAN 51 | #include 52 | #undef WIN32_LEAN_AND_MEAN 53 | #else 54 | #include 55 | #endif 56 | #include 57 | #include 58 | #endif 59 | 60 | 61 | #ifdef BSON_OS_UNIX 62 | #include 63 | #include 64 | #endif 65 | 66 | 67 | #include 68 | 69 | 70 | #include 71 | #include 72 | #include 73 | #include 74 | #include 75 | #include 76 | #include 77 | #include 78 | #include 79 | #include 80 | #include 81 | 82 | 83 | BSON_BEGIN_DECLS 84 | 85 | #if !defined(_MSC_VER) || (_MSC_VER >= 1800) 86 | #include 87 | #endif 88 | #ifdef _MSC_VER 89 | #ifndef __cplusplus 90 | /* benign redefinition of type */ 91 | #pragma warning(disable : 4142) 92 | #ifndef _SSIZE_T_DEFINED 93 | #define _SSIZE_T_DEFINED 94 | typedef SSIZE_T ssize_t; 95 | #endif 96 | #ifndef _SIZE_T_DEFINED 97 | #define _SIZE_T_DEFINED 98 | typedef SIZE_T size_t; 99 | #endif 100 | #pragma warning(default : 4142) 101 | #else 102 | /* 103 | * MSVC++ does not include ssize_t, just size_t. 104 | * So we need to synthesize that as well. 105 | */ 106 | #pragma warning(disable : 4142) 107 | #ifndef _SSIZE_T_DEFINED 108 | #define _SSIZE_T_DEFINED 109 | typedef SSIZE_T ssize_t; 110 | #endif 111 | #pragma warning(default : 4142) 112 | #endif 113 | #ifndef PRIi32 114 | #define PRIi32 "d" 115 | #endif 116 | #ifndef PRId32 117 | #define PRId32 "d" 118 | #endif 119 | #ifndef PRIu32 120 | #define PRIu32 "u" 121 | #endif 122 | #ifndef PRIi64 123 | #define PRIi64 "I64i" 124 | #endif 125 | #ifndef PRId64 126 | #define PRId64 "I64i" 127 | #endif 128 | #ifndef PRIu64 129 | #define PRIu64 "I64u" 130 | #endif 131 | #endif 132 | 133 | /* Derive the maximum representable value of signed integer type T using the 134 | * formula 2^(N - 1) - 1 where N is the number of bits in type T. This assumes 135 | * T is represented using two's complement. */ 136 | #define BSON_NUMERIC_LIMITS_MAX_SIGNED(T) ((T) ((((size_t) 0x01u) << (sizeof (T) * (size_t) CHAR_BIT - 1u)) - 1u)) 137 | 138 | /* Derive the minimum representable value of signed integer type T as one less 139 | * than the negation of its maximum representable value. This assumes T is 140 | * represented using two's complement. */ 141 | #define BSON_NUMERIC_LIMITS_MIN_SIGNED(T, max) ((T) ((-(max)) - 1)) 142 | 143 | /* Derive the maximum representable value of unsigned integer type T by flipping 144 | * all its bits to 1. */ 145 | #define BSON_NUMERIC_LIMITS_MAX_UNSIGNED(T) ((T) (~((T) 0))) 146 | 147 | #ifndef SSIZE_MAX 148 | #define SSIZE_MAX BSON_NUMERIC_LIMITS_MAX_SIGNED (ssize_t) 149 | #endif 150 | 151 | #ifndef SSIZE_MIN 152 | #define SSIZE_MIN BSON_NUMERIC_LIMITS_MIN_SIGNED (ssize_t, SSIZE_MAX) 153 | #endif 154 | 155 | #if defined(__MINGW32__) && !defined(INIT_ONCE_STATIC_INIT) 156 | #define INIT_ONCE_STATIC_INIT RTL_RUN_ONCE_INIT 157 | typedef RTL_RUN_ONCE INIT_ONCE; 158 | #endif 159 | 160 | #ifdef BSON_HAVE_STDBOOL_H 161 | #include 162 | #elif !defined(__bool_true_false_are_defined) 163 | #ifndef __cplusplus 164 | typedef signed char bool; 165 | #define false 0 166 | #define true 1 167 | #endif 168 | #define __bool_true_false_are_defined 1 169 | #endif 170 | 171 | 172 | #if defined(__GNUC__) 173 | #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) 174 | #define bson_sync_synchronize() __sync_synchronize () 175 | #elif defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) || defined(__x86_64__) 176 | #define bson_sync_synchronize() asm volatile ("mfence" ::: "memory") 177 | #else 178 | #define bson_sync_synchronize() asm volatile ("sync" ::: "memory") 179 | #endif 180 | #elif defined(_MSC_VER) 181 | #define bson_sync_synchronize() MemoryBarrier () 182 | #endif 183 | 184 | 185 | #if !defined(va_copy) && defined(__va_copy) 186 | #define va_copy(dst, src) __va_copy (dst, src) 187 | #endif 188 | 189 | 190 | #if !defined(va_copy) 191 | #define va_copy(dst, src) ((dst) = (src)) 192 | #endif 193 | 194 | 195 | #ifdef _MSC_VER 196 | /** Expands the arguments if compiling with MSVC, otherwise empty */ 197 | #define BSON_IF_MSVC(...) __VA_ARGS__ 198 | /** Expands the arguments if compiling with GCC or Clang, otherwise empty */ 199 | #define BSON_IF_GNU_LIKE(...) 200 | #elif defined(__GNUC__) || defined(__clang__) 201 | /** Expands the arguments if compiling with MSVC, otherwise empty */ 202 | #define BSON_IF_MSVC(...) 203 | /** Expands the arguments if compiling with GCC or Clang, otherwise empty */ 204 | #define BSON_IF_GNU_LIKE(...) __VA_ARGS__ 205 | #endif 206 | 207 | #ifdef BSON_OS_WIN32 208 | /** Expands the arguments if compiling for Windows, otherwise empty */ 209 | #define BSON_IF_WINDOWS(...) __VA_ARGS__ 210 | /** Expands the arguments if compiling for POSIX, otherwise empty */ 211 | #define BSON_IF_POSIX(...) 212 | #elif defined(BSON_OS_UNIX) 213 | /** Expands the arguments if compiling for Windows, otherwise empty */ 214 | #define BSON_IF_WINDOWS(...) 215 | /** Expands the arguments if compiling for POSIX, otherwise empty */ 216 | #define BSON_IF_POSIX(...) __VA_ARGS__ 217 | #endif 218 | 219 | 220 | BSON_END_DECLS 221 | 222 | 223 | #endif /* BSON_COMPAT_H */ 224 | -------------------------------------------------------------------------------- /bsonjs/bson/bson-config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-present MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #if !defined(BSON_INSIDE) && !defined(BSON_COMPILATION) 18 | #error "Only can be included directly." 19 | #endif 20 | 21 | #ifndef BSON_CONFIG_H 22 | #define BSON_CONFIG_H 23 | 24 | #define PY_SSIZE_T_CLEAN /* Make "s#" use Py_ssize_t rather than int. */ 25 | 26 | /* 27 | * Rely on CPython to make libbson portable 28 | */ 29 | #include 30 | 31 | 32 | /* 33 | * Define to 1234 for Little Endian, 4321 for Big Endian. 34 | */ 35 | #ifdef WORDS_BIGENDIAN 36 | # define BSON_BYTE_ORDER 4321 37 | #else 38 | # define BSON_BYTE_ORDER 1234 39 | #endif 40 | 41 | 42 | /* 43 | * Define to 1 if you have stdbool.h 44 | */ 45 | #define BSON_HAVE_STDBOOL_H 1 46 | #if BSON_HAVE_STDBOOL_H != 1 47 | # undef BSON_HAVE_STDBOOL_H 48 | #endif 49 | 50 | 51 | /* 52 | * Define to 1 for POSIX-like systems, 2 for Windows. 53 | */ 54 | #ifdef MS_WINDOWS 55 | # define BSON_OS 2 56 | #else 57 | # define BSON_OS 1 58 | #endif 59 | 60 | 61 | /* 62 | * Define to 1 if you have clock_gettime() available. 63 | */ 64 | #ifdef HAVE_CLOCK_GETTIME 65 | # define BSON_HAVE_CLOCK_GETTIME 1 66 | #endif 67 | 68 | #if BSON_HAVE_CLOCK_GETTIME != 1 69 | # undef BSON_HAVE_CLOCK_GETTIME 70 | #endif 71 | 72 | 73 | /* 74 | * Define to 1 if you have strings.h available on your platform. 75 | */ 76 | #define BSON_HAVE_STRINGS_H 0 77 | #if BSON_HAVE_STRINGS_H != 1 78 | # undef BSON_HAVE_STRINGS_H 79 | #endif 80 | 81 | 82 | /* 83 | * Define to 1 if you have strnlen available on your platform. 84 | */ 85 | #define BSON_HAVE_STRNLEN 0 86 | #if BSON_HAVE_STRNLEN != 1 87 | # undef BSON_HAVE_STRNLEN 88 | #endif 89 | 90 | 91 | /* 92 | * Define to 1 if you have snprintf available on your platform. 93 | */ 94 | #ifdef MS_WINDOWS 95 | # define BSON_HAVE_SNPRINTF 0 96 | #else 97 | # define BSON_HAVE_SNPRINTF 1 98 | #endif 99 | 100 | #if BSON_HAVE_SNPRINTF != 1 101 | # undef BSON_HAVE_SNPRINTF 102 | #endif 103 | 104 | 105 | /* 106 | * Define to 1 if you have gmtime_r available on your platform. 107 | */ 108 | #ifdef MS_WINDOWS 109 | # define BSON_HAVE_GMTIME_R 0 110 | #else 111 | # define BSON_HAVE_GMTIME_R 1 112 | #endif 113 | 114 | #if BSON_HAVE_GMTIME_R != 1 115 | # undef BSON_HAVE_GMTIME_R 116 | #endif 117 | 118 | 119 | /* 120 | * Define to 1 if you have struct timespec available on your platform. 121 | */ 122 | #ifdef HAVE_CLOCK_GETTIME 123 | # define BSON_HAVE_TIMESPEC 1 124 | #endif 125 | 126 | #if BSON_HAVE_TIMESPEC != 1 127 | # undef BSON_HAVE_TIMESPEC 128 | #endif 129 | 130 | 131 | /* 132 | * Define to 1 if you want extra aligned types in libbson 133 | */ 134 | #define BSON_EXTRA_ALIGN 1 135 | #if BSON_EXTRA_ALIGN != 1 136 | # undef BSON_EXTRA_ALIGN 137 | #endif 138 | 139 | 140 | /* 141 | * Define to 1 if you have SYS_gettid syscall 142 | */ 143 | #define BSON_HAVE_SYSCALL_TID 0 144 | #if BSON_HAVE_SYSCALL_TID != 1 145 | # undef BSON_HAVE_SYSCALL_TID 146 | #endif 147 | 148 | 149 | #ifdef MS_WINDOWS 150 | # define BSON_HAVE_RAND_R 0 151 | #else 152 | # define BSON_HAVE_RAND_R 1 153 | #endif 154 | #if BSON_HAVE_RAND_R != 1 155 | # undef BSON_HAVE_RAND_R 156 | #endif 157 | 158 | 159 | #define BSON_HAVE_STRLCPY 0 160 | #if BSON_HAVE_STRLCPY != 1 161 | # undef BSON_HAVE_STRLCPY 162 | #endif 163 | 164 | #endif /* BSON_CONFIG_H */ 165 | -------------------------------------------------------------------------------- /bsonjs/bson/bson-context-private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | 20 | #ifndef BSON_CONTEXT_PRIVATE_H 21 | #define BSON_CONTEXT_PRIVATE_H 22 | 23 | 24 | #include 25 | #include "common-thread-private.h" 26 | 27 | 28 | BSON_BEGIN_DECLS 29 | 30 | 31 | enum { 32 | BSON_OID_RANDOMESS_OFFSET = 4, 33 | BSON_OID_RANDOMNESS_SIZE = 5, 34 | BSON_OID_SEQ32_OFFSET = 9, 35 | BSON_OID_SEQ32_SIZE = 3, 36 | BSON_OID_SEQ64_OFFSET = 4, 37 | BSON_OID_SEQ64_SIZE = 8 38 | }; 39 | 40 | struct _bson_context_t { 41 | /* flags are defined in bson_context_flags_t */ 42 | int flags; 43 | uint32_t seq32; 44 | uint64_t seq64; 45 | uint8_t randomness[BSON_OID_RANDOMNESS_SIZE]; 46 | uint64_t pid; 47 | }; 48 | 49 | /** 50 | * @brief Insert the context's randomness data into the given OID 51 | * 52 | * @param context A context for some random data 53 | * @param oid The OID to update. 54 | */ 55 | void 56 | _bson_context_set_oid_rand (bson_context_t *context, bson_oid_t *oid); 57 | 58 | /** 59 | * @brief Insert the context's sequence counter into the given OID. Increments 60 | * the context's sequence counter. 61 | * 62 | * @param context The context with the counter to get+update 63 | * @param oid The OID to modify 64 | */ 65 | void 66 | _bson_context_set_oid_seq32 (bson_context_t *context, bson_oid_t *oid); 67 | 68 | /** 69 | * @brief Write a 64-bit counter from the given context into the OID. Increments 70 | * the context's sequence counter. 71 | * 72 | * @param context The context with the counter to get+update 73 | * @param oid The OID to modify 74 | * 75 | * @note Only used by the deprecated @ref bson_oid_init_sequence 76 | */ 77 | void 78 | _bson_context_set_oid_seq64 (bson_context_t *context, bson_oid_t *oid); 79 | 80 | 81 | BSON_END_DECLS 82 | 83 | 84 | #endif /* BSON_CONTEXT_PRIVATE_H */ 85 | -------------------------------------------------------------------------------- /bsonjs/bson/bson-context.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include "common-thread-private.h" 31 | 32 | 33 | #ifndef HOST_NAME_MAX 34 | #define HOST_NAME_MAX 256 35 | #endif 36 | 37 | 38 | /* 39 | * Globals. 40 | */ 41 | static bson_context_t gContextDefault; 42 | 43 | static BSON_INLINE uint64_t 44 | _bson_getpid (void) 45 | { 46 | uint64_t pid; 47 | #ifdef BSON_OS_WIN32 48 | DWORD real_pid; 49 | 50 | real_pid = GetCurrentProcessId (); 51 | pid = (real_pid & 0xFFFF) ^ ((real_pid >> 16) & 0xFFFF); 52 | #else 53 | pid = (uint64_t) getpid (); 54 | #endif 55 | 56 | return pid; 57 | } 58 | 59 | 60 | void 61 | _bson_context_set_oid_seq32 (bson_context_t *context, /* IN */ 62 | bson_oid_t *oid) /* OUT */ 63 | { 64 | uint32_t seq = (uint32_t) bson_atomic_int32_fetch_add ( 65 | (DECL_ATOMIC_INTEGRAL_INT32 *) &context->seq32, 1, bson_memory_order_seq_cst); 66 | seq = BSON_UINT32_TO_BE (seq); 67 | memcpy (&oid->bytes[BSON_OID_SEQ32_OFFSET], ((uint8_t *) &seq) + 1, BSON_OID_SEQ32_SIZE); 68 | } 69 | 70 | 71 | void 72 | _bson_context_set_oid_seq64 (bson_context_t *context, /* IN */ 73 | bson_oid_t *oid) /* OUT */ 74 | { 75 | uint64_t seq = (uint64_t) bson_atomic_int64_fetch_add ((int64_t *) &context->seq64, 1, bson_memory_order_seq_cst); 76 | 77 | seq = BSON_UINT64_TO_BE (seq); 78 | memcpy (&oid->bytes[BSON_OID_SEQ64_OFFSET], &seq, BSON_OID_SEQ64_SIZE); 79 | } 80 | 81 | /* 82 | * -------------------------------------------------------------------------- 83 | * 84 | * _bson_context_get_hostname 85 | * 86 | * Gets the hostname of the machine, logs a warning on failure. "out" 87 | * must be an array of HOST_NAME_MAX bytes. 88 | * 89 | * -------------------------------------------------------------------------- 90 | */ 91 | static void 92 | _bson_context_get_hostname (char out[HOST_NAME_MAX]) 93 | { 94 | if (gethostname (out, HOST_NAME_MAX) != 0) { 95 | if (errno == ENAMETOOLONG) { 96 | fprintf (stderr, "hostname exceeds %d characters, truncating.", HOST_NAME_MAX); 97 | } else { 98 | fprintf (stderr, "unable to get hostname: %d", errno); 99 | } 100 | } 101 | out[HOST_NAME_MAX - 1] = '\0'; 102 | } 103 | 104 | 105 | /*** ======================================== 106 | * The below SipHash implementation is based on the original public-domain 107 | * reference implementation from Jean-Philippe Aumasson and DJB 108 | * (https://github.com/veorq/SipHash). 109 | */ 110 | 111 | /* in-place rotate a 64bit number */ 112 | void 113 | _bson_rotl_u64 (uint64_t *p, int nbits) 114 | { 115 | *p = (*p << nbits) | (*p >> (64 - nbits)); 116 | } 117 | 118 | /* Write the little-endian representation of 'val' into 'out' */ 119 | void 120 | _u64_into_u8x8_le (uint8_t out[8], uint64_t val) 121 | { 122 | val = BSON_UINT64_TO_LE (val); 123 | memcpy (out, &val, sizeof val); 124 | } 125 | 126 | /* Read a little-endian representation of a 64bit number from 'in' */ 127 | uint64_t 128 | _u8x8_le_to_u64 (const uint8_t in[8]) 129 | { 130 | uint64_t r; 131 | memcpy (&r, in, sizeof r); 132 | return BSON_UINT64_FROM_LE (r); 133 | } 134 | 135 | /* Perform one SipHash round */ 136 | void 137 | _sip_round (uint64_t *v0, uint64_t *v1, uint64_t *v2, uint64_t *v3) 138 | { 139 | *v0 += *v1; 140 | _bson_rotl_u64 (v1, 13); 141 | *v1 ^= *v0; 142 | _bson_rotl_u64 (v0, 32); 143 | *v2 += *v3; 144 | _bson_rotl_u64 (v3, 16); 145 | *v3 ^= *v2; 146 | *v0 += *v3; 147 | _bson_rotl_u64 (v3, 21); 148 | *v3 ^= *v0; 149 | *v2 += *v1; 150 | _bson_rotl_u64 (v1, 17); 151 | *v1 ^= *v2; 152 | _bson_rotl_u64 (v2, 32); 153 | } 154 | 155 | void 156 | _siphash (const void *in, const size_t inlen, const uint64_t key[2], uint64_t digest[2]) 157 | { 158 | const unsigned char *ni = (const unsigned char *) in; 159 | const unsigned char *kk = (const unsigned char *) key; 160 | uint8_t digest_buf[16] = {0}; 161 | 162 | const int C_ROUNDS = 2; 163 | const int D_ROUNDS = 4; 164 | 165 | uint64_t v0 = UINT64_C (0x736f6d6570736575); 166 | uint64_t v1 = UINT64_C (0x646f72616e646f6d); 167 | uint64_t v2 = UINT64_C (0x6c7967656e657261); 168 | uint64_t v3 = UINT64_C (0x7465646279746573); 169 | uint64_t k0 = _u8x8_le_to_u64 (kk); 170 | uint64_t k1 = _u8x8_le_to_u64 (kk + 8); 171 | uint64_t m; 172 | int i; 173 | const unsigned char *end = ni + inlen - (inlen % sizeof (uint64_t)); 174 | const int left = inlen & 7; 175 | uint64_t b = ((uint64_t) inlen) << 56; 176 | v3 ^= k1; 177 | v2 ^= k0; 178 | v1 ^= k1; 179 | v0 ^= k0; 180 | 181 | v1 ^= 0xee; 182 | 183 | for (; ni != end; ni += 8) { 184 | m = _u8x8_le_to_u64 (ni); 185 | v3 ^= m; 186 | 187 | for (i = 0; i < C_ROUNDS; ++i) 188 | _sip_round (&v0, &v1, &v2, &v3); 189 | 190 | v0 ^= m; 191 | } 192 | 193 | switch (left) { 194 | case 7: 195 | b |= ((uint64_t) ni[6]) << 48; 196 | /* FALLTHRU */ 197 | case 6: 198 | b |= ((uint64_t) ni[5]) << 40; 199 | /* FALLTHRU */ 200 | case 5: 201 | b |= ((uint64_t) ni[4]) << 32; 202 | /* FALLTHRU */ 203 | case 4: 204 | b |= ((uint64_t) ni[3]) << 24; 205 | /* FALLTHRU */ 206 | case 3: 207 | b |= ((uint64_t) ni[2]) << 16; 208 | /* FALLTHRU */ 209 | case 2: 210 | b |= ((uint64_t) ni[1]) << 8; 211 | /* FALLTHRU */ 212 | case 1: 213 | b |= ((uint64_t) ni[0]); 214 | break; 215 | default: 216 | BSON_UNREACHABLE ("Invalid remainder during SipHash"); 217 | case 0: 218 | break; 219 | } 220 | 221 | v3 ^= b; 222 | 223 | for (i = 0; i < C_ROUNDS; ++i) 224 | _sip_round (&v0, &v1, &v2, &v3); 225 | 226 | v0 ^= b; 227 | 228 | v2 ^= 0xee; 229 | 230 | for (i = 0; i < D_ROUNDS; ++i) 231 | _sip_round (&v0, &v1, &v2, &v3); 232 | 233 | b = v0 ^ v1 ^ v2 ^ v3; 234 | _u64_into_u8x8_le (digest_buf, b); 235 | 236 | v1 ^= 0xdd; 237 | 238 | for (i = 0; i < D_ROUNDS; ++i) 239 | _sip_round (&v0, &v1, &v2, &v3); 240 | 241 | b = v0 ^ v1 ^ v2 ^ v3; 242 | _u64_into_u8x8_le (digest_buf + 8, b); 243 | 244 | memcpy (digest, digest_buf, sizeof digest_buf); 245 | } 246 | 247 | /* 248 | * The seed consists of the following hashed together: 249 | * - current time (with microsecond resolution) 250 | * - current pid 251 | * - current hostname 252 | * - The init-call counter 253 | */ 254 | struct _init_rand_params { 255 | struct timeval time; 256 | uint64_t pid; 257 | char hostname[HOST_NAME_MAX]; 258 | int64_t rand_call_counter; 259 | }; 260 | 261 | static void 262 | _bson_context_init_random (bson_context_t *context, bool init_seq) 263 | { 264 | /* Keep an atomic counter of this function being called. This is used to add 265 | * additional input to the random hash, ensuring no two calls in a single 266 | * process will receive identical hash inputs, even occurring at the same 267 | * microsecond. */ 268 | static int64_t s_rand_call_counter = INT64_MIN; 269 | 270 | /* The message digest of the random params */ 271 | uint64_t digest[2] = {0}; 272 | uint64_t key[2] = {0}; 273 | /* The randomness parameters */ 274 | struct _init_rand_params rand_params; 275 | 276 | /* Init each part of the randomness source: */ 277 | memset (&rand_params, 0, sizeof rand_params); 278 | bson_gettimeofday (&rand_params.time); 279 | rand_params.pid = _bson_getpid (); 280 | _bson_context_get_hostname (rand_params.hostname); 281 | rand_params.rand_call_counter = bson_atomic_int64_fetch_add (&s_rand_call_counter, 1, bson_memory_order_seq_cst); 282 | 283 | /* Generate a SipHash key. We do not care about secrecy or determinism, only 284 | * uniqueness. */ 285 | memcpy (key, &rand_params, sizeof key); 286 | key[1] = ~key[0]; 287 | 288 | /* Hash the param struct */ 289 | _siphash (&rand_params, sizeof rand_params, key, digest); 290 | 291 | /** Initialize the rand and sequence counters with our random digest */ 292 | memcpy (context->randomness, digest, sizeof context->randomness); 293 | if (init_seq) { 294 | memcpy (&context->seq32, digest + 1, sizeof context->seq32); 295 | memcpy (&context->seq64, digest + 1, sizeof context->seq64); 296 | /* Chop off some initial bits for nicer counter behavior. This allows the 297 | * low digit to start at a zero, and prevents immediately wrapping the 298 | * counter in subsequent calls to set_oid_seq. */ 299 | context->seq32 &= ~UINT32_C (0xf0000f); 300 | context->seq64 &= ~UINT64_C (0xf0000f); 301 | } 302 | 303 | /* Remember the PID we saw here. This may change in case of fork() */ 304 | context->pid = rand_params.pid; 305 | } 306 | 307 | static void 308 | _bson_context_init (bson_context_t *context, bson_context_flags_t flags) 309 | { 310 | context->flags = (int) flags; 311 | _bson_context_init_random (context, true /* Init counters */); 312 | } 313 | 314 | 315 | void 316 | _bson_context_set_oid_rand (bson_context_t *context, bson_oid_t *oid) 317 | { 318 | BSON_ASSERT (context); 319 | BSON_ASSERT (oid); 320 | 321 | if (context->flags & BSON_CONTEXT_DISABLE_PID_CACHE) { 322 | /* User has requested that we check if our PID has changed. This can occur 323 | * after a call to fork() */ 324 | uint64_t now_pid = _bson_getpid (); 325 | if (now_pid != context->pid) { 326 | _bson_context_init_random (context, false /* Do not update the sequence counters */); 327 | } 328 | } 329 | /* Copy the stored randomness into the OID */ 330 | memcpy (oid->bytes + BSON_OID_RANDOMESS_OFFSET, &context->randomness, BSON_OID_RANDOMNESS_SIZE); 331 | } 332 | 333 | 334 | bson_context_t * 335 | bson_context_new (bson_context_flags_t flags) 336 | { 337 | bson_context_t *context; 338 | 339 | context = bson_malloc0 (sizeof *context); 340 | _bson_context_init (context, flags); 341 | 342 | return context; 343 | } 344 | 345 | 346 | void 347 | bson_context_destroy (bson_context_t *context) /* IN */ 348 | { 349 | bson_free (context); 350 | } 351 | 352 | 353 | static BSON_ONCE_FUN (_bson_context_init_default) 354 | { 355 | _bson_context_init (&gContextDefault, BSON_CONTEXT_DISABLE_PID_CACHE); 356 | BSON_ONCE_RETURN; 357 | } 358 | 359 | 360 | bson_context_t * 361 | bson_context_get_default (void) 362 | { 363 | static bson_once_t once = BSON_ONCE_INIT; 364 | 365 | bson_once (&once, _bson_context_init_default); 366 | 367 | return &gContextDefault; 368 | } 369 | -------------------------------------------------------------------------------- /bsonjs/bson/bson-context.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | 20 | #ifndef BSON_CONTEXT_H 21 | #define BSON_CONTEXT_H 22 | 23 | 24 | #include 25 | #include 26 | 27 | 28 | BSON_BEGIN_DECLS 29 | 30 | 31 | /** 32 | * @brief Initialize a new context with the given flags 33 | * 34 | * @param flags Flags used to configure the behavior of the context. For most 35 | * cases, this should be BSON_CONTEXT_NONE. 36 | * 37 | * @return A newly allocated context. Must be freed with bson_context_destroy() 38 | * 39 | * @note If you expect your pid to change without notice, such as from an 40 | * unexpected call to fork(), then specify BSON_CONTEXT_DISABLE_PID_CACHE in 41 | * `flags`. 42 | */ 43 | BSON_EXPORT (bson_context_t *) 44 | bson_context_new (bson_context_flags_t flags); 45 | 46 | /** 47 | * @brief Destroy and free a bson_context_t created by bson_context_new() 48 | */ 49 | BSON_EXPORT (void) 50 | bson_context_destroy (bson_context_t *context); 51 | 52 | /** 53 | * @brief Obtain a pointer to the application-default bson_context_t 54 | * 55 | * @note This context_t MUST NOT be passed to bson_context_destroy() 56 | */ 57 | BSON_EXPORT (bson_context_t *) 58 | bson_context_get_default (void); 59 | 60 | 61 | BSON_END_DECLS 62 | 63 | 64 | #endif /* BSON_CONTEXT_H */ 65 | -------------------------------------------------------------------------------- /bsonjs/bson/bson-decimal128.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | 20 | #ifndef BSON_DECIMAL128_H 21 | #define BSON_DECIMAL128_H 22 | 23 | 24 | #include 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | 31 | /** 32 | * BSON_DECIMAL128_STRING: 33 | * 34 | * The length of a decimal128 string (with null terminator). 35 | * 36 | * 1 for the sign 37 | * 35 for digits and radix 38 | * 2 for exponent indicator and sign 39 | * 4 for exponent digits 40 | */ 41 | #define BSON_DECIMAL128_STRING 43 42 | #define BSON_DECIMAL128_INF "Infinity" 43 | #define BSON_DECIMAL128_NAN "NaN" 44 | 45 | 46 | BSON_BEGIN_DECLS 47 | 48 | BSON_EXPORT (void) 49 | bson_decimal128_to_string (const bson_decimal128_t *dec, char *str); 50 | 51 | 52 | /* Note: @string must be ASCII characters only! */ 53 | BSON_EXPORT (bool) 54 | bson_decimal128_from_string (const char *string, bson_decimal128_t *dec); 55 | 56 | BSON_EXPORT (bool) 57 | bson_decimal128_from_string_w_len (const char *string, int len, bson_decimal128_t *dec); 58 | 59 | BSON_END_DECLS 60 | 61 | 62 | #endif /* BSON_DECIMAL128_H */ 63 | -------------------------------------------------------------------------------- /bsonjs/bson/bson-endian.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | 20 | #ifndef BSON_ENDIAN_H 21 | #define BSON_ENDIAN_H 22 | 23 | 24 | #if defined(__sun) 25 | #include 26 | #endif 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | 33 | BSON_BEGIN_DECLS 34 | 35 | 36 | #define BSON_BIG_ENDIAN 4321 37 | #define BSON_LITTLE_ENDIAN 1234 38 | 39 | 40 | #if defined(__sun) 41 | #define BSON_UINT16_SWAP_LE_BE(v) BSWAP_16 ((uint16_t) v) 42 | #define BSON_UINT32_SWAP_LE_BE(v) BSWAP_32 ((uint32_t) v) 43 | #define BSON_UINT64_SWAP_LE_BE(v) BSWAP_64 ((uint64_t) v) 44 | #elif defined(__clang__) && defined(__clang_major__) && defined(__clang_minor__) && (__clang_major__ >= 3) && \ 45 | (__clang_minor__ >= 1) 46 | #if __has_builtin(__builtin_bswap16) 47 | #define BSON_UINT16_SWAP_LE_BE(v) __builtin_bswap16 (v) 48 | #endif 49 | #if __has_builtin(__builtin_bswap32) 50 | #define BSON_UINT32_SWAP_LE_BE(v) __builtin_bswap32 (v) 51 | #endif 52 | #if __has_builtin(__builtin_bswap64) 53 | #define BSON_UINT64_SWAP_LE_BE(v) __builtin_bswap64 (v) 54 | #endif 55 | #elif defined(__GNUC__) && (__GNUC__ >= 4) 56 | #if __GNUC__ > 4 || (defined(__GNUC_MINOR__) && __GNUC_MINOR__ >= 3) 57 | #define BSON_UINT32_SWAP_LE_BE(v) __builtin_bswap32 ((uint32_t) v) 58 | #define BSON_UINT64_SWAP_LE_BE(v) __builtin_bswap64 ((uint64_t) v) 59 | #endif 60 | #if __GNUC__ > 4 || (defined(__GNUC_MINOR__) && __GNUC_MINOR__ >= 8) 61 | #define BSON_UINT16_SWAP_LE_BE(v) __builtin_bswap16 ((uint32_t) v) 62 | #endif 63 | #endif 64 | 65 | 66 | #ifndef BSON_UINT16_SWAP_LE_BE 67 | #define BSON_UINT16_SWAP_LE_BE(v) __bson_uint16_swap_slow ((uint16_t) v) 68 | #endif 69 | 70 | 71 | #ifndef BSON_UINT32_SWAP_LE_BE 72 | #define BSON_UINT32_SWAP_LE_BE(v) __bson_uint32_swap_slow ((uint32_t) v) 73 | #endif 74 | 75 | 76 | #ifndef BSON_UINT64_SWAP_LE_BE 77 | #define BSON_UINT64_SWAP_LE_BE(v) __bson_uint64_swap_slow ((uint64_t) v) 78 | #endif 79 | 80 | 81 | #if BSON_BYTE_ORDER == BSON_LITTLE_ENDIAN 82 | #define BSON_UINT16_FROM_LE(v) ((uint16_t) v) 83 | #define BSON_UINT16_TO_LE(v) ((uint16_t) v) 84 | #define BSON_UINT16_FROM_BE(v) BSON_UINT16_SWAP_LE_BE (v) 85 | #define BSON_UINT16_TO_BE(v) BSON_UINT16_SWAP_LE_BE (v) 86 | #define BSON_UINT32_FROM_LE(v) ((uint32_t) v) 87 | #define BSON_UINT32_TO_LE(v) ((uint32_t) v) 88 | #define BSON_UINT32_FROM_BE(v) BSON_UINT32_SWAP_LE_BE (v) 89 | #define BSON_UINT32_TO_BE(v) BSON_UINT32_SWAP_LE_BE (v) 90 | #define BSON_UINT64_FROM_LE(v) ((uint64_t) v) 91 | #define BSON_UINT64_TO_LE(v) ((uint64_t) v) 92 | #define BSON_UINT64_FROM_BE(v) BSON_UINT64_SWAP_LE_BE (v) 93 | #define BSON_UINT64_TO_BE(v) BSON_UINT64_SWAP_LE_BE (v) 94 | #define BSON_DOUBLE_FROM_LE(v) ((double) v) 95 | #define BSON_DOUBLE_TO_LE(v) ((double) v) 96 | #elif BSON_BYTE_ORDER == BSON_BIG_ENDIAN 97 | #define BSON_UINT16_FROM_LE(v) BSON_UINT16_SWAP_LE_BE (v) 98 | #define BSON_UINT16_TO_LE(v) BSON_UINT16_SWAP_LE_BE (v) 99 | #define BSON_UINT16_FROM_BE(v) ((uint16_t) v) 100 | #define BSON_UINT16_TO_BE(v) ((uint16_t) v) 101 | #define BSON_UINT32_FROM_LE(v) BSON_UINT32_SWAP_LE_BE (v) 102 | #define BSON_UINT32_TO_LE(v) BSON_UINT32_SWAP_LE_BE (v) 103 | #define BSON_UINT32_FROM_BE(v) ((uint32_t) v) 104 | #define BSON_UINT32_TO_BE(v) ((uint32_t) v) 105 | #define BSON_UINT64_FROM_LE(v) BSON_UINT64_SWAP_LE_BE (v) 106 | #define BSON_UINT64_TO_LE(v) BSON_UINT64_SWAP_LE_BE (v) 107 | #define BSON_UINT64_FROM_BE(v) ((uint64_t) v) 108 | #define BSON_UINT64_TO_BE(v) ((uint64_t) v) 109 | #define BSON_DOUBLE_FROM_LE(v) (__bson_double_swap_slow (v)) 110 | #define BSON_DOUBLE_TO_LE(v) (__bson_double_swap_slow (v)) 111 | #else 112 | #error "The endianness of target architecture is unknown." 113 | #endif 114 | 115 | 116 | /* 117 | *-------------------------------------------------------------------------- 118 | * 119 | * __bson_uint16_swap_slow -- 120 | * 121 | * Fallback endianness conversion for 16-bit integers. 122 | * 123 | * Returns: 124 | * The endian swapped version. 125 | * 126 | * Side effects: 127 | * None. 128 | * 129 | *-------------------------------------------------------------------------- 130 | */ 131 | 132 | static BSON_INLINE uint16_t 133 | __bson_uint16_swap_slow (uint16_t v) /* IN */ 134 | { 135 | return (uint16_t) ((v & 0x00FF) << 8) | (uint16_t) ((v & 0xFF00) >> 8); 136 | } 137 | 138 | 139 | /* 140 | *-------------------------------------------------------------------------- 141 | * 142 | * __bson_uint32_swap_slow -- 143 | * 144 | * Fallback endianness conversion for 32-bit integers. 145 | * 146 | * Returns: 147 | * The endian swapped version. 148 | * 149 | * Side effects: 150 | * None. 151 | * 152 | *-------------------------------------------------------------------------- 153 | */ 154 | 155 | static BSON_INLINE uint32_t 156 | __bson_uint32_swap_slow (uint32_t v) /* IN */ 157 | { 158 | return ((v & 0x000000FFU) << 24) | ((v & 0x0000FF00U) << 8) | ((v & 0x00FF0000U) >> 8) | ((v & 0xFF000000U) >> 24); 159 | } 160 | 161 | 162 | /* 163 | *-------------------------------------------------------------------------- 164 | * 165 | * __bson_uint64_swap_slow -- 166 | * 167 | * Fallback endianness conversion for 64-bit integers. 168 | * 169 | * Returns: 170 | * The endian swapped version. 171 | * 172 | * Side effects: 173 | * None. 174 | * 175 | *-------------------------------------------------------------------------- 176 | */ 177 | 178 | static BSON_INLINE uint64_t 179 | __bson_uint64_swap_slow (uint64_t v) /* IN */ 180 | { 181 | return ((v & 0x00000000000000FFULL) << 56) | ((v & 0x000000000000FF00ULL) << 40) | 182 | ((v & 0x0000000000FF0000ULL) << 24) | ((v & 0x00000000FF000000ULL) << 8) | 183 | ((v & 0x000000FF00000000ULL) >> 8) | ((v & 0x0000FF0000000000ULL) >> 24) | 184 | ((v & 0x00FF000000000000ULL) >> 40) | ((v & 0xFF00000000000000ULL) >> 56); 185 | } 186 | 187 | 188 | /* 189 | *-------------------------------------------------------------------------- 190 | * 191 | * __bson_double_swap_slow -- 192 | * 193 | * Fallback endianness conversion for double floating point. 194 | * 195 | * Returns: 196 | * The endian swapped version. 197 | * 198 | * Side effects: 199 | * None. 200 | * 201 | *-------------------------------------------------------------------------- 202 | */ 203 | 204 | BSON_STATIC_ASSERT2 (sizeof_uint64_t, sizeof (double) == sizeof (uint64_t)); 205 | 206 | static BSON_INLINE double 207 | __bson_double_swap_slow (double v) /* IN */ 208 | { 209 | uint64_t uv; 210 | 211 | memcpy (&uv, &v, sizeof (v)); 212 | uv = BSON_UINT64_SWAP_LE_BE (uv); 213 | memcpy (&v, &uv, sizeof (v)); 214 | 215 | return v; 216 | } 217 | 218 | BSON_END_DECLS 219 | 220 | 221 | #endif /* BSON_ENDIAN_H */ 222 | -------------------------------------------------------------------------------- /bsonjs/bson/bson-error.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #include 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | // See `bson_strerror_r()` definition below. 29 | #if !defined(_WIN32) && !defined(__APPLE__) 30 | #include // uselocale() 31 | #endif 32 | 33 | 34 | /* 35 | *-------------------------------------------------------------------------- 36 | * 37 | * bson_set_error -- 38 | * 39 | * Initializes @error using the parameters specified. 40 | * 41 | * @domain is an application specific error domain which should 42 | * describe which module initiated the error. Think of this as the 43 | * exception type. 44 | * 45 | * @code is the @domain specific error code. 46 | * 47 | * @format is used to generate the format string. It uses vsnprintf() 48 | * internally so the format should match what you would use there. 49 | * 50 | * Parameters: 51 | * @error: A #bson_error_t. 52 | * @domain: The error domain. 53 | * @code: The error code. 54 | * @format: A printf style format string. 55 | * 56 | * Returns: 57 | * None. 58 | * 59 | * Side effects: 60 | * @error is initialized. 61 | * 62 | *-------------------------------------------------------------------------- 63 | */ 64 | 65 | void 66 | bson_set_error (bson_error_t *error, /* OUT */ 67 | uint32_t domain, /* IN */ 68 | uint32_t code, /* IN */ 69 | const char *format, /* IN */ 70 | ...) /* IN */ 71 | { 72 | va_list args; 73 | 74 | if (error) { 75 | error->domain = domain; 76 | error->code = code; 77 | 78 | va_start (args, format); 79 | bson_vsnprintf (error->message, sizeof error->message, format, args); 80 | va_end (args); 81 | 82 | error->message[sizeof error->message - 1] = '\0'; 83 | } 84 | } 85 | 86 | 87 | /* 88 | *-------------------------------------------------------------------------- 89 | * 90 | * bson_strerror_r -- 91 | * 92 | * This is a reentrant safe macro for strerror. 93 | * 94 | * The resulting string may be stored in @buf. 95 | * 96 | * Returns: 97 | * A pointer to a static string or @buf. 98 | * 99 | * Side effects: 100 | * None. 101 | * 102 | *-------------------------------------------------------------------------- 103 | */ 104 | 105 | char * 106 | bson_strerror_r (int err_code, /* IN */ 107 | char *buf BSON_MAYBE_UNUSED, /* IN */ 108 | size_t buflen BSON_MAYBE_UNUSED) /* IN */ 109 | { 110 | static const char *unknown_msg = "Unknown error"; 111 | char *ret = NULL; 112 | 113 | #if defined(_WIN32) 114 | // Windows does not provide `strerror_l` or `strerror_r`, but it does 115 | // unconditionally provide `strerror_s`. 116 | if (strerror_s (buf, buflen, err_code) != 0) { 117 | ret = buf; 118 | } 119 | #elif defined(_AIX) 120 | // AIX does not provide strerror_l, and its strerror_r isn't glibc's. 121 | // But it does provide a glibc compatible one called __linux_strerror_r 122 | ret = __linux_strerror_r (err_code, buf, buflen); 123 | #elif defined(__APPLE__) 124 | // Apple does not provide `strerror_l`, but it does unconditionally provide 125 | // the XSI-compliant `strerror_r`, but only when compiling with Apple Clang. 126 | // GNU extensions may still be a problem if we are being compiled with GCC on 127 | // Apple. Avoid the compatibility headaches with GNU extensions and the musl 128 | // library by assuming the implementation will not cause UB when reading the 129 | // error message string even when `strerror_r` fails, as encouraged (but not 130 | // required) by the POSIX spec (see: 131 | // https://pubs.opengroup.org/onlinepubs/9699919799/functions/strerror.html#tag_16_574_08). 132 | (void) strerror_r (err_code, buf, buflen); 133 | #elif defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 700 134 | // The behavior (of `strerror_l`) is undefined if the locale argument to 135 | // `strerror_l()` is the special locale object LC_GLOBAL_LOCALE or is not a 136 | // valid locale object handle. 137 | locale_t locale = uselocale ((locale_t) 0); 138 | // No need to test for error (it can only be [EINVAL]). 139 | if (locale == LC_GLOBAL_LOCALE) { 140 | // Only use our own locale if a thread-local locale was not already set. 141 | // This is just to satisfy `strerror_l`. We do NOT want to unconditionally 142 | // set a thread-local locale. 143 | locale = newlocale (LC_MESSAGES_MASK, "C", (locale_t) 0); 144 | } 145 | BSON_ASSERT (locale != LC_GLOBAL_LOCALE); 146 | 147 | // Avoid `strerror_r` compatibility headaches with GNU extensions and the 148 | // musl library by using `strerror_l` instead. Furthermore, `strerror_r` is 149 | // scheduled to be marked as obsolete in favor of `strerror_l` in the 150 | // upcoming POSIX Issue 8 (see: 151 | // https://www.austingroupbugs.net/view.php?id=655). 152 | // 153 | // POSIX Spec: since strerror_l() is required to return a string for some 154 | // errors, an application wishing to check for all error situations should 155 | // set errno to 0, then call strerror_l(), then check errno. 156 | if (locale != (locale_t) 0) { 157 | errno = 0; 158 | ret = strerror_l (err_code, locale); 159 | 160 | if (errno != 0) { 161 | ret = NULL; 162 | } 163 | 164 | freelocale (locale); 165 | } else { 166 | // Could not obtain a valid `locale_t` object to satisfy `strerror_l`. 167 | // Fallback to `bson_strncpy` below. 168 | } 169 | #elif defined(_GNU_SOURCE) 170 | // Unlikely, but continue supporting use of GNU extension in cases where the 171 | // C Driver is being built without _XOPEN_SOURCE=700. 172 | ret = strerror_r (err_code, buf, buflen); 173 | #else 174 | #error "Unable to find a supported strerror_r candidate" 175 | #endif 176 | 177 | if (!ret) { 178 | bson_strncpy (buf, unknown_msg, buflen); 179 | ret = buf; 180 | } 181 | 182 | return ret; 183 | } 184 | -------------------------------------------------------------------------------- /bsonjs/bson/bson-error.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | 20 | #ifndef BSON_ERROR_H 21 | #define BSON_ERROR_H 22 | 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | 29 | BSON_BEGIN_DECLS 30 | 31 | 32 | #define BSON_ERROR_JSON 1 33 | #define BSON_ERROR_READER 2 34 | #define BSON_ERROR_INVALID 3 35 | 36 | 37 | BSON_EXPORT (void) 38 | bson_set_error (bson_error_t *error, uint32_t domain, uint32_t code, const char *format, ...) BSON_GNUC_PRINTF (4, 5); 39 | BSON_EXPORT (char *) 40 | bson_strerror_r (int err_code, char *buf, size_t buflen); 41 | 42 | 43 | BSON_END_DECLS 44 | 45 | 46 | #endif /* BSON_ERROR_H */ 47 | -------------------------------------------------------------------------------- /bsonjs/bson/bson-iso8601-private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | 20 | #ifndef BSON_ISO8601_PRIVATE_H 21 | #define BSON_ISO8601_PRIVATE_H 22 | 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | 29 | BSON_BEGIN_DECLS 30 | 31 | bool 32 | _bson_iso8601_date_parse (const char *str, int32_t len, int64_t *out, bson_error_t *error); 33 | 34 | /** 35 | * _bson_iso8601_date_format: 36 | * @msecs_since_epoch: A positive number of milliseconds since Jan 1, 1970. 37 | * @str: The string to append the ISO8601-formatted to. 38 | * 39 | * Appends a date formatted like "2012-12-24T12:15:30.500Z" to @str. 40 | */ 41 | void 42 | _bson_iso8601_date_format (int64_t msecs_since_epoch, bson_string_t *str); 43 | 44 | BSON_END_DECLS 45 | 46 | 47 | #endif /* BSON_ISO8601_PRIVATE_H */ 48 | -------------------------------------------------------------------------------- /bsonjs/bson/bson-iso8601.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | 26 | static bool 27 | get_tok (const char *terminals, const char **ptr, int32_t *remaining, const char **out, int32_t *out_len) 28 | { 29 | const char *terminal; 30 | bool found_terminal = false; 31 | 32 | if (!*remaining) { 33 | *out = ""; 34 | *out_len = 0; 35 | } 36 | 37 | *out = *ptr; 38 | *out_len = -1; 39 | 40 | for (; *remaining && !found_terminal; (*ptr)++, (*remaining)--, (*out_len)++) { 41 | for (terminal = terminals; *terminal; terminal++) { 42 | if (**ptr == *terminal) { 43 | found_terminal = true; 44 | break; 45 | } 46 | } 47 | } 48 | 49 | if (!found_terminal) { 50 | (*out_len)++; 51 | } 52 | 53 | return found_terminal; 54 | } 55 | 56 | static bool 57 | digits_only (const char *str, int32_t len) 58 | { 59 | int i; 60 | 61 | for (i = 0; i < len; i++) { 62 | if (!isdigit (str[i])) { 63 | return false; 64 | } 65 | } 66 | 67 | return true; 68 | } 69 | 70 | static bool 71 | parse_num (const char *str, int32_t len, int32_t digits, int32_t min, int32_t max, int32_t *out) 72 | { 73 | int i; 74 | int magnitude = 1; 75 | int32_t value = 0; 76 | 77 | if ((digits >= 0 && len != digits) || !digits_only (str, len)) { 78 | return false; 79 | } 80 | 81 | for (i = 1; i <= len; i++, magnitude *= 10) { 82 | value += (str[len - i] - '0') * magnitude; 83 | } 84 | 85 | if (value < min || value > max) { 86 | return false; 87 | } 88 | 89 | *out = value; 90 | 91 | return true; 92 | } 93 | 94 | bool 95 | _bson_iso8601_date_parse (const char *str, int32_t len, int64_t *out, bson_error_t *error) 96 | { 97 | const char *ptr; 98 | int32_t remaining = len; 99 | 100 | const char *year_ptr = NULL; 101 | const char *month_ptr = NULL; 102 | const char *day_ptr = NULL; 103 | const char *hour_ptr = NULL; 104 | const char *min_ptr = NULL; 105 | const char *sec_ptr = NULL; 106 | const char *millis_ptr = NULL; 107 | const char *tz_ptr = NULL; 108 | 109 | int32_t year_len = 0; 110 | int32_t month_len = 0; 111 | int32_t day_len = 0; 112 | int32_t hour_len = 0; 113 | int32_t min_len = 0; 114 | int32_t sec_len = 0; 115 | int32_t millis_len = 0; 116 | int32_t tz_len = 0; 117 | 118 | int32_t year; 119 | int32_t month; 120 | int32_t day; 121 | int32_t hour; 122 | int32_t min; 123 | int32_t sec = 0; 124 | int64_t millis = 0; 125 | int32_t tz_adjustment = 0; 126 | 127 | struct bson_tm posix_date = {0}; 128 | 129 | #define DATE_PARSE_ERR(msg) \ 130 | bson_set_error ( \ 131 | error, BSON_ERROR_JSON, BSON_JSON_ERROR_READ_INVALID_PARAM, "Could not parse \"%s\" as date: " msg, str); \ 132 | return false 133 | 134 | #define DEFAULT_DATE_PARSE_ERR \ 135 | DATE_PARSE_ERR ("use ISO8601 format yyyy-mm-ddThh:mm plus timezone, either" \ 136 | " \"Z\" or like \"+0500\" or like \"+05:00\"") 137 | 138 | ptr = str; 139 | 140 | /* we have to match at least yyyy-mm-ddThh:mm */ 141 | if (!(get_tok ("-", &ptr, &remaining, &year_ptr, &year_len) && 142 | get_tok ("-", &ptr, &remaining, &month_ptr, &month_len) && 143 | get_tok ("T", &ptr, &remaining, &day_ptr, &day_len) && get_tok (":", &ptr, &remaining, &hour_ptr, &hour_len) && 144 | get_tok (":+-Z", &ptr, &remaining, &min_ptr, &min_len))) { 145 | DEFAULT_DATE_PARSE_ERR; 146 | } 147 | 148 | /* if the minute has a ':' at the end look for seconds */ 149 | if (min_ptr[min_len] == ':') { 150 | if (remaining < 2) { 151 | DATE_PARSE_ERR ("reached end of date while looking for seconds"); 152 | } 153 | 154 | get_tok (".+-Z", &ptr, &remaining, &sec_ptr, &sec_len); 155 | 156 | if (!sec_len) { 157 | DATE_PARSE_ERR ("minute ends in \":\" seconds is required"); 158 | } 159 | } 160 | 161 | /* if we had a second and it is followed by a '.' look for milliseconds */ 162 | if (sec_len && sec_ptr[sec_len] == '.') { 163 | if (remaining < 2) { 164 | DATE_PARSE_ERR ("reached end of date while looking for milliseconds"); 165 | } 166 | 167 | get_tok ("+-Z", &ptr, &remaining, &millis_ptr, &millis_len); 168 | 169 | if (!millis_len) { 170 | DATE_PARSE_ERR ("seconds ends in \".\", milliseconds is required"); 171 | } 172 | } 173 | 174 | /* backtrack by 1 to put ptr on the timezone */ 175 | ptr--; 176 | remaining++; 177 | 178 | get_tok ("", &ptr, &remaining, &tz_ptr, &tz_len); 179 | 180 | if (!parse_num (year_ptr, year_len, 4, -9999, 9999, &year)) { 181 | DATE_PARSE_ERR ("year must be an integer"); 182 | } 183 | 184 | /* values are as in struct tm */ 185 | year -= 1900; 186 | 187 | if (!parse_num (month_ptr, month_len, 2, 1, 12, &month)) { 188 | DATE_PARSE_ERR ("month must be an integer"); 189 | } 190 | 191 | /* values are as in struct tm */ 192 | month -= 1; 193 | 194 | if (!parse_num (day_ptr, day_len, 2, 1, 31, &day)) { 195 | DATE_PARSE_ERR ("day must be an integer"); 196 | } 197 | 198 | if (!parse_num (hour_ptr, hour_len, 2, 0, 23, &hour)) { 199 | DATE_PARSE_ERR ("hour must be an integer"); 200 | } 201 | 202 | if (!parse_num (min_ptr, min_len, 2, 0, 59, &min)) { 203 | DATE_PARSE_ERR ("minute must be an integer"); 204 | } 205 | 206 | if (sec_len && !parse_num (sec_ptr, sec_len, 2, 0, 60, &sec)) { 207 | DATE_PARSE_ERR ("seconds must be an integer"); 208 | } 209 | 210 | if (tz_len > 0) { 211 | if (tz_ptr[0] == 'Z' && tz_len == 1) { 212 | /* valid */ 213 | } else if (tz_ptr[0] == '+' || tz_ptr[0] == '-') { 214 | int32_t tz_hour; 215 | int32_t tz_min; 216 | 217 | if ((tz_len != 5 || !digits_only (tz_ptr + 1, 4)) && 218 | (tz_len != 6 || !digits_only (tz_ptr + 1, 2) || tz_ptr[3] != ':' || !digits_only (tz_ptr + 4, 2))) { 219 | DATE_PARSE_ERR ("could not parse timezone"); 220 | } 221 | 222 | if (!parse_num (tz_ptr + 1, 2, -1, -23, 23, &tz_hour)) { 223 | DATE_PARSE_ERR ("timezone hour must be at most 23"); 224 | } 225 | 226 | int32_t tz_min_offset = tz_ptr[3] == ':' ? 1 : 0; 227 | if (!parse_num (tz_ptr + 3 + tz_min_offset, 2, -1, 0, 59, &tz_min)) { 228 | DATE_PARSE_ERR ("timezone minute must be at most 59"); 229 | } 230 | 231 | /* we inflect the meaning of a 'positive' timezone. Those are hours 232 | * we have to subtract, and vice versa */ 233 | tz_adjustment = (tz_ptr[0] == '-' ? 1 : -1) * ((tz_min * 60) + (tz_hour * 60 * 60)); 234 | 235 | if (!(tz_adjustment > -86400 && tz_adjustment < 86400)) { 236 | DATE_PARSE_ERR ("timezone offset must be less than 24 hours"); 237 | } 238 | } else { 239 | DATE_PARSE_ERR ("timezone is required"); 240 | } 241 | } 242 | 243 | if (millis_len > 0) { 244 | int i; 245 | int magnitude; 246 | millis = 0; 247 | 248 | if (millis_len > 3 || !digits_only (millis_ptr, millis_len)) { 249 | DATE_PARSE_ERR ("milliseconds must be an integer"); 250 | } 251 | 252 | for (i = 1, magnitude = 1; i <= millis_len; i++, magnitude *= 10) { 253 | millis += (millis_ptr[millis_len - i] - '0') * magnitude; 254 | } 255 | 256 | if (millis_len == 1) { 257 | millis *= 100; 258 | } else if (millis_len == 2) { 259 | millis *= 10; 260 | } 261 | 262 | if (millis < 0 || millis > 1000) { 263 | DATE_PARSE_ERR ("milliseconds must be at least 0 and less than 1000"); 264 | } 265 | } 266 | 267 | posix_date.tm_sec = sec; 268 | posix_date.tm_min = min; 269 | posix_date.tm_hour = hour; 270 | posix_date.tm_mday = day; 271 | posix_date.tm_mon = month; 272 | posix_date.tm_year = year; 273 | posix_date.tm_wday = 0; 274 | posix_date.tm_yday = 0; 275 | 276 | millis = 1000 * _bson_timegm (&posix_date) + millis; 277 | millis += tz_adjustment * 1000; 278 | *out = millis; 279 | 280 | return true; 281 | } 282 | 283 | 284 | void 285 | _bson_iso8601_date_format (int64_t msec_since_epoch, bson_string_t *str) 286 | { 287 | time_t t; 288 | int64_t msecs_part; 289 | char buf[64]; 290 | 291 | msecs_part = msec_since_epoch % 1000; 292 | t = (time_t) (msec_since_epoch / 1000); 293 | 294 | #ifdef BSON_HAVE_GMTIME_R 295 | { 296 | struct tm posix_date; 297 | gmtime_r (&t, &posix_date); 298 | strftime (buf, sizeof buf, "%Y-%m-%dT%H:%M:%S", &posix_date); 299 | } 300 | #elif defined(_MSC_VER) 301 | { 302 | /* Windows gmtime_s is thread-safe */ 303 | struct tm time_buf; 304 | gmtime_s (&time_buf, &t); 305 | strftime (buf, sizeof buf, "%Y-%m-%dT%H:%M:%S", &time_buf); 306 | } 307 | #else 308 | strftime (buf, sizeof buf, "%Y-%m-%dT%H:%M:%S", gmtime (&t)); 309 | #endif 310 | 311 | if (msecs_part) { 312 | bson_string_append_printf (str, "%s.%03" PRId64 "Z", buf, msecs_part); 313 | } else { 314 | bson_string_append (str, buf); 315 | bson_string_append_c (str, 'Z'); 316 | } 317 | } 318 | -------------------------------------------------------------------------------- /bsonjs/bson/bson-json-private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | #ifndef BSON_JSON_PRIVATE_H 20 | #define BSON_JSON_PRIVATE_H 21 | 22 | 23 | struct _bson_json_opts_t { 24 | bson_json_mode_t mode; 25 | int32_t max_len; 26 | bool is_outermost_array; 27 | }; 28 | 29 | 30 | #endif /* BSON_JSON_PRIVATE_H */ 31 | -------------------------------------------------------------------------------- /bsonjs/bson/bson-json.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | 20 | #ifndef BSON_JSON_H 21 | #define BSON_JSON_H 22 | 23 | 24 | #include "bson.h" 25 | 26 | 27 | BSON_BEGIN_DECLS 28 | 29 | 30 | typedef struct _bson_json_reader_t bson_json_reader_t; 31 | 32 | 33 | typedef enum { 34 | BSON_JSON_ERROR_READ_CORRUPT_JS = 1, 35 | BSON_JSON_ERROR_READ_INVALID_PARAM, 36 | BSON_JSON_ERROR_READ_CB_FAILURE, 37 | } bson_json_error_code_t; 38 | 39 | 40 | /** 41 | * BSON_MAX_LEN_UNLIMITED 42 | * 43 | * Denotes unlimited length limit when converting BSON to JSON. 44 | */ 45 | #define BSON_MAX_LEN_UNLIMITED -1 46 | 47 | /** 48 | * bson_json_mode_t: 49 | * 50 | * This enumeration contains the different modes to serialize BSON into extended 51 | * JSON. 52 | */ 53 | typedef enum { 54 | BSON_JSON_MODE_LEGACY, 55 | BSON_JSON_MODE_CANONICAL, 56 | BSON_JSON_MODE_RELAXED, 57 | } bson_json_mode_t; 58 | 59 | 60 | BSON_EXPORT (bson_json_opts_t *) 61 | bson_json_opts_new (bson_json_mode_t mode, int32_t max_len); 62 | BSON_EXPORT (void) 63 | bson_json_opts_destroy (bson_json_opts_t *opts); 64 | BSON_EXPORT (void) 65 | bson_json_opts_set_outermost_array (bson_json_opts_t *opts, bool is_outermost_array); 66 | 67 | typedef ssize_t (*bson_json_reader_cb) (void *handle, uint8_t *buf, size_t count); 68 | typedef void (*bson_json_destroy_cb) (void *handle); 69 | 70 | 71 | BSON_EXPORT (bson_json_reader_t *) 72 | bson_json_reader_new ( 73 | void *data, bson_json_reader_cb cb, bson_json_destroy_cb dcb, bool allow_multiple, size_t buf_size); 74 | BSON_EXPORT (bson_json_reader_t *) 75 | bson_json_reader_new_from_fd (int fd, bool close_on_destroy); 76 | BSON_EXPORT (bson_json_reader_t *) 77 | bson_json_reader_new_from_file (const char *filename, bson_error_t *error); 78 | BSON_EXPORT (void) 79 | bson_json_reader_destroy (bson_json_reader_t *reader); 80 | BSON_EXPORT (int) 81 | bson_json_reader_read (bson_json_reader_t *reader, bson_t *bson, bson_error_t *error); 82 | BSON_EXPORT (bson_json_reader_t *) 83 | bson_json_data_reader_new (bool allow_multiple, size_t size); 84 | BSON_EXPORT (void) 85 | bson_json_data_reader_ingest (bson_json_reader_t *reader, const uint8_t *data, size_t len); 86 | 87 | 88 | BSON_END_DECLS 89 | 90 | 91 | #endif /* BSON_JSON_H */ 92 | -------------------------------------------------------------------------------- /bsonjs/bson/bson-keys.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | 24 | static const char *gUint32Strs[] = { 25 | "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", 26 | "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", 27 | "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", 28 | "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "60", "61", "62", "63", 29 | "64", "65", "66", "67", "68", "69", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", 30 | "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "90", "91", "92", "93", "94", "95", 31 | "96", "97", "98", "99", "100", "101", "102", "103", "104", "105", "106", "107", "108", "109", "110", "111", 32 | "112", "113", "114", "115", "116", "117", "118", "119", "120", "121", "122", "123", "124", "125", "126", "127", 33 | "128", "129", "130", "131", "132", "133", "134", "135", "136", "137", "138", "139", "140", "141", "142", "143", 34 | "144", "145", "146", "147", "148", "149", "150", "151", "152", "153", "154", "155", "156", "157", "158", "159", 35 | "160", "161", "162", "163", "164", "165", "166", "167", "168", "169", "170", "171", "172", "173", "174", "175", 36 | "176", "177", "178", "179", "180", "181", "182", "183", "184", "185", "186", "187", "188", "189", "190", "191", 37 | "192", "193", "194", "195", "196", "197", "198", "199", "200", "201", "202", "203", "204", "205", "206", "207", 38 | "208", "209", "210", "211", "212", "213", "214", "215", "216", "217", "218", "219", "220", "221", "222", "223", 39 | "224", "225", "226", "227", "228", "229", "230", "231", "232", "233", "234", "235", "236", "237", "238", "239", 40 | "240", "241", "242", "243", "244", "245", "246", "247", "248", "249", "250", "251", "252", "253", "254", "255", 41 | "256", "257", "258", "259", "260", "261", "262", "263", "264", "265", "266", "267", "268", "269", "270", "271", 42 | "272", "273", "274", "275", "276", "277", "278", "279", "280", "281", "282", "283", "284", "285", "286", "287", 43 | "288", "289", "290", "291", "292", "293", "294", "295", "296", "297", "298", "299", "300", "301", "302", "303", 44 | "304", "305", "306", "307", "308", "309", "310", "311", "312", "313", "314", "315", "316", "317", "318", "319", 45 | "320", "321", "322", "323", "324", "325", "326", "327", "328", "329", "330", "331", "332", "333", "334", "335", 46 | "336", "337", "338", "339", "340", "341", "342", "343", "344", "345", "346", "347", "348", "349", "350", "351", 47 | "352", "353", "354", "355", "356", "357", "358", "359", "360", "361", "362", "363", "364", "365", "366", "367", 48 | "368", "369", "370", "371", "372", "373", "374", "375", "376", "377", "378", "379", "380", "381", "382", "383", 49 | "384", "385", "386", "387", "388", "389", "390", "391", "392", "393", "394", "395", "396", "397", "398", "399", 50 | "400", "401", "402", "403", "404", "405", "406", "407", "408", "409", "410", "411", "412", "413", "414", "415", 51 | "416", "417", "418", "419", "420", "421", "422", "423", "424", "425", "426", "427", "428", "429", "430", "431", 52 | "432", "433", "434", "435", "436", "437", "438", "439", "440", "441", "442", "443", "444", "445", "446", "447", 53 | "448", "449", "450", "451", "452", "453", "454", "455", "456", "457", "458", "459", "460", "461", "462", "463", 54 | "464", "465", "466", "467", "468", "469", "470", "471", "472", "473", "474", "475", "476", "477", "478", "479", 55 | "480", "481", "482", "483", "484", "485", "486", "487", "488", "489", "490", "491", "492", "493", "494", "495", 56 | "496", "497", "498", "499", "500", "501", "502", "503", "504", "505", "506", "507", "508", "509", "510", "511", 57 | "512", "513", "514", "515", "516", "517", "518", "519", "520", "521", "522", "523", "524", "525", "526", "527", 58 | "528", "529", "530", "531", "532", "533", "534", "535", "536", "537", "538", "539", "540", "541", "542", "543", 59 | "544", "545", "546", "547", "548", "549", "550", "551", "552", "553", "554", "555", "556", "557", "558", "559", 60 | "560", "561", "562", "563", "564", "565", "566", "567", "568", "569", "570", "571", "572", "573", "574", "575", 61 | "576", "577", "578", "579", "580", "581", "582", "583", "584", "585", "586", "587", "588", "589", "590", "591", 62 | "592", "593", "594", "595", "596", "597", "598", "599", "600", "601", "602", "603", "604", "605", "606", "607", 63 | "608", "609", "610", "611", "612", "613", "614", "615", "616", "617", "618", "619", "620", "621", "622", "623", 64 | "624", "625", "626", "627", "628", "629", "630", "631", "632", "633", "634", "635", "636", "637", "638", "639", 65 | "640", "641", "642", "643", "644", "645", "646", "647", "648", "649", "650", "651", "652", "653", "654", "655", 66 | "656", "657", "658", "659", "660", "661", "662", "663", "664", "665", "666", "667", "668", "669", "670", "671", 67 | "672", "673", "674", "675", "676", "677", "678", "679", "680", "681", "682", "683", "684", "685", "686", "687", 68 | "688", "689", "690", "691", "692", "693", "694", "695", "696", "697", "698", "699", "700", "701", "702", "703", 69 | "704", "705", "706", "707", "708", "709", "710", "711", "712", "713", "714", "715", "716", "717", "718", "719", 70 | "720", "721", "722", "723", "724", "725", "726", "727", "728", "729", "730", "731", "732", "733", "734", "735", 71 | "736", "737", "738", "739", "740", "741", "742", "743", "744", "745", "746", "747", "748", "749", "750", "751", 72 | "752", "753", "754", "755", "756", "757", "758", "759", "760", "761", "762", "763", "764", "765", "766", "767", 73 | "768", "769", "770", "771", "772", "773", "774", "775", "776", "777", "778", "779", "780", "781", "782", "783", 74 | "784", "785", "786", "787", "788", "789", "790", "791", "792", "793", "794", "795", "796", "797", "798", "799", 75 | "800", "801", "802", "803", "804", "805", "806", "807", "808", "809", "810", "811", "812", "813", "814", "815", 76 | "816", "817", "818", "819", "820", "821", "822", "823", "824", "825", "826", "827", "828", "829", "830", "831", 77 | "832", "833", "834", "835", "836", "837", "838", "839", "840", "841", "842", "843", "844", "845", "846", "847", 78 | "848", "849", "850", "851", "852", "853", "854", "855", "856", "857", "858", "859", "860", "861", "862", "863", 79 | "864", "865", "866", "867", "868", "869", "870", "871", "872", "873", "874", "875", "876", "877", "878", "879", 80 | "880", "881", "882", "883", "884", "885", "886", "887", "888", "889", "890", "891", "892", "893", "894", "895", 81 | "896", "897", "898", "899", "900", "901", "902", "903", "904", "905", "906", "907", "908", "909", "910", "911", 82 | "912", "913", "914", "915", "916", "917", "918", "919", "920", "921", "922", "923", "924", "925", "926", "927", 83 | "928", "929", "930", "931", "932", "933", "934", "935", "936", "937", "938", "939", "940", "941", "942", "943", 84 | "944", "945", "946", "947", "948", "949", "950", "951", "952", "953", "954", "955", "956", "957", "958", "959", 85 | "960", "961", "962", "963", "964", "965", "966", "967", "968", "969", "970", "971", "972", "973", "974", "975", 86 | "976", "977", "978", "979", "980", "981", "982", "983", "984", "985", "986", "987", "988", "989", "990", "991", 87 | "992", "993", "994", "995", "996", "997", "998", "999"}; 88 | 89 | 90 | /* 91 | *-------------------------------------------------------------------------- 92 | * 93 | * bson_uint32_to_string -- 94 | * 95 | * Converts @value to a string. 96 | * 97 | * If @value is from 0 to 1000, it will use a constant string in the 98 | * data section of the library. 99 | * 100 | * If not, a string will be formatted using @str and snprintf(). This 101 | * is much slower, of course and therefore we try to optimize it out. 102 | * 103 | * @strptr will always be set. It will either point to @str or a 104 | * constant string. You will want to use this as your key. 105 | * 106 | * Parameters: 107 | * @value: A #uint32_t to convert to string. 108 | * @strptr: (out): A pointer to the resulting string. 109 | * @str: (out): Storage for a string made with snprintf. 110 | * @size: Size of @str. 111 | * 112 | * Returns: 113 | * The number of bytes in the resulting string excluding the NULL 114 | * terminator. If the output requires more than @size bytes, then @size 115 | * bytes are written and the result is the number of bytes required 116 | * (excluding the NULL terminator) 117 | * 118 | * Side effects: 119 | * None. 120 | * 121 | *-------------------------------------------------------------------------- 122 | */ 123 | 124 | size_t 125 | bson_uint32_to_string (uint32_t value, /* IN */ 126 | const char **strptr, /* OUT */ 127 | char *str, /* OUT */ 128 | size_t size) /* IN */ 129 | { 130 | if (value < 1000) { 131 | *strptr = gUint32Strs[value]; 132 | 133 | if (value < 10) { 134 | return 1; 135 | } else if (value < 100) { 136 | return 2; 137 | } else { 138 | return 3; 139 | } 140 | } 141 | 142 | *strptr = str; 143 | 144 | return bson_snprintf (str, size, "%u", value); 145 | } 146 | -------------------------------------------------------------------------------- /bsonjs/bson/bson-keys.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | 20 | #ifndef BSON_KEYS_H 21 | #define BSON_KEYS_H 22 | 23 | 24 | #include 25 | #include 26 | 27 | 28 | BSON_BEGIN_DECLS 29 | 30 | 31 | BSON_EXPORT (size_t) 32 | bson_uint32_to_string (uint32_t value, const char **strptr, char *str, size_t size); 33 | 34 | 35 | BSON_END_DECLS 36 | 37 | 38 | #endif /* BSON_KEYS_H */ 39 | -------------------------------------------------------------------------------- /bsonjs/bson/bson-md5.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include "common-md5-private.h" 5 | 6 | 7 | void 8 | bson_md5_init (bson_md5_t *pms) 9 | { 10 | mcommon_md5_init (pms); 11 | } 12 | 13 | 14 | void 15 | bson_md5_append (bson_md5_t *pms, const uint8_t *data, uint32_t nbytes) 16 | { 17 | mcommon_md5_append (pms, data, nbytes); 18 | } 19 | 20 | void 21 | bson_md5_finish (bson_md5_t *pms, uint8_t digest[16]) 22 | { 23 | mcommon_md5_finish (pms, digest); 24 | } 25 | -------------------------------------------------------------------------------- /bsonjs/bson/bson-md5.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved. 3 | 4 | This software is provided 'as-is', without any express or implied 5 | warranty. In no event will the authors be held liable for any damages 6 | arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any purpose, 9 | including commercial applications, and to alter it and redistribute it 10 | freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; you must not 13 | claim that you wrote the original software. If you use this software 14 | in a product, an acknowledgement in the product documentation would be 15 | appreciated but is not required. 16 | 2. Altered source versions must be plainly marked as such, and must not be 17 | misrepresented as being the original software. 18 | 3. This notice may not be removed or altered from any source distribution. 19 | 20 | L. Peter Deutsch 21 | ghost@aladdin.com 22 | 23 | */ 24 | /* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */ 25 | /* 26 | Independent implementation of MD5 (RFC 1321). 27 | 28 | This code implements the MD5 Algorithm defined in RFC 1321, whose 29 | text is available at 30 | http://www.ietf.org/rfc/rfc1321.txt 31 | The code is derived from the text of the RFC, including the test suite 32 | (section A.5) but excluding the rest of Appendix A. It does not include 33 | any code or documentation that is identified in the RFC as being 34 | copyrighted. 35 | 36 | The original and principal author of md5.h is L. Peter Deutsch 37 | . Other authors are noted in the change history 38 | that follows (in reverse chronological order): 39 | 40 | 2002-04-13 lpd Removed support for non-ANSI compilers; removed 41 | references to Ghostscript; clarified derivation from RFC 1321; 42 | now handles byte order either statically or dynamically. 43 | 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. 44 | 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); 45 | added conditionalization for C++ compilation from Martin 46 | Purschke . 47 | 1999-05-03 lpd Original version. 48 | */ 49 | 50 | 51 | /* 52 | * The following MD5 implementation has been modified to use types as 53 | * specified in libbson. 54 | */ 55 | 56 | #include 57 | 58 | 59 | #ifndef BSON_MD5_H 60 | #define BSON_MD5_H 61 | 62 | 63 | #include 64 | 65 | 66 | BSON_BEGIN_DECLS 67 | 68 | 69 | typedef struct { 70 | uint32_t count[2]; /* message length in bits, lsw first */ 71 | uint32_t abcd[4]; /* digest buffer */ 72 | uint8_t buf[64]; /* accumulate block */ 73 | } bson_md5_t; 74 | 75 | 76 | BSON_EXPORT (void) 77 | bson_md5_init (bson_md5_t *pms) BSON_GNUC_DEPRECATED; 78 | BSON_EXPORT (void) 79 | bson_md5_append (bson_md5_t *pms, const uint8_t *data, uint32_t nbytes) BSON_GNUC_DEPRECATED; 80 | BSON_EXPORT (void) 81 | bson_md5_finish (bson_md5_t *pms, uint8_t digest[16]) BSON_GNUC_DEPRECATED; 82 | 83 | 84 | BSON_END_DECLS 85 | 86 | 87 | #endif /* BSON_MD5_H */ 88 | -------------------------------------------------------------------------------- /bsonjs/bson/bson-memory.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | 20 | #ifndef BSON_MEMORY_H 21 | #define BSON_MEMORY_H 22 | 23 | 24 | #include 25 | #include 26 | 27 | 28 | BSON_BEGIN_DECLS 29 | 30 | 31 | typedef void *(*bson_realloc_func) (void *mem, size_t num_bytes, void *ctx); 32 | 33 | 34 | typedef struct _bson_mem_vtable_t { 35 | void *(*malloc) (size_t num_bytes); 36 | void *(*calloc) (size_t n_members, size_t num_bytes); 37 | void *(*realloc) (void *mem, size_t num_bytes); 38 | void (*free) (void *mem); 39 | void *(*aligned_alloc) (size_t alignment, size_t num_bytes); 40 | void *padding[3]; 41 | } bson_mem_vtable_t; 42 | 43 | 44 | BSON_EXPORT (void) 45 | bson_mem_set_vtable (const bson_mem_vtable_t *vtable); 46 | BSON_EXPORT (void) 47 | bson_mem_restore_vtable (void); 48 | BSON_EXPORT (void *) 49 | bson_malloc (size_t num_bytes); 50 | BSON_EXPORT (void *) 51 | bson_malloc0 (size_t num_bytes); 52 | BSON_EXPORT (void *) 53 | bson_aligned_alloc (size_t alignment, size_t num_bytes); 54 | BSON_EXPORT (void *) 55 | bson_aligned_alloc0 (size_t alignment, size_t num_bytes); 56 | BSON_EXPORT (void *) 57 | bson_realloc (void *mem, size_t num_bytes); 58 | BSON_EXPORT (void *) 59 | bson_realloc_ctx (void *mem, size_t num_bytes, void *ctx); 60 | BSON_EXPORT (void) 61 | bson_free (void *mem); 62 | BSON_EXPORT (void) 63 | bson_zero_free (void *mem, size_t size); 64 | 65 | 66 | #define BSON_ALIGNED_ALLOC(T) ((T *) (bson_aligned_alloc (BSON_ALIGNOF (T), sizeof (T)))) 67 | #define BSON_ALIGNED_ALLOC0(T) ((T *) (bson_aligned_alloc0 (BSON_ALIGNOF (T), sizeof (T)))) 68 | 69 | 70 | BSON_END_DECLS 71 | 72 | 73 | #endif /* BSON_MEMORY_H */ 74 | -------------------------------------------------------------------------------- /bsonjs/bson/bson-oid.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | 29 | /* 30 | * This table contains an array of two character pairs for every possible 31 | * uint8_t. It is used as a lookup table when encoding a bson_oid_t 32 | * to hex formatted ASCII. Performing two characters at a time roughly 33 | * reduces the number of operations by one-half. 34 | */ 35 | BSON_MAYBE_UNUSED static const uint16_t gHexCharPairs[] = { 36 | #if BSON_BYTE_ORDER == BSON_BIG_ENDIAN 37 | 12336, 12337, 12338, 12339, 12340, 12341, 12342, 12343, 12344, 12345, 12385, 12386, 12387, 12388, 12389, 38 | 12390, 12592, 12593, 12594, 12595, 12596, 12597, 12598, 12599, 12600, 12601, 12641, 12642, 12643, 12644, 39 | 12645, 12646, 12848, 12849, 12850, 12851, 12852, 12853, 12854, 12855, 12856, 12857, 12897, 12898, 12899, 40 | 12900, 12901, 12902, 13104, 13105, 13106, 13107, 13108, 13109, 13110, 13111, 13112, 13113, 13153, 13154, 41 | 13155, 13156, 13157, 13158, 13360, 13361, 13362, 13363, 13364, 13365, 13366, 13367, 13368, 13369, 13409, 42 | 13410, 13411, 13412, 13413, 13414, 13616, 13617, 13618, 13619, 13620, 13621, 13622, 13623, 13624, 13625, 43 | 13665, 13666, 13667, 13668, 13669, 13670, 13872, 13873, 13874, 13875, 13876, 13877, 13878, 13879, 13880, 44 | 13881, 13921, 13922, 13923, 13924, 13925, 13926, 14128, 14129, 14130, 14131, 14132, 14133, 14134, 14135, 45 | 14136, 14137, 14177, 14178, 14179, 14180, 14181, 14182, 14384, 14385, 14386, 14387, 14388, 14389, 14390, 46 | 14391, 14392, 14393, 14433, 14434, 14435, 14436, 14437, 14438, 14640, 14641, 14642, 14643, 14644, 14645, 47 | 14646, 14647, 14648, 14649, 14689, 14690, 14691, 14692, 14693, 14694, 24880, 24881, 24882, 24883, 24884, 48 | 24885, 24886, 24887, 24888, 24889, 24929, 24930, 24931, 24932, 24933, 24934, 25136, 25137, 25138, 25139, 49 | 25140, 25141, 25142, 25143, 25144, 25145, 25185, 25186, 25187, 25188, 25189, 25190, 25392, 25393, 25394, 50 | 25395, 25396, 25397, 25398, 25399, 25400, 25401, 25441, 25442, 25443, 25444, 25445, 25446, 25648, 25649, 51 | 25650, 25651, 25652, 25653, 25654, 25655, 25656, 25657, 25697, 25698, 25699, 25700, 25701, 25702, 25904, 52 | 25905, 25906, 25907, 25908, 25909, 25910, 25911, 25912, 25913, 25953, 25954, 25955, 25956, 25957, 25958, 53 | 26160, 26161, 26162, 26163, 26164, 26165, 26166, 26167, 26168, 26169, 26209, 26210, 26211, 26212, 26213, 54 | 26214 55 | #else 56 | 12336, 12592, 12848, 13104, 13360, 13616, 13872, 14128, 14384, 14640, 24880, 25136, 25392, 25648, 25904, 57 | 26160, 12337, 12593, 12849, 13105, 13361, 13617, 13873, 14129, 14385, 14641, 24881, 25137, 25393, 25649, 58 | 25905, 26161, 12338, 12594, 12850, 13106, 13362, 13618, 13874, 14130, 14386, 14642, 24882, 25138, 25394, 59 | 25650, 25906, 26162, 12339, 12595, 12851, 13107, 13363, 13619, 13875, 14131, 14387, 14643, 24883, 25139, 60 | 25395, 25651, 25907, 26163, 12340, 12596, 12852, 13108, 13364, 13620, 13876, 14132, 14388, 14644, 24884, 61 | 25140, 25396, 25652, 25908, 26164, 12341, 12597, 12853, 13109, 13365, 13621, 13877, 14133, 14389, 14645, 62 | 24885, 25141, 25397, 25653, 25909, 26165, 12342, 12598, 12854, 13110, 13366, 13622, 13878, 14134, 14390, 63 | 14646, 24886, 25142, 25398, 25654, 25910, 26166, 12343, 12599, 12855, 13111, 13367, 13623, 13879, 14135, 64 | 14391, 14647, 24887, 25143, 25399, 25655, 25911, 26167, 12344, 12600, 12856, 13112, 13368, 13624, 13880, 65 | 14136, 14392, 14648, 24888, 25144, 25400, 25656, 25912, 26168, 12345, 12601, 12857, 13113, 13369, 13625, 66 | 13881, 14137, 14393, 14649, 24889, 25145, 25401, 25657, 25913, 26169, 12385, 12641, 12897, 13153, 13409, 67 | 13665, 13921, 14177, 14433, 14689, 24929, 25185, 25441, 25697, 25953, 26209, 12386, 12642, 12898, 13154, 68 | 13410, 13666, 13922, 14178, 14434, 14690, 24930, 25186, 25442, 25698, 25954, 26210, 12387, 12643, 12899, 69 | 13155, 13411, 13667, 13923, 14179, 14435, 14691, 24931, 25187, 25443, 25699, 25955, 26211, 12388, 12644, 70 | 12900, 13156, 13412, 13668, 13924, 14180, 14436, 14692, 24932, 25188, 25444, 25700, 25956, 26212, 12389, 71 | 12645, 12901, 13157, 13413, 13669, 13925, 14181, 14437, 14693, 24933, 25189, 25445, 25701, 25957, 26213, 72 | 12390, 12646, 12902, 13158, 13414, 13670, 13926, 14182, 14438, 14694, 24934, 25190, 25446, 25702, 25958, 73 | 26214 74 | #endif 75 | }; 76 | 77 | 78 | void 79 | bson_oid_init_sequence (bson_oid_t *oid, /* OUT */ 80 | bson_context_t *context) /* IN */ 81 | { 82 | uint32_t now = (uint32_t) (time (NULL)); 83 | 84 | if (!context) { 85 | context = bson_context_get_default (); 86 | } 87 | 88 | now = BSON_UINT32_TO_BE (now); 89 | memcpy (&oid->bytes[0], &now, sizeof (now)); 90 | _bson_context_set_oid_seq64 (context, oid); 91 | } 92 | 93 | 94 | void 95 | bson_oid_init (bson_oid_t *oid, /* OUT */ 96 | bson_context_t *context) /* IN */ 97 | { 98 | uint32_t now = (uint32_t) (time (NULL)); 99 | 100 | BSON_ASSERT (oid); 101 | 102 | if (!context) { 103 | context = bson_context_get_default (); 104 | } 105 | 106 | now = BSON_UINT32_TO_BE (now); 107 | memcpy (&oid->bytes[0], &now, sizeof (now)); 108 | _bson_context_set_oid_rand (context, oid); 109 | _bson_context_set_oid_seq32 (context, oid); 110 | } 111 | 112 | 113 | void 114 | bson_oid_init_from_data (bson_oid_t *oid, /* OUT */ 115 | const uint8_t *data) /* IN */ 116 | { 117 | BSON_ASSERT (oid); 118 | BSON_ASSERT (data); 119 | 120 | memcpy (oid, data, 12); 121 | } 122 | 123 | 124 | void 125 | bson_oid_init_from_string (bson_oid_t *oid, /* OUT */ 126 | const char *str) /* IN */ 127 | { 128 | BSON_ASSERT (oid); 129 | BSON_ASSERT (str); 130 | 131 | bson_oid_init_from_string_unsafe (oid, str); 132 | } 133 | 134 | 135 | time_t 136 | bson_oid_get_time_t (const bson_oid_t *oid) /* IN */ 137 | { 138 | BSON_ASSERT (oid); 139 | 140 | return bson_oid_get_time_t_unsafe (oid); 141 | } 142 | 143 | 144 | void 145 | bson_oid_to_string (const bson_oid_t *oid, /* IN */ 146 | char str[BSON_ENSURE_ARRAY_PARAM_SIZE (25)]) /* OUT */ 147 | { 148 | #if !defined(__i386__) && !defined(__x86_64__) && !defined(_M_IX86) && !defined(_M_X64) 149 | BSON_ASSERT (oid); 150 | BSON_ASSERT (str); 151 | 152 | bson_snprintf (str, 153 | 25, 154 | "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", 155 | oid->bytes[0], 156 | oid->bytes[1], 157 | oid->bytes[2], 158 | oid->bytes[3], 159 | oid->bytes[4], 160 | oid->bytes[5], 161 | oid->bytes[6], 162 | oid->bytes[7], 163 | oid->bytes[8], 164 | oid->bytes[9], 165 | oid->bytes[10], 166 | oid->bytes[11]); 167 | #else 168 | uint16_t *dst; 169 | uint8_t *id = (uint8_t *) oid; 170 | 171 | BSON_ASSERT (oid); 172 | BSON_ASSERT (str); 173 | 174 | dst = (uint16_t *) (void *) str; 175 | dst[0] = gHexCharPairs[id[0]]; 176 | dst[1] = gHexCharPairs[id[1]]; 177 | dst[2] = gHexCharPairs[id[2]]; 178 | dst[3] = gHexCharPairs[id[3]]; 179 | dst[4] = gHexCharPairs[id[4]]; 180 | dst[5] = gHexCharPairs[id[5]]; 181 | dst[6] = gHexCharPairs[id[6]]; 182 | dst[7] = gHexCharPairs[id[7]]; 183 | dst[8] = gHexCharPairs[id[8]]; 184 | dst[9] = gHexCharPairs[id[9]]; 185 | dst[10] = gHexCharPairs[id[10]]; 186 | dst[11] = gHexCharPairs[id[11]]; 187 | str[24] = '\0'; 188 | #endif 189 | } 190 | 191 | 192 | uint32_t 193 | bson_oid_hash (const bson_oid_t *oid) /* IN */ 194 | { 195 | BSON_ASSERT (oid); 196 | 197 | return bson_oid_hash_unsafe (oid); 198 | } 199 | 200 | 201 | int 202 | bson_oid_compare (const bson_oid_t *oid1, /* IN */ 203 | const bson_oid_t *oid2) /* IN */ 204 | { 205 | BSON_ASSERT (oid1); 206 | BSON_ASSERT (oid2); 207 | 208 | return bson_oid_compare_unsafe (oid1, oid2); 209 | } 210 | 211 | 212 | bool 213 | bson_oid_equal (const bson_oid_t *oid1, /* IN */ 214 | const bson_oid_t *oid2) /* IN */ 215 | { 216 | BSON_ASSERT (oid1); 217 | BSON_ASSERT (oid2); 218 | 219 | return bson_oid_equal_unsafe (oid1, oid2); 220 | } 221 | 222 | 223 | void 224 | bson_oid_copy (const bson_oid_t *src, /* IN */ 225 | bson_oid_t *dst) /* OUT */ 226 | { 227 | BSON_ASSERT (src); 228 | BSON_ASSERT (dst); 229 | 230 | bson_oid_copy_unsafe (src, dst); 231 | } 232 | 233 | 234 | bool 235 | bson_oid_is_valid (const char *str, /* IN */ 236 | size_t length) /* IN */ 237 | { 238 | size_t i; 239 | 240 | BSON_ASSERT (str); 241 | 242 | if ((length == 25) && (str[24] == '\0')) { 243 | length = 24; 244 | } 245 | 246 | if (length == 24) { 247 | for (i = 0; i < length; i++) { 248 | switch (str[i]) { 249 | case '0': 250 | case '1': 251 | case '2': 252 | case '3': 253 | case '4': 254 | case '5': 255 | case '6': 256 | case '7': 257 | case '8': 258 | case '9': 259 | case 'a': 260 | case 'b': 261 | case 'c': 262 | case 'd': 263 | case 'e': 264 | case 'f': 265 | case 'A': 266 | case 'B': 267 | case 'C': 268 | case 'D': 269 | case 'E': 270 | case 'F': 271 | break; 272 | default: 273 | return false; 274 | } 275 | } 276 | return true; 277 | } 278 | 279 | return false; 280 | } 281 | -------------------------------------------------------------------------------- /bsonjs/bson/bson-oid.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | 20 | #ifndef BSON_OID_H 21 | #define BSON_OID_H 22 | 23 | 24 | #include 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | 32 | BSON_BEGIN_DECLS 33 | 34 | 35 | BSON_EXPORT (int) 36 | bson_oid_compare (const bson_oid_t *oid1, const bson_oid_t *oid2); 37 | BSON_EXPORT (void) 38 | bson_oid_copy (const bson_oid_t *src, bson_oid_t *dst); 39 | BSON_EXPORT (bool) 40 | bson_oid_equal (const bson_oid_t *oid1, const bson_oid_t *oid2); 41 | BSON_EXPORT (bool) 42 | bson_oid_is_valid (const char *str, size_t length); 43 | BSON_EXPORT (time_t) 44 | bson_oid_get_time_t (const bson_oid_t *oid); 45 | BSON_EXPORT (uint32_t) 46 | bson_oid_hash (const bson_oid_t *oid); 47 | BSON_EXPORT (void) 48 | bson_oid_init (bson_oid_t *oid, bson_context_t *context); 49 | BSON_EXPORT (void) 50 | bson_oid_init_from_data (bson_oid_t *oid, const uint8_t *data); 51 | BSON_EXPORT (void) 52 | bson_oid_init_from_string (bson_oid_t *oid, const char *str); 53 | BSON_EXPORT (void) 54 | bson_oid_init_sequence (bson_oid_t *oid, bson_context_t *context) BSON_GNUC_DEPRECATED_FOR (bson_oid_init); 55 | BSON_EXPORT (void) 56 | bson_oid_to_string (const bson_oid_t *oid, char str[25]); 57 | 58 | 59 | /** 60 | * bson_oid_compare_unsafe: 61 | * @oid1: A bson_oid_t. 62 | * @oid2: A bson_oid_t. 63 | * 64 | * Performs a qsort() style comparison between @oid1 and @oid2. 65 | * 66 | * This function is meant to be as fast as possible and therefore performs 67 | * no argument validation. That is the callers responsibility. 68 | * 69 | * Returns: An integer < 0 if @oid1 is less than @oid2. Zero if they are equal. 70 | * An integer > 0 if @oid1 is greater than @oid2. 71 | */ 72 | static BSON_INLINE int 73 | bson_oid_compare_unsafe (const bson_oid_t *oid1, const bson_oid_t *oid2) 74 | { 75 | return memcmp (oid1, oid2, sizeof *oid1); 76 | } 77 | 78 | 79 | /** 80 | * bson_oid_equal_unsafe: 81 | * @oid1: A bson_oid_t. 82 | * @oid2: A bson_oid_t. 83 | * 84 | * Checks the equality of @oid1 and @oid2. 85 | * 86 | * This function is meant to be as fast as possible and therefore performs 87 | * no checks for argument validity. That is the callers responsibility. 88 | * 89 | * Returns: true if @oid1 and @oid2 are equal; otherwise false. 90 | */ 91 | static BSON_INLINE bool 92 | bson_oid_equal_unsafe (const bson_oid_t *oid1, const bson_oid_t *oid2) 93 | { 94 | return !memcmp (oid1, oid2, sizeof *oid1); 95 | } 96 | 97 | /** 98 | * bson_oid_hash_unsafe: 99 | * @oid: A bson_oid_t. 100 | * 101 | * This function performs a DJB style hash upon the bytes contained in @oid. 102 | * The result is a hash key suitable for use in a hashtable. 103 | * 104 | * This function is meant to be as fast as possible and therefore performs no 105 | * validation of arguments. The caller is responsible to ensure they are 106 | * passing valid arguments. 107 | * 108 | * Returns: A uint32_t containing a hash code. 109 | */ 110 | static BSON_INLINE uint32_t 111 | bson_oid_hash_unsafe (const bson_oid_t *oid) 112 | { 113 | uint32_t hash = 5381; 114 | uint32_t i; 115 | 116 | for (i = 0; i < sizeof oid->bytes; i++) { 117 | hash = ((hash << 5) + hash) + oid->bytes[i]; 118 | } 119 | 120 | return hash; 121 | } 122 | 123 | 124 | /** 125 | * bson_oid_copy_unsafe: 126 | * @src: A bson_oid_t to copy from. 127 | * @dst: A bson_oid_t to copy into. 128 | * 129 | * Copies the contents of @src into @dst. This function is meant to be as 130 | * fast as possible and therefore performs no argument checking. It is the 131 | * callers responsibility to ensure they are passing valid data into the 132 | * function. 133 | */ 134 | static BSON_INLINE void 135 | bson_oid_copy_unsafe (const bson_oid_t *src, bson_oid_t *dst) 136 | { 137 | memcpy (dst, src, sizeof *src); 138 | } 139 | 140 | 141 | /** 142 | * bson_oid_parse_hex_char: 143 | * @hex: A character to parse to its integer value. 144 | * 145 | * This function contains a jump table to return the integer value for a 146 | * character containing a hexadecimal value (0-9, a-f, A-F). If the character 147 | * is not a hexadecimal character then zero is returned. 148 | * 149 | * Returns: An integer between 0 and 15. 150 | */ 151 | static BSON_INLINE uint8_t 152 | bson_oid_parse_hex_char (char hex) 153 | { 154 | switch (hex) { 155 | case '0': 156 | return 0; 157 | case '1': 158 | return 1; 159 | case '2': 160 | return 2; 161 | case '3': 162 | return 3; 163 | case '4': 164 | return 4; 165 | case '5': 166 | return 5; 167 | case '6': 168 | return 6; 169 | case '7': 170 | return 7; 171 | case '8': 172 | return 8; 173 | case '9': 174 | return 9; 175 | case 'a': 176 | case 'A': 177 | return 0xa; 178 | case 'b': 179 | case 'B': 180 | return 0xb; 181 | case 'c': 182 | case 'C': 183 | return 0xc; 184 | case 'd': 185 | case 'D': 186 | return 0xd; 187 | case 'e': 188 | case 'E': 189 | return 0xe; 190 | case 'f': 191 | case 'F': 192 | return 0xf; 193 | default: 194 | return 0; 195 | } 196 | } 197 | 198 | 199 | /** 200 | * bson_oid_init_from_string_unsafe: 201 | * @oid: A bson_oid_t to store the result. 202 | * @str: A 24-character hexadecimal encoded string. 203 | * 204 | * Parses a string containing 24 hexadecimal encoded bytes into a bson_oid_t. 205 | * This function is meant to be as fast as possible and inlined into your 206 | * code. For that purpose, the function does not perform any sort of bounds 207 | * checking and it is the callers responsibility to ensure they are passing 208 | * valid input to the function. 209 | */ 210 | static BSON_INLINE void 211 | bson_oid_init_from_string_unsafe (bson_oid_t *oid, const char *str) 212 | { 213 | int i; 214 | 215 | for (i = 0; i < 12; i++) { 216 | oid->bytes[i] = 217 | (uint8_t) ((bson_oid_parse_hex_char (str[2 * i]) << 4) | (bson_oid_parse_hex_char (str[2 * i + 1]))); 218 | } 219 | } 220 | 221 | 222 | /** 223 | * bson_oid_get_time_t_unsafe: 224 | * @oid: A bson_oid_t. 225 | * 226 | * Fetches the time @oid was generated. 227 | * 228 | * Returns: A time_t containing the UNIX timestamp of generation. 229 | */ 230 | static BSON_INLINE time_t 231 | bson_oid_get_time_t_unsafe (const bson_oid_t *oid) 232 | { 233 | uint32_t t; 234 | 235 | memcpy (&t, oid, sizeof (t)); 236 | return BSON_UINT32_FROM_BE (t); 237 | } 238 | 239 | 240 | BSON_END_DECLS 241 | 242 | 243 | #endif /* BSON_OID_H */ 244 | -------------------------------------------------------------------------------- /bsonjs/bson/bson-prelude.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-present MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #if !defined(BSON_INSIDE) && !defined(BSON_COMPILATION) 18 | #error "Only can be included directly." 19 | #endif 20 | -------------------------------------------------------------------------------- /bsonjs/bson/bson-private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | 20 | #ifndef BSON_PRIVATE_H 21 | #define BSON_PRIVATE_H 22 | 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | 29 | #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) 30 | #define BEGIN_IGNORE_DEPRECATIONS \ 31 | _Pragma ("GCC diagnostic push") _Pragma ("GCC diagnostic ignored \"-Wdeprecated-declarations\"") 32 | #define END_IGNORE_DEPRECATIONS _Pragma ("GCC diagnostic pop") 33 | #elif defined(__clang__) 34 | #define BEGIN_IGNORE_DEPRECATIONS \ 35 | _Pragma ("clang diagnostic push") _Pragma ("clang diagnostic ignored \"-Wdeprecated-declarations\"") 36 | #define END_IGNORE_DEPRECATIONS _Pragma ("clang diagnostic pop") 37 | #else 38 | #define BEGIN_IGNORE_DEPRECATIONS 39 | #define END_IGNORE_DEPRECATIONS 40 | #endif 41 | 42 | 43 | BSON_BEGIN_DECLS 44 | 45 | 46 | typedef enum { 47 | BSON_FLAG_NONE = 0, 48 | BSON_FLAG_INLINE = (1 << 0), 49 | BSON_FLAG_STATIC = (1 << 1), 50 | BSON_FLAG_RDONLY = (1 << 2), 51 | BSON_FLAG_CHILD = (1 << 3), 52 | BSON_FLAG_IN_CHILD = (1 << 4), 53 | BSON_FLAG_NO_FREE = (1 << 5), 54 | } bson_flags_t; 55 | 56 | 57 | #ifdef BSON_MEMCHECK 58 | #define BSON_INLINE_DATA_SIZE (120 - sizeof (char *)) 59 | #else 60 | #define BSON_INLINE_DATA_SIZE 120 61 | #endif 62 | 63 | 64 | BSON_ALIGNED_BEGIN (128) 65 | typedef struct { 66 | bson_flags_t flags; 67 | uint32_t len; 68 | #ifdef BSON_MEMCHECK 69 | char *canary; 70 | #endif 71 | uint8_t data[BSON_INLINE_DATA_SIZE]; 72 | } bson_impl_inline_t BSON_ALIGNED_END (128); 73 | 74 | 75 | BSON_STATIC_ASSERT2 (impl_inline_t, sizeof (bson_impl_inline_t) == 128); 76 | 77 | 78 | BSON_ALIGNED_BEGIN (128) 79 | typedef struct { 80 | bson_flags_t flags; /* flags describing the bson_t */ 81 | /* len is part of the public bson_t declaration. It is not 82 | * exposed through an accessor function. Plus, it's redundant since 83 | * BSON self describes the length in the first four bytes of the 84 | * buffer. */ 85 | uint32_t len; /* length of bson document in bytes */ 86 | bson_t *parent; /* parent bson if a child */ 87 | uint32_t depth; /* Subdocument depth. */ 88 | uint8_t **buf; /* pointer to buffer pointer */ 89 | size_t *buflen; /* pointer to buffer length */ 90 | size_t offset; /* our offset inside *buf */ 91 | uint8_t *alloc; /* buffer that we own. */ 92 | size_t alloclen; /* length of buffer that we own. */ 93 | bson_realloc_func realloc; /* our realloc implementation */ 94 | void *realloc_func_ctx; /* context for our realloc func */ 95 | } bson_impl_alloc_t BSON_ALIGNED_END (128); 96 | 97 | 98 | BSON_STATIC_ASSERT2 (impl_alloc_t, sizeof (bson_impl_alloc_t) <= 128); 99 | 100 | 101 | #define BSON_REGEX_OPTIONS_SORTED "ilmsux" 102 | 103 | BSON_END_DECLS 104 | 105 | 106 | #endif /* BSON_PRIVATE_H */ 107 | -------------------------------------------------------------------------------- /bsonjs/bson/bson-reader.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | 20 | #ifndef BSON_READER_H 21 | #define BSON_READER_H 22 | 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | 29 | BSON_BEGIN_DECLS 30 | 31 | 32 | #define BSON_ERROR_READER_BADFD 1 33 | 34 | 35 | /* 36 | *-------------------------------------------------------------------------- 37 | * 38 | * bson_reader_read_func_t -- 39 | * 40 | * This function is a callback used by bson_reader_t to read the 41 | * next chunk of data from the underlying opaque file descriptor. 42 | * 43 | * This function is meant to operate similar to the read() function 44 | * as part of libc on UNIX-like systems. 45 | * 46 | * Parameters: 47 | * @handle: The handle to read from. 48 | * @buf: The buffer to read into. 49 | * @count: The number of bytes to read. 50 | * 51 | * Returns: 52 | * 0 for end of stream. 53 | * -1 for read failure. 54 | * Greater than zero for number of bytes read into @buf. 55 | * 56 | * Side effects: 57 | * None. 58 | * 59 | *-------------------------------------------------------------------------- 60 | */ 61 | 62 | typedef ssize_t (*bson_reader_read_func_t) (void *handle, /* IN */ 63 | void *buf, /* IN */ 64 | size_t count); /* IN */ 65 | 66 | 67 | /* 68 | *-------------------------------------------------------------------------- 69 | * 70 | * bson_reader_destroy_func_t -- 71 | * 72 | * Destroy callback to release any resources associated with the 73 | * opaque handle. 74 | * 75 | * Parameters: 76 | * @handle: the handle provided to bson_reader_new_from_handle(). 77 | * 78 | * Returns: 79 | * None. 80 | * 81 | * Side effects: 82 | * None. 83 | * 84 | *-------------------------------------------------------------------------- 85 | */ 86 | 87 | typedef void (*bson_reader_destroy_func_t) (void *handle); /* IN */ 88 | 89 | 90 | BSON_EXPORT (bson_reader_t *) 91 | bson_reader_new_from_handle (void *handle, bson_reader_read_func_t rf, bson_reader_destroy_func_t df); 92 | BSON_EXPORT (bson_reader_t *) 93 | bson_reader_new_from_fd (int fd, bool close_on_destroy); 94 | BSON_EXPORT (bson_reader_t *) 95 | bson_reader_new_from_file (const char *path, bson_error_t *error); 96 | BSON_EXPORT (bson_reader_t *) 97 | bson_reader_new_from_data (const uint8_t *data, size_t length); 98 | BSON_EXPORT (void) 99 | bson_reader_destroy (bson_reader_t *reader); 100 | BSON_EXPORT (void) 101 | bson_reader_set_read_func (bson_reader_t *reader, bson_reader_read_func_t func); 102 | BSON_EXPORT (void) 103 | bson_reader_set_destroy_func (bson_reader_t *reader, bson_reader_destroy_func_t func); 104 | BSON_EXPORT (const bson_t *) 105 | bson_reader_read (bson_reader_t *reader, bool *reached_eof); 106 | BSON_EXPORT (off_t) 107 | bson_reader_tell (bson_reader_t *reader); 108 | BSON_EXPORT (void) 109 | bson_reader_reset (bson_reader_t *reader); 110 | 111 | BSON_END_DECLS 112 | 113 | 114 | #endif /* BSON_READER_H */ 115 | -------------------------------------------------------------------------------- /bsonjs/bson/bson-string.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | 20 | #ifndef BSON_STRING_H 21 | #define BSON_STRING_H 22 | 23 | 24 | #include 25 | 26 | #include 27 | #include 28 | 29 | 30 | BSON_BEGIN_DECLS 31 | 32 | 33 | typedef struct { 34 | char *str; 35 | uint32_t len; 36 | uint32_t alloc; 37 | } bson_string_t; 38 | 39 | 40 | BSON_EXPORT (bson_string_t *) 41 | bson_string_new (const char *str); 42 | BSON_EXPORT (char *) 43 | bson_string_free (bson_string_t *string, bool free_segment); 44 | BSON_EXPORT (void) 45 | bson_string_append (bson_string_t *string, const char *str); 46 | BSON_EXPORT (void) 47 | bson_string_append_c (bson_string_t *string, char str); 48 | BSON_EXPORT (void) 49 | bson_string_append_unichar (bson_string_t *string, bson_unichar_t unichar); 50 | BSON_EXPORT (void) 51 | bson_string_append_printf (bson_string_t *string, const char *format, ...) BSON_GNUC_PRINTF (2, 3); 52 | BSON_EXPORT (void) 53 | bson_string_truncate (bson_string_t *string, uint32_t len); 54 | BSON_EXPORT (char *) 55 | bson_strdup (const char *str); 56 | BSON_EXPORT (char *) 57 | bson_strdup_printf (const char *format, ...) BSON_GNUC_PRINTF (1, 2); 58 | BSON_EXPORT (char *) 59 | bson_strdupv_printf (const char *format, va_list args) BSON_GNUC_PRINTF (1, 0); 60 | BSON_EXPORT (char *) 61 | bson_strndup (const char *str, size_t n_bytes); 62 | BSON_EXPORT (void) 63 | bson_strncpy (char *dst, const char *src, size_t size); 64 | BSON_EXPORT (int) 65 | bson_vsnprintf (char *str, size_t size, const char *format, va_list ap) BSON_GNUC_PRINTF (3, 0); 66 | BSON_EXPORT (int) 67 | bson_snprintf (char *str, size_t size, const char *format, ...) BSON_GNUC_PRINTF (3, 4); 68 | BSON_EXPORT (void) 69 | bson_strfreev (char **strv); 70 | BSON_EXPORT (size_t) 71 | bson_strnlen (const char *s, size_t maxlen); 72 | BSON_EXPORT (int64_t) 73 | bson_ascii_strtoll (const char *str, char **endptr, int base); 74 | BSON_EXPORT (int) 75 | bson_strcasecmp (const char *s1, const char *s2); 76 | BSON_EXPORT (bool) 77 | bson_isspace (int c); 78 | 79 | 80 | BSON_END_DECLS 81 | 82 | 83 | #endif /* BSON_STRING_H */ 84 | -------------------------------------------------------------------------------- /bsonjs/bson/bson-timegm-private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | 20 | #ifndef BSON_TIMEGM_PRIVATE_H 21 | #define BSON_TIMEGM_PRIVATE_H 22 | 23 | 24 | #include 25 | #include 26 | 27 | 28 | BSON_BEGIN_DECLS 29 | 30 | /* avoid system-dependent struct tm definitions */ 31 | struct bson_tm { 32 | int64_t tm_sec; /* seconds after the minute [0-60] */ 33 | int64_t tm_min; /* minutes after the hour [0-59] */ 34 | int64_t tm_hour; /* hours since midnight [0-23] */ 35 | int64_t tm_mday; /* day of the month [1-31] */ 36 | int64_t tm_mon; /* months since January [0-11] */ 37 | int64_t tm_year; /* years since 1900 */ 38 | int64_t tm_wday; /* days since Sunday [0-6] */ 39 | int64_t tm_yday; /* days since January 1 [0-365] */ 40 | int64_t tm_isdst; /* Daylight Savings Time flag */ 41 | int64_t tm_gmtoff; /* offset from CUT in seconds */ 42 | const char *tm_zone; /* timezone abbreviation */ 43 | }; 44 | 45 | int64_t 46 | _bson_timegm (struct bson_tm *const tmp); 47 | 48 | BSON_END_DECLS 49 | 50 | 51 | #endif /* BSON_TIMEGM_PRIVATE_H */ 52 | -------------------------------------------------------------------------------- /bsonjs/bson/bson-utf8.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | 20 | #ifndef BSON_UTF8_H 21 | #define BSON_UTF8_H 22 | 23 | 24 | #include 25 | #include 26 | 27 | 28 | BSON_BEGIN_DECLS 29 | 30 | 31 | BSON_EXPORT (bool) 32 | bson_utf8_validate (const char *utf8, size_t utf8_len, bool allow_null); 33 | BSON_EXPORT (char *) 34 | bson_utf8_escape_for_json (const char *utf8, ssize_t utf8_len); 35 | BSON_EXPORT (bson_unichar_t) 36 | bson_utf8_get_char (const char *utf8); 37 | BSON_EXPORT (const char *) 38 | bson_utf8_next_char (const char *utf8); 39 | BSON_EXPORT (void) 40 | bson_utf8_from_unichar (bson_unichar_t unichar, char utf8[6], uint32_t *len); 41 | 42 | 43 | BSON_END_DECLS 44 | 45 | 46 | #endif /* BSON_UTF8_H */ 47 | -------------------------------------------------------------------------------- /bsonjs/bson/bson-value.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | 24 | void 25 | bson_value_copy (const bson_value_t *src, /* IN */ 26 | bson_value_t *dst) /* OUT */ 27 | { 28 | BSON_ASSERT (src); 29 | BSON_ASSERT (dst); 30 | 31 | dst->value_type = src->value_type; 32 | 33 | switch (src->value_type) { 34 | case BSON_TYPE_DOUBLE: 35 | dst->value.v_double = src->value.v_double; 36 | break; 37 | case BSON_TYPE_UTF8: 38 | dst->value.v_utf8.len = src->value.v_utf8.len; 39 | dst->value.v_utf8.str = bson_malloc (src->value.v_utf8.len + 1); 40 | memcpy (dst->value.v_utf8.str, src->value.v_utf8.str, dst->value.v_utf8.len); 41 | dst->value.v_utf8.str[dst->value.v_utf8.len] = '\0'; 42 | break; 43 | case BSON_TYPE_DOCUMENT: 44 | case BSON_TYPE_ARRAY: 45 | dst->value.v_doc.data_len = src->value.v_doc.data_len; 46 | dst->value.v_doc.data = bson_malloc (src->value.v_doc.data_len); 47 | memcpy (dst->value.v_doc.data, src->value.v_doc.data, dst->value.v_doc.data_len); 48 | break; 49 | case BSON_TYPE_BINARY: 50 | dst->value.v_binary.subtype = src->value.v_binary.subtype; 51 | dst->value.v_binary.data_len = src->value.v_binary.data_len; 52 | dst->value.v_binary.data = bson_malloc (src->value.v_binary.data_len); 53 | if (dst->value.v_binary.data_len) { 54 | memcpy (dst->value.v_binary.data, src->value.v_binary.data, dst->value.v_binary.data_len); 55 | } 56 | break; 57 | case BSON_TYPE_OID: 58 | bson_oid_copy (&src->value.v_oid, &dst->value.v_oid); 59 | break; 60 | case BSON_TYPE_BOOL: 61 | dst->value.v_bool = src->value.v_bool; 62 | break; 63 | case BSON_TYPE_DATE_TIME: 64 | dst->value.v_datetime = src->value.v_datetime; 65 | break; 66 | case BSON_TYPE_REGEX: 67 | dst->value.v_regex.regex = bson_strdup (src->value.v_regex.regex); 68 | dst->value.v_regex.options = bson_strdup (src->value.v_regex.options); 69 | break; 70 | case BSON_TYPE_DBPOINTER: 71 | dst->value.v_dbpointer.collection_len = src->value.v_dbpointer.collection_len; 72 | dst->value.v_dbpointer.collection = bson_malloc (src->value.v_dbpointer.collection_len + 1); 73 | memcpy ( 74 | dst->value.v_dbpointer.collection, src->value.v_dbpointer.collection, dst->value.v_dbpointer.collection_len); 75 | dst->value.v_dbpointer.collection[dst->value.v_dbpointer.collection_len] = '\0'; 76 | bson_oid_copy (&src->value.v_dbpointer.oid, &dst->value.v_dbpointer.oid); 77 | break; 78 | case BSON_TYPE_CODE: 79 | dst->value.v_code.code_len = src->value.v_code.code_len; 80 | dst->value.v_code.code = bson_malloc (src->value.v_code.code_len + 1); 81 | memcpy (dst->value.v_code.code, src->value.v_code.code, dst->value.v_code.code_len); 82 | dst->value.v_code.code[dst->value.v_code.code_len] = '\0'; 83 | break; 84 | case BSON_TYPE_SYMBOL: 85 | dst->value.v_symbol.len = src->value.v_symbol.len; 86 | dst->value.v_symbol.symbol = bson_malloc (src->value.v_symbol.len + 1); 87 | memcpy (dst->value.v_symbol.symbol, src->value.v_symbol.symbol, dst->value.v_symbol.len); 88 | dst->value.v_symbol.symbol[dst->value.v_symbol.len] = '\0'; 89 | break; 90 | case BSON_TYPE_CODEWSCOPE: 91 | dst->value.v_codewscope.code_len = src->value.v_codewscope.code_len; 92 | dst->value.v_codewscope.code = bson_malloc (src->value.v_codewscope.code_len + 1); 93 | memcpy (dst->value.v_codewscope.code, src->value.v_codewscope.code, dst->value.v_codewscope.code_len); 94 | dst->value.v_codewscope.code[dst->value.v_codewscope.code_len] = '\0'; 95 | dst->value.v_codewscope.scope_len = src->value.v_codewscope.scope_len; 96 | dst->value.v_codewscope.scope_data = bson_malloc (src->value.v_codewscope.scope_len); 97 | memcpy ( 98 | dst->value.v_codewscope.scope_data, src->value.v_codewscope.scope_data, dst->value.v_codewscope.scope_len); 99 | break; 100 | case BSON_TYPE_INT32: 101 | dst->value.v_int32 = src->value.v_int32; 102 | break; 103 | case BSON_TYPE_TIMESTAMP: 104 | dst->value.v_timestamp.timestamp = src->value.v_timestamp.timestamp; 105 | dst->value.v_timestamp.increment = src->value.v_timestamp.increment; 106 | break; 107 | case BSON_TYPE_INT64: 108 | dst->value.v_int64 = src->value.v_int64; 109 | break; 110 | case BSON_TYPE_DECIMAL128: 111 | dst->value.v_decimal128 = src->value.v_decimal128; 112 | break; 113 | case BSON_TYPE_UNDEFINED: 114 | case BSON_TYPE_NULL: 115 | case BSON_TYPE_MAXKEY: 116 | case BSON_TYPE_MINKEY: 117 | break; 118 | case BSON_TYPE_EOD: 119 | default: 120 | BSON_ASSERT (false); 121 | return; 122 | } 123 | } 124 | 125 | 126 | void 127 | bson_value_destroy (bson_value_t *value) /* IN */ 128 | { 129 | if (!value) { 130 | return; 131 | } 132 | 133 | switch (value->value_type) { 134 | case BSON_TYPE_UTF8: 135 | bson_free (value->value.v_utf8.str); 136 | break; 137 | case BSON_TYPE_DOCUMENT: 138 | case BSON_TYPE_ARRAY: 139 | bson_free (value->value.v_doc.data); 140 | break; 141 | case BSON_TYPE_BINARY: 142 | bson_free (value->value.v_binary.data); 143 | break; 144 | case BSON_TYPE_REGEX: 145 | bson_free (value->value.v_regex.regex); 146 | bson_free (value->value.v_regex.options); 147 | break; 148 | case BSON_TYPE_DBPOINTER: 149 | bson_free (value->value.v_dbpointer.collection); 150 | break; 151 | case BSON_TYPE_CODE: 152 | bson_free (value->value.v_code.code); 153 | break; 154 | case BSON_TYPE_SYMBOL: 155 | bson_free (value->value.v_symbol.symbol); 156 | break; 157 | case BSON_TYPE_CODEWSCOPE: 158 | bson_free (value->value.v_codewscope.code); 159 | bson_free (value->value.v_codewscope.scope_data); 160 | break; 161 | case BSON_TYPE_DOUBLE: 162 | case BSON_TYPE_UNDEFINED: 163 | case BSON_TYPE_OID: 164 | case BSON_TYPE_BOOL: 165 | case BSON_TYPE_DATE_TIME: 166 | case BSON_TYPE_NULL: 167 | case BSON_TYPE_INT32: 168 | case BSON_TYPE_TIMESTAMP: 169 | case BSON_TYPE_INT64: 170 | case BSON_TYPE_DECIMAL128: 171 | case BSON_TYPE_MAXKEY: 172 | case BSON_TYPE_MINKEY: 173 | case BSON_TYPE_EOD: 174 | default: 175 | break; 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /bsonjs/bson/bson-value.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | 20 | #ifndef BSON_VALUE_H 21 | #define BSON_VALUE_H 22 | 23 | 24 | #include 25 | #include 26 | 27 | 28 | BSON_BEGIN_DECLS 29 | 30 | 31 | BSON_EXPORT (void) 32 | bson_value_copy (const bson_value_t *src, bson_value_t *dst); 33 | BSON_EXPORT (void) 34 | bson_value_destroy (bson_value_t *value); 35 | 36 | 37 | BSON_END_DECLS 38 | 39 | 40 | #endif /* BSON_VALUE_H */ 41 | -------------------------------------------------------------------------------- /bsonjs/bson/bson-version-functions.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #include 19 | #include 20 | 21 | 22 | /** 23 | * bson_get_major_version: 24 | * 25 | * Helper function to return the runtime major version of the library. 26 | */ 27 | int 28 | bson_get_major_version (void) 29 | { 30 | return BSON_MAJOR_VERSION; 31 | } 32 | 33 | 34 | /** 35 | * bson_get_minor_version: 36 | * 37 | * Helper function to return the runtime minor version of the library. 38 | */ 39 | int 40 | bson_get_minor_version (void) 41 | { 42 | return BSON_MINOR_VERSION; 43 | } 44 | 45 | /** 46 | * bson_get_micro_version: 47 | * 48 | * Helper function to return the runtime micro version of the library. 49 | */ 50 | int 51 | bson_get_micro_version (void) 52 | { 53 | return BSON_MICRO_VERSION; 54 | } 55 | 56 | /** 57 | * bson_get_version: 58 | * 59 | * Helper function to return the runtime string version of the library. 60 | */ 61 | const char * 62 | bson_get_version (void) 63 | { 64 | return BSON_VERSION_S; 65 | } 66 | 67 | /** 68 | * bson_check_version: 69 | * 70 | * True if libmongoc's version is greater than or equal to the required 71 | * version. 72 | */ 73 | bool 74 | bson_check_version (int required_major, int required_minor, int required_micro) 75 | { 76 | return BSON_CHECK_VERSION (required_major, required_minor, required_micro); 77 | } 78 | -------------------------------------------------------------------------------- /bsonjs/bson/bson-version-functions.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #include 19 | 20 | 21 | #ifndef BSON_VERSION_FUNCTIONS_H 22 | #define BSON_VERSION_FUNCTIONS_H 23 | 24 | #include 25 | 26 | BSON_BEGIN_DECLS 27 | 28 | BSON_EXPORT (int) 29 | bson_get_major_version (void); 30 | BSON_EXPORT (int) 31 | bson_get_minor_version (void); 32 | BSON_EXPORT (int) 33 | bson_get_micro_version (void); 34 | BSON_EXPORT (const char *) 35 | bson_get_version (void); 36 | BSON_EXPORT (bool) 37 | bson_check_version (int required_major, int required_minor, int required_micro); 38 | 39 | BSON_END_DECLS 40 | 41 | #endif /* BSON_VERSION_FUNCTIONS_H */ 42 | -------------------------------------------------------------------------------- /bsonjs/bson/bson-version.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #if !defined(BSON_INSIDE) && !defined(BSON_COMPILATION) 19 | #error "Only can be included directly." 20 | #endif 21 | 22 | // clang-format off 23 | 24 | #ifndef BSON_VERSION_H 25 | #define BSON_VERSION_H 26 | 27 | 28 | /** 29 | * BSON_MAJOR_VERSION: 30 | * 31 | * BSON major version component (e.g. 1 if %BSON_VERSION is 1.2.3) 32 | */ 33 | #define BSON_MAJOR_VERSION (1) 34 | 35 | 36 | /** 37 | * BSON_MINOR_VERSION: 38 | * 39 | * BSON minor version component (e.g. 2 if %BSON_VERSION is 1.2.3) 40 | */ 41 | #define BSON_MINOR_VERSION (27) 42 | 43 | 44 | /** 45 | * BSON_MICRO_VERSION: 46 | * 47 | * BSON micro version component (e.g. 3 if %BSON_VERSION is 1.2.3) 48 | */ 49 | #define BSON_MICRO_VERSION (2) 50 | 51 | 52 | /** 53 | * BSON_PRERELEASE_VERSION: 54 | * 55 | * BSON prerelease version component (e.g. pre if %BSON_VERSION is 1.2.3-pre) 56 | */ 57 | #define BSON_PRERELEASE_VERSION () 58 | 59 | /** 60 | * BSON_VERSION: 61 | * 62 | * BSON version. 63 | */ 64 | #define BSON_VERSION (1.27.2) 65 | 66 | 67 | /** 68 | * BSON_VERSION_S: 69 | * 70 | * BSON version, encoded as a string, useful for printing and 71 | * concatenation. 72 | */ 73 | #define BSON_VERSION_S "1.27.2" 74 | 75 | 76 | /** 77 | * BSON_VERSION_HEX: 78 | * 79 | * BSON version, encoded as an hexadecimal number, useful for 80 | * integer comparisons. 81 | */ 82 | #define BSON_VERSION_HEX (BSON_MAJOR_VERSION << 24 | \ 83 | BSON_MINOR_VERSION << 16 | \ 84 | BSON_MICRO_VERSION << 8) 85 | 86 | 87 | /** 88 | * BSON_CHECK_VERSION: 89 | * @major: required major version 90 | * @minor: required minor version 91 | * @micro: required micro version 92 | * 93 | * Compile-time version checking. Evaluates to %TRUE if the version 94 | * of BSON is greater than or equal to the required one. 95 | */ 96 | #define BSON_CHECK_VERSION(major,minor,micro) \ 97 | (BSON_MAJOR_VERSION > (major) || \ 98 | (BSON_MAJOR_VERSION == (major) && BSON_MINOR_VERSION > (minor)) || \ 99 | (BSON_MAJOR_VERSION == (major) && BSON_MINOR_VERSION == (minor) && \ 100 | BSON_MICRO_VERSION >= (micro))) 101 | 102 | #endif /* BSON_VERSION_H */ 103 | -------------------------------------------------------------------------------- /bsonjs/bson/bson-writer.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #include 19 | #include 20 | 21 | 22 | struct _bson_writer_t { 23 | bool ready; 24 | uint8_t **buf; 25 | size_t *buflen; 26 | size_t offset; 27 | bson_realloc_func realloc_func; 28 | void *realloc_func_ctx; 29 | bson_t b; 30 | }; 31 | 32 | 33 | /* 34 | *-------------------------------------------------------------------------- 35 | * 36 | * bson_writer_new -- 37 | * 38 | * Creates a new instance of bson_writer_t using the buffer, length, 39 | * offset, and realloc() function supplied. 40 | * 41 | * The caller is expected to clean up the structure when finished 42 | * using bson_writer_destroy(). 43 | * 44 | * Parameters: 45 | * @buf: (inout): A pointer to a target buffer. 46 | * @buflen: (inout): A pointer to the buffer length. 47 | * @offset: The offset in the target buffer to start from. 48 | * @realloc_func: A realloc() style function or NULL. 49 | * 50 | * Returns: 51 | * A newly allocated bson_writer_t that should be freed with 52 | * bson_writer_destroy(). 53 | * 54 | * Side effects: 55 | * None. 56 | * 57 | *-------------------------------------------------------------------------- 58 | */ 59 | 60 | bson_writer_t * 61 | bson_writer_new (uint8_t **buf, /* IN */ 62 | size_t *buflen, /* IN */ 63 | size_t offset, /* IN */ 64 | bson_realloc_func realloc_func, /* IN */ 65 | void *realloc_func_ctx) /* IN */ 66 | { 67 | bson_writer_t *writer; 68 | 69 | writer = BSON_ALIGNED_ALLOC0 (bson_writer_t); 70 | writer->buf = buf; 71 | writer->buflen = buflen; 72 | writer->offset = offset; 73 | writer->realloc_func = realloc_func; 74 | writer->realloc_func_ctx = realloc_func_ctx; 75 | writer->ready = true; 76 | 77 | return writer; 78 | } 79 | 80 | 81 | /* 82 | *-------------------------------------------------------------------------- 83 | * 84 | * bson_writer_destroy -- 85 | * 86 | * Cleanup after @writer and release any allocated memory. Note that 87 | * the buffer supplied to bson_writer_new() is NOT freed from this 88 | * method. The caller is responsible for that. 89 | * 90 | * Returns: 91 | * None. 92 | * 93 | * Side effects: 94 | * None. 95 | * 96 | *-------------------------------------------------------------------------- 97 | */ 98 | 99 | void 100 | bson_writer_destroy (bson_writer_t *writer) /* IN */ 101 | { 102 | bson_free (writer); 103 | } 104 | 105 | 106 | /* 107 | *-------------------------------------------------------------------------- 108 | * 109 | * bson_writer_get_length -- 110 | * 111 | * Fetches the current length of the content written by the buffer 112 | * (including the initial offset). This includes a partly written 113 | * document currently being written. 114 | * 115 | * This is useful if you want to check to see if you've passed a given 116 | * memory boundary that cannot be sent in a packet. See 117 | * bson_writer_rollback() to abort the current document being written. 118 | * 119 | * Returns: 120 | * The number of bytes written plus initial offset. 121 | * 122 | * Side effects: 123 | * None. 124 | * 125 | *-------------------------------------------------------------------------- 126 | */ 127 | 128 | size_t 129 | bson_writer_get_length (bson_writer_t *writer) /* IN */ 130 | { 131 | return writer->offset + writer->b.len; 132 | } 133 | 134 | 135 | /* 136 | *-------------------------------------------------------------------------- 137 | * 138 | * bson_writer_begin -- 139 | * 140 | * Begins writing a new document. The caller may use the bson 141 | * structure to write out a new BSON document. When completed, the 142 | * caller must call either bson_writer_end() or 143 | * bson_writer_rollback(). 144 | * 145 | * Parameters: 146 | * @writer: A bson_writer_t. 147 | * @bson: (out): A location for a bson_t*. 148 | * 149 | * Returns: 150 | * true if the underlying realloc was successful; otherwise false. 151 | * 152 | * Side effects: 153 | * @bson is initialized if true is returned. 154 | * 155 | *-------------------------------------------------------------------------- 156 | */ 157 | 158 | bool 159 | bson_writer_begin (bson_writer_t *writer, /* IN */ 160 | bson_t **bson) /* OUT */ 161 | { 162 | bson_impl_alloc_t *b; 163 | bool grown = false; 164 | 165 | BSON_ASSERT (writer); 166 | BSON_ASSERT (writer->ready); 167 | BSON_ASSERT (bson); 168 | 169 | writer->ready = false; 170 | 171 | memset (&writer->b, 0, sizeof (bson_t)); 172 | 173 | b = (bson_impl_alloc_t *) &writer->b; 174 | b->flags = BSON_FLAG_STATIC | BSON_FLAG_NO_FREE; 175 | b->len = 5; 176 | b->parent = NULL; 177 | b->buf = writer->buf; 178 | b->buflen = writer->buflen; 179 | b->offset = writer->offset; 180 | b->alloc = NULL; 181 | b->alloclen = 0; 182 | b->realloc = writer->realloc_func; 183 | b->realloc_func_ctx = writer->realloc_func_ctx; 184 | 185 | while ((writer->offset + writer->b.len) > *writer->buflen) { 186 | if (!writer->realloc_func) { 187 | memset (&writer->b, 0, sizeof (bson_t)); 188 | writer->ready = true; 189 | return false; 190 | } 191 | grown = true; 192 | 193 | if (!*writer->buflen) { 194 | *writer->buflen = 64; 195 | } else { 196 | (*writer->buflen) *= 2; 197 | } 198 | } 199 | 200 | if (grown) { 201 | *writer->buf = writer->realloc_func (*writer->buf, *writer->buflen, writer->realloc_func_ctx); 202 | } 203 | 204 | memset ((*writer->buf) + writer->offset + 1, 0, 5); 205 | (*writer->buf)[writer->offset] = 5; 206 | 207 | *bson = &writer->b; 208 | 209 | return true; 210 | } 211 | 212 | 213 | /* 214 | *-------------------------------------------------------------------------- 215 | * 216 | * bson_writer_end -- 217 | * 218 | * Complete writing of a bson_writer_t to the buffer supplied. 219 | * 220 | * Returns: 221 | * None. 222 | * 223 | * Side effects: 224 | * None. 225 | * 226 | *-------------------------------------------------------------------------- 227 | */ 228 | 229 | void 230 | bson_writer_end (bson_writer_t *writer) /* IN */ 231 | { 232 | BSON_ASSERT (writer); 233 | BSON_ASSERT (!writer->ready); 234 | 235 | writer->offset += writer->b.len; 236 | memset (&writer->b, 0, sizeof (bson_t)); 237 | writer->ready = true; 238 | } 239 | 240 | 241 | /* 242 | *-------------------------------------------------------------------------- 243 | * 244 | * bson_writer_rollback -- 245 | * 246 | * Abort the appending of the current bson_t to the memory region 247 | * managed by @writer. This is useful if you detected that you went 248 | * past a particular memory limit. For example, MongoDB has 48MB 249 | * message limits. 250 | * 251 | * Returns: 252 | * None. 253 | * 254 | * Side effects: 255 | * None. 256 | * 257 | *-------------------------------------------------------------------------- 258 | */ 259 | 260 | void 261 | bson_writer_rollback (bson_writer_t *writer) /* IN */ 262 | { 263 | BSON_ASSERT (writer); 264 | 265 | if (writer->b.len) { 266 | memset (&writer->b, 0, sizeof (bson_t)); 267 | } 268 | 269 | writer->ready = true; 270 | } 271 | -------------------------------------------------------------------------------- /bsonjs/bson/bson-writer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | 20 | #ifndef BSON_WRITER_H 21 | #define BSON_WRITER_H 22 | 23 | 24 | #include "bson.h" 25 | 26 | 27 | BSON_BEGIN_DECLS 28 | 29 | 30 | /** 31 | * bson_writer_t: 32 | * 33 | * The bson_writer_t structure is a helper for writing a series of BSON 34 | * documents to a single malloc() buffer. You can provide a realloc() style 35 | * function to grow the buffer as you go. 36 | * 37 | * This is useful if you want to build a series of BSON documents right into 38 | * the target buffer for an outgoing packet. The offset parameter allows you to 39 | * start at an offset of the target buffer. 40 | */ 41 | typedef struct _bson_writer_t bson_writer_t; 42 | 43 | 44 | BSON_EXPORT (bson_writer_t *) 45 | bson_writer_new (uint8_t **buf, size_t *buflen, size_t offset, bson_realloc_func realloc_func, void *realloc_func_ctx); 46 | BSON_EXPORT (void) 47 | bson_writer_destroy (bson_writer_t *writer); 48 | BSON_EXPORT (size_t) 49 | bson_writer_get_length (bson_writer_t *writer); 50 | BSON_EXPORT (bool) 51 | bson_writer_begin (bson_writer_t *writer, bson_t **bson); 52 | BSON_EXPORT (void) 53 | bson_writer_end (bson_writer_t *writer); 54 | BSON_EXPORT (void) 55 | bson_writer_rollback (bson_writer_t *writer); 56 | 57 | 58 | BSON_END_DECLS 59 | 60 | 61 | #endif /* BSON_WRITER_H */ 62 | -------------------------------------------------------------------------------- /bsonjs/bsonjs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "bsonjs.h" 18 | #include 19 | 20 | 21 | PyDoc_STRVAR(bsonjs_documentation, 22 | "A library for converting between BSON and MongoDB Extended JSON.\n" 23 | "\n" 24 | "This module provides the functions `dump(s)` and `load(s)` that wrap\n" 25 | "native libbson functions. https://github.com/mongodb/libbson"); 26 | 27 | char * 28 | bson_str_to_json(const char *bson, size_t bson_len, size_t *json_len, const 29 | int mode) 30 | { 31 | char *json; 32 | const bson_t *b; 33 | bson_reader_t *reader; 34 | 35 | reader = bson_reader_new_from_data((const uint8_t *)bson, bson_len); 36 | 37 | b = bson_reader_read(reader, NULL); 38 | if (!b) { 39 | PyErr_SetString(PyExc_ValueError, "invalid BSON document"); 40 | bson_reader_destroy(reader); 41 | return NULL; 42 | } 43 | if (mode == 1) { 44 | json = bson_as_relaxed_extended_json(b, json_len); 45 | } else if (mode == 2) { 46 | json = bson_as_canonical_extended_json(b, json_len); 47 | } else if (mode == 0) { 48 | json = bson_as_json(b, json_len); 49 | } else { 50 | PyErr_SetString(PyExc_ValueError, "The value of mode must be one of: " 51 | "bsonjs.RELAXED, bsonjs.LEGACY, " 52 | "or bsonjs.CANONICAL."); 53 | bson_reader_destroy(reader); 54 | return NULL; 55 | } 56 | 57 | bson_reader_destroy(reader); 58 | 59 | if (!json) { 60 | PyErr_SetString(PyExc_ValueError, "invalid BSON document"); 61 | return NULL; 62 | } 63 | 64 | return json; 65 | } 66 | 67 | static PyObject * 68 | _dumps(PyObject *bson, int mode) 69 | { 70 | PyObject *rv; 71 | char *bson_str, *json; 72 | Py_ssize_t bson_len; 73 | size_t json_len; 74 | 75 | if (PyBytes_AsStringAndSize(bson, &bson_str, &bson_len) == -1) { 76 | // error is already set 77 | return NULL; 78 | } 79 | json = bson_str_to_json(bson_str, (size_t)bson_len, &json_len, mode); 80 | if (!json) { 81 | // error is already set 82 | return NULL; 83 | } 84 | 85 | rv = Py_BuildValue("s#", json, json_len); 86 | bson_free((void *)json); 87 | return rv; 88 | } 89 | 90 | PyDoc_STRVAR(dump__doc__, 91 | "dump(bson, fp)\n" 92 | "\n" 93 | "Decode the BSON bytes object `bson` to MongoDB Extended JSON 2.0 relaxed\n" 94 | "mode written to `fp` (a `.write()`-supporting file-like object).\n" 95 | "\n" 96 | "Accepts a keyword argument `mode` which can be one of `bsonjs.RELAXED`\n" 97 | "`bsonjs.CANONICAL`, or `bsonjs.LEGACY`. Where `RELAXED` and `CANONICAL` \n" 98 | "correspond to the MongoDB Extended JSON 2.0 modes and `LEGACY` uses libbson's\n" 99 | "legacy JSON format"); 100 | 101 | static PyObject * 102 | dump(PyObject *self, PyObject *args, PyObject *kwargs) 103 | { 104 | PyObject *bson, *file, *json; 105 | static char *kwlist[] = {"", "", "mode", NULL}; 106 | int mode = 1; 107 | if (!PyArg_ParseTupleAndKeywords(args, kwargs, "SO|i", kwlist, &bson, 108 | &file, 109 | &mode)) { 110 | return NULL; 111 | } 112 | 113 | json = _dumps(bson, mode); 114 | if (!json) { 115 | return NULL; 116 | } 117 | 118 | if (PyFile_WriteObject(json, file, Py_PRINT_RAW) == -1) { 119 | Py_DECREF(json); 120 | return NULL; 121 | } 122 | 123 | Py_DECREF(json); 124 | Py_RETURN_NONE; 125 | } 126 | 127 | PyDoc_STRVAR(dumps__doc__, 128 | "dumps(bson) -> str\n" 129 | "\n" 130 | "Decode the BSON bytes object `bson` to MongoDB Extended JSON 2.0 relaxed\n" 131 | "mode. \n" 132 | "Accepts a keyword argument `mode` which can be one of `bsonjs.RELAXED`\n" 133 | "`bsonjs.CANONICAL`, or `bsonjs.LEGACY`. Where `RELAXED` and `CANONICAL` \n" 134 | "correspond to the MongoDB Extended JSON 2.0 modes and `LEGACY` uses libbson's\n" 135 | "legacy JSON format"); 136 | static PyObject * 137 | dumps(PyObject *self, PyObject *args, PyObject *kwargs) 138 | { 139 | PyObject *bson; 140 | int mode = 1; 141 | static char *kwlist[] = {"", "mode", NULL}; 142 | if (!PyArg_ParseTupleAndKeywords(args, kwargs, "S|i", kwlist, &bson, 143 | &mode)) { 144 | return NULL; 145 | } 146 | return _dumps(bson, mode); 147 | } 148 | 149 | static PyObject * 150 | _json_to_bson(const char *json, Py_ssize_t json_len) { 151 | bson_t b = BSON_INITIALIZER; 152 | bson_error_t error = {0}; 153 | PyObject *bson; 154 | 155 | if (!bson_init_from_json(&b, json, (ssize_t)json_len, &error)) { 156 | char *msg = "no JSON object could be decoded"; 157 | if (strlen(error.message)) { 158 | msg = error.message; 159 | } 160 | PyErr_SetString(PyExc_ValueError, msg); 161 | return NULL; 162 | } 163 | 164 | bson = PyBytes_FromStringAndSize((const char *)bson_get_data(&b), b.len); 165 | 166 | bson_destroy(&b); 167 | return bson; 168 | } 169 | 170 | 171 | PyDoc_STRVAR(load__doc__, 172 | "load(fp) -> bytes\n" 173 | "\n" 174 | "Encode `fp` (a `.read()`-supporting file-like object containing a MongoDB\n" 175 | "Extended JSON document) to BSON bytes.\n" 176 | "This function wraps `bson_init_from_json` from libbson."); 177 | 178 | static PyObject * 179 | load(PyObject *self, PyObject *args) 180 | { 181 | char *json_str; 182 | Py_ssize_t json_len; 183 | PyObject *file, *json, *bson; 184 | 185 | if (!PyArg_ParseTuple(args, "O", &file)) { 186 | return NULL; 187 | } 188 | 189 | json = PyObject_CallMethod(file, "read", NULL); 190 | if (!json) { 191 | return NULL; 192 | } 193 | 194 | // Convert unicode to bytes 195 | if (PyUnicode_Check(json)) { 196 | PyObject *json_utf = PyUnicode_AsUTF8String(json); 197 | Py_DECREF(json); 198 | if (!json_utf) { 199 | return NULL; 200 | } 201 | json = json_utf; 202 | } 203 | 204 | if (PyBytes_AsStringAndSize(json, &json_str, &json_len) == -1) { 205 | return NULL; 206 | } 207 | 208 | bson = _json_to_bson(json_str, json_len); 209 | 210 | Py_DECREF(json); 211 | return bson; 212 | } 213 | 214 | PyDoc_STRVAR(loads__doc__, 215 | "load(json) -> bytes\n" 216 | "\n" 217 | "Encode `json` (a `str` or `bytes-like object` containing a MongoDB Extended\n" 218 | "JSON document) to BSON bytes.\n" 219 | "This function wraps `bson_init_from_json` from libbson."); 220 | 221 | static PyObject * 222 | loads(PyObject *self, PyObject *args) 223 | { 224 | const char *json_str; 225 | Py_ssize_t json_len; 226 | 227 | if (!PyArg_ParseTuple(args, "s#", &json_str, &json_len)) { 228 | return NULL; 229 | } 230 | 231 | return _json_to_bson(json_str, json_len); 232 | } 233 | 234 | static PyMethodDef BsonjsClientMethods[] = { 235 | {"dump", (PyCFunction)(void(*)(void))dump, METH_VARARGS | METH_KEYWORDS, dump__doc__}, 236 | {"dumps", (PyCFunction)(void(*)(void))dumps, METH_VARARGS | METH_KEYWORDS, dumps__doc__}, 237 | {"load", load, METH_VARARGS, load__doc__}, 238 | {"loads", loads, METH_VARARGS, loads__doc__}, 239 | {NULL, NULL, 0, NULL} 240 | }; 241 | 242 | 243 | #define INITERROR return NULL 244 | 245 | static struct PyModuleDef moduledef = { 246 | PyModuleDef_HEAD_INIT, 247 | "bsonjs", 248 | bsonjs_documentation, 249 | -1, 250 | BsonjsClientMethods, 251 | NULL, 252 | NULL, 253 | NULL, 254 | NULL, 255 | }; 256 | 257 | PyMODINIT_FUNC 258 | PyInit_bsonjs(void) 259 | { 260 | PyObject* module = PyModule_Create(&moduledef); 261 | if (module == NULL) { 262 | INITERROR; 263 | } 264 | 265 | if (PyModule_AddObject(module, 266 | "__version__", 267 | PyUnicode_FromString("0.3.0"))) { 268 | Py_DECREF(module); 269 | INITERROR; 270 | } 271 | PyModule_AddIntConstant(module, "LEGACY", 0); 272 | PyModule_AddIntConstant(module, "RELAXED", 1); 273 | PyModule_AddIntConstant(module, "CANONICAL", 2); 274 | return module; 275 | } 276 | -------------------------------------------------------------------------------- /bsonjs/bsonjs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #define PY_SSIZE_T_CLEAN /* Make "s#" use Py_ssize_t rather than int. */ 18 | #include 19 | 20 | static PyObject * 21 | dump(PyObject *self, PyObject *args, PyObject *kwargs); 22 | 23 | static PyObject * 24 | dumps(PyObject *self, PyObject *args, PyObject *kwargs); 25 | 26 | static PyObject * 27 | load(PyObject *self, PyObject *args); 28 | 29 | static PyObject * 30 | loads(PyObject *self, PyObject *args); 31 | 32 | -------------------------------------------------------------------------------- /bsonjs/common/common-b64-private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-present MongoDB Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "common-prelude.h" 18 | 19 | #ifndef COMMON_B64_PRIVATE_H 20 | #define COMMON_B64_PRIVATE_H 21 | 22 | #include 23 | 24 | #define mcommon_b64_ntop_calculate_target_size COMMON_NAME (b64_ntop_calculate_target_size) 25 | #define mcommon_b64_pton_calculate_target_size COMMON_NAME (b64_pton_calculate_target_size) 26 | #define mcommon_b64_ntop COMMON_NAME (b64_ntop) 27 | #define mcommon_b64_pton COMMON_NAME (b64_pton) 28 | 29 | /** 30 | * When encoding from "network" (raw data) to "presentation" (base64 encoded). 31 | * Includes the trailing null byte. */ 32 | size_t 33 | mcommon_b64_ntop_calculate_target_size (size_t raw_size); 34 | 35 | /* When encoding from "presentation" (base64 encoded) to "network" (raw data). 36 | * This may be an overestimate if the base64 data includes spaces. For a more 37 | * accurate size, call b64_pton (src, NULL, 0), which will read the src 38 | * data and return an exact size. */ 39 | size_t 40 | mcommon_b64_pton_calculate_target_size (size_t base64_encoded_size); 41 | 42 | /* Returns the number of bytes written (excluding NULL byte) to target on 43 | * success or -1 on error. Adds a trailing NULL byte. 44 | * Encodes from "network" (raw data) to "presentation" (base64 encoded), 45 | * hence the obscure name "ntop". 46 | */ 47 | int 48 | mcommon_b64_ntop (uint8_t const *src, size_t srclength, char *target, size_t targsize); 49 | 50 | /** If target is not NULL, the number of bytes written to target on success or 51 | * -1 on error. If target is NULL, returns the exact number of bytes that would 52 | * be written to target on decoding. Encodes from "presentation" (base64 53 | * encoded) to "network" (raw data), hence the obscure name "pton". 54 | */ 55 | int 56 | mcommon_b64_pton (char const *src, uint8_t *target, size_t targsize); 57 | 58 | #endif /* COMMON_B64_PRIVATE_H */ 59 | -------------------------------------------------------------------------------- /bsonjs/common/common-config.h: -------------------------------------------------------------------------------- 1 | #ifndef COMMON_CONFIG_H 2 | #define COMMON_CONFIG_H 3 | 4 | #define MONGOC_ENABLE_DEBUG_ASSERTIONS 0 5 | 6 | #if MONGOC_ENABLE_DEBUG_ASSERTIONS != 1 7 | # undef MONGOC_ENABLE_DEBUG_ASSERTIONS 8 | #endif 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /bsonjs/common/common-macros-private.h: -------------------------------------------------------------------------------- 1 | 2 | #include "common-prelude.h" 3 | 4 | #ifndef MONGO_C_DRIVER_COMMON_MACROS_H 5 | #define MONGO_C_DRIVER_COMMON_MACROS_H 6 | 7 | /* Test only assert. Is a noop unless -DENABLE_DEBUG_ASSERTIONS=ON is set 8 | * during configuration */ 9 | #if defined(MONGOC_ENABLE_DEBUG_ASSERTIONS) && defined(BSON_OS_UNIX) 10 | #define MONGOC_DEBUG_ASSERT(statement) BSON_ASSERT (statement) 11 | #else 12 | #define MONGOC_DEBUG_ASSERT(statement) ((void) 0) 13 | #endif 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /bsonjs/common/common-md5-private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-present MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "common-prelude.h" 18 | 19 | #ifndef COMMON_MD5_PRIVATE_H 20 | #define COMMON_MD5_PRIVATE_H 21 | 22 | #include "bson/bson.h" 23 | 24 | BSON_BEGIN_DECLS 25 | 26 | #define mcommon_md5_init COMMON_NAME (md5_init) 27 | #define mcommon_md5_append COMMON_NAME (md5_append) 28 | #define mcommon_md5_finish COMMON_NAME (md5_finish) 29 | 30 | void 31 | mcommon_md5_init (bson_md5_t *pms); 32 | void 33 | mcommon_md5_append (bson_md5_t *pms, const uint8_t *data, uint32_t nbytes); 34 | void 35 | mcommon_md5_finish (bson_md5_t *pms, uint8_t digest[16]); 36 | 37 | BSON_END_DECLS 38 | 39 | #endif /* COMMON_MD5_PRIVATE_H */ 40 | -------------------------------------------------------------------------------- /bsonjs/common/common-prelude.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-present MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #if !defined(MONGOC_INSIDE) && !defined(MONGOC_COMPILATION) && !defined(BSON_COMPILATION) && !defined(BSON_INSIDE) 18 | #error "Only or can be included directly." 19 | #endif 20 | 21 | #define COMMON_NAME_1(a, b) COMMON_NAME_2 (a, b) 22 | #define COMMON_NAME_2(a, b) a##_##b 23 | 24 | #if defined(MCOMMON_NAME_PREFIX) && !defined(__INTELLISENSE__) 25 | #define COMMON_NAME(Name) COMMON_NAME_1 (MCOMMON_NAME_PREFIX, Name) 26 | #else 27 | #define COMMON_NAME(Name) COMMON_NAME_1 (mcommon, Name) 28 | #endif 29 | -------------------------------------------------------------------------------- /bsonjs/common/common-thread-private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "common-prelude.h" 18 | #include "common-config.h" 19 | #include "common-macros-private.h" 20 | 21 | #ifndef COMMON_THREAD_PRIVATE_H 22 | #define COMMON_THREAD_PRIVATE_H 23 | 24 | #define BSON_INSIDE 25 | #include "bson/bson-compat.h" 26 | #include "bson/bson-config.h" 27 | #include "bson/bson-macros.h" 28 | #undef BSON_INSIDE 29 | 30 | BSON_BEGIN_DECLS 31 | 32 | #define mcommon_thread_create COMMON_NAME (thread_create) 33 | #define mcommon_thread_join COMMON_NAME (thread_join) 34 | 35 | #if defined(BSON_OS_UNIX) 36 | #include 37 | 38 | #define BSON_ONCE_FUN(n) void n (void) 39 | #define BSON_ONCE_RETURN return 40 | #define BSON_ONCE_INIT PTHREAD_ONCE_INIT 41 | #define bson_once(o, c) \ 42 | do { \ 43 | BSON_ASSERT (pthread_once ((o), (c)) == 0); \ 44 | } while (0) 45 | #define bson_once_t pthread_once_t 46 | #define bson_thread_t pthread_t 47 | #define BSON_THREAD_FUN(_function_name, _arg_name) void *(_function_name) (void *(_arg_name)) 48 | #define BSON_THREAD_FUN_TYPE(_function_name) void *(*(_function_name)) (void *) 49 | #define BSON_THREAD_RETURN return NULL 50 | 51 | /* this macro can be defined as a as a build configuration option 52 | * with -DENABLE_DEBUG_ASSERTIONS=ON. its purpose is to allow for functions 53 | * that require a mutex to be locked on entry to assert that the mutex 54 | * is actually locked. 55 | * this can prevent bugs where a caller forgets to lock the mutex. */ 56 | 57 | #ifndef MONGOC_ENABLE_DEBUG_ASSERTIONS 58 | 59 | #define bson_mutex_destroy(m) \ 60 | do { \ 61 | BSON_ASSERT (pthread_mutex_destroy ((m)) == 0); \ 62 | } while (0) 63 | 64 | #define bson_mutex_init(_n) \ 65 | do { \ 66 | BSON_ASSERT (pthread_mutex_init ((_n), NULL) == 0); \ 67 | } while (0) 68 | 69 | #define bson_mutex_lock(m) \ 70 | do { \ 71 | BSON_ASSERT (pthread_mutex_lock ((m)) == 0); \ 72 | } while (0) 73 | 74 | #define bson_mutex_t pthread_mutex_t 75 | 76 | #define bson_mutex_unlock(m) \ 77 | do { \ 78 | BSON_ASSERT (pthread_mutex_unlock ((m)) == 0); \ 79 | } while (0) 80 | 81 | #else 82 | typedef struct { 83 | pthread_t lock_owner; 84 | pthread_mutex_t wrapped_mutex; 85 | bool valid_tid; 86 | } bson_mutex_t; 87 | 88 | #define bson_mutex_destroy(mutex) \ 89 | do { \ 90 | BSON_ASSERT (pthread_mutex_destroy (&(mutex)->wrapped_mutex) == 0); \ 91 | } while (0); 92 | 93 | #define bson_mutex_init(mutex) \ 94 | do { \ 95 | BSON_ASSERT (pthread_mutex_init (&(mutex)->wrapped_mutex, NULL) == 0); \ 96 | (mutex)->valid_tid = false; \ 97 | } while (0); 98 | 99 | #define bson_mutex_lock(mutex) \ 100 | do { \ 101 | BSON_ASSERT (pthread_mutex_lock (&(mutex)->wrapped_mutex) == 0); \ 102 | (mutex)->lock_owner = pthread_self (); \ 103 | (mutex)->valid_tid = true; \ 104 | } while (0); 105 | 106 | #define bson_mutex_unlock(mutex) \ 107 | do { \ 108 | (mutex)->valid_tid = false; \ 109 | BSON_ASSERT (pthread_mutex_unlock (&(mutex)->wrapped_mutex) == 0); \ 110 | } while (0); 111 | 112 | #endif 113 | 114 | #else 115 | #include 116 | #define BSON_ONCE_FUN(n) BOOL CALLBACK n (PINIT_ONCE _ignored_a, PVOID _ignored_b, PVOID *_ignored_c) 117 | #define BSON_ONCE_INIT INIT_ONCE_STATIC_INIT 118 | #define BSON_ONCE_RETURN return true 119 | #define bson_mutex_destroy DeleteCriticalSection 120 | #define bson_mutex_init InitializeCriticalSection 121 | #define bson_mutex_lock EnterCriticalSection 122 | #define bson_mutex_t CRITICAL_SECTION 123 | #define bson_mutex_unlock LeaveCriticalSection 124 | #define bson_once(o, c) \ 125 | do { \ 126 | BSON_ASSERT (InitOnceExecuteOnce ((o), (c), NULL, NULL)); \ 127 | } while (0) 128 | #define bson_once_t INIT_ONCE 129 | #define bson_thread_t HANDLE 130 | #define BSON_THREAD_FUN(_function_name, _arg_name) unsigned (__stdcall _function_name) (void *(_arg_name)) 131 | #define BSON_THREAD_FUN_TYPE(_function_name) unsigned (__stdcall * _function_name) (void *) 132 | #define BSON_THREAD_RETURN return 0 133 | #endif 134 | 135 | /* Functions that require definitions get the common prefix (_mongoc for 136 | * libmongoc or _bson for libbson) to avoid duplicate symbols when linking both 137 | * libbson and libmongoc statically. */ 138 | int 139 | mcommon_thread_join (bson_thread_t thread); 140 | // mcommon_thread_create returns 0 on success. Returns a non-zero error code on 141 | // error. Callers may use `bson_strerror_r` to get an error message from the 142 | // returned error code. 143 | int 144 | mcommon_thread_create (bson_thread_t *thread, BSON_THREAD_FUN_TYPE (func), void *arg); 145 | 146 | #if defined(MONGOC_ENABLE_DEBUG_ASSERTIONS) && defined(BSON_OS_UNIX) 147 | #define mcommon_mutex_is_locked COMMON_NAME (mutex_is_locked) 148 | bool 149 | mcommon_mutex_is_locked (bson_mutex_t *mutex); 150 | #endif 151 | 152 | /** 153 | * @brief A shared mutex (a read-write lock) 154 | * 155 | * A shared mutex can be locked in 'shared' mode or 'exclusive' mode. Only one 156 | * thread may hold exclusive mode at a time. Any number of threads may hold 157 | * the lock in shared mode simultaneously. No thread can hold in exclusive mode 158 | * while another thread holds in shared mode, and vice-versa. 159 | */ 160 | typedef struct bson_shared_mutex_t { 161 | BSON_IF_WINDOWS (SRWLOCK native;) 162 | BSON_IF_POSIX (pthread_rwlock_t native;) 163 | } bson_shared_mutex_t; 164 | 165 | static BSON_INLINE void 166 | bson_shared_mutex_init (bson_shared_mutex_t *mtx) 167 | { 168 | BSON_IF_WINDOWS (InitializeSRWLock (&mtx->native)); 169 | BSON_IF_POSIX (BSON_ASSERT (pthread_rwlock_init (&mtx->native, NULL) == 0);) 170 | } 171 | 172 | static BSON_INLINE void 173 | bson_shared_mutex_destroy (bson_shared_mutex_t *mtx) 174 | { 175 | BSON_IF_WINDOWS ((void) mtx;) 176 | BSON_IF_POSIX (BSON_ASSERT (pthread_rwlock_destroy (&mtx->native) == 0);) 177 | } 178 | 179 | static BSON_INLINE void 180 | bson_shared_mutex_lock_shared (bson_shared_mutex_t *mtx) 181 | { 182 | BSON_IF_WINDOWS (AcquireSRWLockShared (&mtx->native);) 183 | BSON_IF_POSIX (BSON_ASSERT (pthread_rwlock_rdlock (&mtx->native) == 0);) 184 | } 185 | 186 | static BSON_INLINE void 187 | bson_shared_mutex_lock (bson_shared_mutex_t *mtx) 188 | { 189 | BSON_IF_WINDOWS (AcquireSRWLockExclusive (&mtx->native);) 190 | BSON_IF_POSIX (BSON_ASSERT (pthread_rwlock_wrlock (&mtx->native) == 0);) 191 | } 192 | 193 | static BSON_INLINE void 194 | bson_shared_mutex_unlock (bson_shared_mutex_t *mtx) 195 | { 196 | BSON_IF_WINDOWS (ReleaseSRWLockExclusive (&mtx->native);) 197 | BSON_IF_POSIX (BSON_ASSERT (pthread_rwlock_unlock (&mtx->native) == 0);) 198 | } 199 | 200 | static BSON_INLINE void 201 | bson_shared_mutex_unlock_shared (bson_shared_mutex_t *mtx) 202 | { 203 | BSON_IF_WINDOWS (ReleaseSRWLockShared (&mtx->native);) 204 | BSON_IF_POSIX (BSON_ASSERT (pthread_rwlock_unlock (&mtx->native) == 0);) 205 | } 206 | 207 | BSON_END_DECLS 208 | 209 | #endif /* COMMON_THREAD_PRIVATE_H */ 210 | -------------------------------------------------------------------------------- /bsonjs/common/common-thread.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-present MongoDB, Inc. 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 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "common-thread-private.h" 18 | 19 | #include 20 | 21 | #if defined(BSON_OS_UNIX) 22 | int 23 | mcommon_thread_create (bson_thread_t *thread, BSON_THREAD_FUN_TYPE (func), void *arg) 24 | { 25 | BSON_ASSERT_PARAM (thread); 26 | BSON_ASSERT_PARAM (func); 27 | BSON_ASSERT (arg || true); // optional. 28 | return pthread_create (thread, NULL, func, arg); 29 | } 30 | int 31 | mcommon_thread_join (bson_thread_t thread) 32 | { 33 | return pthread_join (thread, NULL); 34 | } 35 | 36 | #if defined(MONGOC_ENABLE_DEBUG_ASSERTIONS) && defined(BSON_OS_UNIX) 37 | bool 38 | mcommon_mutex_is_locked (bson_mutex_t *mutex) 39 | { 40 | return mutex->valid_tid && pthread_equal (pthread_self (), mutex->lock_owner); 41 | } 42 | #endif 43 | 44 | #else 45 | int 46 | mcommon_thread_create (bson_thread_t *thread, BSON_THREAD_FUN_TYPE (func), void *arg) 47 | { 48 | BSON_ASSERT_PARAM (thread); 49 | BSON_ASSERT_PARAM (func); 50 | BSON_ASSERT (arg || true); // optional. 51 | 52 | *thread = (HANDLE) _beginthreadex (NULL, 0, func, arg, 0, NULL); 53 | if (0 == *thread) { 54 | return errno; 55 | } 56 | return 0; 57 | } 58 | int 59 | mcommon_thread_join (bson_thread_t thread) 60 | { 61 | int ret; 62 | 63 | /* zero indicates success for WaitForSingleObject. */ 64 | ret = WaitForSingleObject (thread, INFINITE); 65 | if (WAIT_OBJECT_0 != ret) { 66 | return ret; 67 | } 68 | /* zero indicates failure for CloseHandle. */ 69 | ret = CloseHandle (thread); 70 | if (0 == ret) { 71 | return 1; 72 | } 73 | return 0; 74 | } 75 | #endif 76 | -------------------------------------------------------------------------------- /bsonjs/jsonsl/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2015 M. Nunberg, mnunberg@haskalah.org 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /build-wheels.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -ex 2 | 3 | if [ "$#" -ne 1 ]; then 4 | echo "$0 requires one argument: " 5 | echo "For example: $0 /user/home/git/python-bsonjs" 6 | exit 1 7 | fi 8 | 9 | BSONJS_SOURCE_DIRECTORY="$1" 10 | cd "$BSONJS_SOURCE_DIRECTORY" 11 | 12 | ls -la 13 | if [ -z "$PYTHON_BINARY" ]; then 14 | PYTHON_BINARY="python" 15 | fi 16 | 17 | $PYTHON_BINARY --version 18 | 19 | if [ ! "$(uname)" == "Linux" ]; then 20 | $PYTHON_BINARY -m pip install wheel 21 | fi 22 | # Build limited abi3 wheel. 23 | $PYTHON_BINARY setup.py bdist_wheel 24 | # https://github.com/pypa/manylinux/issues/49 25 | rm -rf build 26 | 27 | # Audit wheels and write multilinux1 tag 28 | # Only if on linux 29 | if [ "$(uname)" == "Linux" ]; then 30 | for whl in dist/*.whl; do 31 | # Skip already built manylinux wheels. 32 | if [[ "$whl" != *"manylinux"* ]]; then 33 | auditwheel repair $whl -w dist 34 | rm $whl 35 | fi 36 | done 37 | fi 38 | 39 | # Install packages and test. 40 | for PYBIN in /opt/python/*/bin; do 41 | if [[ ! "${PYBIN}" =~ (39|310) || "${PYBIN}" =~ (pypy) ]]; then 42 | continue 43 | fi 44 | "${PYBIN}/pip" install python-bsonjs --no-index -f dist 45 | # The tests require PyMongo. 46 | "${PYBIN}/pip" install 'pymongo>=4' 47 | for TEST_FILE in "${BSONJS_SOURCE_DIRECTORY}"/test/test_*.py; do 48 | "${PYBIN}/python" "$TEST_FILE" -v 49 | done 50 | done 51 | 52 | ls -lah dist 53 | -------------------------------------------------------------------------------- /docker-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ "$#" -ne 0 ]; then 4 | echo "$0 takes no arguments" 5 | exit 1 6 | fi 7 | 8 | set -e -x 9 | 10 | 11 | DOCKER_IMAGE=quay.io/pypa/manylinux1_x86_64 12 | docker pull "$DOCKER_IMAGE" 13 | docker run --rm -v `pwd`:/io "$DOCKER_IMAGE" /io/build-wheels.sh /io 14 | 15 | DOCKER_IMAGE=quay.io/pypa/manylinux1_i686 16 | docker pull "$DOCKER_IMAGE" 17 | docker run --rm -v `pwd`:/io "$DOCKER_IMAGE" linux32 /io/build-wheels.sh /io 18 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools>=65"] 3 | build-backend = "setuptools.build_meta" 4 | 5 | [tool.setuptools] 6 | packages = [] 7 | 8 | [project] 9 | name = "python-bsonjs" 10 | version = "0.7.0.dev0" 11 | description = "A library for converting between BSON and JSON." 12 | readme = "README.rst" 13 | license = { file = "LICENSE" } 14 | requires-python = ">=3.9" 15 | authors = [ 16 | { name = "Shane Harvey", email = "shane.harvey@mongodb.com" }, 17 | ] 18 | keywords = [ 19 | "BSON", 20 | "JSON", 21 | "PyMongo", 22 | ] 23 | classifiers = [ 24 | "Development Status :: 4 - Beta", 25 | "Intended Audience :: Developers", 26 | "License :: OSI Approved :: Apache Software License", 27 | "Operating System :: MacOS :: MacOS X", 28 | "Operating System :: Microsoft :: Windows", 29 | "Operating System :: POSIX", 30 | "Programming Language :: Python :: 3", 31 | "Programming Language :: Python :: 3 :: Only", 32 | "Programming Language :: Python :: 3.9", 33 | "Programming Language :: Python :: Implementation :: CPython", 34 | "Programming Language :: Python :: 3.10", 35 | "Programming Language :: Python :: 3.11", 36 | "Programming Language :: Python :: 3.12", 37 | "Programming Language :: Python :: 3.13", 38 | ] 39 | 40 | [project.urls] 41 | Homepage = "https://github.com/mongodb-labs/python-bsonjs" 42 | 43 | [project.optional-dependencies] 44 | test = ["pymongo>=4", "pytest"] -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 MongoDB, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import glob 16 | import sys 17 | 18 | from setuptools import setup, Extension 19 | 20 | libraries = [] 21 | if sys.platform == "win32": 22 | libraries.append("ws2_32") 23 | elif sys.platform != "darwin": 24 | # librt may be needed for clock_gettime() 25 | libraries.append("rt") 26 | 27 | setup( 28 | ext_modules=[ 29 | Extension( 30 | "bsonjs", 31 | sources=["bsonjs/bsonjs.c"] + glob.glob("bsonjs/*/*.c"), 32 | include_dirs=["bsonjs", 33 | "bsonjs/bson", 34 | "bsonjs/jsonsl", 35 | "bsonjs/common"], 36 | py_limited_api=True, 37 | define_macros=[("BSON_COMPILATION", 1), 38 | ("Py_LIMITED_API", "0x03060000")], 39 | libraries=libraries 40 | ) 41 | ], 42 | options={'bdist_wheel': {'py_limited_api': 'cp37'} } 43 | ) 44 | -------------------------------------------------------------------------------- /test/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 MongoDB, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | import sys 15 | 16 | if sys.version_info[0] == 2: 17 | from StringIO import StringIO 18 | else: 19 | from io import StringIO 20 | 21 | import unittest 22 | -------------------------------------------------------------------------------- /vendor.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | VERSION="1.27.2" 4 | rm -rf mongo-c-driver 5 | git clone git@github.com:mongodb/mongo-c-driver.git 6 | pushd mongo-c-driver 7 | git checkout $VERSION 8 | python build/calc_release_version.py > VERSION_CURRENT 9 | mkdir cmake-build && cd cmake-build 10 | cmake -DENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF -DENABLE_MONGOC=OFF .. 11 | popd 12 | rm -r bsonjs/bson 13 | rm -r bsonjs/jsonsl 14 | rm -r bsonjs/common 15 | rsync -r mongo-c-driver/src/libbson/src/bson/*.[hc] bsonjs/bson/ 16 | rsync -r mongo-c-driver/src/libbson/src/jsonsl/*.[hc] bsonjs/jsonsl/ 17 | rsync -r mongo-c-driver/src/libbson/src/jsonsl/LICENSE bsonjs/jsonsl/ 18 | 19 | rsync -r mongo-c-driver/src/common/*.[hc] bsonjs/common/ 20 | rsync -r mongo-c-driver/cmake-build/src/common/*.[hc] bsonjs/common/ 21 | 22 | rsync -r mongo-c-driver/cmake-build/src/libbson/src/bson/*.[hc] bsonjs/bson/ 23 | 24 | # Ignore autogenerated bson-config.h 25 | git diff -- bsonjs/bson/bson-config.h | tee 26 | echo "**** Review libbson's autogenerated src/bson/bson-config.h (above) for newly added (or removed) macros ****" 27 | git checkout -- bsonjs/bson/bson-config.h 28 | --------------------------------------------------------------------------------