Compare commits

...

No commits in common. "0.1.7" and "main" have entirely different histories.
0.1.7 ... main

472 changed files with 7023 additions and 55925 deletions

33
.github/workflows/docs.yaml vendored Normal file
View file

@ -0,0 +1,33 @@
name: docs
on: ["push", "pull_request"]
jobs:
docs:
# We want to run on external PRs, but not on our own internal PRs as they'll be run
# by the push to the branch.
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
cache: "pip"
cache-dependency-path: |
requirements.txt
docs/requirements.txt
- name: Build
run: |
pip install -r requirements.txt
make cython
- name: Sphinx Documentation Generator
run: |
pip install -r docs/requirements.txt
make docs

22
.github/workflows/lint.yaml vendored Normal file
View file

@ -0,0 +1,22 @@
name: lint
on: ["push", "pull_request"]
jobs:
lint:
# We want to run on external PRs, but not on our own internal PRs as they'll be run
# by the push to the branch.
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: ruff check
run: |
pipx run ruff check --diff msgpack/ test/ setup.py
- name: ruff format
run: |
pipx run ruff format --diff msgpack/ test/ setup.py

61
.github/workflows/test.yml vendored Normal file
View file

@ -0,0 +1,61 @@
name: Run tests
on:
push:
branches: [main]
pull_request:
create:
jobs:
test:
strategy:
matrix:
os: ["ubuntu-latest", "windows-latest", "windows-11-arm", "macos-latest"]
py: ["3.14", "3.14t", "3.13", "3.12", "3.11", "3.10"]
exclude:
- os: windows-11-arm
py: "3.10"
runs-on: ${{ matrix.os }}
name: Run test with Python ${{ matrix.py }} on ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.py }}
allow-prereleases: true
cache: "pip"
- name: Prepare
shell: bash
run: |
python -m pip install -r requirements.txt pytest
- name: Build
shell: bash
run: |
make cython
pip install .
- name: Test (C extension)
shell: bash
run: |
pytest -v test
- name: Test (pure Python fallback)
shell: bash
run: |
MSGPACK_PUREPYTHON=1 pytest -v test
- name: build packages
shell: bash
run: |
python -m build -nv
- name: upload packages
uses: actions/upload-artifact@v4
with:
name: dist-${{ matrix.os }}-${{ matrix.py }}
path: dist

88
.github/workflows/wheel.yml vendored Normal file
View file

@ -0,0 +1,88 @@
name: Build sdist and Wheels
on:
push:
branches: [main]
release:
types:
- published
workflow_dispatch:
jobs:
build_wheels:
strategy:
matrix:
# macos-13 is for intel
os: ["ubuntu-24.04", "ubuntu-24.04-arm", "windows-latest", "windows-11-arm", "macos-13", "macos-latest"]
runs-on: ${{ matrix.os }}
name: Build wheels on ${{ matrix.os }}
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: "3.x"
cache: "pip"
- name: Cythonize
shell: bash
run: |
pip install -r requirements.txt
make cython
- name: Build
uses: pypa/cibuildwheel@v3.3.0
env:
CIBW_TEST_REQUIRES: "pytest"
CIBW_TEST_COMMAND: "pytest {package}/test"
CIBW_SKIP: "pp* cp38-* cp39-* cp310-win_arm64"
- name: Build sdist
if: runner.os == 'Linux' && runner.arch == 'X64'
run: |
pip install build
python -m build -s -o wheelhouse
- name: Upload Wheels to artifact
uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.os }}
path: wheelhouse
# combine all wheels into one artifact
combine_wheels:
needs: [build_wheels]
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v4
with:
# unpacks all CIBW artifacts into dist/
pattern: wheels-*
path: dist
merge-multiple: true
- name: Upload Wheels to artifact
uses: actions/upload-artifact@v4
with:
name: wheels-all
path: dist
# https://github.com/pypa/cibuildwheel/blob/main/examples/github-deploy.yml
upload_pypi:
needs: [build_wheels]
runs-on: ubuntu-latest
environment: pypi
permissions:
id-token: write
if: github.event_name == 'release' && github.event.action == 'published'
# or, alternatively, upload to PyPI on every tag starting with 'v' (remove on: release above to use this)
# if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
steps:
- uses: actions/download-artifact@v4
with:
# unpacks all CIBW artifacts into dist/
pattern: wheels-*
path: dist
merge-multiple: true
- uses: pypa/gh-action-pypi-publish@release/v1
#with:
# To test: repository-url: https://test.pypi.org/legacy/

18
.gitignore vendored
View file

@ -1,3 +1,17 @@
*.o MANIFEST
build/*
dist/*
.tox
.python-version
*.pyc
*.pyo
*.so *.so
ruby/Makefile *~
msgpack/__version__.py
msgpack/*.c
msgpack/*.cpp
*.egg-info
/venv
/tags
/docs/_build
.cache

24
.readthedocs.yaml Normal file
View file

@ -0,0 +1,24 @@
# Read the Docs configuration file for Sphinx projects.
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details.
version: 2
build:
os: ubuntu-22.04
tools:
python: "3.11"
apt_packages:
- build-essential
jobs:
pre_install:
- pip install -r requirements.txt
- make cython
python:
install:
- method: pip
path: .
- requirements: docs/requirements.txt
sphinx:
configuration: docs/conf.py

View file

@ -1,4 +1,4 @@
Copyright (C) 2008-2010 FURUHASHI Sadayuki Copyright (C) 2008-2011 INADA Naoki <songofacandy@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

625
ChangeLog.rst Normal file
View file

@ -0,0 +1,625 @@
1.1.2
=====
Release Date: 2025-10-08
This release does not change source code. It updates only building wheels:
* Update Cython to v3.1.4
* Update cibuildwheel to v3.2.0
* Drop Python 3.8
* Add Python 3.14
* Add windows-arm
1.1.1
=====
Release Date: 2025-06-13
* No change from 1.1.1rc1.
1.1.1rc1
========
Release Date: 2025-06-06
* Update Cython to 3.1.1 and cibuildwheel to 2.23.3.
1.1.0
=====
Release Date: 2024-09-10
* use ``PyLong_*`` instead of ``PyInt_*`` for compatibility with
future Cython. (#620)
1.1.0rc2
========
Release Date: 2024-08-19
* Update Cython to 3.0.11 for better Python 3.13 support.
* Update cibuildwheel to 2.20.0 to build Python 3.13 wheels.
1.1.0rc1
========
Release Date: 2024-05-07
* Update Cython to 3.0.10 to reduce C warnings and future support for Python 3.13.
* Stop using C++ mode in Cython to reduce compile error on some compilers.
* ``Packer()`` has ``buf_size`` option to specify initial size of
internal buffer to reduce reallocation.
* The default internal buffer size of ``Packer()`` is reduced from
1MiB to 256KiB to optimize for common use cases. Use ``buf_size``
if you are packing large data.
* ``Timestamp.to_datetime()`` and ``Timestamp.from_datetime()`` become
more accurate by avoiding floating point calculations. (#591)
* The Cython code for ``Unpacker`` has been slightly rewritten for maintainability.
* The fallback implementation of ``Packer()`` and ``Unpacker()`` now uses keyword-only
arguments to improve compatibility with the Cython implementation.
1.0.8
=====
Release Date: 2024-03-01
* Update Cython to 3.0.8. This fixes memory leak when iterating
``Unpacker`` object on Python 3.12.
* Do not include C/Cython files in binary wheels.
1.0.7
=====
Release Date: 2023-09-28
* Fix build error of extension module on Windows. (#567)
* ``setup.py`` doesn't skip build error of extension module. (#568)
1.0.6
=====
Release Date: 2023-09-21
.. note::
v1.0.6 Wheels for Windows don't contain extension module.
Please upgrade to v1.0.7 or newer.
* Add Python 3.12 wheels (#517)
* Remove Python 2.7, 3.6, and 3.7 support
1.0.5
=====
Release Date: 2023-03-08
* Use ``__BYTE_ORDER__`` instead of ``__BYTE_ORDER`` for portability. (#513, #514)
* Add Python 3.11 wheels (#517)
* fallback: Fix packing multidimensional memoryview (#527)
1.0.4
=====
Release Date: 2022-06-03
* Support Python 3.11 (beta).
* Don't define `__*_ENDIAN__` macro on Unix. by @methane in https://github.com/msgpack/msgpack-python/pull/495
* Use PyFloat_Pack8() on Python 3.11a7 by @vstinner in https://github.com/msgpack/msgpack-python/pull/499
* Fix Unpacker max_buffer_length handling by @methane in https://github.com/msgpack/msgpack-python/pull/506
1.0.3
=====
Release Date: 2021-11-24 JST
* Fix Docstring (#459)
* Fix error formatting (#463)
* Improve error message about strict_map_key (#485)
1.0.2
=====
* Fix year 2038 problem regression in 1.0.1. (#451)
1.0.1
=====
* Add Python 3.9 and linux/arm64 wheels. (#439)
* Fixed Unpacker.tell() after read_bytes() (#426)
* Fixed unpacking datetime before epoch on Windows (#433)
* Fixed fallback Packer didn't check DateTime.tzinfo (#434)
1.0.0
=====
Release Date: 2020-02-17
* Remove Python 2 support from the ``msgpack/_cmsgpack``.
``msgpack/fallback`` still supports Python 2.
* Remove ``encoding`` option from the Packer and Unpacker.
* Unpacker: The default value of ``max_buffer_size`` is changed to 100MiB.
* Unpacker: ``strict_map_key`` is True by default now.
* Unpacker: String map keys are interned.
* Drop old buffer protocol support.
* Support Timestamp type.
* Support serializing and decerializing ``datetime`` object
with tzinfo.
* Unpacker: ``Fix Unpacker.read_bytes()`` in fallback implementation. (#352)
0.6.2
=====
Release Date: 2019-09-20
* Support Python 3.8.
* Update Cython to 0.29.13 for support Python 3.8.
* Some small optimizations.
0.6.1
======
Release Date: 2019-01-25
This release is for mitigating pain caused by v0.6.0 reduced max input limits
for security reason.
* ``unpackb(data)`` configures ``max_*_len`` options from ``len(data)``,
instead of static default sizes.
* ``Unpacker(max_buffer_len=N)`` configures ``max_*_len`` options from ``N``,
instead of static default sizes.
* ``max_bin_len``, ``max_str_len``, and ``max_ext_len`` are deprecated.
Since this is minor release, it's document only deprecation.
0.6.0
======
Release Date: 2018-11-30
This release contains some backward incompatible changes for security reason (DoS).
Important changes
-----------------
* unpacker: Default value of input limits are smaller than before to avoid DoS attack.
If you need to handle large data, you need to specify limits manually. (#319)
* Unpacker doesn't wrap underlying ``ValueError`` (including ``UnicodeError``) into
``UnpackValueError``. If you want to catch all exception during unpack, you need
to use ``try ... except Exception`` with minimum try code block. (#323, #233)
* ``PackValueError`` and ``PackOverflowError`` are also removed. You need to catch
normal ``ValueError`` and ``OverflowError``. (#323, #233)
* Unpacker has ``strict_map_key`` option now. When it is true, only bytes and str
(unicode in Python 2) are allowed for map keys. It is recommended to avoid
hashdos. Default value of this option is False for backward compatibility reason.
But it will be changed True in 1.0. (#296, #334)
Other changes
-------------
* Extension modules are merged. There is ``msgpack._cmsgpack`` instead of
``msgpack._packer`` and ``msgpack._unpacker``. (#314, #328)
* Add ``Unpacker.getbuffer()`` method. (#320)
* unpacker: ``msgpack.StackError`` is raised when input data contains too
nested data. (#331)
* unpacker: ``msgpack.FormatError`` is raised when input data is not valid
msgpack format. (#331)
0.5.6
======
* Fix fallback.Unpacker.feed() dropped unused data from buffer (#287)
* Resurrect fallback.unpack() and _unpacker.unpack().
They were removed at 0.5.5 but it breaks backward compatibility. (#288, #290)
0.5.5
======
* Fix memory leak in pure Python Unpacker.feed() (#283)
* Fix unpack() didn't support `raw` option (#285)
0.5.4
======
* Undeprecate ``unicode_errors`` option. (#278)
0.5.3
======
* Fixed regression when passing ``unicode_errors`` to Packer but not ``encoding``. (#277)
0.5.2
======
* Add ``raw`` option to Unpacker. It is preferred way than ``encoding`` option.
* Packer.pack() reset buffer on exception (#274)
0.5.1
======
* Remove FutureWarning about use_bin_type option (#271)
0.5.0
======
There are some deprecations. Please read changes carefully.
Changes
-------
* Drop Python 2.6 and ~3.4 support. Python 2.7 and 3.5+ are supported.
* Deprecate useless custom exceptions. Use ValueError instead of PackValueError,
Exception instead of PackException and UnpackException, etc...
See msgpack/exceptions.py
* Add *strict_types* option to packer. It can be used to serialize subclass of
builtin types. For example, when packing object which type is subclass of dict,
``default()`` is called. ``default()`` is called for tuple too.
* Pure Python implementation supports packing memoryview object.
* Support packing bytearray.
* Add ``Unpacker.tell()``. And ``write_bytes`` option is deprecated.
Bugs fixed
----------
* Fixed zero length raw can't be decoded when encoding is specified. (#236)
0.4.8
=====
:release date: 2016-07-29
Bugs fixed
----------
* Calling ext_hook with wrong length. (Only on Windows, maybe. #203)
0.4.7
=====
:release date: 2016-01-25
Bugs fixed
----------
* Memory leak when unpack is failed
Changes
-------
* Reduce compiler warnings while building extension module
* unpack() now accepts ext_hook argument like Unpacker and unpackb()
* Update Cython version to 0.23.4
* default function is called when integer overflow
0.4.6
=====
:release date: 2015-03-13
Bugs fixed
----------
* fallback.Unpacker: Fix Data corruption when OutOfData.
This bug only affects "Streaming unpacking."
0.4.5
=====
:release date: 2015-01-25
Incompatible Changes
--------------------
Changes
-------
Bugs fixed
----------
* Fix test failure on pytest 2.3. (by @ktdreyer)
* Fix typos in ChangeLog. (Thanks to @dmick)
* Improve README.rst (by @msabramo)
0.4.4
=====
:release date: 2015-01-09
Incompatible Changes
--------------------
Changes
-------
Bugs fixed
----------
* Fix compile error.
0.4.3
=====
:release date: 2015-01-07
Incompatible Changes
--------------------
Changes
-------
Bugs fixed
----------
* Unpacker may unpack wrong uint32 value on 32bit or LLP64 environment. (#101)
* Build failed on Windows Python 2.7.
0.4.2
=====
:release date: 2014-03-26
Incompatible Changes
--------------------
Changes
-------
Bugs fixed
----------
* Unpacker doesn't increment refcount of ExtType hook.
* Packer raises no exception for inputs doesn't fit to msgpack format.
0.4.1
=====
:release date: 2014-02-17
Incompatible Changes
--------------------
Changes
-------
* fallback.Unpacker.feed() supports bytearray.
Bugs fixed
----------
* Unpacker doesn't increment refcount of hooks. Hooks may be GCed while unpacking.
* Unpacker may read unfilled internal buffer.
0.4.0
=====
:release date: 2013-10-21
Incompatible Changes
--------------------
* Raises TypeError instead of ValueError when packer receives unsupported type.
Changes
-------
* Support New msgpack spec.
0.3.0
=====
Incompatible Changes
--------------------
* Default value of ``use_list`` is ``True`` for now. (It was ``False`` for 0.2.x)
You should pass it explicitly for compatibility to 0.2.x.
* `Unpacker.unpack()` and some unpack methods now raise `OutOfData` instead of
`StopIteration`. `StopIteration` is used for iterator protocol only.
Changes
-------
* Pure Python fallback module is added. (thanks to bwesterb)
* Add ``.skip()`` method to ``Unpacker`` (thanks to jnothman)
* Add capturing feature. You can pass the writable object to
``Unpacker.unpack()`` as a second parameter.
* Add ``Packer.pack_array_header`` and ``Packer.pack_map_header``.
These methods only pack header of each type.
* Add ``autoreset`` option to ``Packer`` (default: True).
Packer doesn't return packed bytes and clear internal buffer.
* Add ``Packer.pack_map_pairs``. It packs sequence of pair to map type.
0.2.4
=====
:release date: 2012-12-22
Bugs fixed
----------
* Fix SEGV when object_hook or object_pairs_hook raise Exception. (#39)
0.2.3
=====
:release date: 2012-12-11
Changes
-------
* Warn when use_list is not specified. It's default value will be changed in 0.3.
Bugs fixed
----------
* Can't pack subclass of dict.
0.2.2
=====
:release date: 2012-09-21
Changes
-------
* Add ``use_single_float`` option to ``Packer``. When it is true, packs float
object in single precision format.
Bugs fixed
----------
* ``unpack()`` didn't restores gc state when it called with gc disabled.
``unpack()`` doesn't control gc now instead of restoring gc state collectly.
User can control gc state when gc cause performance issue.
* ``Unpacker``'s ``read_size`` option didn't used.
0.2.1
=====
:release date: 2012-08-20
Changes
-------
* Add ``max_buffer_size`` parameter to Unpacker. It limits internal buffer size
and allows unpack data from untrusted source safely.
* Unpacker's buffer reallocation algorithm is less greedy now. It cause performance
decrease in rare case but memory efficient and don't allocate than ``max_buffer_size``.
Bugs fixed
----------
* Fix msgpack didn't work on SPARC Solaris. It was because choosing wrong byteorder
on compilation time. Use ``sys.byteorder`` to get correct byte order.
Very thanks to Chris Casey for giving test environment to me.
0.2.0
=====
:release date: 2012-06-27
Changes
-------
* Drop supporting Python 2.5 and unify tests for Py2 and Py3.
* Use new version of msgpack-c. It packs correctly on big endian platforms.
* Remove deprecated packs and unpacks API.
Bugs fixed
----------
* #8 Packing subclass of dict raises TypeError. (Thanks to Steeve Morin.)
0.1.13
======
:release date: 2012-04-21
New
---
* Don't accept subtype of list and tuple as msgpack list. (Steeve Morin)
It allows customize how it serialized with ``default`` argument.
Bugs fixed
----------
* Fix wrong error message. (David Wolever)
* Fix memory leak while unpacking when ``object_hook`` or ``list_hook`` is used.
(Steeve Morin)
Other changes
-------------
* setup.py works on Python 2.5 (Steffen Siering)
* Optimization for serializing dict.
0.1.12
======
:release date: 2011-12-27
Bugs fixed
----------
* Re-enable packs/unpacks removed at 0.1.11. It will be removed when 0.2 is released.
0.1.11
======
:release date: 2011-12-26
Bugs fixed
----------
* Include test code for Python3 to sdist. (Johan Bergström)
* Fix compilation error on MSVC. (davidgaleano)
0.1.10
======
:release date: 2011-08-22
New feature
-----------
* Add ``encoding`` and ``unicode_errors`` option to packer and unpacker.
When this option is specified, (un)packs unicode object instead of bytes.
This enables using msgpack as a replacement of json. (tailhook)
0.1.9
=====
:release date: 2011-01-29
New feature
-----------
* ``use_list`` option is added to unpack(b) like Unpacker.
(Use keyword argument because order of parameters are different)
Bugs fixed
----------
* Fix typo.
* Add MemoryError check.
0.1.8
=====
:release date: 2011-01-10
New feature
-----------
* Support ``loads`` and ``dumps`` aliases for API compatibility with
simplejson and pickle.
* Add *object_hook* and *list_hook* option to unpacker. It allows you to
hook unpacking mapping type and array type.
* Add *default* option to packer. It allows you to pack unsupported types.
* unpacker accepts (old) buffer types.
Bugs fixed
----------
* Fix segv around ``Unpacker.feed`` or ``Unpacker(file)``.
0.1.7
=====
:release date: 2010-11-02
New feature
-----------
* Add *object_hook* and *list_hook* option to unpacker. It allows you to
hook unpacking mapping type and array type.
* Add *default* option to packer. It allows you to pack unsupported types.
* unpacker accepts (old) buffer types.
Bugs fixed
----------
* Compilation error on win32.

17
DEVELOP.md Normal file
View file

@ -0,0 +1,17 @@
# Developer's note
### Build
```
$ make cython
```
### Test
MessagePack uses `pytest` for testing.
Run test with following command:
```
$ make test
```

View file

@ -1,3 +1,5 @@
include setup.py include setup.py
include COPYING include COPYING
include README.md
recursive-include msgpack *.h *.c *.pyx recursive-include msgpack *.h *.c *.pyx
recursive-include test *.py

59
Makefile Normal file
View file

@ -0,0 +1,59 @@
PYTHON_SOURCES = msgpack test setup.py
.PHONY: all
all: cython
python setup.py build_ext -i -f
.PHONY: format
format:
ruff format $(PYTHON_SOURCES)
.PHONY: lint
lint:
ruff check $(PYTHON_SOURCES)
.PHONY: doc
doc:
cd docs && sphinx-build -n -v -W --keep-going -b html -d doctrees . html
.PHONY: pyupgrade
pyupgrade:
@find $(PYTHON_SOURCES) -name '*.py' -type f -exec pyupgrade --py37-plus '{}' \;
.PHONY: cython
cython:
cython msgpack/_cmsgpack.pyx
.PHONY: test
test: cython
pip install -e .
pytest -v test
MSGPACK_PUREPYTHON=1 pytest -v test
.PHONY: serve-doc
serve-doc: all
cd docs && make serve
.PHONY: clean
clean:
rm -rf build
rm -f msgpack/_cmsgpack.cpp
rm -f msgpack/_cmsgpack.*.so
rm -f msgpack/_cmsgpack.*.pyd
rm -rf msgpack/__pycache__
rm -rf test/__pycache__
.PHONY: update-docker
update-docker:
docker pull quay.io/pypa/manylinux2014_i686
docker pull quay.io/pypa/manylinux2014_x86_64
docker pull quay.io/pypa/manylinux2014_aarch64
.PHONY: linux-wheel
linux-wheel:
docker run --rm -v `pwd`:/project -w /project quay.io/pypa/manylinux2014_i686 bash docker/buildwheel.sh
docker run --rm -v `pwd`:/project -w /project quay.io/pypa/manylinux2014_x86_64 bash docker/buildwheel.sh
.PHONY: linux-arm64-wheel
linux-arm64-wheel:
docker run --rm -v `pwd`:/project -w /project quay.io/pypa/manylinux2014_aarch64 bash docker/buildwheel.sh

251
README.md
View file

@ -1,37 +1,242 @@
MessagePack # MessagePack for Python
===========
Extremely efficient object serialization library. It's like JSON, but very fast and small. [![Build Status](https://github.com/msgpack/msgpack-python/actions/workflows/wheel.yml/badge.svg)](https://github.com/msgpack/msgpack-python/actions/workflows/wheel.yml)
[![Documentation Status](https://readthedocs.org/projects/msgpack-python/badge/?version=latest)](https://msgpack-python.readthedocs.io/en/latest/?badge=latest)
## What is this?
[MessagePack](https://msgpack.org/) is an efficient binary serialization format.
It lets you exchange data among multiple languages like JSON.
But it's faster and smaller.
This package provides CPython bindings for reading and writing MessagePack data.
## Install
```
$ pip install msgpack
```
### Pure Python implementation
The extension module in msgpack (`msgpack._cmsgpack`) does not support PyPy.
But msgpack provides a pure Python implementation (`msgpack.fallback`) for PyPy.
## What's MessagePack? ### Windows
MessagePack is a binary-based efficient object serialization library. It enables to exchange structured objects between many languages like JSON. But unlike JSON, it is very fast and small. If you can't use a binary distribution, you need to install Visual Studio
or the Windows SDK on Windows.
Typical small integer (like flags or error code) is saved only in 1 byte, and typical short string only needs 1 byte except the length of the string itself. \[1,2,3\] (3 elements array) is serialized in 4 bytes using MessagePack as follows: Without the extension, the pure Python implementation on CPython runs slowly.
require 'msgpack'
msg = [1,2,3].to_msgpack #=> "\x93\x01\x02\x03"
MessagePack.unpack(msg) #=> [1,2,3]
## Performance ## How to use
![Serialization + Deserialization Speed Test](http://msgpack.sourceforge.net/index/speedtest.png) ### One-shot pack & unpack
In this test, it measured the elapsed time of serializing and deserializing 200,000 target objects. The target object consists of the three integers and 512 bytes string. Use `packb` for packing and `unpackb` for unpacking.
The source code of this test is available from [frsyuki' serializer-speed-test repository.](http://github.com/frsyuki/serializer-speed-test) msgpack provides `dumps` and `loads` as aliases for compatibility with
`json` and `pickle`.
`pack` and `dump` pack to a file-like object.
`unpack` and `load` unpack from a file-like object.
```pycon
>>> import msgpack
>>> msgpack.packb([1, 2, 3])
'\x93\x01\x02\x03'
>>> msgpack.unpackb(_)
[1, 2, 3]
```
Read the docstring for options.
## Getting Started ### Streaming unpacking
Usage and other documents about implementations in each language are found at [the web site.](http://msgpack.sourceforge.net/) `Unpacker` is a "streaming unpacker". It unpacks multiple objects from one
stream (or from bytes provided through its `feed` method).
```py
import msgpack
from io import BytesIO
buf = BytesIO()
for i in range(100):
buf.write(msgpack.packb(i))
buf.seek(0)
unpacker = msgpack.Unpacker(buf)
for unpacked in unpacker:
print(unpacked)
```
## Learn More ### Packing/unpacking of custom data types
- [Project Web Site](http://msgpack.sourceforge.net/) It is also possible to pack/unpack custom data types. Here is an example for
- [MessagePack format specification](http://msgpack.sourceforge.net/spec) `datetime.datetime`.
- [Repository at github](http://github.com/msgpack/msgpack)
- [Wiki](http://msgpack.sourceforge.net/start)
- [MessagePack-RPC](http://github.com/msgpack/msgpack-rpc)
```py
import datetime
import msgpack
useful_dict = {
"id": 1,
"created": datetime.datetime.now(),
}
def decode_datetime(obj):
if '__datetime__' in obj:
obj = datetime.datetime.strptime(obj["as_str"], "%Y%m%dT%H:%M:%S.%f")
return obj
def encode_datetime(obj):
if isinstance(obj, datetime.datetime):
return {'__datetime__': True, 'as_str': obj.strftime("%Y%m%dT%H:%M:%S.%f")}
return obj
packed_dict = msgpack.packb(useful_dict, default=encode_datetime)
this_dict_again = msgpack.unpackb(packed_dict, object_hook=decode_datetime)
```
`Unpacker`'s `object_hook` callback receives a dict; the
`object_pairs_hook` callback may instead be used to receive a list of
key-value pairs.
NOTE: msgpack can encode datetime with tzinfo into standard ext type for now.
See `datetime` option in `Packer` docstring.
### Extended types
It is also possible to pack/unpack custom data types using the **ext** type.
```pycon
>>> import msgpack
>>> import array
>>> def default(obj):
... if isinstance(obj, array.array) and obj.typecode == 'd':
... return msgpack.ExtType(42, obj.tostring())
... raise TypeError("Unknown type: %r" % (obj,))
...
>>> def ext_hook(code, data):
... if code == 42:
... a = array.array('d')
... a.fromstring(data)
... return a
... return ExtType(code, data)
...
>>> data = array.array('d', [1.2, 3.4])
>>> packed = msgpack.packb(data, default=default)
>>> unpacked = msgpack.unpackb(packed, ext_hook=ext_hook)
>>> data == unpacked
True
```
### Advanced unpacking control
As an alternative to iteration, `Unpacker` objects provide `unpack`,
`skip`, `read_array_header`, and `read_map_header` methods. The former two
read an entire message from the stream, respectively deserializing and returning
the result, or ignoring it. The latter two methods return the number of elements
in the upcoming container, so that each element in an array, or key-value pair
in a map, can be unpacked or skipped individually.
## Notes
### String and binary types in the old MessagePack spec
Early versions of msgpack didn't distinguish string and binary types.
The type for representing both string and binary types was named **raw**.
You can pack into and unpack from this old spec using `use_bin_type=False`
and `raw=True` options.
```pycon
>>> import msgpack
>>> msgpack.unpackb(msgpack.packb([b'spam', 'eggs'], use_bin_type=False), raw=True)
[b'spam', b'eggs']
>>> msgpack.unpackb(msgpack.packb([b'spam', 'eggs'], use_bin_type=True), raw=False)
[b'spam', 'eggs']
```
### ext type
To use the **ext** type, pass a `msgpack.ExtType` object to the packer.
```pycon
>>> import msgpack
>>> packed = msgpack.packb(msgpack.ExtType(42, b'xyzzy'))
>>> msgpack.unpackb(packed)
ExtType(code=42, data='xyzzy')
```
You can use it with `default` and `ext_hook`. See below.
### Security
When unpacking data received from an unreliable source, msgpack provides
two security options.
`max_buffer_size` (default: `100*1024*1024`) limits the internal buffer size.
It is also used to limit preallocated list sizes.
`strict_map_key` (default: `True`) limits the type of map keys to bytes and str.
While the MessagePack spec doesn't limit map key types,
there is a risk of a hash DoS.
If you need to support other types for map keys, use `strict_map_key=False`.
### Performance tips
CPython's GC starts when the number of allocated objects grows.
This means unpacking may trigger unnecessary GC.
You can use `gc.disable()` when unpacking a large message.
A list is the default sequence type in Python.
However, a tuple is lighter than a list.
You can use `use_list=False` while unpacking when performance is important.
## Major breaking changes in the history
### msgpack 0.5
The package name on PyPI was changed from `msgpack-python` to `msgpack` in 0.5.
When upgrading from msgpack-0.4 or earlier, do `pip uninstall msgpack-python` before
`pip install -U msgpack`.
### msgpack 1.0
* Python 2 support
* The extension module no longer supports Python 2.
The pure Python implementation (`msgpack.fallback`) is used for Python 2.
* msgpack 1.0.6 drops official support of Python 2.7, as pip and
GitHub Action "setup-python" no longer supports Python 2.7.
* Packer
* Packer uses `use_bin_type=True` by default.
Bytes are encoded in the bin type in MessagePack.
* The `encoding` option is removed. UTF-8 is always used.
* Unpacker
* Unpacker uses `raw=False` by default. It assumes str values are valid UTF-8 strings
and decodes them to Python str (Unicode) objects.
* `encoding` option is removed. You can use `raw=True` to support old format (e.g. unpack into bytes, not str).
* The default value of `max_buffer_size` is changed from 0 to 100 MiB to avoid DoS attacks.
You need to pass `max_buffer_size=0` if you have large but safe data.
* The default value of `strict_map_key` is changed to True to avoid hash DoS.
You need to pass `strict_map_key=False` if you have data that contain map keys
whose type is neither bytes nor str.

5
SECURITY.md Normal file
View file

@ -0,0 +1,5 @@
## Security contact information
To report a security vulnerability, please use the
[Tidelift security contact](https://tidelift.com/security).
Tidelift will coordinate the fix and disclosure.

38
benchmark/benchmark.py Normal file
View file

@ -0,0 +1,38 @@
from msgpack import fallback
try:
from msgpack import _cmsgpack
has_ext = True
except ImportError:
has_ext = False
import timeit
def profile(name, func):
times = timeit.repeat(func, number=1000, repeat=4)
times = ", ".join(["%8f" % t for t in times])
print("%-30s %40s" % (name, times))
def simple(name, data):
if has_ext:
packer = _cmsgpack.Packer()
profile("packing %s (ext)" % name, lambda: packer.pack(data))
packer = fallback.Packer()
profile("packing %s (fallback)" % name, lambda: packer.pack(data))
data = packer.pack(data)
if has_ext:
profile("unpacking %s (ext)" % name, lambda: _cmsgpack.unpackb(data))
profile("unpacking %s (fallback)" % name, lambda: fallback.unpackb(data))
def main():
simple("integers", [7] * 10000)
simple("bytes", [b"x" * n for n in range(100)] * 10)
simple("lists", [[]] * 10000)
simple("dicts", [{}] * 10000)
main()

View file

@ -1 +0,0 @@
FURUHASHI Sadayuki <frsyuki _at_ users.sourceforge.jp>

View file

@ -1,37 +0,0 @@
2010-08-29 version 0.5.4:
* includes msgpack_vc2008.vcproj file in source package
* fixes type::fix_int types
2010-08-27 version 0.5.3:
* adds type::fix_{u,}int{8,16,32,64} types
* adds msgpack_pack_fix_{u,}int{8,16,32,64} functions
* adds packer<Stream>::pack_fix_{u,}int{8,16,32,64} functions
* fixes include paths
2010-07-14 version 0.5.2:
* type::raw::str(), operator==, operator!=, operator< and operator> are now const
* generates version.h using AC_OUTPUT macro in ./configure
2010-07-06 version 0.5.1:
* Add msgpack_vrefbuffer_new and msgpack_vrefbuffer_free
* Add msgpack_sbuffer_new and msgpack_sbuffer_free
* Add msgpack_unpacker_next and msgpack_unpack_next
* msgpack::unpack returns void
* Add MSGPACK_VERSION{,_MAJOR,_MINOR} macros to check header version
* Add msgpack_version{,_major,_minor} functions to check library version
* ./configure supports --disable-cxx option not to build C++ API
2010-04-29 version 0.5.0:
* msgpack_object_type is changed. MSGPACK_OBJECT_NIL is now 0x00.
* New safe streaming deserializer API.
* Add object::object(const T&) and object::operator=(const T&)
* Add operator==(object, const T&)
* MSGPACK_DEFINE macro defines msgpack_object(object* obj, zone* z)
* C++ programs doesn't need to link "msgpackc" library.

File diff suppressed because it is too large Load diff

View file

@ -1,202 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View file

@ -1,20 +0,0 @@
SUBDIRS = src test
DOC_FILES = \
README.md \
LICENSE \
NOTICE \
msgpack_vc8.vcproj \
msgpack_vc8.sln \
msgpack_vc2008.vcproj \
msgpack_vc2008.sln \
msgpack_vc.postbuild.bat
EXTRA_DIST = \
$(DOC_FILES)
doxygen:
./preprocess clean
cd src && $(MAKE) doxygen
./preprocess

View file

@ -1,4 +0,0 @@
MessagePack is developed by FURUHASHI Sadayuki, licensed under Apache License,
Version 2.0. The original software and related information is available at
http://msgpack.sourceforge.jp/.

View file

@ -1,73 +0,0 @@
MessagePack for C/C++
=====================
Binary-based efficient object serialization library.
## Installation
Download latest package from [releases of MessagePack](http://sourceforge.net/projects/msgpack/files/) and extract it.
On UNIX-like platform, run ./configure && make && sudo make install:
$ ./configure
$ make
$ sudo make install
On Windows, open msgpack_vc8.vcproj or msgpack_vc2008 file and build it using batch build. DLLs are built on lib folder,
and the headers are built on include folder.
To use the library in your program, include msgpack.hpp header and link "msgpack" library.
## Example
#include <msgpack.hpp>
#include <vector>
int main(void) {
// This is target object.
std::vector<std::string> target;
target.push_back("Hello,");
target.push_back("World!");
// Serialize it.
msgpack::sbuffer buffer; // simple buffer
msgpack::pack(&buffer, target);
// Deserialize the serialized data.
msgpack::unpacked msg; // includes memory pool and deserialized object
msgpack::unpack(&msg, sbuf.data(), sbuf.size());
msgpack::object obj = msg.get();
// Print the deserialized object to stdout.
std::cout << obj << std::endl; // ["Hello," "World!"]
// Convert the deserialized object to staticaly typed object.
std::vector<std::string> result;
obj.convert(&result);
// If the type is mismatched, it throws msgpack::type_error.
obj.as<int>(); // type is mismatched, msgpack::type_error is thrown
}
API documents and other example codes are available at the [wiki.](http://redmine.msgpack.org/projects/msgpack/wiki)
## License
Copyright (C) 2008-2010 FURUHASHI Sadayuki
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
See also NOTICE file.

View file

@ -1,127 +0,0 @@
#!/bin/sh
# vim:ts=4:sw=4
# Calls autotools to build configure script and Makefile.in.
# Generated automatically using bootstrapper 0.2.1
# http://bootstrapper.sourceforge.net/
#
# Copyright (C) 2002 Anthony Ventimiglia
#
# This bootstrap script is free software; you can redistribute
# it and/or modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
#
# Calls proper programs to create configure script and Makefile.in files.
# if run with the --clean option, bootstrap removes files it generates. To
# clean all autogenerated files (eg: for cvs imports) first run
# make distclean, then bootstrap --clean
# see bootstrapper(1) for more infor
if test x"$1" = x"--help"; then
echo "$0: automatic bootstrapping utility for GNU Autotools"
echo " cleans up old autogenerated files and runs autoconf,"
echo " automake and aclocal on local directory"
echo
echo " --clean clean up auto-generated files without"
echo " creating new scripts"
echo
exit 0
fi
mkdir -p ac
test -f AUTHORS || touch AUTHORS
test -f COPYING || touch COPYING
test -f ChangeLog || touch ChangeLog
test -f NEWS || touch NEWS
test -f README || cp -f README.md README
./preprocess
if [ $? -ne 0 ]; then
exit 1
fi
ACLOCAL="aclocal"
ACLOCAL_FILES="aclocal.m4"
ALWAYS_CLEAN="config.status config.log config.cache libtool"
AUTOCONF="autoconf"
AUTOCONF_FILES="configure"
AUTOHEADER="autoheader"
AUTOHEADER_FILES=""
AUTOMAKE="automake --add-missing --copy"
AUTOMAKE_FILES="config.sub stamp-h.in ltmain.sh missing mkinstalldirs install-sh config.guess"
CONFIG_AUX_DIR="."
CONFIG_FILES="stamp-h ltconfig"
CONFIG_HEADER=""
if [ x`uname` = x"Darwin" ]; then
LIBTOOLIZE="glibtoolize --force --copy"
else
LIBTOOLIZE="libtoolize --force --copy"
fi
LIBTOOLIZE_FILES="config.sub ltmain.sh config.guess"
RM="rm"
SUBDIRS="[]"
# These are files created by configure, so we'll always clean them
for i in $ALWAYS_CLEAN; do
test -f $i && \
$RM $i
done
if test x"$1" = x"--clean"; then
#
#Clean Files left by previous bootstrap run
#
if test -n "$CONFIG_AUX_DIR";
then CONFIG_AUX_DIR="$CONFIG_AUX_DIR/"
fi
# Clean Libtoolize generated files
for cf in $LIBTOOLIZE_FILES; do
cf="$CONFIG_AUX_DIR$cf"
test -f $cf && \
$RM $cf
done
#aclocal.m4 created by aclocal
test -f $ACLOCAL_FILES && $RM $ACLOCAL_FILES
#Clean Autoheader Generated files
for cf in $AUTOHEADER_FILES; do
cf=$CONFIG_AUX_DIR$cf
test -f $cf && \
$RM $cf
done
# remove config header (Usaually config.h)
test -n "$CONFIG_HEADER" && test -f $CONFIG_HEADER && $RM $CONFIG_HEADER
#Clean Automake generated files
for cf in $AUTOMAKE_FILES; do
cf=$CONFIG_AUX_DIR$cf
test -f $cf && \
$RM $cf
done
for i in $SUBDIRS; do
test -f $i/Makefile.in && \
$RM $i/Makefile.in
done
#Autoconf generated files
for cf in $AUTOCONF_FILES; do
test -f $cf && \
$RM $cf
done
for cf in $CONFIG_FILES; do
cf="$CONFIG_AUX_DIR$cf"
test -f $cf && \
$RM $cf
done
else
$LIBTOOLIZE
$ACLOCAL
$AUTOHEADER
$AUTOMAKE
$AUTOCONF
fi

View file

@ -1,75 +0,0 @@
AC_INIT(src/object.cpp)
AC_CONFIG_AUX_DIR(ac)
AM_INIT_AUTOMAKE(msgpack, 0.5.4)
AC_CONFIG_HEADER(config.h)
AC_SUBST(CFLAGS)
CFLAGS="-O4 -Wall $CFLAGS"
AC_SUBST(CXXFLAGS)
CXXFLAGS="-O4 -Wall $CXXFLAGS"
AC_PROG_CC
AC_MSG_CHECKING([if C++ API is enabled])
AC_ARG_ENABLE(cxx,
AS_HELP_STRING([--disable-cxx],
[don't build C++ API]) )
AC_MSG_RESULT([$enable_cxx])
if test "$enable_cxx" != "no"; then
AC_PROG_CXX
AM_PROG_CC_C_O
fi
AM_CONDITIONAL(ENABLE_CXX, test "$enable_cxx" != "no")
AC_PROG_LIBTOOL
AM_PROG_AS
AC_MSG_CHECKING([if debug option is enabled])
AC_ARG_ENABLE(debug,
AS_HELP_STRING([--disable-debug],
[disable assert macros and omit -g option]) )
AC_MSG_RESULT([$enable_debug])
if test "$enable_debug" != "no"; then
CXXFLAGS="$CXXFLAGS -g"
CFLAGS="$CFLAGS -g"
else
CXXFLAGS="$CXXFLAGS -DNDEBUG"
CFLAGS="$CFLAGS -DNDEBUG"
fi
AC_CACHE_CHECK([for __sync_* atomic operations], msgpack_cv_atomic_ops, [
AC_TRY_LINK([
int atomic_sub(int i) { return __sync_sub_and_fetch(&i, 1); }
int atomic_add(int i) { return __sync_add_and_fetch(&i, 1); }
], [], msgpack_cv_atomic_ops="yes")
])
if test "$msgpack_cv_atomic_ops" != "yes"; then
AC_MSG_ERROR([__sync_* atomic operations are not supported.
Note that gcc < 4.1 is not supported.
If you are using gcc >= 4.1 and the default target CPU architecture is "i386", try to
add CFLAGS="--march=i686" and CXXFLAGS="-march=i686" options to ./configure as follows:
$ ./configure CFLAGS="-march=i686" CXXFLAGS="-march=i686"
])
fi
major=`echo $VERSION | sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'`
minor=`echo $VERSION | sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'`
AC_SUBST(VERSION_MAJOR, $major)
AC_SUBST(VERSION_MINOR, $minor)
AC_OUTPUT([Makefile
src/Makefile
src/msgpack/version.h
test/Makefile])

View file

@ -1,45 +0,0 @@
IF NOT EXIST include MKDIR include
IF NOT EXIST include\msgpack MKDIR include\msgpack
IF NOT EXIST include\msgpack\type MKDIR include\msgpack\type
IF NOT EXIST include\msgpack\type\tr1 MKDIR include\msgpack\type\tr1
copy src\msgpack\pack_define.h include\msgpack\
copy src\msgpack\pack_template.h include\msgpack\
copy src\msgpack\unpack_define.h include\msgpack\
copy src\msgpack\unpack_template.h include\msgpack\
copy src\msgpack\sysdep.h include\msgpack\
copy src\msgpack.h include\
copy src\msgpack\sbuffer.h include\msgpack\
copy src\msgpack\version.h include\msgpack\
copy src\msgpack\vrefbuffer.h include\msgpack\
copy src\msgpack\zbuffer.h include\msgpack\
copy src\msgpack\pack.h include\msgpack\
copy src\msgpack\unpack.h include\msgpack\
copy src\msgpack\object.h include\msgpack\
copy src\msgpack\zone.h include\msgpack\
copy src\msgpack.hpp include\
copy src\msgpack\sbuffer.hpp include\msgpack\
copy src\msgpack\vrefbuffer.hpp include\msgpack\
copy src\msgpack\zbuffer.hpp include\msgpack\
copy src\msgpack\pack.hpp include\msgpack\
copy src\msgpack\unpack.hpp include\msgpack\
copy src\msgpack\object.hpp include\msgpack\
copy src\msgpack\zone.hpp include\msgpack\
copy src\msgpack\type.hpp include\msgpack\type\
copy src\msgpack\type\bool.hpp include\msgpack\type\
copy src\msgpack\type\deque.hpp include\msgpack\type\
copy src\msgpack\type\fixint.hpp include\msgpack\type\
copy src\msgpack\type\float.hpp include\msgpack\type\
copy src\msgpack\type\int.hpp include\msgpack\type\
copy src\msgpack\type\list.hpp include\msgpack\type\
copy src\msgpack\type\map.hpp include\msgpack\type\
copy src\msgpack\type\nil.hpp include\msgpack\type\
copy src\msgpack\type\pair.hpp include\msgpack\type\
copy src\msgpack\type\raw.hpp include\msgpack\type\
copy src\msgpack\type\set.hpp include\msgpack\type\
copy src\msgpack\type\string.hpp include\msgpack\type\
copy src\msgpack\type\vector.hpp include\msgpack\type\
copy src\msgpack\type\tuple.hpp include\msgpack\type\
copy src\msgpack\type\define.hpp include\msgpack\type\
copy src\msgpack\type\tr1\unordered_map.hpp include\msgpack\type\
copy src\msgpack\type\tr1\unordered_set.hpp include\msgpack\type\

View file

@ -1,20 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual C++ Express 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MessagePack", "msgpack_vc8.vcproj", "{122A2EA4-B283-4241-9655-786DE78283B2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{122A2EA4-B283-4241-9655-786DE78283B2}.Debug|Win32.ActiveCfg = Debug|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.Debug|Win32.Build.0 = Debug|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.Release|Win32.ActiveCfg = Release|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View file

@ -1,299 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="MessagePack"
ProjectGUID="{122A2EA4-B283-4241-9655-786DE78283B2}"
RootNamespace="MessagePack"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
Description="Gathering header files"
CommandLine="msgpack_vc.postbuild.bat"
Outputs="include"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="."
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="true"
BasicRuntimeChecks="1"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
OutputFile="lib\msgpackd.lib"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
Description="Gathering header files"
CommandLine="msgpack_vc.postbuild.bat"
Outputs="include"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="."
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
OutputFile="lib\msgpack.lib"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\src\objectc.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="2"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\src\unpack.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="2"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\src\version.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="2"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\src\vrefbuffer.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="2"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\src\zone.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="2"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\src\object.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\src\msgpack\pack_define.h"
>
</File>
<File
RelativePath=".\src\msgpack\pack_template.h"
>
</File>
<File
RelativePath=".\src\msgpack\sysdep.h"
>
</File>
<File
RelativePath=".\src\msgpack\unpack_define.h"
>
</File>
<File
RelativePath=".\src\msgpack\unpack_template.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -1,34 +0,0 @@
#!/bin/sh
preprocess() {
ruby -r erb -e 'puts ERB.new(ARGF.read).result' $1.erb > $1.tmp
if [ "$?" != 0 ]; then
echo ""
echo "** preprocess failed **"
echo ""
exit 1
else
mv $1.tmp $1
fi
}
if [ "$1" == "clean" ];then
rm -f src/msgpack/type/tuple.hpp
rm -f src/msgpack/type/define.hpp
rm -f src/msgpack/zone.hpp
else
preprocess src/msgpack/type/tuple.hpp
preprocess src/msgpack/type/define.hpp
preprocess src/msgpack/zone.hpp
fi
cp -f ../msgpack/sysdep.h src/msgpack/
cp -f ../msgpack/pack_define.h src/msgpack/
cp -f ../msgpack/pack_template.h src/msgpack/
cp -f ../msgpack/unpack_define.h src/msgpack/
cp -f ../msgpack/unpack_template.h src/msgpack/
cp -f ../test/cases.mpac test/
cp -f ../test/cases_compact.mpac test/
sed -e 's/8\.00/9.00/' < msgpack_vc8.vcproj > msgpack_vc2008.vcproj
sed -e 's/9\.00/10.00/' -e 's/msgpack_vc8/msgpack_vc2008/' < msgpack_vc8.sln > msgpack_vc2008.sln

View file

@ -1,101 +0,0 @@
lib_LTLIBRARIES = libmsgpack.la
libmsgpack_la_SOURCES = \
unpack.c \
objectc.c \
version.c \
vrefbuffer.c \
zone.c
if ENABLE_CXX
libmsgpack_la_SOURCES += \
object.cpp
endif
# -version-info CURRENT:REVISION:AGE
libmsgpack_la_LDFLAGS = -version-info 3:0:0
# backward compatibility
lib_LTLIBRARIES += libmsgpackc.la
libmsgpackc_la_SOURCES = \
unpack.c \
objectc.c \
version.c \
vrefbuffer.c \
zone.c
libmsgpackc_la_LDFLAGS = -version-info 2:0:0
nobase_include_HEADERS = \
msgpack/pack_define.h \
msgpack/pack_template.h \
msgpack/unpack_define.h \
msgpack/unpack_template.h \
msgpack/sysdep.h \
msgpack.h \
msgpack/sbuffer.h \
msgpack/version.h \
msgpack/vrefbuffer.h \
msgpack/zbuffer.h \
msgpack/pack.h \
msgpack/unpack.h \
msgpack/object.h \
msgpack/zone.h
if ENABLE_CXX
nobase_include_HEADERS += \
msgpack.hpp \
msgpack/sbuffer.hpp \
msgpack/vrefbuffer.hpp \
msgpack/zbuffer.hpp \
msgpack/pack.hpp \
msgpack/unpack.hpp \
msgpack/object.hpp \
msgpack/zone.hpp \
msgpack/type.hpp \
msgpack/type/bool.hpp \
msgpack/type/deque.hpp \
msgpack/type/float.hpp \
msgpack/type/fixint.hpp \
msgpack/type/int.hpp \
msgpack/type/list.hpp \
msgpack/type/map.hpp \
msgpack/type/nil.hpp \
msgpack/type/pair.hpp \
msgpack/type/raw.hpp \
msgpack/type/set.hpp \
msgpack/type/string.hpp \
msgpack/type/vector.hpp \
msgpack/type/tuple.hpp \
msgpack/type/define.hpp \
msgpack/type/tr1/unordered_map.hpp \
msgpack/type/tr1/unordered_set.hpp
endif
EXTRA_DIST = \
msgpack/version.h.in \
msgpack/zone.hpp.erb \
msgpack/type/define.hpp.erb \
msgpack/type/tuple.hpp.erb
doxygen_c:
cat ../Doxyfile > Doxyfile_c
echo "FILE_PATTERNS = *.h" >> Doxyfile_c
echo "OUTPUT_DIRECTORY = doc_c" >> Doxyfile_c
echo "PROJECT_NAME = \"MessagePack for C\"" >> Doxyfile_c
doxygen Doxyfile_c
doxygen_cpp:
cat ../Doxyfile > Doxyfile_cpp
echo "FILE_PATTERNS = *.hpp" >> Doxyfile_cpp
echo "OUTPUT_DIRECTORY = doc_cpp" >> Doxyfile_cpp
echo "PROJECT_NAME = \"MessagePack for C++\"" >> Doxyfile_cpp
doxygen Doxyfile_cpp
doxygen: doxygen_c doxygen_cpp

View file

@ -1,30 +0,0 @@
/*
* MessagePack for C
*
* Copyright (C) 2008-2009 FURUHASHI Sadayuki
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @defgroup msgpack MessagePack C
* @{
* @}
*/
#include "msgpack/object.h"
#include "msgpack/zone.h"
#include "msgpack/pack.h"
#include "msgpack/unpack.h"
#include "msgpack/sbuffer.h"
#include "msgpack/vrefbuffer.h"
#include "msgpack/version.h"

View file

@ -1,24 +0,0 @@
//
// MessagePack for C++
//
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "msgpack/object.hpp"
#include "msgpack/zone.hpp"
#include "msgpack/pack.hpp"
#include "msgpack/unpack.hpp"
#include "msgpack/sbuffer.hpp"
#include "msgpack/vrefbuffer.hpp"
#include "msgpack.h"

View file

@ -1,98 +0,0 @@
/*
* MessagePack for C dynamic typing routine
*
* Copyright (C) 2008-2009 FURUHASHI Sadayuki
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MSGPACK_OBJECT_H__
#define MSGPACK_OBJECT_H__
#include "zone.h"
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup msgpack_object Dynamically typed object
* @ingroup msgpack
* @{
*/
typedef enum {
MSGPACK_OBJECT_NIL = 0x00,
MSGPACK_OBJECT_BOOLEAN = 0x01,
MSGPACK_OBJECT_POSITIVE_INTEGER = 0x02,
MSGPACK_OBJECT_NEGATIVE_INTEGER = 0x03,
MSGPACK_OBJECT_DOUBLE = 0x04,
MSGPACK_OBJECT_RAW = 0x05,
MSGPACK_OBJECT_ARRAY = 0x06,
MSGPACK_OBJECT_MAP = 0x07,
} msgpack_object_type;
struct msgpack_object;
struct msgpack_object_kv;
typedef struct {
uint32_t size;
struct msgpack_object* ptr;
} msgpack_object_array;
typedef struct {
uint32_t size;
struct msgpack_object_kv* ptr;
} msgpack_object_map;
typedef struct {
uint32_t size;
const char* ptr;
} msgpack_object_raw;
typedef union {
bool boolean;
uint64_t u64;
int64_t i64;
double dec;
msgpack_object_array array;
msgpack_object_map map;
msgpack_object_raw raw;
} msgpack_object_union;
typedef struct msgpack_object {
msgpack_object_type type;
msgpack_object_union via;
} msgpack_object;
typedef struct msgpack_object_kv {
msgpack_object key;
msgpack_object val;
} msgpack_object_kv;
void msgpack_object_print(FILE* out, msgpack_object o);
bool msgpack_object_equal(const msgpack_object x, const msgpack_object y);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* msgpack/object.h */

View file

@ -1,412 +0,0 @@
//
// MessagePack for C++ static resolution routine
//
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef MSGPACK_OBJECT_HPP__
#define MSGPACK_OBJECT_HPP__
#include "object.h"
#include "pack.hpp"
#include "zone.hpp"
#include <string.h>
#include <stdexcept>
#include <typeinfo>
#include <limits>
#include <ostream>
namespace msgpack {
class type_error : public std::bad_cast { };
namespace type {
enum object_type {
NIL = MSGPACK_OBJECT_NIL,
BOOLEAN = MSGPACK_OBJECT_BOOLEAN,
POSITIVE_INTEGER = MSGPACK_OBJECT_POSITIVE_INTEGER,
NEGATIVE_INTEGER = MSGPACK_OBJECT_NEGATIVE_INTEGER,
DOUBLE = MSGPACK_OBJECT_DOUBLE,
RAW = MSGPACK_OBJECT_RAW,
ARRAY = MSGPACK_OBJECT_ARRAY,
MAP = MSGPACK_OBJECT_MAP,
};
}
struct object;
struct object_kv;
struct object_array {
uint32_t size;
object* ptr;
};
struct object_map {
uint32_t size;
object_kv* ptr;
};
struct object_raw {
uint32_t size;
const char* ptr;
};
struct object {
union union_type {
bool boolean;
uint64_t u64;
int64_t i64;
double dec;
object_array array;
object_map map;
object_raw raw;
object_raw ref; // obsolete
};
type::object_type type;
union_type via;
bool is_nil() const { return type == type::NIL; }
template <typename T>
T as() const;
template <typename T>
void convert(T* v) const;
object();
object(msgpack_object o);
template <typename T>
explicit object(const T& v);
template <typename T>
object(const T& v, zone* z);
template <typename T>
object& operator=(const T& v);
operator msgpack_object() const;
struct with_zone;
private:
struct implicit_type;
public:
implicit_type convert() const;
};
struct object_kv {
object key;
object val;
};
struct object::with_zone : object {
with_zone(msgpack::zone* zone) : zone(zone) { }
msgpack::zone* zone;
private:
with_zone();
};
bool operator==(const object x, const object y);
bool operator!=(const object x, const object y);
template <typename T>
bool operator==(const object x, const T& y);
template <typename T>
bool operator==(const T& y, const object x);
template <typename T>
bool operator!=(const object x, const T& y);
template <typename T>
bool operator!=(const T& y, const object x);
std::ostream& operator<< (std::ostream& s, const object o);
// serialize operator
template <typename Stream, typename T>
packer<Stream>& operator<< (packer<Stream>& o, const T& v);
// convert operator
template <typename T>
T& operator>> (object o, T& v);
// deconvert operator
template <typename T>
void operator<< (object::with_zone& o, const T& v);
struct object::implicit_type {
implicit_type(object o) : obj(o) { }
~implicit_type() { }
template <typename T>
operator T() { return obj.as<T>(); }
private:
object obj;
};
// obsolete
template <typename Type>
class define : public Type {
public:
typedef Type msgpack_type;
typedef define<Type> define_type;
define() {}
define(const msgpack_type& v) : msgpack_type(v) {}
template <typename Packer>
void msgpack_pack(Packer& o) const
{
o << static_cast<const msgpack_type&>(*this);
}
void msgpack_unpack(object o)
{
o >> static_cast<msgpack_type&>(*this);
}
};
template <typename Stream>
template <typename T>
inline packer<Stream>& packer<Stream>::pack(const T& v)
{
*this << v;
return *this;
}
inline object& operator>> (object o, object& v)
{
v = o;
return v;
}
template <typename T>
inline T& operator>> (object o, T& v)
{
v.msgpack_unpack(o.convert());
return v;
}
template <typename Stream, typename T>
inline packer<Stream>& operator<< (packer<Stream>& o, const T& v)
{
v.msgpack_pack(o);
return o;
}
template <typename T>
void operator<< (object::with_zone& o, const T& v)
{
v.msgpack_object(static_cast<object*>(&o), o.zone);
}
inline bool operator==(const object x, const object y)
{
return msgpack_object_equal(x, y);
}
template <typename T>
inline bool operator==(const object x, const T& y)
try {
return x == object(y);
} catch (msgpack::type_error&) {
return false;
}
inline bool operator!=(const object x, const object y)
{ return !(x == y); }
template <typename T>
inline bool operator==(const T& y, const object x)
{ return x == y; }
template <typename T>
inline bool operator!=(const object x, const T& y)
{ return !(x == y); }
template <typename T>
inline bool operator!=(const T& y, const object x)
{ return x != y; }
inline object::implicit_type object::convert() const
{
return implicit_type(*this);
}
template <typename T>
inline void object::convert(T* v) const
{
*this >> *v;
}
template <typename T>
inline T object::as() const
{
T v;
convert(&v);
return v;
}
inline object::object()
{
type = type::NIL;
}
template <typename T>
inline object::object(const T& v)
{
*this << v;
}
template <typename T>
inline object& object::operator=(const T& v)
{
*this = object(v);
return *this;
}
template <typename T>
object::object(const T& v, zone* z)
{
with_zone oz(z);
oz << v;
type = oz.type;
via = oz.via;
}
inline object::object(msgpack_object o)
{
// FIXME beter way?
::memcpy(this, &o, sizeof(o));
}
inline void operator<< (object& o, msgpack_object v)
{
// FIXME beter way?
::memcpy(&o, &v, sizeof(v));
}
inline object::operator msgpack_object() const
{
// FIXME beter way?
msgpack_object obj;
::memcpy(&obj, this, sizeof(obj));
return obj;
}
// obsolete
template <typename T>
inline void convert(T& v, object o)
{
o.convert(&v);
}
// obsolete
template <typename Stream, typename T>
inline void pack(packer<Stream>& o, const T& v)
{
o.pack(v);
}
// obsolete
template <typename Stream, typename T>
inline void pack_copy(packer<Stream>& o, T v)
{
pack(o, v);
}
template <typename Stream>
packer<Stream>& operator<< (packer<Stream>& o, const object& v)
{
switch(v.type) {
case type::NIL:
o.pack_nil();
return o;
case type::BOOLEAN:
if(v.via.boolean) {
o.pack_true();
} else {
o.pack_false();
}
return o;
case type::POSITIVE_INTEGER:
o.pack_uint64(v.via.u64);
return o;
case type::NEGATIVE_INTEGER:
o.pack_int64(v.via.i64);
return o;
case type::DOUBLE:
o.pack_double(v.via.dec);
return o;
case type::RAW:
o.pack_raw(v.via.raw.size);
o.pack_raw_body(v.via.raw.ptr, v.via.raw.size);
return o;
case type::ARRAY:
o.pack_array(v.via.array.size);
for(object* p(v.via.array.ptr),
* const pend(v.via.array.ptr + v.via.array.size);
p < pend; ++p) {
o << *p;
}
return o;
case type::MAP:
o.pack_map(v.via.map.size);
for(object_kv* p(v.via.map.ptr),
* const pend(v.via.map.ptr + v.via.map.size);
p < pend; ++p) {
o << p->key;
o << p->val;
}
return o;
default:
throw type_error();
}
}
} // namespace msgpack
#include "msgpack/type.hpp"
#endif /* msgpack/object.hpp */

View file

@ -1,146 +0,0 @@
/*
* MessagePack for C packing routine
*
* Copyright (C) 2008-2009 FURUHASHI Sadayuki
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MSGPACK_PACK_H__
#define MSGPACK_PACK_H__
#include "pack_define.h"
#include "object.h"
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup msgpack_buffer Buffers
* @ingroup msgpack
* @{
* @}
*/
/**
* @defgroup msgpack_pack Serializer
* @ingroup msgpack
* @{
*/
typedef int (*msgpack_packer_write)(void* data, const char* buf, unsigned int len);
typedef struct msgpack_packer {
void* data;
msgpack_packer_write callback;
} msgpack_packer;
static void msgpack_packer_init(msgpack_packer* pk, void* data, msgpack_packer_write callback);
static msgpack_packer* msgpack_packer_new(void* data, msgpack_packer_write callback);
static void msgpack_packer_free(msgpack_packer* pk);
static int msgpack_pack_short(msgpack_packer* pk, short d);
static int msgpack_pack_int(msgpack_packer* pk, int d);
static int msgpack_pack_long(msgpack_packer* pk, long d);
static int msgpack_pack_long_long(msgpack_packer* pk, long long d);
static int msgpack_pack_unsigned_short(msgpack_packer* pk, unsigned short d);
static int msgpack_pack_unsigned_int(msgpack_packer* pk, unsigned int d);
static int msgpack_pack_unsigned_long(msgpack_packer* pk, unsigned long d);
static int msgpack_pack_unsigned_long_long(msgpack_packer* pk, unsigned long long d);
static int msgpack_pack_uint8(msgpack_packer* pk, uint8_t d);
static int msgpack_pack_uint16(msgpack_packer* pk, uint16_t d);
static int msgpack_pack_uint32(msgpack_packer* pk, uint32_t d);
static int msgpack_pack_uint64(msgpack_packer* pk, uint64_t d);
static int msgpack_pack_int8(msgpack_packer* pk, int8_t d);
static int msgpack_pack_int16(msgpack_packer* pk, int16_t d);
static int msgpack_pack_int32(msgpack_packer* pk, int32_t d);
static int msgpack_pack_int64(msgpack_packer* pk, int64_t d);
static int msgpack_pack_fix_uint8(msgpack_packer* pk, uint8_t d);
static int msgpack_pack_fix_uint16(msgpack_packer* pk, uint16_t d);
static int msgpack_pack_fix_uint32(msgpack_packer* pk, uint32_t d);
static int msgpack_pack_fix_uint64(msgpack_packer* pk, uint64_t d);
static int msgpack_pack_fix_int8(msgpack_packer* pk, int8_t d);
static int msgpack_pack_fix_int16(msgpack_packer* pk, int16_t d);
static int msgpack_pack_fix_int32(msgpack_packer* pk, int32_t d);
static int msgpack_pack_fix_int64(msgpack_packer* pk, int64_t d);
static int msgpack_pack_float(msgpack_packer* pk, float d);
static int msgpack_pack_double(msgpack_packer* pk, double d);
static int msgpack_pack_nil(msgpack_packer* pk);
static int msgpack_pack_true(msgpack_packer* pk);
static int msgpack_pack_false(msgpack_packer* pk);
static int msgpack_pack_array(msgpack_packer* pk, unsigned int n);
static int msgpack_pack_map(msgpack_packer* pk, unsigned int n);
static int msgpack_pack_raw(msgpack_packer* pk, size_t l);
static int msgpack_pack_raw_body(msgpack_packer* pk, const void* b, size_t l);
int msgpack_pack_object(msgpack_packer* pk, msgpack_object d);
/** @} */
#define msgpack_pack_inline_func(name) \
inline int msgpack_pack ## name
#define msgpack_pack_inline_func_cint(name) \
inline int msgpack_pack ## name
#define msgpack_pack_inline_func_cint(name) \
inline int msgpack_pack ## name
#define msgpack_pack_inline_func_fixint(name) \
inline int msgpack_pack_fix ## name
#define msgpack_pack_user msgpack_packer*
#define msgpack_pack_append_buffer(user, buf, len) \
return (*(user)->callback)((user)->data, (const char*)buf, len)
#include "pack_template.h"
inline void msgpack_packer_init(msgpack_packer* pk, void* data, msgpack_packer_write callback)
{
pk->data = data;
pk->callback = callback;
}
inline msgpack_packer* msgpack_packer_new(void* data, msgpack_packer_write callback)
{
msgpack_packer* pk = (msgpack_packer*)calloc(1, sizeof(msgpack_packer));
if(!pk) { return NULL; }
msgpack_packer_init(pk, data, callback);
return pk;
}
inline void msgpack_packer_free(msgpack_packer* pk)
{
free(pk);
}
#ifdef __cplusplus
}
#endif
#endif /* msgpack/pack.h */

View file

@ -1,318 +0,0 @@
//
// MessagePack for C++ serializing routine
//
// Copyright (C) 2008-2010 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef MSGPACK_PACK_HPP__
#define MSGPACK_PACK_HPP__
#include "pack_define.h"
#include <stdexcept>
#include <limits.h>
namespace msgpack {
template <typename Stream>
class packer {
public:
packer(Stream* s);
packer(Stream& s);
~packer();
public:
template <typename T>
packer<Stream>& pack(const T& v);
packer<Stream>& pack_uint8(uint8_t d);
packer<Stream>& pack_uint16(uint16_t d);
packer<Stream>& pack_uint32(uint32_t d);
packer<Stream>& pack_uint64(uint64_t d);
packer<Stream>& pack_int8(int8_t d);
packer<Stream>& pack_int16(int16_t d);
packer<Stream>& pack_int32(int32_t d);
packer<Stream>& pack_int64(int64_t d);
packer<Stream>& pack_fix_uint8(uint8_t d);
packer<Stream>& pack_fix_uint16(uint16_t d);
packer<Stream>& pack_fix_uint32(uint32_t d);
packer<Stream>& pack_fix_uint64(uint64_t d);
packer<Stream>& pack_fix_int8(int8_t d);
packer<Stream>& pack_fix_int16(int16_t d);
packer<Stream>& pack_fix_int32(int32_t d);
packer<Stream>& pack_fix_int64(int64_t d);
packer<Stream>& pack_short(short d);
packer<Stream>& pack_int(int d);
packer<Stream>& pack_long(long d);
packer<Stream>& pack_long_long(long long d);
packer<Stream>& pack_unsigned_short(unsigned short d);
packer<Stream>& pack_unsigned_int(unsigned int d);
packer<Stream>& pack_unsigned_long(unsigned long d);
packer<Stream>& pack_unsigned_long_long(unsigned long long d);
packer<Stream>& pack_float(float d);
packer<Stream>& pack_double(double d);
packer<Stream>& pack_nil();
packer<Stream>& pack_true();
packer<Stream>& pack_false();
packer<Stream>& pack_array(unsigned int n);
packer<Stream>& pack_map(unsigned int n);
packer<Stream>& pack_raw(size_t l);
packer<Stream>& pack_raw_body(const char* b, size_t l);
private:
static void _pack_uint8(Stream& x, uint8_t d);
static void _pack_uint16(Stream& x, uint16_t d);
static void _pack_uint32(Stream& x, uint32_t d);
static void _pack_uint64(Stream& x, uint64_t d);
static void _pack_int8(Stream& x, int8_t d);
static void _pack_int16(Stream& x, int16_t d);
static void _pack_int32(Stream& x, int32_t d);
static void _pack_int64(Stream& x, int64_t d);
static void _pack_fix_uint8(Stream& x, uint8_t d);
static void _pack_fix_uint16(Stream& x, uint16_t d);
static void _pack_fix_uint32(Stream& x, uint32_t d);
static void _pack_fix_uint64(Stream& x, uint64_t d);
static void _pack_fix_int8(Stream& x, int8_t d);
static void _pack_fix_int16(Stream& x, int16_t d);
static void _pack_fix_int32(Stream& x, int32_t d);
static void _pack_fix_int64(Stream& x, int64_t d);
static void _pack_short(Stream& x, short d);
static void _pack_int(Stream& x, int d);
static void _pack_long(Stream& x, long d);
static void _pack_long_long(Stream& x, long long d);
static void _pack_unsigned_short(Stream& x, unsigned short d);
static void _pack_unsigned_int(Stream& x, unsigned int d);
static void _pack_unsigned_long(Stream& x, unsigned long d);
static void _pack_unsigned_long_long(Stream& x, unsigned long long d);
static void _pack_float(Stream& x, float d);
static void _pack_double(Stream& x, double d);
static void _pack_nil(Stream& x);
static void _pack_true(Stream& x);
static void _pack_false(Stream& x);
static void _pack_array(Stream& x, unsigned int n);
static void _pack_map(Stream& x, unsigned int n);
static void _pack_raw(Stream& x, size_t l);
static void _pack_raw_body(Stream& x, const void* b, size_t l);
static void append_buffer(Stream& x, const unsigned char* buf, unsigned int len)
{ x.write((const char*)buf, len); }
private:
Stream& m_stream;
private:
packer();
};
template <typename Stream, typename T>
inline void pack(Stream* s, const T& v)
{
packer<Stream>(s).pack(v);
}
template <typename Stream, typename T>
inline void pack(Stream& s, const T& v)
{
packer<Stream>(s).pack(v);
}
#define msgpack_pack_inline_func(name) \
template <typename Stream> \
inline void packer<Stream>::_pack ## name
#define msgpack_pack_inline_func_cint(name) \
template <typename Stream> \
inline void packer<Stream>::_pack ## name
#define msgpack_pack_inline_func_fixint(name) \
template <typename Stream> \
inline void packer<Stream>::_pack_fix ## name
#define msgpack_pack_user Stream&
#define msgpack_pack_append_buffer append_buffer
#include "pack_template.h"
template <typename Stream>
packer<Stream>::packer(Stream* s) : m_stream(*s) { }
template <typename Stream>
packer<Stream>::packer(Stream& s) : m_stream(s) { }
template <typename Stream>
packer<Stream>::~packer() { }
template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_uint8(uint8_t d)
{ _pack_uint8(m_stream, d); return *this; }
template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_uint16(uint16_t d)
{ _pack_uint16(m_stream, d); return *this; }
template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_uint32(uint32_t d)
{ _pack_uint32(m_stream, d); return *this; }
template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_uint64(uint64_t d)
{ _pack_uint64(m_stream, d); return *this; }
template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_int8(int8_t d)
{ _pack_int8(m_stream, d); return *this; }
template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_int16(int16_t d)
{ _pack_int16(m_stream, d); return *this; }
template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_int32(int32_t d)
{ _pack_int32(m_stream, d); return *this; }
template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_int64(int64_t d)
{ _pack_int64(m_stream, d); return *this;}
template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_fix_uint8(uint8_t d)
{ _pack_fix_uint8(m_stream, d); return *this; }
template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_fix_uint16(uint16_t d)
{ _pack_fix_uint16(m_stream, d); return *this; }
template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_fix_uint32(uint32_t d)
{ _pack_fix_uint32(m_stream, d); return *this; }
template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_fix_uint64(uint64_t d)
{ _pack_fix_uint64(m_stream, d); return *this; }
template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_fix_int8(int8_t d)
{ _pack_fix_int8(m_stream, d); return *this; }
template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_fix_int16(int16_t d)
{ _pack_fix_int16(m_stream, d); return *this; }
template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_fix_int32(int32_t d)
{ _pack_fix_int32(m_stream, d); return *this; }
template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_fix_int64(int64_t d)
{ _pack_fix_int64(m_stream, d); return *this;}
template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_short(short d)
{ _pack_short(m_stream, d); return *this; }
template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_int(int d)
{ _pack_int(m_stream, d); return *this; }
template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_long(long d)
{ _pack_long(m_stream, d); return *this; }
template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_long_long(long long d)
{ _pack_long_long(m_stream, d); return *this; }
template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_unsigned_short(unsigned short d)
{ _pack_unsigned_short(m_stream, d); return *this; }
template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_unsigned_int(unsigned int d)
{ _pack_unsigned_int(m_stream, d); return *this; }
template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_unsigned_long(unsigned long d)
{ _pack_unsigned_long(m_stream, d); return *this; }
template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_unsigned_long_long(unsigned long long d)
{ _pack_unsigned_long_long(m_stream, d); return *this; }
template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_float(float d)
{ _pack_float(m_stream, d); return *this; }
template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_double(double d)
{ _pack_double(m_stream, d); return *this; }
template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_nil()
{ _pack_nil(m_stream); return *this; }
template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_true()
{ _pack_true(m_stream); return *this; }
template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_false()
{ _pack_false(m_stream); return *this; }
template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_array(unsigned int n)
{ _pack_array(m_stream, n); return *this; }
template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_map(unsigned int n)
{ _pack_map(m_stream, n); return *this; }
template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_raw(size_t l)
{ _pack_raw(m_stream, l); return *this; }
template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_raw_body(const char* b, size_t l)
{ _pack_raw_body(m_stream, b, l); return *this; }
} // namespace msgpack
#endif /* msgpack/pack.hpp */

View file

@ -1,111 +0,0 @@
/*
* MessagePack for C simple buffer implementation
*
* Copyright (C) 2008-2009 FURUHASHI Sadayuki
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MSGPACK_SBUFFER_H__
#define MSGPACK_SBUFFER_H__
#include <stdlib.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup msgpack_sbuffer Simple buffer
* @ingroup msgpack_buffer
* @{
*/
typedef struct msgpack_sbuffer {
size_t size;
char* data;
size_t alloc;
} msgpack_sbuffer;
static inline void msgpack_sbuffer_init(msgpack_sbuffer* sbuf)
{
memset(sbuf, 0, sizeof(msgpack_sbuffer));
}
static inline void msgpack_sbuffer_destroy(msgpack_sbuffer* sbuf)
{
free(sbuf->data);
}
static inline msgpack_sbuffer* msgpack_sbuffer_new(void)
{
return (msgpack_sbuffer*)calloc(1, sizeof(msgpack_sbuffer));
}
static inline void msgpack_sbuffer_free(msgpack_sbuffer* sbuf)
{
if(sbuf == NULL) { return; }
msgpack_sbuffer_destroy(sbuf);
free(sbuf);
}
#ifndef MSGPACK_SBUFFER_INIT_SIZE
#define MSGPACK_SBUFFER_INIT_SIZE 8192
#endif
static inline int msgpack_sbuffer_write(void* data, const char* buf, unsigned int len)
{
msgpack_sbuffer* sbuf = (msgpack_sbuffer*)data;
if(sbuf->alloc - sbuf->size < len) {
size_t nsize = (sbuf->alloc) ?
sbuf->alloc * 2 : MSGPACK_SBUFFER_INIT_SIZE;
while(nsize < sbuf->size + len) { nsize *= 2; }
void* tmp = realloc(sbuf->data, nsize);
if(!tmp) { return -1; }
sbuf->data = (char*)tmp;
sbuf->alloc = nsize;
}
memcpy(sbuf->data + sbuf->size, buf, len);
sbuf->size += len;
return 0;
}
static inline char* msgpack_sbuffer_release(msgpack_sbuffer* sbuf)
{
char* tmp = sbuf->data;
sbuf->size = 0;
sbuf->data = NULL;
sbuf->alloc = 0;
return tmp;
}
static inline void msgpack_sbuffer_clear(msgpack_sbuffer* sbuf)
{
sbuf->size = 0;
}
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* msgpack/sbuffer.h */

View file

@ -1,112 +0,0 @@
//
// MessagePack for C++ simple buffer implementation
//
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef MSGPACK_SBUFFER_HPP__
#define MSGPACK_SBUFFER_HPP__
#include "sbuffer.h"
#include <stdexcept>
namespace msgpack {
class sbuffer : public msgpack_sbuffer {
public:
sbuffer(size_t initsz = MSGPACK_SBUFFER_INIT_SIZE)
{
if(initsz == 0) {
base::data = NULL;
} else {
base::data = (char*)::malloc(initsz);
if(!base::data) {
throw std::bad_alloc();
}
}
base::size = 0;
base::alloc = initsz;
}
~sbuffer()
{
::free(base::data);
}
public:
void write(const char* buf, unsigned int len)
{
if(base::alloc - base::size < len) {
expand_buffer(len);
}
memcpy(base::data + base::size, buf, len);
base::size += len;
}
char* data()
{
return base::data;
}
const char* data() const
{
return base::data;
}
size_t size() const
{
return base::size;
}
char* release()
{
return msgpack_sbuffer_release(this);
}
void clear()
{
msgpack_sbuffer_clear(this);
}
private:
void expand_buffer(size_t len)
{
size_t nsize = (base::alloc > 0) ?
base::alloc * 2 : MSGPACK_SBUFFER_INIT_SIZE;
while(nsize < base::size + len) { nsize *= 2; }
void* tmp = realloc(base::data, nsize);
if(!tmp) {
throw std::bad_alloc();
}
base::data = (char*)tmp;
base::alloc = nsize;
}
private:
typedef msgpack_sbuffer base;
private:
sbuffer(const sbuffer&);
};
} // namespace msgpack
#endif /* msgpack/sbuffer.hpp */

View file

@ -1,16 +0,0 @@
#include "type/bool.hpp"
#include "type/deque.hpp"
#include "type/fixint.hpp"
#include "type/float.hpp"
#include "type/int.hpp"
#include "type/list.hpp"
#include "type/map.hpp"
#include "type/nil.hpp"
#include "type/pair.hpp"
#include "type/raw.hpp"
#include "type/set.hpp"
#include "type/string.hpp"
#include "type/vector.hpp"
#include "type/tuple.hpp"
#include "type/define.hpp"

View file

@ -1,55 +0,0 @@
//
// MessagePack for C++ static resolution routine
//
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef MSGPACK_TYPE_BOOL_HPP__
#define MSGPACK_TYPE_BOOL_HPP__
#include "msgpack/object.hpp"
#include <vector>
namespace msgpack {
inline bool& operator>> (object o, bool& v)
{
if(o.type != type::BOOLEAN) { throw type_error(); }
v = o.via.boolean;
return v;
}
template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const bool& v)
{
if(v) { o.pack_true(); }
else { o.pack_false(); }
return o;
}
inline void operator<< (object& o, bool v)
{
o.type = type::BOOLEAN;
o.via.boolean = v;
}
inline void operator<< (object::with_zone& o, bool v)
{ static_cast<object&>(o) << v; }
} // namespace msgpack
#endif /* msgpack/type/bool.hpp */

View file

@ -1,117 +0,0 @@
//
// MessagePack for C++ static resolution routine
//
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef MSGPACK_TYPE_DEFINE_HPP__
#define MSGPACK_TYPE_DEFINE_HPP__
#define MSGPACK_DEFINE(...) \
template <typename Packer> \
void msgpack_pack(Packer& pk) const \
{ \
msgpack::type::make_define(__VA_ARGS__).msgpack_pack(pk); \
} \
void msgpack_unpack(msgpack::object o) \
{ \
msgpack::type::make_define(__VA_ARGS__).msgpack_unpack(o); \
}\
template <typename MSGPACK_OBJECT> \
void msgpack_object(MSGPACK_OBJECT* o, msgpack::zone* z) const \
{ \
msgpack::type::make_define(__VA_ARGS__).msgpack_object(o, z); \
}
namespace msgpack {
namespace type {
<% GENERATION_LIMIT = 31 %>
template <typename A0 = void<%1.upto(GENERATION_LIMIT+1) {|i|%>, typename A<%=i%> = void<%}%>>
struct define;
template <>
struct define<> {
typedef define<> value_type;
typedef tuple<> tuple_type;
template <typename Packer>
void msgpack_pack(Packer& pk) const
{
pk.pack_array(1);
}
void msgpack_unpack(msgpack::object o)
{
if(o.type != type::ARRAY) { throw type_error(); }
}
void msgpack_object(msgpack::object* o, msgpack::zone* z) const
{
o->type = type::ARRAY;
o->via.array.ptr = NULL;
o->via.array.size = 0;
}
};
<%0.upto(GENERATION_LIMIT) {|i|%>
template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
struct define<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> {
typedef define<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> value_type;
typedef tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> tuple_type;
define(A0& _a0<%1.upto(i) {|j|%>, A<%=j%>& _a<%=j%><%}%>) :
a0(_a0)<%1.upto(i) {|j|%>, a<%=j%>(_a<%=j%>)<%}%> {}
template <typename Packer>
void msgpack_pack(Packer& pk) const
{
pk.pack_array(<%=i+1%>);
<%0.upto(i) {|j|%>
pk.pack(a<%=j%>);<%}%>
}
void msgpack_unpack(msgpack::object o)
{
if(o.type != type::ARRAY) { throw type_error(); }
const size_t size = o.via.array.size;
<%0.upto(i) {|j|%>
if(size <= <%=j%>) { return; } o.via.array.ptr[<%=j%>].convert(&a<%=j%>);<%}%>
}
void msgpack_object(msgpack::object* o, msgpack::zone* z) const
{
o->type = type::ARRAY;
o->via.array.ptr = (object*)z->malloc(sizeof(object)*<%=i+1%>);
o->via.array.size = <%=i+1%>;
<%0.upto(i) {|j|%>
o->via.array.ptr[<%=j%>] = object(a<%=j%>, z);<%}%>
}
<%0.upto(i) {|j|%>
A<%=j%>& a<%=j%>;<%}%>
};
<%}%>
inline define<> make_define()
{
return define<>();
}
<%0.upto(GENERATION_LIMIT) {|i|%>
template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
define<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> make_define(A0& a0<%1.upto(i) {|j|%>, A<%=j%>& a<%=j%><%}%>)
{
return define<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>(a0<%1.upto(i) {|j|%>, a<%=j%><%}%>);
}
<%}%>
} // namespace type
} // namespace msgpack
#endif /* msgpack/type/define.hpp */

View file

@ -1,77 +0,0 @@
//
// MessagePack for C++ static resolution routine
//
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef MSGPACK_TYPE_DEQUE_HPP__
#define MSGPACK_TYPE_DEQUE_HPP__
#include "msgpack/object.hpp"
#include <deque>
namespace msgpack {
template <typename T>
inline std::deque<T>& operator>> (object o, std::deque<T>& v)
{
if(o.type != type::ARRAY) { throw type_error(); }
v.resize(o.via.array.size);
object* p = o.via.array.ptr;
object* const pend = o.via.array.ptr + o.via.array.size;
typename std::deque<T>::iterator it = v.begin();
for(; p < pend; ++p, ++it) {
p->convert(&*it);
}
return v;
}
template <typename Stream, typename T>
inline packer<Stream>& operator<< (packer<Stream>& o, const std::deque<T>& v)
{
o.pack_array(v.size());
for(typename std::deque<T>::const_iterator it(v.begin()), it_end(v.end());
it != it_end; ++it) {
o.pack(*it);
}
return o;
}
template <typename T>
inline void operator<< (object::with_zone& o, const std::deque<T>& v)
{
o.type = type::ARRAY;
if(v.empty()) {
o.via.array.ptr = NULL;
o.via.array.size = 0;
} else {
object* p = (object*)o.zone->malloc(sizeof(object)*v.size());
object* const pend = p + v.size();
o.via.array.ptr = p;
o.via.array.size = v.size();
typename std::deque<T>::const_iterator it(v.begin());
do {
*p = object(*it, o.zone);
++p;
++it;
} while(p < pend);
}
}
} // namespace msgpack
#endif /* msgpack/type/deque.hpp */

View file

@ -1,172 +0,0 @@
//
// MessagePack for C++ static resolution routine
//
// Copyright (C) 2020 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef MSGPACK_TYPE_FIXINT_HPP__
#define MSGPACK_TYPE_FIXINT_HPP__
#include "msgpack/object.hpp"
#include "msgpack/type/int.hpp"
namespace msgpack {
namespace type {
template <typename T>
struct fix_int {
fix_int() : value(0) { }
fix_int(T value) : value(value) { }
operator T() const { return value; }
T get() const { return value; }
private:
T value;
};
typedef fix_int<uint8_t> fix_uint8;
typedef fix_int<uint16_t> fix_uint16;
typedef fix_int<uint32_t> fix_uint32;
typedef fix_int<uint64_t> fix_uint64;
typedef fix_int<int8_t> fix_int8;
typedef fix_int<int16_t> fix_int16;
typedef fix_int<int32_t> fix_int32;
typedef fix_int<int64_t> fix_int64;
} // namespace type
inline type::fix_int8& operator>> (object o, type::fix_int8& v)
{ v = type::detail::convert_integer<int8_t>(o); return v; }
inline type::fix_int16& operator>> (object o, type::fix_int16& v)
{ v = type::detail::convert_integer<int16_t>(o); return v; }
inline type::fix_int32& operator>> (object o, type::fix_int32& v)
{ v = type::detail::convert_integer<int32_t>(o); return v; }
inline type::fix_int64& operator>> (object o, type::fix_int64& v)
{ v = type::detail::convert_integer<int64_t>(o); return v; }
inline type::fix_uint8& operator>> (object o, type::fix_uint8& v)
{ v = type::detail::convert_integer<uint8_t>(o); return v; }
inline type::fix_uint16& operator>> (object o, type::fix_uint16& v)
{ v = type::detail::convert_integer<uint16_t>(o); return v; }
inline type::fix_uint32& operator>> (object o, type::fix_uint32& v)
{ v = type::detail::convert_integer<uint32_t>(o); return v; }
inline type::fix_uint64& operator>> (object o, type::fix_uint64& v)
{ v = type::detail::convert_integer<uint64_t>(o); return v; }
template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_int8& v)
{ o.pack_fix_int8(v); return o; }
template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_int16& v)
{ o.pack_fix_int16(v); return o; }
template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_int32& v)
{ o.pack_fix_int32(v); return o; }
template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_int64& v)
{ o.pack_fix_int64(v); return o; }
template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_uint8& v)
{ o.pack_fix_uint8(v); return o; }
template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_uint16& v)
{ o.pack_fix_uint16(v); return o; }
template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_uint32& v)
{ o.pack_fix_uint32(v); return o; }
template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_uint64& v)
{ o.pack_fix_uint64(v); return o; }
inline void operator<< (object& o, type::fix_int8 v)
{ v.get() < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v.get() : o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); }
inline void operator<< (object& o, type::fix_int16 v)
{ v.get() < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v.get() : o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); }
inline void operator<< (object& o, type::fix_int32 v)
{ v.get() < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v.get() : o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); }
inline void operator<< (object& o, type::fix_int64 v)
{ v.get() < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v.get() : o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); }
inline void operator<< (object& o, type::fix_uint8 v)
{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); }
inline void operator<< (object& o, type::fix_uint16 v)
{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); }
inline void operator<< (object& o, type::fix_uint32 v)
{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); }
inline void operator<< (object& o, type::fix_uint64 v)
{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); }
inline void operator<< (object::with_zone& o, type::fix_int8 v)
{ static_cast<object&>(o) << v; }
inline void operator<< (object::with_zone& o, type::fix_int16 v)
{ static_cast<object&>(o) << v; }
inline void operator<< (object::with_zone& o, type::fix_int32 v)
{ static_cast<object&>(o) << v; }
inline void operator<< (object::with_zone& o, type::fix_int64 v)
{ static_cast<object&>(o) << v; }
inline void operator<< (object::with_zone& o, type::fix_uint8 v)
{ static_cast<object&>(o) << v; }
inline void operator<< (object::with_zone& o, type::fix_uint16 v)
{ static_cast<object&>(o) << v; }
inline void operator<< (object::with_zone& o, type::fix_uint32 v)
{ static_cast<object&>(o) << v; }
inline void operator<< (object::with_zone& o, type::fix_uint64 v)
{ static_cast<object&>(o) << v; }
} // namespace msgpack
#endif /* msgpack/type/fixint.hpp */

View file

@ -1,82 +0,0 @@
//
// MessagePack for C++ static resolution routine
//
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef MSGPACK_TYPE_FLOAT_HPP__
#define MSGPACK_TYPE_FLOAT_HPP__
#include "msgpack/object.hpp"
#include <vector>
namespace msgpack {
// FIXME check overflow, underflow
inline float& operator>> (object o, float& v)
{
if(o.type != type::DOUBLE) { throw type_error(); }
v = o.via.dec;
return v;
}
template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const float& v)
{
o.pack_float(v);
return o;
}
inline double& operator>> (object o, double& v)
{
if(o.type != type::DOUBLE) { throw type_error(); }
v = o.via.dec;
return v;
}
template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const double& v)
{
o.pack_double(v);
return o;
}
inline void operator<< (object& o, float v)
{
o.type = type::DOUBLE;
o.via.dec = v;
}
inline void operator<< (object& o, double v)
{
o.type = type::DOUBLE;
o.via.dec = v;
}
inline void operator<< (object::with_zone& o, float v)
{ static_cast<object&>(o) << v; }
inline void operator<< (object::with_zone& o, double v)
{ static_cast<object&>(o) << v; }
} // namespace msgpack
#endif /* msgpack/type/float.hpp */

View file

@ -1,211 +0,0 @@
//
// MessagePack for C++ static resolution routine
//
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef MSGPACK_TYPE_INT_HPP__
#define MSGPACK_TYPE_INT_HPP__
#include "msgpack/object.hpp"
#include <limits>
namespace msgpack {
namespace type {
namespace detail {
template <typename T, bool Signed>
struct convert_integer_sign;
template <typename T>
struct convert_integer_sign<T, true> {
static inline T convert(object o) {
if(o.type == type::POSITIVE_INTEGER) {
if(o.via.u64 > (uint64_t)std::numeric_limits<T>::max())
{ throw type_error(); }
return o.via.u64;
} else if(o.type == type::NEGATIVE_INTEGER) {
if(o.via.i64 < (int64_t)std::numeric_limits<T>::min())
{ throw type_error(); }
return o.via.i64;
}
throw type_error();
}
};
template <typename T>
struct convert_integer_sign<T, false> {
static inline T convert(object o) {
if(o.type == type::POSITIVE_INTEGER) {
if(o.via.u64 > (uint64_t)std::numeric_limits<T>::max())
{ throw type_error(); }
return o.via.u64;
}
throw type_error();
}
};
template <typename T>
static inline T convert_integer(object o)
{
return detail::convert_integer_sign<T, std::numeric_limits<T>::is_signed>::convert(o);
}
} // namespace detail
} // namespace type
inline signed char& operator>> (object o, signed char& v)
{ v = type::detail::convert_integer<signed char>(o); return v; }
inline signed short& operator>> (object o, signed short& v)
{ v = type::detail::convert_integer<signed short>(o); return v; }
inline signed int& operator>> (object o, signed int& v)
{ v = type::detail::convert_integer<signed int>(o); return v; }
inline signed long& operator>> (object o, signed long& v)
{ v = type::detail::convert_integer<signed long>(o); return v; }
inline signed long long& operator>> (object o, signed long long& v)
{ v = type::detail::convert_integer<signed long long>(o); return v; }
inline unsigned char& operator>> (object o, unsigned char& v)
{ v = type::detail::convert_integer<unsigned char>(o); return v; }
inline unsigned short& operator>> (object o, unsigned short& v)
{ v = type::detail::convert_integer<unsigned short>(o); return v; }
inline unsigned int& operator>> (object o, unsigned int& v)
{ v = type::detail::convert_integer<unsigned int>(o); return v; }
inline unsigned long& operator>> (object o, unsigned long& v)
{ v = type::detail::convert_integer<unsigned long>(o); return v; }
inline unsigned long long& operator>> (object o, unsigned long long& v)
{ v = type::detail::convert_integer<unsigned long long>(o); return v; }
template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const signed char& v)
{ o.pack_int8(v); return o; }
template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const signed short& v)
{ o.pack_short(v); return o; }
template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const signed int& v)
{ o.pack_int(v); return o; }
template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const signed long& v)
{ o.pack_long(v); return o; }
template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const signed long long& v)
{ o.pack_long_long(v); return o; }
template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const unsigned char& v)
{ o.pack_uint8(v); return o; }
template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const unsigned short& v)
{ o.pack_unsigned_short(v); return o; }
template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const unsigned int& v)
{ o.pack_unsigned_int(v); return o; }
template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const unsigned long& v)
{ o.pack_unsigned_long(v); return o; }
template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const unsigned long long& v)
{ o.pack_unsigned_long_long(v); return o; }
inline void operator<< (object& o, signed char v)
{ v < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v : o.type = type::POSITIVE_INTEGER, o.via.u64 = v; }
inline void operator<< (object& o, signed short v)
{ v < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v : o.type = type::POSITIVE_INTEGER, o.via.u64 = v; }
inline void operator<< (object& o, signed int v)
{ v < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v : o.type = type::POSITIVE_INTEGER, o.via.u64 = v; }
inline void operator<< (object& o, signed long v)
{ v < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v : o.type = type::POSITIVE_INTEGER, o.via.u64 = v; }
inline void operator<< (object& o, signed long long v)
{ v < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v : o.type = type::POSITIVE_INTEGER, o.via.u64 = v; }
inline void operator<< (object& o, unsigned char v)
{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v; }
inline void operator<< (object& o, unsigned short v)
{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v; }
inline void operator<< (object& o, unsigned int v)
{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v; }
inline void operator<< (object& o, unsigned long v)
{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v; }
inline void operator<< (object& o, unsigned long long v)
{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v; }
inline void operator<< (object::with_zone& o, signed char v)
{ static_cast<object&>(o) << v; }
inline void operator<< (object::with_zone& o, signed short v)
{ static_cast<object&>(o) << v; }
inline void operator<< (object::with_zone& o, signed int v)
{ static_cast<object&>(o) << v; }
inline void operator<< (object::with_zone& o, signed long v)
{ static_cast<object&>(o) << v; }
inline void operator<< (object::with_zone& o, signed long long v)
{ static_cast<object&>(o) << v; }
inline void operator<< (object::with_zone& o, unsigned char v)
{ static_cast<object&>(o) << v; }
inline void operator<< (object::with_zone& o, unsigned short v)
{ static_cast<object&>(o) << v; }
inline void operator<< (object::with_zone& o, unsigned int v)
{ static_cast<object&>(o) << v; }
inline void operator<< (object::with_zone& o, unsigned long v)
{ static_cast<object&>(o) << v; }
inline void operator<< (object::with_zone& o, unsigned long long v)
{ static_cast<object&>(o) << v; }
} // namespace msgpack
#endif /* msgpack/type/int.hpp */

View file

@ -1,77 +0,0 @@
//
// MessagePack for C++ static resolution routine
//
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef MSGPACK_TYPE_LIST_HPP__
#define MSGPACK_TYPE_LIST_HPP__
#include "msgpack/object.hpp"
#include <list>
namespace msgpack {
template <typename T>
inline std::list<T>& operator>> (object o, std::list<T>& v)
{
if(o.type != type::ARRAY) { throw type_error(); }
v.resize(o.via.array.size);
object* p = o.via.array.ptr;
object* const pend = o.via.array.ptr + o.via.array.size;
typename std::list<T>::iterator it = v.begin();
for(; p < pend; ++p, ++it) {
p->convert(&*it);
}
return v;
}
template <typename Stream, typename T>
inline packer<Stream>& operator<< (packer<Stream>& o, const std::list<T>& v)
{
o.pack_array(v.size());
for(typename std::list<T>::const_iterator it(v.begin()), it_end(v.end());
it != it_end; ++it) {
o.pack(*it);
}
return o;
}
template <typename T>
inline void operator<< (object::with_zone& o, const std::list<T>& v)
{
o.type = type::ARRAY;
if(v.empty()) {
o.via.array.ptr = NULL;
o.via.array.size = 0;
} else {
object* p = (object*)o.zone->malloc(sizeof(object)*v.size());
object* const pend = p + v.size();
o.via.array.ptr = p;
o.via.array.size = v.size();
typename std::list<T>::const_iterator it(v.begin());
do {
*p = object(*it, o.zone);
++p;
++it;
} while(p < pend);
}
}
} // namespace msgpack
#endif /* msgpack/type/list.hpp */

View file

@ -1,205 +0,0 @@
//
// MessagePack for C++ static resolution routine
//
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef MSGPACK_TYPE_MAP_HPP__
#define MSGPACK_TYPE_MAP_HPP__
#include "msgpack/object.hpp"
#include <map>
#include <vector>
#include <algorithm>
namespace msgpack {
namespace type {
template <typename K, typename V>
class assoc_vector : public std::vector< std::pair<K, V> > {};
namespace detail {
template <typename K, typename V>
struct pair_first_less {
bool operator() (const std::pair<K, V>& x, const std::pair<K, V>& y) const
{ return x.first < y.first; }
};
}
} //namespace type
template <typename K, typename V>
inline type::assoc_vector<K,V>& operator>> (object o, type::assoc_vector<K,V>& v)
{
if(o.type != type::MAP) { throw type_error(); }
v.resize(o.via.map.size);
object_kv* p = o.via.map.ptr;
object_kv* const pend = o.via.map.ptr + o.via.map.size;
std::pair<K, V>* it(&v.front());
for(; p < pend; ++p, ++it) {
p->key.convert(&it->first);
p->val.convert(&it->second);
}
std::sort(v.begin(), v.end(), type::detail::pair_first_less<K,V>());
return v;
}
template <typename Stream, typename K, typename V>
inline packer<Stream>& operator<< (packer<Stream>& o, const type::assoc_vector<K,V>& v)
{
o.pack_map(v.size());
for(typename type::assoc_vector<K,V>::const_iterator it(v.begin()), it_end(v.end());
it != it_end; ++it) {
o.pack(it->first);
o.pack(it->second);
}
return o;
}
template <typename K, typename V>
inline void operator<< (object::with_zone& o, const type::assoc_vector<K,V>& v)
{
o.type = type::MAP;
if(v.empty()) {
o.via.map.ptr = NULL;
o.via.map.size = 0;
} else {
object_kv* p = (object_kv*)o.zone->malloc(sizeof(object_kv)*v.size());
object_kv* const pend = p + v.size();
o.via.map.ptr = p;
o.via.map.size = v.size();
typename type::assoc_vector<K,V>::const_iterator it(v.begin());
do {
p->key = object(it->first, o.zone);
p->val = object(it->second, o.zone);
++p;
++it;
} while(p < pend);
}
}
template <typename K, typename V>
inline std::map<K, V> operator>> (object o, std::map<K, V>& v)
{
if(o.type != type::MAP) { throw type_error(); }
object_kv* p(o.via.map.ptr);
object_kv* const pend(o.via.map.ptr + o.via.map.size);
for(; p != pend; ++p) {
K key;
p->key.convert(&key);
typename std::map<K,V>::iterator it(v.lower_bound(key));
if(it != v.end() && !(key < it->first)) {
p->val.convert(&it->second);
} else {
V val;
p->val.convert(&val);
v.insert(it, std::pair<K,V>(key, val));
}
}
return v;
}
template <typename Stream, typename K, typename V>
inline packer<Stream>& operator<< (packer<Stream>& o, const std::map<K,V>& v)
{
o.pack_map(v.size());
for(typename std::map<K,V>::const_iterator it(v.begin()), it_end(v.end());
it != it_end; ++it) {
o.pack(it->first);
o.pack(it->second);
}
return o;
}
template <typename K, typename V>
inline void operator<< (object::with_zone& o, const std::map<K,V>& v)
{
o.type = type::MAP;
if(v.empty()) {
o.via.map.ptr = NULL;
o.via.map.size = 0;
} else {
object_kv* p = (object_kv*)o.zone->malloc(sizeof(object_kv)*v.size());
object_kv* const pend = p + v.size();
o.via.map.ptr = p;
o.via.map.size = v.size();
typename std::map<K,V>::const_iterator it(v.begin());
do {
p->key = object(it->first, o.zone);
p->val = object(it->second, o.zone);
++p;
++it;
} while(p < pend);
}
}
template <typename K, typename V>
inline std::multimap<K, V> operator>> (object o, std::multimap<K, V>& v)
{
if(o.type != type::MAP) { throw type_error(); }
object_kv* p(o.via.map.ptr);
object_kv* const pend(o.via.map.ptr + o.via.map.size);
for(; p != pend; ++p) {
std::pair<K, V> value;
p->key.convert(&value.first);
p->val.convert(&value.second);
v.insert(value);
}
return v;
}
template <typename Stream, typename K, typename V>
inline packer<Stream>& operator<< (packer<Stream>& o, const std::multimap<K,V>& v)
{
o.pack_map(v.size());
for(typename std::multimap<K,V>::const_iterator it(v.begin()), it_end(v.end());
it != it_end; ++it) {
o.pack(it->first);
o.pack(it->second);
}
return o;
}
template <typename K, typename V>
inline void operator<< (object::with_zone& o, const std::multimap<K,V>& v)
{
o.type = type::MAP;
if(v.empty()) {
o.via.map.ptr = NULL;
o.via.map.size = 0;
} else {
object_kv* p = (object_kv*)o.zone->malloc(sizeof(object_kv)*v.size());
object_kv* const pend = p + v.size();
o.via.map.ptr = p;
o.via.map.size = v.size();
typename std::multimap<K,V>::const_iterator it(v.begin());
do {
p->key = object(it->first, o.zone);
p->val = object(it->second, o.zone);
++p;
++it;
} while(p < pend);
}
}
} // namespace msgpack
#endif /* msgpack/type/map.hpp */

View file

@ -1,65 +0,0 @@
//
// MessagePack for C++ static resolution routine
//
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef MSGPACK_TYPE_NIL_HPP__
#define MSGPACK_TYPE_NIL_HPP__
#include "msgpack/object.hpp"
namespace msgpack {
namespace type {
struct nil { };
} // namespace type
inline type::nil& operator>> (object o, type::nil& v)
{
if(o.type != type::NIL) { throw type_error(); }
return v;
}
template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const type::nil& v)
{
o.pack_nil();
return o;
}
inline void operator<< (object& o, type::nil v)
{
o.type = type::NIL;
}
inline void operator<< (object::with_zone& o, type::nil v)
{ static_cast<object&>(o) << v; }
template <>
inline void object::as<void>() const
{
msgpack::type::nil v;
convert(&v);
}
} // namespace msgpack
#endif /* msgpack/type/nil.hpp */

View file

@ -1,61 +0,0 @@
//
// MessagePack for C++ static resolution routine
//
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef MSGPACK_TYPE_PAIR_HPP__
#define MSGPACK_TYPE_PAIR_HPP__
#include "msgpack/object.hpp"
#include <utility>
namespace msgpack {
template <typename T1, typename T2>
inline std::pair<T1, T2>& operator>> (object o, std::pair<T1, T2>& v)
{
if(o.type != type::ARRAY) { throw type_error(); }
if(o.via.array.size != 2) { throw type_error(); }
o.via.array.ptr[0].convert(&v.first);
o.via.array.ptr[1].convert(&v.second);
return v;
}
template <typename Stream, typename T1, typename T2>
inline packer<Stream>& operator<< (packer<Stream>& o, const std::pair<T1, T2>& v)
{
o.pack_array(2);
o.pack(v.first);
o.pack(v.second);
return o;
}
template <typename T1, typename T2>
inline void operator<< (object::with_zone& o, const std::pair<T1, T2>& v)
{
o.type = type::ARRAY;
object* p = (object*)o.zone->malloc(sizeof(object)*2);
o.via.array.ptr = p;
o.via.array.size = 2;
p[0] = object(v.first, o.zone);
p[1] = object(v.second, o.zone);
}
} // namespace msgpack
#endif /* msgpack/type/pair.hpp */

View file

@ -1,94 +0,0 @@
//
// MessagePack for C++ static resolution routine
//
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef MSGPACK_TYPE_RAW_HPP__
#define MSGPACK_TYPE_RAW_HPP__
#include "msgpack/object.hpp"
#include <string.h>
#include <string>
namespace msgpack {
namespace type {
struct raw_ref {
raw_ref() : size(0), ptr(NULL) {}
raw_ref(const char* p, uint32_t s) : size(s), ptr(p) {}
uint32_t size;
const char* ptr;
std::string str() const { return std::string(ptr, size); }
bool operator== (const raw_ref& x) const
{
return size == x.size && memcmp(ptr, x.ptr, size) == 0;
}
bool operator!= (const raw_ref& x) const
{
return !(*this != x);
}
bool operator< (const raw_ref& x) const
{
if(size == x.size) { return memcmp(ptr, x.ptr, size) < 0; }
else { return size < x.size; }
}
bool operator> (const raw_ref& x) const
{
if(size == x.size) { return memcmp(ptr, x.ptr, size) > 0; }
else { return size > x.size; }
}
};
} // namespace type
inline type::raw_ref& operator>> (object o, type::raw_ref& v)
{
if(o.type != type::RAW) { throw type_error(); }
v.ptr = o.via.raw.ptr;
v.size = o.via.raw.size;
return v;
}
template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const type::raw_ref& v)
{
o.pack_raw(v.size);
o.pack_raw_body(v.ptr, v.size);
return o;
}
inline void operator<< (object& o, const type::raw_ref& v)
{
o.type = type::RAW;
o.via.raw.ptr = v.ptr;
o.via.raw.size = v.size;
}
inline void operator<< (object::with_zone& o, const type::raw_ref& v)
{ static_cast<object&>(o) << v; }
} // namespace msgpack
#endif /* msgpack/type/raw.hpp */

View file

@ -1,122 +0,0 @@
//
// MessagePack for C++ static resolution routine
//
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef MSGPACK_TYPE_SET_HPP__
#define MSGPACK_TYPE_SET_HPP__
#include "msgpack/object.hpp"
#include <set>
namespace msgpack {
template <typename T>
inline std::set<T>& operator>> (object o, std::set<T>& v)
{
if(o.type != type::ARRAY) { throw type_error(); }
object* p = o.via.array.ptr + o.via.array.size;
object* const pbegin = o.via.array.ptr;
while(p > pbegin) {
--p;
v.insert(p->as<T>());
}
return v;
}
template <typename Stream, typename T>
inline packer<Stream>& operator<< (packer<Stream>& o, const std::set<T>& v)
{
o.pack_array(v.size());
for(typename std::set<T>::const_iterator it(v.begin()), it_end(v.end());
it != it_end; ++it) {
o.pack(*it);
}
return o;
}
template <typename T>
inline void operator<< (object::with_zone& o, const std::set<T>& v)
{
o.type = type::ARRAY;
if(v.empty()) {
o.via.array.ptr = NULL;
o.via.array.size = 0;
} else {
object* p = (object*)o.zone->malloc(sizeof(object)*v.size());
object* const pend = p + v.size();
o.via.array.ptr = p;
o.via.array.size = v.size();
typename std::set<T>::const_iterator it(v.begin());
do {
*p = object(*it, o.zone);
++p;
++it;
} while(p < pend);
}
}
template <typename T>
inline std::multiset<T>& operator>> (object o, std::multiset<T>& v)
{
if(o.type != type::ARRAY) { throw type_error(); }
object* p = o.via.array.ptr + o.via.array.size;
object* const pbegin = o.via.array.ptr;
while(p > pbegin) {
--p;
v.insert(p->as<T>());
}
return v;
}
template <typename Stream, typename T>
inline packer<Stream>& operator<< (packer<Stream>& o, const std::multiset<T>& v)
{
o.pack_array(v.size());
for(typename std::multiset<T>::const_iterator it(v.begin()), it_end(v.end());
it != it_end; ++it) {
o.pack(*it);
}
return o;
}
template <typename T>
inline void operator<< (object::with_zone& o, const std::multiset<T>& v)
{
o.type = type::ARRAY;
if(v.empty()) {
o.via.array.ptr = NULL;
o.via.array.size = 0;
} else {
object* p = (object*)o.zone->malloc(sizeof(object)*v.size());
object* const pend = p + v.size();
o.via.array.ptr = p;
o.via.array.size = v.size();
typename std::multiset<T>::const_iterator it(v.begin());
do {
*p = object(*it, o.zone);
++p;
++it;
} while(p < pend);
}
}
} // namespace msgpack
#endif /* msgpack/type/set.hpp */

View file

@ -1,62 +0,0 @@
//
// MessagePack for C++ static resolution routine
//
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef MSGPACK_TYPE_STRING_HPP__
#define MSGPACK_TYPE_STRING_HPP__
#include "msgpack/object.hpp"
#include <string>
namespace msgpack {
inline std::string& operator>> (object o, std::string& v)
{
if(o.type != type::RAW) { throw type_error(); }
v.assign(o.via.raw.ptr, o.via.raw.size);
return v;
}
template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const std::string& v)
{
o.pack_raw(v.size());
o.pack_raw_body(v.data(), v.size());
return o;
}
inline void operator<< (object::with_zone& o, const std::string& v)
{
o.type = type::RAW;
char* ptr = (char*)o.zone->malloc(v.size());
o.via.raw.ptr = ptr;
o.via.raw.size = v.size();
memcpy(ptr, v.data(), v.size());
}
inline void operator<< (object& o, const std::string& v)
{
o.type = type::RAW;
o.via.raw.ptr = v.data();
o.via.raw.size = v.size();
}
} // namespace msgpack
#endif /* msgpack/type/string.hpp */

View file

@ -1,129 +0,0 @@
//
// MessagePack for C++ static resolution routine
//
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef MSGPACK_TYPE_TR1_UNORDERED_MAP_HPP__
#define MSGPACK_TYPE_TR1_UNORDERED_MAP_HPP__
#include "msgpack/object.hpp"
#include <tr1/unordered_map>
namespace msgpack {
template <typename K, typename V>
inline std::tr1::unordered_map<K, V> operator>> (object o, std::tr1::unordered_map<K, V>& v)
{
if(o.type != type::MAP) { throw type_error(); }
object_kv* p(o.via.map.ptr);
object_kv* const pend(o.via.map.ptr + o.via.map.size);
for(; p != pend; ++p) {
K key;
p->key.convert(&key);
p->val.convert(&v[key]);
}
return v;
}
template <typename Stream, typename K, typename V>
inline packer<Stream>& operator<< (packer<Stream>& o, const std::tr1::unordered_map<K,V>& v)
{
o.pack_map(v.size());
for(typename std::tr1::unordered_map<K,V>::const_iterator it(v.begin()), it_end(v.end());
it != it_end; ++it) {
o.pack(it->first);
o.pack(it->second);
}
return o;
}
template <typename K, typename V>
inline void operator<< (object::with_zone& o, const std::tr1::unordered_map<K,V>& v)
{
o.type = type::MAP;
if(v.empty()) {
o.via.map.ptr = NULL;
o.via.map.size = 0;
} else {
object_kv* p = (object_kv*)o.zone->malloc(sizeof(object_kv)*v.size());
object_kv* const pend = p + v.size();
o.via.map.ptr = p;
o.via.map.size = v.size();
typename std::tr1::unordered_map<K,V>::const_iterator it(v.begin());
do {
p->key = object(it->first, o.zone);
p->val = object(it->second, o.zone);
++p;
++it;
} while(p < pend);
}
}
template <typename K, typename V>
inline std::tr1::unordered_multimap<K, V> operator>> (object o, std::tr1::unordered_multimap<K, V>& v)
{
if(o.type != type::MAP) { throw type_error(); }
object_kv* p(o.via.map.ptr);
object_kv* const pend(o.via.map.ptr + o.via.map.size);
for(; p != pend; ++p) {
std::pair<K, V> value;
p->key.convert(&value.first);
p->val.convert(&value.second);
v.insert(value);
}
return v;
}
template <typename Stream, typename K, typename V>
inline packer<Stream>& operator<< (packer<Stream>& o, const std::tr1::unordered_multimap<K,V>& v)
{
o.pack_map(v.size());
for(typename std::tr1::unordered_multimap<K,V>::const_iterator it(v.begin()), it_end(v.end());
it != it_end; ++it) {
o.pack(it->first);
o.pack(it->second);
}
return o;
}
template <typename K, typename V>
inline void operator<< (object::with_zone& o, const std::tr1::unordered_multimap<K,V>& v)
{
o.type = type::MAP;
if(v.empty()) {
o.via.map.ptr = NULL;
o.via.map.size = 0;
} else {
object_kv* p = (object_kv*)o.zone->malloc(sizeof(object_kv)*v.size());
object_kv* const pend = p + v.size();
o.via.map.ptr = p;
o.via.map.size = v.size();
typename std::tr1::unordered_multimap<K,V>::const_iterator it(v.begin());
do {
p->key = object(it->first, o.zone);
p->val = object(it->second, o.zone);
++p;
++it;
} while(p < pend);
}
}
} // namespace msgpack
#endif /* msgpack/type/map.hpp */

View file

@ -1,122 +0,0 @@
//
// MessagePack for C++ static resolution routine
//
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef MSGPACK_TYPE_TR1_UNORDERED_SET_HPP__
#define MSGPACK_TYPE_TR1_UNORDERED_SET_HPP__
#include "msgpack/object.hpp"
#include <tr1/unordered_set>
namespace msgpack {
template <typename T>
inline std::tr1::unordered_set<T>& operator>> (object o, std::tr1::unordered_set<T>& v)
{
if(o.type != type::ARRAY) { throw type_error(); }
object* p = o.via.array.ptr + o.via.array.size;
object* const pbegin = o.via.array.ptr;
while(p > pbegin) {
--p;
v.insert(p->as<T>());
}
return v;
}
template <typename Stream, typename T>
inline packer<Stream>& operator<< (packer<Stream>& o, const std::tr1::unordered_set<T>& v)
{
o.pack_array(v.size());
for(typename std::tr1::unordered_set<T>::const_iterator it(v.begin()), it_end(v.end());
it != it_end; ++it) {
o.pack(*it);
}
return o;
}
template <typename T>
inline void operator<< (object::with_zone& o, const std::tr1::unordered_set<T>& v)
{
o.type = type::ARRAY;
if(v.empty()) {
o.via.array.ptr = NULL;
o.via.array.size = 0;
} else {
object* p = (object*)o.zone->malloc(sizeof(object)*v.size());
object* const pend = p + v.size();
o.via.array.ptr = p;
o.via.array.size = v.size();
typename std::tr1::unordered_set<T>::const_iterator it(v.begin());
do {
*p = object(*it, o.zone);
++p;
++it;
} while(p < pend);
}
}
template <typename T>
inline std::tr1::unordered_multiset<T>& operator>> (object o, std::tr1::unordered_multiset<T>& v)
{
if(o.type != type::ARRAY) { throw type_error(); }
object* p = o.via.array.ptr + o.via.array.size;
object* const pbegin = o.via.array.ptr;
while(p > pbegin) {
--p;
v.insert(p->as<T>());
}
return v;
}
template <typename Stream, typename T>
inline packer<Stream>& operator<< (packer<Stream>& o, const std::tr1::unordered_multiset<T>& v)
{
o.pack_array(v.size());
for(typename std::tr1::unordered_multiset<T>::const_iterator it(v.begin()), it_end(v.end());
it != it_end; ++it) {
o.pack(*it);
}
return o;
}
template <typename T>
inline void operator<< (object::with_zone& o, const std::tr1::unordered_multiset<T>& v)
{
o.type = type::ARRAY;
if(v.empty()) {
o.via.array.ptr = NULL;
o.via.array.size = 0;
} else {
object* p = (object*)o.zone->malloc(sizeof(object)*v.size());
object* const pend = p + v.size();
o.via.array.ptr = p;
o.via.array.size = v.size();
typename std::tr1::unordered_multiset<T>::const_iterator it(v.begin());
do {
*p = object(*it, o.zone);
++p;
++it;
} while(p < pend);
}
}
} // namespace msgpack
#endif /* msgpack/type/set.hpp */

View file

@ -1,206 +0,0 @@
//
// MessagePack for C++ static resolution routine
//
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef MSGPACK_TYPE_TUPLE_HPP__
#define MSGPACK_TYPE_TUPLE_HPP__
#include "msgpack/object.hpp"
namespace msgpack {
namespace type {
// FIXME operator==
// FIXME operator!=
<% GENERATION_LIMIT = 31 %>
template <typename A0 = void<%1.upto(GENERATION_LIMIT+1) {|i|%>, typename A<%=i%> = void<%}%>>
struct tuple;
template <typename Tuple, int N>
struct tuple_element;
template <typename Tuple, int N>
struct const_tuple_element;
template <typename T>
struct tuple_type {
typedef T type;
typedef T value_type;
typedef T& reference;
typedef const T& const_reference;
typedef const T& transparent_reference;
};
template <typename T>
struct tuple_type<T&> {
typedef T type;
typedef T& value_type;
typedef T& reference;
typedef const T& const_reference;
typedef T& transparent_reference;
};
template <typename T>
struct tuple_type<const T&> {
typedef T type;
typedef T& value_type;
typedef T& reference;
typedef const T& const_reference;
typedef const T& transparent_reference;
};
<%0.upto(GENERATION_LIMIT) {|i|%>
<%0.upto(i) {|j|%>
template <typename A0<%1.upto(i) {|k|%>, typename A<%=k%><%}%>>
struct tuple_element<tuple<A0<%1.upto(i) {|k|%>, A<%=k%><%}%>>, <%=j%>> : tuple_type<A<%=j%>> {
tuple_element(tuple<A0<%1.upto(i) {|k|%>, A<%=k%> <%}%>>& x) : _x(x.a<%=j%>) {}
typename tuple_type<A<%=j%>>::reference get() { return _x; }
typename tuple_type<A<%=j%>>::const_reference get() const { return _x; }
private:
typename tuple_type<A<%=j%>>::reference _x;
};
<%}%>
<%}%>
<%0.upto(GENERATION_LIMIT) {|i|%>
<%0.upto(i) {|j|%>
template <typename A0<%1.upto(i) {|k|%>, typename A<%=k%><%}%>>
struct const_tuple_element<tuple<A0<%1.upto(i) {|k|%>, A<%=k%><%}%>>, <%=j%>> : tuple_type<A<%=j%>> {
const_tuple_element(const tuple<A0<%1.upto(i) {|k|%>, A<%=k%><%}%>>& x) : _x(x.a<%=j%>) {}
typename tuple_type<A<%=j%>>::const_reference get() const { return _x; }
private:
typename tuple_type<A<%=j%>>::const_reference _x;
};
<%}%>
<%}%>
template <>
struct tuple<> {
tuple() {}
tuple(object o) { o.convert(this); }
typedef tuple<> value_type;
};
<%0.upto(GENERATION_LIMIT) {|i|%>
template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
struct tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> {
typedef tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> value_type;
tuple() {}
tuple(typename tuple_type<A0>::transparent_reference _a0<%1.upto(i) {|j|%>, typename tuple_type<A<%=j%>>::transparent_reference _a<%=j%><%}%>) :
a0(_a0)<%1.upto(i) {|j|%>, a<%=j%>(_a<%=j%>)<%}%> {}
tuple(object o) { o.convert(this); }
template <int N> typename tuple_element<value_type, N>::reference get()
{ return tuple_element<value_type, N>(*this).get(); }
template <int N> typename const_tuple_element<value_type, N>::const_reference get() const
{ return const_tuple_element<value_type, N>(*this).get(); }
<%0.upto(i) {|j|%>
A<%=j%> a<%=j%>;<%}%>
};
<%}%>
inline tuple<> make_tuple()
{
return tuple<>();
}
<%0.upto(GENERATION_LIMIT) {|i|%>
template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> make_tuple(typename tuple_type<A0>::transparent_reference a0<%1.upto(i) {|j|%>, typename tuple_type<A<%=j%>>::transparent_reference a<%=j%><%}%>)
{
return tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>(a0<%1.upto(i) {|j|%>, a<%=j%><%}%>);
}
<%}%>
} // namespace type
inline type::tuple<>& operator>> (
object o,
type::tuple<>& v) {
if(o.type != type::ARRAY) { throw type_error(); }
return v;
}
<%0.upto(GENERATION_LIMIT) {|i|%>
template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& operator>> (
object o,
type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& v) {
if(o.type != type::ARRAY) { throw type_error(); }
if(o.via.array.size < <%=i+1%>) { throw type_error(); }
<%0.upto(i) {|j|%>
o.via.array.ptr[<%=j%>].convert<typename type::tuple_type<A<%=j%>>::type>(&v.template get<<%=j%>>());<%}%>
return v;
}
<%}%>
template <typename Stream>
const packer<Stream>& operator<< (
packer<Stream>& o,
const type::tuple<>& v) {
o.pack_array(0);
return o;
}
<%0.upto(GENERATION_LIMIT) {|i|%>
template <typename Stream, typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
const packer<Stream>& operator<< (
packer<Stream>& o,
const type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& v) {
o.pack_array(<%=i+1%>);
<%0.upto(i) {|j|%>
o.pack(v.template get<<%=j%>>());<%}%>
return o;
}
<%}%>
inline void operator<< (
object::with_zone& o,
const type::tuple<>& v) {
o.type = type::ARRAY;
o.via.array.ptr = NULL;
o.via.array.size = 0;
}
<%0.upto(GENERATION_LIMIT) {|i|%>
template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
inline void operator<< (
object::with_zone& o,
const type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& v) {
o.type = type::ARRAY;
o.via.array.ptr = (object*)o.zone->malloc(sizeof(object)*<%=i+1%>);
o.via.array.size = <%=i+1%>;
<%0.upto(i) {|j|%>
o.via.array.ptr[<%=j%>] = object(v.template get<<%=j%>>(), o.zone);<%}%>
}
<%}%>
} // namespace msgpack
//inline std::ostream& operator<< (std::ostream& o, const msgpack::type::tuple<>& v) {
// return o << "[]";
//}
//<%0.upto(GENERATION_LIMIT) {|i|%>
//template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
//inline std::ostream& operator<< (std::ostream& o,
// const msgpack::type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& v) {
// return o << "["
// <%0.upto(i) {|j|%>
// <<<%if j != 0 then%> ", " <<<%end%> v.template get<<%=j%>>()<%}%>
// << "]";
//}
//<%}%>
#endif /* msgpack/type/tuple.hpp */

View file

@ -1,81 +0,0 @@
//
// MessagePack for C++ static resolution routine
//
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef MSGPACK_TYPE_VECTOR_HPP__
#define MSGPACK_TYPE_VECTOR_HPP__
#include "msgpack/object.hpp"
#include <vector>
namespace msgpack {
template <typename T>
inline std::vector<T>& operator>> (object o, std::vector<T>& v)
{
if(o.type != type::ARRAY) { throw type_error(); }
v.resize(o.via.array.size);
if(o.via.array.size > 0) {
object* p = o.via.array.ptr;
object* const pend = o.via.array.ptr + o.via.array.size;
T* it = &v[0];
do {
p->convert(it);
++p;
++it;
} while(p < pend);
}
return v;
}
template <typename Stream, typename T>
inline packer<Stream>& operator<< (packer<Stream>& o, const std::vector<T>& v)
{
o.pack_array(v.size());
for(typename std::vector<T>::const_iterator it(v.begin()), it_end(v.end());
it != it_end; ++it) {
o.pack(*it);
}
return o;
}
template <typename T>
inline void operator<< (object::with_zone& o, const std::vector<T>& v)
{
o.type = type::ARRAY;
if(v.empty()) {
o.via.array.ptr = NULL;
o.via.array.size = 0;
} else {
object* p = (object*)o.zone->malloc(sizeof(object)*v.size());
object* const pend = p + v.size();
o.via.array.ptr = p;
o.via.array.size = v.size();
typename std::vector<T>::const_iterator it(v.begin());
do {
*p = object(*it, o.zone);
++p;
++it;
} while(p < pend);
}
}
} // namespace msgpack
#endif /* msgpack/type/vector.hpp */

View file

@ -1,260 +0,0 @@
/*
* MessagePack for C unpacking routine
*
* Copyright (C) 2008-2009 FURUHASHI Sadayuki
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MSGPACK_UNPACKER_H__
#define MSGPACK_UNPACKER_H__
#include "zone.h"
#include "object.h"
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup msgpack_unpack Deserializer
* @ingroup msgpack
* @{
*/
typedef struct msgpack_unpacked {
msgpack_zone* zone;
msgpack_object data;
} msgpack_unpacked;
bool msgpack_unpack_next(msgpack_unpacked* result,
const char* data, size_t len, size_t* off);
/** @} */
/**
* @defgroup msgpack_unpacker Streaming deserializer
* @ingroup msgpack
* @{
*/
typedef struct msgpack_unpacker {
char* buffer;
size_t used;
size_t free;
size_t off;
size_t parsed;
msgpack_zone* z;
size_t initial_buffer_size;
void* ctx;
} msgpack_unpacker;
#ifndef MSGPACK_UNPACKER_INIT_BUFFER_SIZE
#define MSGPACK_UNPACKER_INIT_BUFFER_SIZE (64*1024)
#endif
/**
* Initializes a streaming deserializer.
* The initialized deserializer must be destroyed by msgpack_unpacker_destroy(msgpack_unpacker*).
*/
bool msgpack_unpacker_init(msgpack_unpacker* mpac, size_t initial_buffer_size);
/**
* Destroys a streaming deserializer initialized by msgpack_unpacker_init(msgpack_unpacker*, size_t).
*/
void msgpack_unpacker_destroy(msgpack_unpacker* mpac);
/**
* Creates a streaming deserializer.
* The created deserializer must be destroyed by msgpack_unpacker_free(msgpack_unpacker*).
*/
msgpack_unpacker* msgpack_unpacker_new(size_t initial_buffer_size);
/**
* Frees a streaming deserializer created by msgpack_unpacker_new(size_t).
*/
void msgpack_unpacker_free(msgpack_unpacker* mpac);
#ifndef MSGPACK_UNPACKER_RESERVE_SIZE
#define MSGPACK_UNPACKER_RESERVE_SIZE (32*1024)
#endif
/**
* Reserves free space of the internal buffer.
* Use this function to fill the internal buffer with
* msgpack_unpacker_buffer(msgpack_unpacker*),
* msgpack_unpacker_buffer_capacity(const msgpack_unpacker*) and
* msgpack_unpacker_buffer_consumed(msgpack_unpacker*).
*/
static inline bool msgpack_unpacker_reserve_buffer(msgpack_unpacker* mpac, size_t size);
/**
* Gets pointer to the free space of the internal buffer.
* Use this function to fill the internal buffer with
* msgpack_unpacker_reserve_buffer(msgpack_unpacker*, size_t),
* msgpack_unpacker_buffer_capacity(const msgpack_unpacker*) and
* msgpack_unpacker_buffer_consumed(msgpack_unpacker*).
*/
static inline char* msgpack_unpacker_buffer(msgpack_unpacker* mpac);
/**
* Gets size of the free space of the internal buffer.
* Use this function to fill the internal buffer with
* msgpack_unpacker_reserve_buffer(msgpack_unpacker*, size_t),
* msgpack_unpacker_buffer(const msgpack_unpacker*) and
* msgpack_unpacker_buffer_consumed(msgpack_unpacker*).
*/
static inline size_t msgpack_unpacker_buffer_capacity(const msgpack_unpacker* mpac);
/**
* Notifies the deserializer that the internal buffer filled.
* Use this function to fill the internal buffer with
* msgpack_unpacker_reserve_buffer(msgpack_unpacker*, size_t),
* msgpack_unpacker_buffer(msgpack_unpacker*) and
* msgpack_unpacker_buffer_capacity(const msgpack_unpacker*).
*/
static inline void msgpack_unpacker_buffer_consumed(msgpack_unpacker* mpac, size_t size);
/**
* Deserializes one object.
* Returns true if it successes. Otherwise false is returned.
* @param pac pointer to an initialized msgpack_unpacked object.
*/
bool msgpack_unpacker_next(msgpack_unpacker* mpac, msgpack_unpacked* pac);
/**
* Initializes a msgpack_unpacked object.
* The initialized object must be destroyed by msgpack_unpacked_destroy(msgpack_unpacker*).
* Use the object with msgpack_unpacker_next(msgpack_unpacker*, msgpack_unpacked*) or
* msgpack_unpack_next(msgpack_unpacked*, const char*, size_t, size_t*).
*/
static inline void msgpack_unpacked_init(msgpack_unpacked* result);
/**
* Destroys a streaming deserializer initialized by msgpack_unpacked().
*/
static inline void msgpack_unpacked_destroy(msgpack_unpacked* result);
/**
* Releases the memory zone from msgpack_unpacked object.
* The released zone must be freed by msgpack_zone_free(msgpack_zone*).
*/
static inline msgpack_zone* msgpack_unpacked_release_zone(msgpack_unpacked* result);
int msgpack_unpacker_execute(msgpack_unpacker* mpac);
msgpack_object msgpack_unpacker_data(msgpack_unpacker* mpac);
msgpack_zone* msgpack_unpacker_release_zone(msgpack_unpacker* mpac);
void msgpack_unpacker_reset_zone(msgpack_unpacker* mpac);
void msgpack_unpacker_reset(msgpack_unpacker* mpac);
static inline size_t msgpack_unpacker_message_size(const msgpack_unpacker* mpac);
/** @} */
// obsolete
typedef enum {
MSGPACK_UNPACK_SUCCESS = 2,
MSGPACK_UNPACK_EXTRA_BYTES = 1,
MSGPACK_UNPACK_CONTINUE = 0,
MSGPACK_UNPACK_PARSE_ERROR = -1,
} msgpack_unpack_return;
// obsolete
msgpack_unpack_return
msgpack_unpack(const char* data, size_t len, size_t* off,
msgpack_zone* result_zone, msgpack_object* result);
static inline size_t msgpack_unpacker_parsed_size(const msgpack_unpacker* mpac);
bool msgpack_unpacker_flush_zone(msgpack_unpacker* mpac);
bool msgpack_unpacker_expand_buffer(msgpack_unpacker* mpac, size_t size);
bool msgpack_unpacker_reserve_buffer(msgpack_unpacker* mpac, size_t size)
{
if(mpac->free >= size) { return true; }
return msgpack_unpacker_expand_buffer(mpac, size);
}
char* msgpack_unpacker_buffer(msgpack_unpacker* mpac)
{
return mpac->buffer + mpac->used;
}
size_t msgpack_unpacker_buffer_capacity(const msgpack_unpacker* mpac)
{
return mpac->free;
}
void msgpack_unpacker_buffer_consumed(msgpack_unpacker* mpac, size_t size)
{
mpac->used += size;
mpac->free -= size;
}
size_t msgpack_unpacker_message_size(const msgpack_unpacker* mpac)
{
return mpac->parsed - mpac->off + mpac->used;
}
size_t msgpack_unpacker_parsed_size(const msgpack_unpacker* mpac)
{
return mpac->parsed;
}
void msgpack_unpacked_init(msgpack_unpacked* result)
{
memset(result, 0, sizeof(msgpack_unpacked));
}
void msgpack_unpacked_destroy(msgpack_unpacked* result)
{
if(result->zone != NULL) {
msgpack_zone_free(result->zone);
result->zone = NULL;
memset(&result->data, 0, sizeof(msgpack_object));
}
}
msgpack_zone* msgpack_unpacked_release_zone(msgpack_unpacked* result)
{
if(result->zone != NULL) {
msgpack_zone* z = result->zone;
result->zone = NULL;
return z;
}
return NULL;
}
#ifdef __cplusplus
}
#endif
#endif /* msgpack/unpack.h */

View file

@ -1,384 +0,0 @@
//
// MessagePack for C++ deserializing routine
//
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef MSGPACK_UNPACK_HPP__
#define MSGPACK_UNPACK_HPP__
#include "unpack.h"
#include "object.hpp"
#include "zone.hpp"
#include <memory>
#include <stdexcept>
// backward compatibility
#ifndef MSGPACK_UNPACKER_DEFAULT_INITIAL_BUFFER_SIZE
#define MSGPACK_UNPACKER_DEFAULT_INITIAL_BUFFER_SIZE MSGPACK_UNPACKER_INIT_BUFFER_SIZE
#endif
namespace msgpack {
struct unpack_error : public std::runtime_error {
unpack_error(const std::string& msg) :
std::runtime_error(msg) { }
};
class unpacked {
public:
unpacked() { }
unpacked(object obj, std::auto_ptr<msgpack::zone> z) :
m_obj(obj), m_zone(z) { }
object& get()
{ return m_obj; }
const object& get() const
{ return m_obj; }
std::auto_ptr<msgpack::zone>& zone()
{ return m_zone; }
const std::auto_ptr<msgpack::zone>& zone() const
{ return m_zone; }
private:
object m_obj;
std::auto_ptr<msgpack::zone> m_zone;
};
class unpacker : public msgpack_unpacker {
public:
unpacker(size_t init_buffer_size = MSGPACK_UNPACKER_INIT_BUFFER_SIZE);
~unpacker();
public:
/*! 1. reserve buffer. at least `size' bytes of capacity will be ready */
void reserve_buffer(size_t size = MSGPACK_UNPACKER_RESERVE_SIZE);
/*! 2. read data to the buffer() up to buffer_capacity() bytes */
char* buffer();
size_t buffer_capacity() const;
/*! 3. specify the number of bytes actually copied */
void buffer_consumed(size_t size);
/*! 4. repeat next() until it retunrs false */
bool next(unpacked* result);
/*! 5. check if the size of message doesn't exceed assumption. */
size_t message_size() const;
// Basic usage of the unpacker is as following:
//
// msgpack::unpacker pac;
// while( /* input is readable */ ) {
//
// // 1.
// pac.reserve_buffer(32*1024);
//
// // 2.
// size_t bytes = input.readsome(pac.buffer(), pac.buffer_capacity());
//
// // error handling ...
//
// // 3.
// pac.buffer_consumed(bytes);
//
// // 4.
// msgpack::unpacked result;
// while(pac.next(&result)) {
// // do some with the object with the zone.
// msgpack::object obj = result.get();
// std::auto_ptr<msgpack:zone> z = result.zone();
// on_message(obj, z);
//
// //// boost::shared_ptr is also usable:
// // boost::shared_ptr<msgpack::zone> life(z.release());
// // on_message(result.get(), life);
// }
//
// // 5.
// if(pac.message_size() > 10*1024*1024) {
// throw std::runtime_error("message is too large");
// }
// }
//
/*! for backward compatibility */
bool execute();
/*! for backward compatibility */
object data();
/*! for backward compatibility */
zone* release_zone();
/*! for backward compatibility */
void reset_zone();
/*! for backward compatibility */
void reset();
public:
// These functions are usable when non-MessagePack message follows after
// MessagePack message.
size_t parsed_size() const;
/*! get address of the buffer that is not parsed */
char* nonparsed_buffer();
size_t nonparsed_size() const;
/*! skip specified size of non-parsed buffer, leaving the buffer */
// Note that the `size' argument must be smaller than nonparsed_size()
void skip_nonparsed_buffer(size_t size);
/*! remove unparsed buffer from unpacker */
// Note that reset() leaves non-parsed buffer.
void remove_nonparsed_buffer();
private:
typedef msgpack_unpacker base;
private:
unpacker(const unpacker&);
};
static void unpack(unpacked* result,
const char* data, size_t len, size_t* offset = NULL);
// obsolete
typedef enum {
UNPACK_SUCCESS = 2,
UNPACK_EXTRA_BYTES = 1,
UNPACK_CONTINUE = 0,
UNPACK_PARSE_ERROR = -1,
} unpack_return;
// obsolete
static unpack_return unpack(const char* data, size_t len, size_t* off,
zone* z, object* result);
// obsolete
static object unpack(const char* data, size_t len, zone& z, size_t* off = NULL);
inline unpacker::unpacker(size_t initial_buffer_size)
{
if(!msgpack_unpacker_init(this, initial_buffer_size)) {
throw std::bad_alloc();
}
}
inline unpacker::~unpacker()
{
msgpack_unpacker_destroy(this);
}
inline void unpacker::reserve_buffer(size_t size)
{
if(!msgpack_unpacker_reserve_buffer(this, size)) {
throw std::bad_alloc();
}
}
inline char* unpacker::buffer()
{
return msgpack_unpacker_buffer(this);
}
inline size_t unpacker::buffer_capacity() const
{
return msgpack_unpacker_buffer_capacity(this);
}
inline void unpacker::buffer_consumed(size_t size)
{
return msgpack_unpacker_buffer_consumed(this, size);
}
inline bool unpacker::next(unpacked* result)
{
int ret = msgpack_unpacker_execute(this);
if(ret < 0) {
throw unpack_error("parse error");
}
if(ret == 0) {
result->zone().reset();
result->get() = object();
return false;
} else {
result->zone().reset( release_zone() );
result->get() = data();
reset();
return true;
}
}
inline bool unpacker::execute()
{
int ret = msgpack_unpacker_execute(this);
if(ret < 0) {
throw unpack_error("parse error");
} else if(ret == 0) {
return false;
} else {
return true;
}
}
inline object unpacker::data()
{
return msgpack_unpacker_data(this);
}
inline zone* unpacker::release_zone()
{
if(!msgpack_unpacker_flush_zone(this)) {
throw std::bad_alloc();
}
zone* r = new zone();
msgpack_zone old = *base::z;
*base::z = *r;
*static_cast<msgpack_zone*>(r) = old;
return r;
}
inline void unpacker::reset_zone()
{
msgpack_unpacker_reset_zone(this);
}
inline void unpacker::reset()
{
msgpack_unpacker_reset(this);
}
inline size_t unpacker::message_size() const
{
return msgpack_unpacker_message_size(this);
}
inline size_t unpacker::parsed_size() const
{
return msgpack_unpacker_parsed_size(this);
}
inline char* unpacker::nonparsed_buffer()
{
return base::buffer + base::off;
}
inline size_t unpacker::nonparsed_size() const
{
return base::used - base::off;
}
inline void unpacker::skip_nonparsed_buffer(size_t size)
{
base::off += size;
}
inline void unpacker::remove_nonparsed_buffer()
{
base::used = base::off;
}
inline void unpack(unpacked* result,
const char* data, size_t len, size_t* offset)
{
msgpack::object obj;
std::auto_ptr<msgpack::zone> z(new zone());
unpack_return ret = (unpack_return)msgpack_unpack(
data, len, offset, z.get(),
reinterpret_cast<msgpack_object*>(&obj));
switch(ret) {
case UNPACK_SUCCESS:
result->get() = obj;
result->zone() = z;
return;
case UNPACK_EXTRA_BYTES:
result->get() = obj;
result->zone() = z;
return;
case UNPACK_CONTINUE:
throw unpack_error("insufficient bytes");
case UNPACK_PARSE_ERROR:
default:
throw unpack_error("parse error");
}
}
// obsolete
inline unpack_return unpack(const char* data, size_t len, size_t* off,
zone* z, object* result)
{
return (unpack_return)msgpack_unpack(data, len, off,
z, reinterpret_cast<msgpack_object*>(result));
}
// obsolete
inline object unpack(const char* data, size_t len, zone& z, size_t* off)
{
object result;
switch( msgpack::unpack(data, len, off, &z, &result) ) {
case UNPACK_SUCCESS:
return result;
case UNPACK_EXTRA_BYTES:
if(off) {
return result;
} else {
throw unpack_error("extra bytes");
}
case UNPACK_CONTINUE:
throw unpack_error("insufficient bytes");
case UNPACK_PARSE_ERROR:
default:
throw unpack_error("parse error");
}
}
} // namespace msgpack
#endif /* msgpack/unpack.hpp */

View file

@ -1,40 +0,0 @@
/*
* MessagePack for C version information
*
* Copyright (C) 2008-2009 FURUHASHI Sadayuki
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MSGPACK_VERSION_H__
#define MSGPACK_VERSION_H__
#ifdef __cplusplus
extern "C" {
#endif
const char* msgpack_version(void);
int msgpack_version_major(void);
int msgpack_version_minor(void);
#define MSGPACK_VERSION "@VERSION@"
#define MSGPACK_VERSION_MAJOR @VERSION_MAJOR@
#define MSGPACK_VERSION_MINOR @VERSION_MINOR@
#ifdef __cplusplus
}
#endif
#endif /* msgpack/version.h */

View file

@ -1,142 +0,0 @@
/*
* MessagePack for C zero-copy buffer implementation
*
* Copyright (C) 2008-2009 FURUHASHI Sadayuki
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MSGPACK_VREFBUFFER_H__
#define MSGPACK_VREFBUFFER_H__
#include "zone.h"
#include <stdlib.h>
#ifndef _WIN32
#include <sys/uio.h>
#else
struct iovec {
void *iov_base;
size_t iov_len;
};
#endif
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup msgpack_vrefbuffer Vectored Referencing buffer
* @ingroup msgpack_buffer
* @{
*/
struct msgpack_vrefbuffer_chunk;
typedef struct msgpack_vrefbuffer_chunk msgpack_vrefbuffer_chunk;
typedef struct msgpack_vrefbuffer_inner_buffer {
size_t free;
char* ptr;
msgpack_vrefbuffer_chunk* head;
} msgpack_vrefbuffer_inner_buffer;
typedef struct msgpack_vrefbuffer {
struct iovec* tail;
struct iovec* end;
struct iovec* array;
size_t chunk_size;
size_t ref_size;
msgpack_vrefbuffer_inner_buffer inner_buffer;
} msgpack_vrefbuffer;
#ifndef MSGPACK_VREFBUFFER_REF_SIZE
#define MSGPACK_VREFBUFFER_REF_SIZE 32
#endif
#ifndef MSGPACK_VREFBUFFER_CHUNK_SIZE
#define MSGPACK_VREFBUFFER_CHUNK_SIZE 8192
#endif
bool msgpack_vrefbuffer_init(msgpack_vrefbuffer* vbuf,
size_t ref_size, size_t chunk_size);
void msgpack_vrefbuffer_destroy(msgpack_vrefbuffer* vbuf);
static inline msgpack_vrefbuffer* msgpack_vrefbuffer_new(size_t ref_size, size_t chunk_size);
static inline void msgpack_vrefbuffer_free(msgpack_vrefbuffer* vbuf);
static inline int msgpack_vrefbuffer_write(void* data, const char* buf, unsigned int len);
static inline const struct iovec* msgpack_vrefbuffer_vec(const msgpack_vrefbuffer* vref);
static inline size_t msgpack_vrefbuffer_veclen(const msgpack_vrefbuffer* vref);
int msgpack_vrefbuffer_append_copy(msgpack_vrefbuffer* vbuf,
const char* buf, unsigned int len);
int msgpack_vrefbuffer_append_ref(msgpack_vrefbuffer* vbuf,
const char* buf, unsigned int len);
int msgpack_vrefbuffer_migrate(msgpack_vrefbuffer* vbuf, msgpack_vrefbuffer* to);
void msgpack_vrefbuffer_clear(msgpack_vrefbuffer* vref);
/** @} */
msgpack_vrefbuffer* msgpack_vrefbuffer_new(size_t ref_size, size_t chunk_size)
{
msgpack_vrefbuffer* vbuf = (msgpack_vrefbuffer*)malloc(sizeof(msgpack_vrefbuffer));
if(!msgpack_vrefbuffer_init(vbuf, ref_size, chunk_size)) {
free(vbuf);
return NULL;
}
return vbuf;
}
void msgpack_vrefbuffer_free(msgpack_vrefbuffer* vbuf)
{
if(vbuf == NULL) { return; }
msgpack_vrefbuffer_destroy(vbuf);
free(vbuf);
}
int msgpack_vrefbuffer_write(void* data, const char* buf, unsigned int len)
{
msgpack_vrefbuffer* vbuf = (msgpack_vrefbuffer*)data;
if(len < vbuf->ref_size) {
return msgpack_vrefbuffer_append_copy(vbuf, buf, len);
} else {
return msgpack_vrefbuffer_append_ref(vbuf, buf, len);
}
}
const struct iovec* msgpack_vrefbuffer_vec(const msgpack_vrefbuffer* vref)
{
return vref->array;
}
size_t msgpack_vrefbuffer_veclen(const msgpack_vrefbuffer* vref)
{
return vref->tail - vref->array;
}
#ifdef __cplusplus
}
#endif
#endif /* msgpack/vrefbuffer.h */

View file

@ -1,97 +0,0 @@
//
// MessagePack for C++ zero-copy buffer implementation
//
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef MSGPACK_VREFBUFFER_HPP__
#define MSGPACK_VREFBUFFER_HPP__
#include "vrefbuffer.h"
#include <stdexcept>
namespace msgpack {
class vrefbuffer : public msgpack_vrefbuffer {
public:
vrefbuffer(size_t ref_size = MSGPACK_VREFBUFFER_REF_SIZE,
size_t chunk_size = MSGPACK_VREFBUFFER_CHUNK_SIZE)
{
msgpack_vrefbuffer_init(this, ref_size, chunk_size);
}
~vrefbuffer()
{
msgpack_vrefbuffer_destroy(this);
}
public:
void write(const char* buf, unsigned int len)
{
if(len < base::ref_size) {
append_copy(buf, len);
} else {
append_ref(buf, len);
}
}
void append_ref(const char* buf, size_t len)
{
if(msgpack_vrefbuffer_append_ref(this, buf, len) < 0) {
throw std::bad_alloc();
}
}
void append_copy(const char* buf, size_t len)
{
if(msgpack_vrefbuffer_append_copy(this, buf, len) < 0) {
throw std::bad_alloc();
}
}
const struct iovec* vector() const
{
return msgpack_vrefbuffer_vec(this);
}
size_t vector_size() const
{
return msgpack_vrefbuffer_veclen(this);
}
void migrate(vrefbuffer* to)
{
if(msgpack_vrefbuffer_migrate(this, to) < 0) {
throw std::bad_alloc();
}
}
void clear()
{
msgpack_vrefbuffer_clear(this);
}
private:
typedef msgpack_vrefbuffer base;
private:
vrefbuffer(const vrefbuffer&);
};
} // namespace msgpack
#endif /* msgpack/vrefbuffer.hpp */

View file

@ -1,207 +0,0 @@
/*
* MessagePack for C deflate buffer implementation
*
* Copyright (C) 2010 FURUHASHI Sadayuki
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MSGPACK_ZBUFFER_H__
#define MSGPACK_ZBUFFER_H__
#include "sysdep.h"
#include <stdlib.h>
#include <string.h>
#include <zlib.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup msgpack_zbuffer Compressed buffer
* @ingroup msgpack_buffer
* @{
*/
typedef struct msgpack_zbuffer {
z_stream stream;
char* data;
size_t init_size;
} msgpack_zbuffer;
#ifndef MSGPACK_ZBUFFER_INIT_SIZE
#define MSGPACK_ZBUFFER_INIT_SIZE 8192
#endif
static inline bool msgpack_zbuffer_init(msgpack_zbuffer* zbuf,
int level, size_t init_size);
static inline void msgpack_zbuffer_destroy(msgpack_zbuffer* zbuf);
static inline msgpack_zbuffer* msgpack_zbuffer_new(int level, size_t init_size);
static inline void msgpack_zbuffer_free(msgpack_zbuffer* zbuf);
static inline char* msgpack_zbuffer_flush(msgpack_zbuffer* zbuf);
static inline const char* msgpack_zbuffer_data(const msgpack_zbuffer* zbuf);
static inline size_t msgpack_zbuffer_size(const msgpack_zbuffer* zbuf);
static inline bool msgpack_zbuffer_reset(msgpack_zbuffer* zbuf);
static inline void msgpack_zbuffer_reset_buffer(msgpack_zbuffer* zbuf);
static inline char* msgpack_zbuffer_release_buffer(msgpack_zbuffer* zbuf);
#ifndef MSGPACK_ZBUFFER_RESERVE_SIZE
#define MSGPACK_ZBUFFER_RESERVE_SIZE 512
#endif
static inline int msgpack_zbuffer_write(void* data, const char* buf, unsigned int len);
static inline bool msgpack_zbuffer_expand(msgpack_zbuffer* zbuf);
bool msgpack_zbuffer_init(msgpack_zbuffer* zbuf,
int level, size_t init_size)
{
memset(zbuf, 0, sizeof(msgpack_zbuffer));
zbuf->init_size = init_size;
if(deflateInit(&zbuf->stream, level) != Z_OK) {
free(zbuf->data);
return false;
}
return true;
}
void msgpack_zbuffer_destroy(msgpack_zbuffer* zbuf)
{
deflateEnd(&zbuf->stream);
free(zbuf->data);
}
msgpack_zbuffer* msgpack_zbuffer_new(int level, size_t init_size)
{
msgpack_zbuffer* zbuf = (msgpack_zbuffer*)malloc(sizeof(msgpack_zbuffer));
if(!msgpack_zbuffer_init(zbuf, level, init_size)) {
free(zbuf);
return NULL;
}
return zbuf;
}
void msgpack_zbuffer_free(msgpack_zbuffer* zbuf)
{
if(zbuf == NULL) { return; }
msgpack_zbuffer_destroy(zbuf);
free(zbuf);
}
bool msgpack_zbuffer_expand(msgpack_zbuffer* zbuf)
{
size_t used = (char*)zbuf->stream.next_out - zbuf->data;
size_t csize = used + zbuf->stream.avail_out;
size_t nsize = (csize == 0) ? zbuf->init_size : csize * 2;
char* tmp = (char*)realloc(zbuf->data, nsize);
if(tmp == NULL) {
return false;
}
zbuf->data = tmp;
zbuf->stream.next_out = (Bytef*)(tmp + used);
zbuf->stream.avail_out = nsize - used;
return true;
}
int msgpack_zbuffer_write(void* data, const char* buf, unsigned int len)
{
msgpack_zbuffer* zbuf = (msgpack_zbuffer*)data;
zbuf->stream.next_in = (Bytef*)buf;
zbuf->stream.avail_in = len;
do {
if(zbuf->stream.avail_out < MSGPACK_ZBUFFER_RESERVE_SIZE) {
if(!msgpack_zbuffer_expand(zbuf)) {
return -1;
}
}
if(deflate(&zbuf->stream, Z_NO_FLUSH) != Z_OK) {
return -1;
}
} while(zbuf->stream.avail_in > 0);
return 0;
}
char* msgpack_zbuffer_flush(msgpack_zbuffer* zbuf)
{
while(true) {
switch(deflate(&zbuf->stream, Z_FINISH)) {
case Z_STREAM_END:
return zbuf->data;
case Z_OK:
if(!msgpack_zbuffer_expand(zbuf)) {
return NULL;
}
break;
default:
return NULL;
}
}
}
const char* msgpack_zbuffer_data(const msgpack_zbuffer* zbuf)
{
return zbuf->data;
}
size_t msgpack_zbuffer_size(const msgpack_zbuffer* zbuf)
{
return (char*)zbuf->stream.next_out - zbuf->data;
}
void msgpack_zbuffer_reset_buffer(msgpack_zbuffer* zbuf)
{
zbuf->stream.avail_out += (char*)zbuf->stream.next_out - zbuf->data;
zbuf->stream.next_out = (Bytef*)zbuf->data;
}
bool msgpack_zbuffer_reset(msgpack_zbuffer* zbuf)
{
if(deflateReset(&zbuf->stream) != Z_OK) {
return false;
}
msgpack_zbuffer_reset_buffer(zbuf);
return true;
}
char* msgpack_zbuffer_release_buffer(msgpack_zbuffer* zbuf)
{
char* tmp = zbuf->data;
zbuf->data = NULL;
zbuf->stream.next_out = NULL;
zbuf->stream.avail_out = 0;
return tmp;
}
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* msgpack/zbuffer.h */

View file

@ -1,100 +0,0 @@
//
// MessagePack for C++ deflate buffer implementation
//
// Copyright (C) 2010 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef MSGPACK_ZBUFFER_HPP__
#define MSGPACK_ZBUFFER_HPP__
#include "zbuffer.h"
#include <stdexcept>
namespace msgpack {
class zbuffer : public msgpack_zbuffer {
public:
zbuffer(int level = Z_DEFAULT_COMPRESSION,
size_t init_size = MSGPACK_ZBUFFER_INIT_SIZE)
{
msgpack_zbuffer_init(this, level, init_size);
}
~zbuffer()
{
msgpack_zbuffer_destroy(this);
}
public:
void write(const char* buf, unsigned int len)
{
if(msgpack_zbuffer_write(this, buf, len) < 0) {
throw std::bad_alloc();
}
}
char* flush()
{
char* buf = msgpack_zbuffer_flush(this);
if(!buf) {
throw std::bad_alloc();
}
return buf;
}
char* data()
{
return base::data;
}
const char* data() const
{
return base::data;
}
size_t size() const
{
return msgpack_zbuffer_size(this);
}
void reset()
{
if(!msgpack_zbuffer_reset(this)) {
throw std::bad_alloc();
}
}
void reset_buffer()
{
msgpack_zbuffer_reset_buffer(this);
}
char* release_buffer()
{
return msgpack_zbuffer_release_buffer(this);
}
private:
typedef msgpack_zbuffer base;
private:
zbuffer(const zbuffer&);
};
} // namespace msgpack
#endif /* msgpack/zbuffer.hpp */

View file

@ -1,147 +0,0 @@
/*
* MessagePack for C memory pool implementation
*
* Copyright (C) 2008-2010 FURUHASHI Sadayuki
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MSGPACK_ZONE_H__
#define MSGPACK_ZONE_H__
#include "sysdep.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup msgpack_zone Memory zone
* @ingroup msgpack
* @{
*/
typedef struct msgpack_zone_finalizer {
void (*func)(void* data);
void* data;
} msgpack_zone_finalizer;
typedef struct msgpack_zone_finalizer_array {
msgpack_zone_finalizer* tail;
msgpack_zone_finalizer* end;
msgpack_zone_finalizer* array;
} msgpack_zone_finalizer_array;
struct msgpack_zone_chunk;
typedef struct msgpack_zone_chunk msgpack_zone_chunk;
typedef struct msgpack_zone_chunk_list {
size_t free;
char* ptr;
msgpack_zone_chunk* head;
} msgpack_zone_chunk_list;
typedef struct msgpack_zone {
msgpack_zone_chunk_list chunk_list;
msgpack_zone_finalizer_array finalizer_array;
size_t chunk_size;
} msgpack_zone;
#ifndef MSGPACK_ZONE_CHUNK_SIZE
#define MSGPACK_ZONE_CHUNK_SIZE 8192
#endif
bool msgpack_zone_init(msgpack_zone* zone, size_t chunk_size);
void msgpack_zone_destroy(msgpack_zone* zone);
msgpack_zone* msgpack_zone_new(size_t chunk_size);
void msgpack_zone_free(msgpack_zone* zone);
static inline void* msgpack_zone_malloc(msgpack_zone* zone, size_t size);
static inline void* msgpack_zone_malloc_no_align(msgpack_zone* zone, size_t size);
static inline bool msgpack_zone_push_finalizer(msgpack_zone* zone,
void (*func)(void* data), void* data);
static inline void msgpack_zone_swap(msgpack_zone* a, msgpack_zone* b);
bool msgpack_zone_is_empty(msgpack_zone* zone);
void msgpack_zone_clear(msgpack_zone* zone);
/** @} */
#ifndef MSGPACK_ZONE_ALIGN
#define MSGPACK_ZONE_ALIGN sizeof(int)
#endif
void* msgpack_zone_malloc_expand(msgpack_zone* zone, size_t size);
void* msgpack_zone_malloc_no_align(msgpack_zone* zone, size_t size)
{
msgpack_zone_chunk_list* cl = &zone->chunk_list;
if(zone->chunk_list.free < size) {
return msgpack_zone_malloc_expand(zone, size);
}
char* ptr = cl->ptr;
cl->free -= size;
cl->ptr += size;
return ptr;
}
void* msgpack_zone_malloc(msgpack_zone* zone, size_t size)
{
return msgpack_zone_malloc_no_align(zone,
((size)+((MSGPACK_ZONE_ALIGN)-1)) & ~((MSGPACK_ZONE_ALIGN)-1));
}
bool msgpack_zone_push_finalizer_expand(msgpack_zone* zone,
void (*func)(void* data), void* data);
bool msgpack_zone_push_finalizer(msgpack_zone* zone,
void (*func)(void* data), void* data)
{
msgpack_zone_finalizer_array* const fa = &zone->finalizer_array;
msgpack_zone_finalizer* fin = fa->tail;
if(fin == fa->end) {
return msgpack_zone_push_finalizer_expand(zone, func, data);
}
fin->func = func;
fin->data = data;
++fa->tail;
return true;
}
void msgpack_zone_swap(msgpack_zone* a, msgpack_zone* b)
{
msgpack_zone tmp = *a;
*a = *b;
*b = tmp;
}
#ifdef __cplusplus
}
#endif
#endif /* msgpack/zone.h */

View file

@ -1,155 +0,0 @@
//
// MessagePack for C++ memory pool
//
// Copyright (C) 2008-2010 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef MSGPACK_ZONE_HPP__
#define MSGPACK_ZONE_HPP__
#include "zone.h"
#include <cstdlib>
#include <memory>
#include <vector>
<% GENERATION_LIMIT = 15 %>
namespace msgpack {
class zone : public msgpack_zone {
public:
zone(size_t chunk_size = MSGPACK_ZONE_CHUNK_SIZE);
~zone();
public:
void* malloc(size_t size);
void* malloc_no_align(size_t size);
void push_finalizer(void (*func)(void*), void* data);
template <typename T>
void push_finalizer(std::auto_ptr<T> obj);
void clear();
void swap(zone& o);
<%0.upto(GENERATION_LIMIT) {|i|%>
template <typename T<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
T* allocate(<%=(1..i).map{|j|"A#{j} a#{j}"}.join(', ')%>);
<%}%>
private:
void undo_malloc(size_t size);
template <typename T>
static void object_destructor(void* obj);
typedef msgpack_zone base;
private:
zone(const zone&);
};
inline zone::zone(size_t chunk_size)
{
msgpack_zone_init(this, chunk_size);
}
inline zone::~zone()
{
msgpack_zone_destroy(this);
}
inline void* zone::malloc(size_t size)
{
void* ptr = msgpack_zone_malloc(this, size);
if(!ptr) {
throw std::bad_alloc();
}
return ptr;
}
inline void* zone::malloc_no_align(size_t size)
{
void* ptr = msgpack_zone_malloc_no_align(this, size);
if(!ptr) {
throw std::bad_alloc();
}
return ptr;
}
inline void zone::push_finalizer(void (*func)(void*), void* data)
{
if(!msgpack_zone_push_finalizer(this, func, data)) {
throw std::bad_alloc();
}
}
template <typename T>
inline void zone::push_finalizer(std::auto_ptr<T> obj)
{
if(!msgpack_zone_push_finalizer(this, &zone::object_destructor<T>, obj.get())) {
throw std::bad_alloc();
}
obj.release();
}
inline void zone::clear()
{
msgpack_zone_clear(this);
}
inline void zone::swap(zone& o)
{
msgpack_zone_swap(this, &o);
}
template <typename T>
void zone::object_destructor(void* obj)
{
reinterpret_cast<T*>(obj)->~T();
}
inline void zone::undo_malloc(size_t size)
{
base::chunk_list.ptr -= size;
base::chunk_list.free += size;
}
<%0.upto(GENERATION_LIMIT) {|i|%>
template <typename T<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
T* zone::allocate(<%=(1..i).map{|j|"A#{j} a#{j}"}.join(', ')%>)
{
void* x = malloc(sizeof(T));
if(!msgpack_zone_push_finalizer(this, &zone::object_destructor<T>, x)) {
undo_malloc(sizeof(T));
throw std::bad_alloc();
}
try {
return new (x) T(<%=(1..i).map{|j|"a#{j}"}.join(', ')%>);
} catch (...) {
--base::finalizer_array.tail;
undo_malloc(sizeof(T));
throw;
}
}
<%}%>
} // namespace msgpack
#endif /* msgpack/zone.hpp */

View file

@ -1,87 +0,0 @@
//
// MessagePack for C++ dynamic typed objects
//
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "msgpack/object.hpp"
namespace msgpack {
std::ostream& operator<< (std::ostream& s, const object o)
{
switch(o.type) {
case type::NIL:
s << "nil";
break;
case type::BOOLEAN:
s << (o.via.boolean ? "true" : "false");
break;
case type::POSITIVE_INTEGER:
s << o.via.u64;
break;
case type::NEGATIVE_INTEGER:
s << o.via.i64;
break;
case type::DOUBLE:
s << o.via.dec;
break;
case type::RAW:
(s << '"').write(o.via.raw.ptr, o.via.raw.size) << '"';
break;
case type::ARRAY:
s << "[";
if(o.via.array.size != 0) {
object* p(o.via.array.ptr);
s << *p;
++p;
for(object* const pend(o.via.array.ptr + o.via.array.size);
p < pend; ++p) {
s << ", " << *p;
}
}
s << "]";
break;
case type::MAP:
s << "{";
if(o.via.map.size != 0) {
object_kv* p(o.via.map.ptr);
s << p->key << "=>" << p->val;
++p;
for(object_kv* const pend(o.via.map.ptr + o.via.map.size);
p < pend; ++p) {
s << ", " << p->key << "=>" << p->val;
}
}
s << "}";
break;
default:
// FIXME
s << "#<UNKNOWN " << (uint16_t)o.type << ">";
}
return s;
}
} // namespace msgpack

View file

@ -1,237 +0,0 @@
/*
* MessagePack for C dynamic typing routine
*
* Copyright (C) 2008-2009 FURUHASHI Sadayuki
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "msgpack/object.h"
#include "msgpack/pack.h"
#include <stdio.h>
#include <string.h>
#ifndef _MSC_VER
#include <inttypes.h>
#else
#ifndef PRIu64
#define PRIu64 "I64u"
#endif
#ifndef PRIi64
#define PRIi64 "I64d"
#endif
#endif
int msgpack_pack_object(msgpack_packer* pk, msgpack_object d)
{
switch(d.type) {
case MSGPACK_OBJECT_NIL:
return msgpack_pack_nil(pk);
case MSGPACK_OBJECT_BOOLEAN:
if(d.via.boolean) {
return msgpack_pack_true(pk);
} else {
return msgpack_pack_false(pk);
}
case MSGPACK_OBJECT_POSITIVE_INTEGER:
return msgpack_pack_uint64(pk, d.via.u64);
case MSGPACK_OBJECT_NEGATIVE_INTEGER:
return msgpack_pack_int64(pk, d.via.i64);
case MSGPACK_OBJECT_DOUBLE:
return msgpack_pack_double(pk, d.via.dec);
case MSGPACK_OBJECT_RAW:
{
int ret = msgpack_pack_raw(pk, d.via.raw.size);
if(ret < 0) { return ret; }
return msgpack_pack_raw_body(pk, d.via.raw.ptr, d.via.raw.size);
}
case MSGPACK_OBJECT_ARRAY:
{
int ret = msgpack_pack_array(pk, d.via.array.size);
if(ret < 0) { return ret; }
msgpack_object* o = d.via.array.ptr;
msgpack_object* const oend = d.via.array.ptr + d.via.array.size;
for(; o != oend; ++o) {
ret = msgpack_pack_object(pk, *o);
if(ret < 0) { return ret; }
}
return 0;
}
case MSGPACK_OBJECT_MAP:
{
int ret = msgpack_pack_map(pk, d.via.map.size);
if(ret < 0) { return ret; }
msgpack_object_kv* kv = d.via.map.ptr;
msgpack_object_kv* const kvend = d.via.map.ptr + d.via.map.size;
for(; kv != kvend; ++kv) {
ret = msgpack_pack_object(pk, kv->key);
if(ret < 0) { return ret; }
ret = msgpack_pack_object(pk, kv->val);
if(ret < 0) { return ret; }
}
return 0;
}
default:
return -1;
}
}
void msgpack_object_print(FILE* out, msgpack_object o)
{
switch(o.type) {
case MSGPACK_OBJECT_NIL:
fprintf(out, "nil");
break;
case MSGPACK_OBJECT_BOOLEAN:
fprintf(out, (o.via.boolean ? "true" : "false"));
break;
case MSGPACK_OBJECT_POSITIVE_INTEGER:
fprintf(out, "%"PRIu64, o.via.u64);
break;
case MSGPACK_OBJECT_NEGATIVE_INTEGER:
fprintf(out, "%"PRIi64, o.via.i64);
break;
case MSGPACK_OBJECT_DOUBLE:
fprintf(out, "%f", o.via.dec);
break;
case MSGPACK_OBJECT_RAW:
fprintf(out, "\"");
fwrite(o.via.raw.ptr, o.via.raw.size, 1, out);
fprintf(out, "\"");
break;
case MSGPACK_OBJECT_ARRAY:
fprintf(out, "[");
if(o.via.array.size != 0) {
msgpack_object* p = o.via.array.ptr;
msgpack_object_print(out, *p);
++p;
msgpack_object* const pend = o.via.array.ptr + o.via.array.size;
for(; p < pend; ++p) {
fprintf(out, ", ");
msgpack_object_print(out, *p);
}
}
fprintf(out, "]");
break;
case MSGPACK_OBJECT_MAP:
fprintf(out, "{");
if(o.via.map.size != 0) {
msgpack_object_kv* p = o.via.map.ptr;
msgpack_object_print(out, p->key);
fprintf(out, "=>");
msgpack_object_print(out, p->val);
++p;
msgpack_object_kv* const pend = o.via.map.ptr + o.via.map.size;
for(; p < pend; ++p) {
fprintf(out, ", ");
msgpack_object_print(out, p->key);
fprintf(out, "=>");
msgpack_object_print(out, p->val);
}
}
fprintf(out, "}");
break;
default:
// FIXME
fprintf(out, "#<UNKNOWN %hu %"PRIu64">", o.type, o.via.u64);
}
}
bool msgpack_object_equal(const msgpack_object x, const msgpack_object y)
{
if(x.type != y.type) { return false; }
switch(x.type) {
case MSGPACK_OBJECT_NIL:
return true;
case MSGPACK_OBJECT_BOOLEAN:
return x.via.boolean == y.via.boolean;
case MSGPACK_OBJECT_POSITIVE_INTEGER:
return x.via.u64 == y.via.u64;
case MSGPACK_OBJECT_NEGATIVE_INTEGER:
return x.via.i64 == y.via.i64;
case MSGPACK_OBJECT_DOUBLE:
return x.via.dec == y.via.dec;
case MSGPACK_OBJECT_RAW:
return x.via.raw.size == y.via.raw.size &&
memcmp(x.via.raw.ptr, y.via.raw.ptr, x.via.raw.size) == 0;
case MSGPACK_OBJECT_ARRAY:
if(x.via.array.size != y.via.array.size) {
return false;
} else if(x.via.array.size == 0) {
return true;
} else {
msgpack_object* px = x.via.array.ptr;
msgpack_object* const pxend = x.via.array.ptr + x.via.array.size;
msgpack_object* py = y.via.array.ptr;
do {
if(!msgpack_object_equal(*px, *py)) {
return false;
}
++px;
++py;
} while(px < pxend);
return true;
}
case MSGPACK_OBJECT_MAP:
if(x.via.map.size != y.via.map.size) {
return false;
} else if(x.via.map.size == 0) {
return true;
} else {
msgpack_object_kv* px = x.via.map.ptr;
msgpack_object_kv* const pxend = x.via.map.ptr + x.via.map.size;
msgpack_object_kv* py = y.via.map.ptr;
do {
if(!msgpack_object_equal(px->key, py->key) || !msgpack_object_equal(px->val, py->val)) {
return false;
}
++px;
++py;
} while(px < pxend);
return true;
}
default:
return false;
}
}

View file

@ -1,459 +0,0 @@
/*
* MessagePack for C unpacking routine
*
* Copyright (C) 2008-2009 FURUHASHI Sadayuki
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "msgpack/unpack.h"
#include "msgpack/unpack_define.h"
#include <stdlib.h>
typedef struct {
msgpack_zone* z;
bool referenced;
} unpack_user;
#define msgpack_unpack_struct(name) \
struct template ## name
#define msgpack_unpack_func(ret, name) \
ret template ## name
#define msgpack_unpack_callback(name) \
template_callback ## name
#define msgpack_unpack_object msgpack_object
#define msgpack_unpack_user unpack_user
struct template_context;
typedef struct template_context template_context;
static void template_init(template_context* ctx);
static msgpack_object template_data(template_context* ctx);
static int template_execute(template_context* ctx,
const char* data, size_t len, size_t* off);
static inline msgpack_object template_callback_root(unpack_user* u)
{ msgpack_object o = {}; return o; }
static inline int template_callback_uint8(unpack_user* u, uint8_t d, msgpack_object* o)
{ o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = d; return 0; }
static inline int template_callback_uint16(unpack_user* u, uint16_t d, msgpack_object* o)
{ o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = d; return 0; }
static inline int template_callback_uint32(unpack_user* u, uint32_t d, msgpack_object* o)
{ o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = d; return 0; }
static inline int template_callback_uint64(unpack_user* u, uint64_t d, msgpack_object* o)
{ o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = d; return 0; }
static inline int template_callback_int8(unpack_user* u, int8_t d, msgpack_object* o)
{ if(d >= 0) { o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = d; return 0; }
else { o->type = MSGPACK_OBJECT_NEGATIVE_INTEGER; o->via.i64 = d; return 0; } }
static inline int template_callback_int16(unpack_user* u, int16_t d, msgpack_object* o)
{ if(d >= 0) { o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = d; return 0; }
else { o->type = MSGPACK_OBJECT_NEGATIVE_INTEGER; o->via.i64 = d; return 0; } }
static inline int template_callback_int32(unpack_user* u, int32_t d, msgpack_object* o)
{ if(d >= 0) { o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = d; return 0; }
else { o->type = MSGPACK_OBJECT_NEGATIVE_INTEGER; o->via.i64 = d; return 0; } }
static inline int template_callback_int64(unpack_user* u, int64_t d, msgpack_object* o)
{ if(d >= 0) { o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = d; return 0; }
else { o->type = MSGPACK_OBJECT_NEGATIVE_INTEGER; o->via.i64 = d; return 0; } }
static inline int template_callback_float(unpack_user* u, float d, msgpack_object* o)
{ o->type = MSGPACK_OBJECT_DOUBLE; o->via.dec = d; return 0; }
static inline int template_callback_double(unpack_user* u, double d, msgpack_object* o)
{ o->type = MSGPACK_OBJECT_DOUBLE; o->via.dec = d; return 0; }
static inline int template_callback_nil(unpack_user* u, msgpack_object* o)
{ o->type = MSGPACK_OBJECT_NIL; return 0; }
static inline int template_callback_true(unpack_user* u, msgpack_object* o)
{ o->type = MSGPACK_OBJECT_BOOLEAN; o->via.boolean = true; return 0; }
static inline int template_callback_false(unpack_user* u, msgpack_object* o)
{ o->type = MSGPACK_OBJECT_BOOLEAN; o->via.boolean = false; return 0; }
static inline int template_callback_array(unpack_user* u, unsigned int n, msgpack_object* o)
{
o->type = MSGPACK_OBJECT_ARRAY;
o->via.array.size = 0;
o->via.array.ptr = (msgpack_object*)msgpack_zone_malloc(u->z, n*sizeof(msgpack_object));
if(o->via.array.ptr == NULL) { return -1; }
return 0;
}
static inline int template_callback_array_item(unpack_user* u, msgpack_object* c, msgpack_object o)
{ c->via.array.ptr[c->via.array.size++] = o; return 0; }
static inline int template_callback_map(unpack_user* u, unsigned int n, msgpack_object* o)
{
o->type = MSGPACK_OBJECT_MAP;
o->via.map.size = 0;
o->via.map.ptr = (msgpack_object_kv*)msgpack_zone_malloc(u->z, n*sizeof(msgpack_object_kv));
if(o->via.map.ptr == NULL) { return -1; }
return 0;
}
static inline int template_callback_map_item(unpack_user* u, msgpack_object* c, msgpack_object k, msgpack_object v)
{
c->via.map.ptr[c->via.map.size].key = k;
c->via.map.ptr[c->via.map.size].val = v;
++c->via.map.size;
return 0;
}
static inline int template_callback_raw(unpack_user* u, const char* b, const char* p, unsigned int l, msgpack_object* o)
{
o->type = MSGPACK_OBJECT_RAW;
o->via.raw.ptr = p;
o->via.raw.size = l;
u->referenced = true;
return 0;
}
#include "msgpack/unpack_template.h"
#define CTX_CAST(m) ((template_context*)(m))
#define CTX_REFERENCED(mpac) CTX_CAST((mpac)->ctx)->user.referenced
#define COUNTER_SIZE (sizeof(_msgpack_atomic_counter_t))
static inline void init_count(void* buffer)
{
*(volatile _msgpack_atomic_counter_t*)buffer = 1;
}
static inline void decl_count(void* buffer)
{
// atomic if(--*(_msgpack_atomic_counter_t*)buffer == 0) { free(buffer); }
if(_msgpack_sync_decr_and_fetch((volatile _msgpack_atomic_counter_t*)buffer) == 0) {
free(buffer);
}
}
static inline void incr_count(void* buffer)
{
// atomic ++*(_msgpack_atomic_counter_t*)buffer;
_msgpack_sync_incr_and_fetch((volatile _msgpack_atomic_counter_t*)buffer);
}
static inline _msgpack_atomic_counter_t get_count(void* buffer)
{
return *(volatile _msgpack_atomic_counter_t*)buffer;
}
bool msgpack_unpacker_init(msgpack_unpacker* mpac, size_t initial_buffer_size)
{
if(initial_buffer_size < COUNTER_SIZE) {
initial_buffer_size = COUNTER_SIZE;
}
char* buffer = (char*)malloc(initial_buffer_size);
if(buffer == NULL) {
return false;
}
void* ctx = malloc(sizeof(template_context));
if(ctx == NULL) {
free(buffer);
return false;
}
msgpack_zone* z = msgpack_zone_new(MSGPACK_ZONE_CHUNK_SIZE);
if(z == NULL) {
free(ctx);
free(buffer);
return false;
}
mpac->buffer = buffer;
mpac->used = COUNTER_SIZE;
mpac->free = initial_buffer_size - mpac->used;
mpac->off = COUNTER_SIZE;
mpac->parsed = 0;
mpac->initial_buffer_size = initial_buffer_size;
mpac->z = z;
mpac->ctx = ctx;
init_count(mpac->buffer);
template_init(CTX_CAST(mpac->ctx));
CTX_CAST(mpac->ctx)->user.z = mpac->z;
CTX_CAST(mpac->ctx)->user.referenced = false;
return true;
}
void msgpack_unpacker_destroy(msgpack_unpacker* mpac)
{
msgpack_zone_free(mpac->z);
free(mpac->ctx);
decl_count(mpac->buffer);
}
msgpack_unpacker* msgpack_unpacker_new(size_t initial_buffer_size)
{
msgpack_unpacker* mpac = (msgpack_unpacker*)malloc(sizeof(msgpack_unpacker));
if(mpac == NULL) {
return NULL;
}
if(!msgpack_unpacker_init(mpac, initial_buffer_size)) {
free(mpac);
return NULL;
}
return mpac;
}
void msgpack_unpacker_free(msgpack_unpacker* mpac)
{
msgpack_unpacker_destroy(mpac);
free(mpac);
}
bool msgpack_unpacker_expand_buffer(msgpack_unpacker* mpac, size_t size)
{
if(mpac->used == mpac->off && get_count(mpac->buffer) == 1
&& !CTX_REFERENCED(mpac)) {
// rewind buffer
mpac->free += mpac->used - COUNTER_SIZE;
mpac->used = COUNTER_SIZE;
mpac->off = COUNTER_SIZE;
if(mpac->free >= size) {
return true;
}
}
if(mpac->off == COUNTER_SIZE) {
size_t next_size = (mpac->used + mpac->free) * 2; // include COUNTER_SIZE
while(next_size < size + mpac->used) {
next_size *= 2;
}
char* tmp = (char*)realloc(mpac->buffer, next_size);
if(tmp == NULL) {
return false;
}
mpac->buffer = tmp;
mpac->free = next_size - mpac->used;
} else {
size_t next_size = mpac->initial_buffer_size; // include COUNTER_SIZE
size_t not_parsed = mpac->used - mpac->off;
while(next_size < size + not_parsed + COUNTER_SIZE) {
next_size *= 2;
}
char* tmp = (char*)malloc(next_size);
if(tmp == NULL) {
return false;
}
init_count(tmp);
memcpy(tmp+COUNTER_SIZE, mpac->buffer+mpac->off, not_parsed);
if(CTX_REFERENCED(mpac)) {
if(!msgpack_zone_push_finalizer(mpac->z, decl_count, mpac->buffer)) {
free(tmp);
return false;
}
CTX_REFERENCED(mpac) = false;
} else {
decl_count(mpac->buffer);
}
mpac->buffer = tmp;
mpac->used = not_parsed + COUNTER_SIZE;
mpac->free = next_size - mpac->used;
mpac->off = COUNTER_SIZE;
}
return true;
}
int msgpack_unpacker_execute(msgpack_unpacker* mpac)
{
size_t off = mpac->off;
int ret = template_execute(CTX_CAST(mpac->ctx),
mpac->buffer, mpac->used, &mpac->off);
if(mpac->off > off) {
mpac->parsed += mpac->off - off;
}
return ret;
}
msgpack_object msgpack_unpacker_data(msgpack_unpacker* mpac)
{
return template_data(CTX_CAST(mpac->ctx));
}
msgpack_zone* msgpack_unpacker_release_zone(msgpack_unpacker* mpac)
{
if(!msgpack_unpacker_flush_zone(mpac)) {
return NULL;
}
msgpack_zone* r = msgpack_zone_new(MSGPACK_ZONE_CHUNK_SIZE);
if(r == NULL) {
return NULL;
}
msgpack_zone* old = mpac->z;
mpac->z = r;
return old;
}
void msgpack_unpacker_reset_zone(msgpack_unpacker* mpac)
{
msgpack_zone_clear(mpac->z);
}
bool msgpack_unpacker_flush_zone(msgpack_unpacker* mpac)
{
if(CTX_REFERENCED(mpac)) {
if(!msgpack_zone_push_finalizer(mpac->z, decl_count, mpac->buffer)) {
return false;
}
CTX_REFERENCED(mpac) = false;
incr_count(mpac->buffer);
}
return true;
}
void msgpack_unpacker_reset(msgpack_unpacker* mpac)
{
template_init(CTX_CAST(mpac->ctx));
// don't reset referenced flag
mpac->parsed = 0;
}
bool msgpack_unpacker_next(msgpack_unpacker* mpac, msgpack_unpacked* result)
{
if(result->zone != NULL) {
msgpack_zone_free(result->zone);
}
int ret = msgpack_unpacker_execute(mpac);
if(ret <= 0) {
result->zone = NULL;
memset(&result->data, 0, sizeof(msgpack_object));
return false;
}
result->zone = msgpack_unpacker_release_zone(mpac);
result->data = msgpack_unpacker_data(mpac);
msgpack_unpacker_reset(mpac);
return true;
}
msgpack_unpack_return
msgpack_unpack(const char* data, size_t len, size_t* off,
msgpack_zone* result_zone, msgpack_object* result)
{
size_t noff = 0;
if(off != NULL) { noff = *off; }
if(len <= noff) {
// FIXME
return MSGPACK_UNPACK_CONTINUE;
}
template_context ctx;
template_init(&ctx);
ctx.user.z = result_zone;
ctx.user.referenced = false;
int e = template_execute(&ctx, data, len, &noff);
if(e < 0) {
return MSGPACK_UNPACK_PARSE_ERROR;
}
if(off != NULL) { *off = noff; }
if(e == 0) {
return MSGPACK_UNPACK_CONTINUE;
}
*result = template_data(&ctx);
if(noff < len) {
return MSGPACK_UNPACK_EXTRA_BYTES;
}
return MSGPACK_UNPACK_SUCCESS;
}
bool msgpack_unpack_next(msgpack_unpacked* result,
const char* data, size_t len, size_t* off)
{
msgpack_unpacked_destroy(result);
size_t noff = 0;
if(off != NULL) { noff = *off; }
if(len <= noff) {
return false;
}
msgpack_zone* z = msgpack_zone_new(MSGPACK_ZONE_CHUNK_SIZE);
template_context ctx;
template_init(&ctx);
ctx.user.z = z;
ctx.user.referenced = false;
int e = template_execute(&ctx, data, len, &noff);
if(e <= 0) {
msgpack_zone_free(z);
return false;
}
if(off != NULL) { *off = noff; }
result->zone = z;
result->data = template_data(&ctx);
return true;
}

View file

@ -1,17 +0,0 @@
#include "msgpack.h"
const char* msgpack_version(void)
{
return MSGPACK_VERSION;
}
int msgpack_version_major(void)
{
return MSGPACK_VERSION_MAJOR;
}
int msgpack_version_minor(void)
{
return MSGPACK_VERSION_MINOR;
}

View file

@ -1,220 +0,0 @@
/*
* MessagePack for C zero-copy buffer implementation
*
* Copyright (C) 2008-2009 FURUHASHI Sadayuki
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "msgpack/vrefbuffer.h"
#include <stdlib.h>
#include <string.h>
struct msgpack_vrefbuffer_chunk {
struct msgpack_vrefbuffer_chunk* next;
/* data ... */
};
bool msgpack_vrefbuffer_init(msgpack_vrefbuffer* vbuf,
size_t ref_size, size_t chunk_size)
{
vbuf->chunk_size = chunk_size;
vbuf->ref_size = ref_size;
size_t nfirst = (sizeof(struct iovec) < 72/2) ?
72 / sizeof(struct iovec) : 8;
struct iovec* array = (struct iovec*)malloc(
sizeof(struct iovec) * nfirst);
if(array == NULL) {
return false;
}
vbuf->tail = array;
vbuf->end = array + nfirst;
vbuf->array = array;
msgpack_vrefbuffer_chunk* chunk = (msgpack_vrefbuffer_chunk*)malloc(
sizeof(msgpack_vrefbuffer_chunk) + chunk_size);
if(chunk == NULL) {
free(array);
return false;
}
msgpack_vrefbuffer_inner_buffer* const ib = &vbuf->inner_buffer;
ib->free = chunk_size;
ib->ptr = ((char*)chunk) + sizeof(msgpack_vrefbuffer_chunk);
ib->head = chunk;
chunk->next = NULL;
return true;
}
void msgpack_vrefbuffer_destroy(msgpack_vrefbuffer* vbuf)
{
msgpack_vrefbuffer_chunk* c = vbuf->inner_buffer.head;
while(true) {
msgpack_vrefbuffer_chunk* n = c->next;
free(c);
if(n != NULL) {
c = n;
} else {
break;
}
}
free(vbuf->array);
}
void msgpack_vrefbuffer_clear(msgpack_vrefbuffer* vbuf)
{
msgpack_vrefbuffer_chunk* c = vbuf->inner_buffer.head->next;
msgpack_vrefbuffer_chunk* n;
while(c != NULL) {
n = c->next;
free(c);
c = n;
}
msgpack_vrefbuffer_inner_buffer* const ib = &vbuf->inner_buffer;
msgpack_vrefbuffer_chunk* chunk = ib->head;
chunk->next = NULL;
ib->free = vbuf->chunk_size;
ib->ptr = ((char*)chunk) + sizeof(msgpack_vrefbuffer_chunk);
vbuf->tail = vbuf->array;
}
int msgpack_vrefbuffer_append_ref(msgpack_vrefbuffer* vbuf,
const char* buf, unsigned int len)
{
if(vbuf->tail == vbuf->end) {
const size_t nused = vbuf->tail - vbuf->array;
const size_t nnext = nused * 2;
struct iovec* nvec = (struct iovec*)realloc(
vbuf->array, sizeof(struct iovec)*nnext);
if(nvec == NULL) {
return -1;
}
vbuf->array = nvec;
vbuf->end = nvec + nnext;
vbuf->tail = nvec + nused;
}
vbuf->tail->iov_base = (char*)buf;
vbuf->tail->iov_len = len;
++vbuf->tail;
return 0;
}
int msgpack_vrefbuffer_append_copy(msgpack_vrefbuffer* vbuf,
const char* buf, unsigned int len)
{
msgpack_vrefbuffer_inner_buffer* const ib = &vbuf->inner_buffer;
if(ib->free < len) {
size_t sz = vbuf->chunk_size;
if(sz < len) {
sz = len;
}
msgpack_vrefbuffer_chunk* chunk = (msgpack_vrefbuffer_chunk*)malloc(
sizeof(msgpack_vrefbuffer_chunk) + sz);
if(chunk == NULL) {
return -1;
}
chunk->next = ib->head;
ib->head = chunk;
ib->free = sz;
ib->ptr = ((char*)chunk) + sizeof(msgpack_vrefbuffer_chunk);
}
char* m = ib->ptr;
memcpy(m, buf, len);
ib->free -= len;
ib->ptr += len;
if(vbuf->tail != vbuf->array && m ==
(const char*)((vbuf->tail-1)->iov_base) + (vbuf->tail-1)->iov_len) {
(vbuf->tail-1)->iov_len += len;
return 0;
} else {
return msgpack_vrefbuffer_append_ref(vbuf, m, len);
}
}
int msgpack_vrefbuffer_migrate(msgpack_vrefbuffer* vbuf, msgpack_vrefbuffer* to)
{
size_t sz = vbuf->chunk_size;
msgpack_vrefbuffer_chunk* empty = (msgpack_vrefbuffer_chunk*)malloc(
sizeof(msgpack_vrefbuffer_chunk) + sz);
if(empty == NULL) {
return -1;
}
empty->next = NULL;
const size_t nused = vbuf->tail - vbuf->array;
if(to->tail + nused < vbuf->end) {
const size_t tosize = to->tail - to->array;
const size_t reqsize = nused + tosize;
size_t nnext = (to->end - to->array) * 2;
while(nnext < reqsize) {
nnext *= 2;
}
struct iovec* nvec = (struct iovec*)realloc(
to->array, sizeof(struct iovec)*nnext);
if(nvec == NULL) {
free(empty);
return -1;
}
to->array = nvec;
to->end = nvec + nnext;
to->tail = nvec + tosize;
}
memcpy(to->tail, vbuf->array, sizeof(struct iovec)*nused);
to->tail += nused;
vbuf->tail = vbuf->array;
msgpack_vrefbuffer_inner_buffer* const ib = &vbuf->inner_buffer;
msgpack_vrefbuffer_inner_buffer* const toib = &to->inner_buffer;
msgpack_vrefbuffer_chunk* last = ib->head;
while(last->next != NULL) {
last = last->next;
}
last->next = toib->head;
toib->head = ib->head;
if(toib->free < ib->free) {
toib->free = ib->free;
toib->ptr = ib->ptr;
}
ib->head = empty;
ib->free = sz;
ib->ptr = ((char*)empty) + sizeof(msgpack_vrefbuffer_chunk);
return 0;
}

View file

@ -1,221 +0,0 @@
/*
* MessagePack for C memory pool implementation
*
* Copyright (C) 2008-2009 FURUHASHI Sadayuki
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "msgpack/zone.h"
#include <stdlib.h>
#include <string.h>
struct msgpack_zone_chunk {
struct msgpack_zone_chunk* next;
/* data ... */
};
static inline bool init_chunk_list(msgpack_zone_chunk_list* cl, size_t chunk_size)
{
msgpack_zone_chunk* chunk = (msgpack_zone_chunk*)malloc(
sizeof(msgpack_zone_chunk) + chunk_size);
if(chunk == NULL) {
return false;
}
cl->head = chunk;
cl->free = chunk_size;
cl->ptr = ((char*)chunk) + sizeof(msgpack_zone_chunk);
chunk->next = NULL;
return true;
}
static inline void destroy_chunk_list(msgpack_zone_chunk_list* cl)
{
msgpack_zone_chunk* c = cl->head;
while(true) {
msgpack_zone_chunk* n = c->next;
free(c);
if(n != NULL) {
c = n;
} else {
break;
}
}
}
static inline void clear_chunk_list(msgpack_zone_chunk_list* cl, size_t chunk_size)
{
msgpack_zone_chunk* c = cl->head;
while(true) {
msgpack_zone_chunk* n = c->next;
if(n != NULL) {
free(c);
c = n;
} else {
break;
}
}
cl->head->next = NULL;
cl->free = chunk_size;
cl->ptr = ((char*)cl->head) + sizeof(msgpack_zone_chunk);
}
void* msgpack_zone_malloc_expand(msgpack_zone* zone, size_t size)
{
msgpack_zone_chunk_list* const cl = &zone->chunk_list;
size_t sz = zone->chunk_size;
while(sz < size) {
sz *= 2;
}
msgpack_zone_chunk* chunk = (msgpack_zone_chunk*)malloc(
sizeof(msgpack_zone_chunk) + sz);
char* ptr = ((char*)chunk) + sizeof(msgpack_zone_chunk);
chunk->next = cl->head;
cl->head = chunk;
cl->free = sz - size;
cl->ptr = ptr + size;
return ptr;
}
static inline void init_finalizer_array(msgpack_zone_finalizer_array* fa)
{
fa->tail = NULL;
fa->end = NULL;
fa->array = NULL;
}
static inline void call_finalizer_array(msgpack_zone_finalizer_array* fa)
{
msgpack_zone_finalizer* fin = fa->tail;
for(; fin != fa->array; --fin) {
(*(fin-1)->func)((fin-1)->data);
}
}
static inline void destroy_finalizer_array(msgpack_zone_finalizer_array* fa)
{
call_finalizer_array(fa);
free(fa->array);
}
static inline void clear_finalizer_array(msgpack_zone_finalizer_array* fa)
{
call_finalizer_array(fa);
fa->tail = fa->array;
}
bool msgpack_zone_push_finalizer_expand(msgpack_zone* zone,
void (*func)(void* data), void* data)
{
msgpack_zone_finalizer_array* const fa = &zone->finalizer_array;
const size_t nused = fa->end - fa->array;
size_t nnext;
if(nused == 0) {
nnext = (sizeof(msgpack_zone_finalizer) < 72/2) ?
72 / sizeof(msgpack_zone_finalizer) : 8;
} else {
nnext = nused * 2;
}
msgpack_zone_finalizer* tmp =
(msgpack_zone_finalizer*)realloc(fa->array,
sizeof(msgpack_zone_finalizer) * nnext);
if(tmp == NULL) {
return false;
}
fa->array = tmp;
fa->end = tmp + nnext;
fa->tail = tmp + nused;
fa->tail->func = func;
fa->tail->data = data;
++fa->tail;
return true;
}
bool msgpack_zone_is_empty(msgpack_zone* zone)
{
msgpack_zone_chunk_list* const cl = &zone->chunk_list;
msgpack_zone_finalizer_array* const fa = &zone->finalizer_array;
return cl->free == zone->chunk_size && cl->head->next == NULL &&
fa->tail == fa->array;
}
void msgpack_zone_destroy(msgpack_zone* zone)
{
destroy_finalizer_array(&zone->finalizer_array);
destroy_chunk_list(&zone->chunk_list);
}
void msgpack_zone_clear(msgpack_zone* zone)
{
clear_finalizer_array(&zone->finalizer_array);
clear_chunk_list(&zone->chunk_list, zone->chunk_size);
}
bool msgpack_zone_init(msgpack_zone* zone, size_t chunk_size)
{
zone->chunk_size = chunk_size;
if(!init_chunk_list(&zone->chunk_list, chunk_size)) {
return false;
}
init_finalizer_array(&zone->finalizer_array);
return true;
}
msgpack_zone* msgpack_zone_new(size_t chunk_size)
{
msgpack_zone* zone = (msgpack_zone*)malloc(
sizeof(msgpack_zone) + chunk_size);
if(zone == NULL) {
return NULL;
}
zone->chunk_size = chunk_size;
if(!init_chunk_list(&zone->chunk_list, chunk_size)) {
free(zone);
return NULL;
}
init_finalizer_array(&zone->finalizer_array);
return zone;
}
void msgpack_zone_free(msgpack_zone* zone)
{
if(zone == NULL) { return; }
msgpack_zone_destroy(zone);
free(zone);
}

View file

@ -1,54 +0,0 @@
AM_CPPFLAGS = -I../src
AM_C_CPPFLAGS = -I../src
AM_LDFLAGS = ../src/libmsgpack.la -lgtest_main
check_PROGRAMS = \
zone \
pack_unpack \
pack_unpack_c \
streaming \
streaming_c \
object \
convert \
buffer \
cases \
fixint \
fixint_c \
version \
msgpackc_test \
msgpack_test
TESTS = $(check_PROGRAMS)
zone_SOURCES = zone.cc
pack_unpack_SOURCES = pack_unpack.cc
pack_unpack_c_SOURCES = pack_unpack_c.cc
streaming_SOURCES = streaming.cc
streaming_c_SOURCES = streaming_c.cc
object_SOURCES = object.cc
convert_SOURCES = convert.cc
buffer_SOURCES = buffer.cc
buffer_LDADD = -lz
cases_SOURCES = cases.cc
fixint_SOURCES = fixint.cc
fixint_c_SOURCES = fixint_c.cc
version_SOURCES = version.cc
msgpackc_test_SOURCES = msgpackc_test.cpp
msgpack_test_SOURCES = msgpack_test.cpp
EXTRA_DIST = cases.mpac cases_compact.mpac

View file

@ -1,75 +0,0 @@
#include <msgpack.hpp>
#include <msgpack/zbuffer.hpp>
#include <gtest/gtest.h>
#include <string.h>
TEST(buffer, sbuffer)
{
msgpack::sbuffer sbuf;
sbuf.write("a", 1);
sbuf.write("a", 1);
sbuf.write("a", 1);
EXPECT_EQ(3, sbuf.size());
EXPECT_TRUE( memcmp(sbuf.data(), "aaa", 3) == 0 );
sbuf.clear();
sbuf.write("a", 1);
sbuf.write("a", 1);
sbuf.write("a", 1);
EXPECT_EQ(3, sbuf.size());
EXPECT_TRUE( memcmp(sbuf.data(), "aaa", 3) == 0 );
}
TEST(buffer, vrefbuffer)
{
msgpack::vrefbuffer vbuf;
vbuf.write("a", 1);
vbuf.write("a", 1);
vbuf.write("a", 1);
const struct iovec* vec = vbuf.vector();
size_t veclen = vbuf.vector_size();
msgpack::sbuffer sbuf;
for(size_t i=0; i < veclen; ++i) {
sbuf.write((const char*)vec[i].iov_base, vec[i].iov_len);
}
EXPECT_EQ(3, sbuf.size());
EXPECT_TRUE( memcmp(sbuf.data(), "aaa", 3) == 0 );
vbuf.clear();
vbuf.write("a", 1);
vbuf.write("a", 1);
vbuf.write("a", 1);
vec = vbuf.vector();
veclen = vbuf.vector_size();
sbuf.clear();
for(size_t i=0; i < veclen; ++i) {
sbuf.write((const char*)vec[i].iov_base, vec[i].iov_len);
}
EXPECT_EQ(3, sbuf.size());
EXPECT_TRUE( memcmp(sbuf.data(), "aaa", 3) == 0 );
}
TEST(buffer, zbuffer)
{
msgpack::zbuffer zbuf;
zbuf.write("a", 1);
zbuf.write("a", 1);
zbuf.write("a", 1);
zbuf.flush();
char* data = zbuf.data();
size_t size = zbuf.size();
}

View file

@ -1,38 +0,0 @@
#include <msgpack.hpp>
#include <fstream>
#include <gtest/gtest.h>
static void feed_file(msgpack::unpacker& pac, const char* path)
{
std::ifstream fin(path);
while(true) {
pac.reserve_buffer(32*1024);
fin.read(pac.buffer(), pac.buffer_capacity());
if(fin.bad()) {
throw std::runtime_error("read failed");
}
pac.buffer_consumed(fin.gcount());
if(fin.fail()) {
break;
}
}
}
TEST(cases, format)
{
msgpack::unpacker pac;
msgpack::unpacker pac_compact;
feed_file(pac, "cases.mpac");
feed_file(pac_compact, "cases_compact.mpac");
msgpack::unpacked result;
while(pac.next(&result)) {
msgpack::unpacked result_compact;
EXPECT_TRUE( pac_compact.next(&result_compact) );
EXPECT_EQ(result_compact.get(), result.get());
}
EXPECT_FALSE( pac_compact.next(&result) );
}

View file

@ -1,74 +0,0 @@
#include <msgpack.hpp>
#include <gtest/gtest.h>
class compatibility {
public:
compatibility() : str1("default"), str2("default") { }
std::string str1;
std::string str2;
MSGPACK_DEFINE(str1, str2);
};
TEST(convert, compatibility_less)
{
std::vector<std::string> src(1);
src[0] = "kumofs";
msgpack::zone z;
msgpack::object obj(src, &z);
compatibility c;
EXPECT_NO_THROW( obj.convert(&c) );
EXPECT_EQ("kumofs", c.str1);
EXPECT_EQ("default", c.str2);
}
TEST(convert, compatibility_more)
{
std::vector<std::string> src(3);
src[0] = "kumofs";
src[1] = "mpio";
src[2] = "cloudy";
msgpack::zone z;
msgpack::object obj(src, &z);
compatibility to;
EXPECT_NO_THROW( obj.convert(&to) );
EXPECT_EQ("kumofs", to.str1);
EXPECT_EQ("mpio", to.str2);
}
class enum_member {
public:
enum_member() : flag(A) { }
enum flags_t {
A = 0,
B = 1,
};
flags_t flag;
MSGPACK_DEFINE((int&)flag);
};
TEST(convert, enum_member)
{
enum_member src;
src.flag = enum_member::B;
msgpack::zone z;
msgpack::object obj(src, &z);
enum_member to;
EXPECT_NO_THROW( obj.convert(&to) );
EXPECT_EQ(enum_member::B, to.flag);
}

View file

@ -1,55 +0,0 @@
#include <msgpack.hpp>
#include <gtest/gtest.h>
template <typename T>
void check_size(size_t size) {
T v(0);
msgpack::sbuffer sbuf;
msgpack::pack(sbuf, v);
EXPECT_EQ(size, sbuf.size());
}
TEST(fixint, size)
{
check_size<msgpack::type::fix_int8>(2);
check_size<msgpack::type::fix_int16>(3);
check_size<msgpack::type::fix_int32>(5);
check_size<msgpack::type::fix_int64>(9);
check_size<msgpack::type::fix_uint8>(2);
check_size<msgpack::type::fix_uint16>(3);
check_size<msgpack::type::fix_uint32>(5);
check_size<msgpack::type::fix_uint64>(9);
}
template <typename T>
void check_convert() {
T v1(-11);
msgpack::sbuffer sbuf;
msgpack::pack(sbuf, v1);
msgpack::unpacked msg;
msgpack::unpack(&msg, sbuf.data(), sbuf.size());
T v2;
msg.get().convert(&v2);
EXPECT_EQ(v1.get(), v2.get());
EXPECT_EQ(msg.get(), msgpack::object(T(v1.get())));
}
TEST(fixint, convert)
{
check_convert<msgpack::type::fix_int8>();
check_convert<msgpack::type::fix_int16>();
check_convert<msgpack::type::fix_int32>();
check_convert<msgpack::type::fix_int64>();
check_convert<msgpack::type::fix_uint8>();
check_convert<msgpack::type::fix_uint16>();
check_convert<msgpack::type::fix_uint32>();
check_convert<msgpack::type::fix_uint64>();
}

View file

@ -1,32 +0,0 @@
#include <msgpack.hpp>
#include <gtest/gtest.h>
TEST(fixint, size)
{
msgpack_sbuffer* sbuf = msgpack_sbuffer_new();
msgpack_packer* pk = msgpack_packer_new(sbuf, msgpack_sbuffer_write);
size_t sum = 0;
EXPECT_EQ(0, msgpack_pack_fix_int8(pk, 0));
EXPECT_EQ(sum+=2, sbuf->size);
EXPECT_EQ(0, msgpack_pack_fix_int16(pk, 0));
EXPECT_EQ(sum+=3, sbuf->size);
EXPECT_EQ(0, msgpack_pack_fix_int32(pk, 0));
EXPECT_EQ(sum+=5, sbuf->size);
EXPECT_EQ(0, msgpack_pack_fix_int64(pk, 0));
EXPECT_EQ(sum+=9, sbuf->size);
EXPECT_EQ(0, msgpack_pack_fix_uint8(pk, 0));
EXPECT_EQ(sum+=2, sbuf->size);
EXPECT_EQ(0, msgpack_pack_fix_uint16(pk, 0));
EXPECT_EQ(sum+=3, sbuf->size);
EXPECT_EQ(0, msgpack_pack_fix_uint32(pk, 0));
EXPECT_EQ(sum+=5, sbuf->size);
EXPECT_EQ(0, msgpack_pack_fix_uint64(pk, 0));
EXPECT_EQ(sum+=9, sbuf->size);
msgpack_sbuffer_free(sbuf);
msgpack_packer_free(pk);
}

View file

@ -1,982 +0,0 @@
#include "msgpack.hpp"
#include <math.h>
#include <string>
#include <vector>
#include <map>
#include <deque>
#include <set>
#include <list>
#include <gtest/gtest.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
using namespace std;
const unsigned int kLoop = 10000;
const unsigned int kElements = 100;
const double kEPS = 1e-10;
#define GEN_TEST(test_type) \
do { \
vector<test_type> v; \
v.push_back(0); \
v.push_back(1); \
v.push_back(2); \
v.push_back(numeric_limits<test_type>::min()); \
v.push_back(numeric_limits<test_type>::max()); \
for (unsigned int i = 0; i < kLoop; i++) \
v.push_back(rand()); \
for (unsigned int i = 0; i < v.size() ; i++) { \
msgpack::sbuffer sbuf; \
test_type val1 = v[i]; \
msgpack::pack(sbuf, val1); \
msgpack::zone z; \
msgpack::object obj; \
msgpack::unpack_return ret = \
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); \
EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); \
test_type val2; \
obj.convert(&val2); \
EXPECT_EQ(val1, val2); \
} \
} while(0)
TEST(MSGPACK, simple_buffer_short)
{
GEN_TEST(short);
}
TEST(MSGPACK, simple_buffer_int)
{
GEN_TEST(int);
}
TEST(MSGPACK, simple_buffer_long)
{
GEN_TEST(long);
}
TEST(MSGPACK, simple_buffer_long_long)
{
GEN_TEST(long long);
}
TEST(MSGPACK, simple_buffer_unsigned_short)
{
GEN_TEST(unsigned short);
}
TEST(MSGPACK, simple_buffer_unsigned_int)
{
GEN_TEST(unsigned int);
}
TEST(MSGPACK, simple_buffer_unsigned_long)
{
GEN_TEST(unsigned long);
}
TEST(MSGPACK, simple_buffer_unsigned_long_long)
{
GEN_TEST(unsigned long long);
}
TEST(MSGPACK, simple_buffer_uint8)
{
GEN_TEST(uint8_t);
}
TEST(MSGPACK, simple_buffer_uint16)
{
GEN_TEST(uint16_t);
}
TEST(MSGPACK, simple_buffer_uint32)
{
GEN_TEST(uint32_t);
}
TEST(MSGPACK, simple_buffer_uint64)
{
GEN_TEST(uint64_t);
}
TEST(MSGPACK, simple_buffer_int8)
{
GEN_TEST(int8_t);
}
TEST(MSGPACK, simple_buffer_int16)
{
GEN_TEST(int16_t);
}
TEST(MSGPACK, simple_buffer_int32)
{
GEN_TEST(int32_t);
}
TEST(MSGPACK, simple_buffer_int64)
{
GEN_TEST(int64_t);
}
TEST(MSGPACK, simple_buffer_float)
{
vector<float> v;
v.push_back(0.0);
v.push_back(-0.0);
v.push_back(1.0);
v.push_back(-1.0);
v.push_back(numeric_limits<float>::min());
v.push_back(numeric_limits<float>::max());
v.push_back(nanf("tag"));
v.push_back(1.0/0.0); // inf
v.push_back(-(1.0/0.0)); // -inf
for (unsigned int i = 0; i < kLoop; i++) {
v.push_back(drand48());
v.push_back(-drand48());
}
for (unsigned int i = 0; i < v.size() ; i++) {
msgpack::sbuffer sbuf;
float val1 = v[i];
msgpack::pack(sbuf, val1);
msgpack::zone z;
msgpack::object obj;
msgpack::unpack_return ret =
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj);
EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret);
float val2;
obj.convert(&val2);
if (isnan(val1))
EXPECT_TRUE(isnan(val2));
else if (isinf(val1))
EXPECT_TRUE(isinf(val2));
else
EXPECT_TRUE(fabs(val2 - val1) <= kEPS);
}
}
TEST(MSGPACK, simple_buffer_double)
{
vector<double> v;
v.push_back(0.0);
v.push_back(-0.0);
v.push_back(1.0);
v.push_back(-1.0);
v.push_back(numeric_limits<double>::min());
v.push_back(numeric_limits<double>::max());
v.push_back(nanf("tag"));
v.push_back(1.0/0.0); // inf
v.push_back(-(1.0/0.0)); // -inf
for (unsigned int i = 0; i < kLoop; i++) {
v.push_back(drand48());
v.push_back(-drand48());
}
for (unsigned int i = 0; i < v.size() ; i++) {
msgpack::sbuffer sbuf;
double val1 = v[i];
msgpack::pack(sbuf, val1);
msgpack::zone z;
msgpack::object obj;
msgpack::unpack_return ret =
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj);
EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret);
double val2;
obj.convert(&val2);
if (isnan(val1))
EXPECT_TRUE(isnan(val2));
else if (isinf(val1))
EXPECT_TRUE(isinf(val2));
else
EXPECT_TRUE(fabs(val2 - val1) <= kEPS);
}
}
TEST(MSGPACK, simple_buffer_true)
{
msgpack::sbuffer sbuf;
bool val1 = true;
msgpack::pack(sbuf, val1);
msgpack::zone z;
msgpack::object obj;
msgpack::unpack_return ret =
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj);
EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret);
bool val2;
obj.convert(&val2);
EXPECT_EQ(val1, val2);
}
TEST(MSGPACK, simple_buffer_false)
{
msgpack::sbuffer sbuf;
bool val1 = false;
msgpack::pack(sbuf, val1);
msgpack::zone z;
msgpack::object obj;
msgpack::unpack_return ret =
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj);
EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret);
bool val2;
obj.convert(&val2);
EXPECT_EQ(val1, val2);
}
//-----------------------------------------------------------------------------
// STL
TEST(MSGPACK_STL, simple_buffer_string)
{
for (unsigned int k = 0; k < kLoop; k++) {
string val1;
for (unsigned int i = 0; i < kElements; i++)
val1 += 'a' + rand() % 26;
msgpack::sbuffer sbuf;
msgpack::pack(sbuf, val1);
msgpack::zone z;
msgpack::object obj;
msgpack::unpack_return ret =
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj);
EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret);
string val2;
obj.convert(&val2);
EXPECT_EQ(val1.size(), val2.size());
EXPECT_EQ(val1, val2);
}
}
TEST(MSGPACK_STL, simple_buffer_vector)
{
for (unsigned int k = 0; k < kLoop; k++) {
vector<int> val1;
for (unsigned int i = 0; i < kElements; i++)
val1.push_back(rand());
msgpack::sbuffer sbuf;
msgpack::pack(sbuf, val1);
msgpack::zone z;
msgpack::object obj;
msgpack::unpack_return ret =
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj);
EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret);
vector<int> val2;
obj.convert(&val2);
EXPECT_EQ(val1.size(), val2.size());
EXPECT_TRUE(equal(val1.begin(), val1.end(), val2.begin()));
}
}
TEST(MSGPACK_STL, simple_buffer_map)
{
for (unsigned int k = 0; k < kLoop; k++) {
map<int, int> val1;
for (unsigned int i = 0; i < kElements; i++)
val1[rand()] = rand();
msgpack::sbuffer sbuf;
msgpack::pack(sbuf, val1);
msgpack::zone z;
msgpack::object obj;
msgpack::unpack_return ret =
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj);
EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret);
map<int, int> val2;
obj.convert(&val2);
EXPECT_EQ(val1.size(), val2.size());
EXPECT_TRUE(equal(val1.begin(), val1.end(), val2.begin()));
}
}
TEST(MSGPACK_STL, simple_buffer_deque)
{
for (unsigned int k = 0; k < kLoop; k++) {
deque<int> val1;
for (unsigned int i = 0; i < kElements; i++)
val1.push_back(rand());
msgpack::sbuffer sbuf;
msgpack::pack(sbuf, val1);
msgpack::zone z;
msgpack::object obj;
msgpack::unpack_return ret =
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj);
EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret);
deque<int> val2;
obj.convert(&val2);
EXPECT_EQ(val1.size(), val2.size());
EXPECT_TRUE(equal(val1.begin(), val1.end(), val2.begin()));
}
}
TEST(MSGPACK_STL, simple_buffer_list)
{
for (unsigned int k = 0; k < kLoop; k++) {
list<int> val1;
for (unsigned int i = 0; i < kElements; i++)
val1.push_back(rand());
msgpack::sbuffer sbuf;
msgpack::pack(sbuf, val1);
msgpack::zone z;
msgpack::object obj;
msgpack::unpack_return ret =
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj);
EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret);
list<int> val2;
obj.convert(&val2);
EXPECT_EQ(val1.size(), val2.size());
EXPECT_TRUE(equal(val1.begin(), val1.end(), val2.begin()));
}
}
TEST(MSGPACK_STL, simple_buffer_set)
{
for (unsigned int k = 0; k < kLoop; k++) {
set<int> val1;
for (unsigned int i = 0; i < kElements; i++)
val1.insert(rand());
msgpack::sbuffer sbuf;
msgpack::pack(sbuf, val1);
msgpack::zone z;
msgpack::object obj;
msgpack::unpack_return ret =
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj);
EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret);
set<int> val2;
obj.convert(&val2);
EXPECT_EQ(val1.size(), val2.size());
EXPECT_TRUE(equal(val1.begin(), val1.end(), val2.begin()));
}
}
TEST(MSGPACK_STL, simple_buffer_pair)
{
for (unsigned int k = 0; k < kLoop; k++) {
pair<int, int> val1 = make_pair(rand(), rand());
msgpack::sbuffer sbuf;
msgpack::pack(sbuf, val1);
msgpack::zone z;
msgpack::object obj;
msgpack::unpack_return ret =
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj);
EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret);
pair<int, int> val2;
obj.convert(&val2);
EXPECT_EQ(val1.first, val2.first);
EXPECT_EQ(val1.second, val2.second);
}
}
TEST(MSGPACK_STL, simple_buffer_multimap)
{
for (unsigned int k = 0; k < kLoop; k++) {
multimap<int, int> val1;
for (unsigned int i = 0; i < kElements; i++) {
int i1 = rand();
val1.insert(make_pair(i1, rand()));
val1.insert(make_pair(i1, rand()));
}
msgpack::sbuffer sbuf;
msgpack::pack(sbuf, val1);
msgpack::zone z;
msgpack::object obj;
msgpack::unpack_return ret =
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj);
EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret);
multimap<int, int> val2;
obj.convert(&val2);
vector<pair<int, int> > v1, v2;
multimap<int, int>::const_iterator it;
for (it = val1.begin(); it != val1.end(); ++it)
v1.push_back(make_pair(it->first, it->second));
for (it = val2.begin(); it != val2.end(); ++it)
v2.push_back(make_pair(it->first, it->second));
EXPECT_EQ(val1.size(), val2.size());
EXPECT_EQ(v1.size(), v2.size());
sort(v1.begin(), v1.end());
sort(v2.begin(), v2.end());
EXPECT_TRUE(v1 == v2);
}
}
TEST(MSGPACK_STL, simple_buffer_multiset)
{
for (unsigned int k = 0; k < kLoop; k++) {
multiset<int> val1;
for (unsigned int i = 0; i < kElements; i++)
val1.insert(rand());
msgpack::sbuffer sbuf;
msgpack::pack(sbuf, val1);
msgpack::zone z;
msgpack::object obj;
msgpack::unpack_return ret =
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj);
EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret);
multiset<int> val2;
obj.convert(&val2);
vector<int> v1, v2;
multiset<int>::const_iterator it;
for (it = val1.begin(); it != val1.end(); ++it)
v1.push_back(*it);
for (it = val2.begin(); it != val2.end(); ++it)
v2.push_back(*it);
EXPECT_EQ(val1.size(), val2.size());
EXPECT_EQ(v1.size(), v2.size());
sort(v1.begin(), v1.end());
sort(v2.begin(), v2.end());
EXPECT_TRUE(v1 == v2);
}
}
// TR1
#ifdef HAVE_TR1_UNORDERED_MAP
#include <tr1/unordered_map>
#include "msgpack/type/tr1/unordered_map.hpp"
TEST(MSGPACK_TR1, simple_buffer_unordered_map)
{
for (unsigned int k = 0; k < kLoop; k++) {
tr1::unordered_map<int, int> val1;
for (unsigned int i = 0; i < kElements; i++)
val1[rand()] = rand();
msgpack::sbuffer sbuf;
msgpack::pack(sbuf, val1);
msgpack::zone z;
msgpack::object obj;
msgpack::unpack_return ret =
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj);
EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret);
tr1::unordered_map<int, int> val2;
obj.convert(&val2);
EXPECT_EQ(val1.size(), val2.size());
tr1::unordered_map<int, int>::const_iterator it;
for (it = val1.begin(); it != val1.end(); ++it) {
EXPECT_TRUE(val2.find(it->first) != val2.end());
EXPECT_EQ(it->second, val2.find(it->first)->second);
}
}
}
TEST(MSGPACK_TR1, simple_buffer_unordered_multimap)
{
for (unsigned int k = 0; k < kLoop; k++) {
tr1::unordered_multimap<int, int> val1;
for (unsigned int i = 0; i < kElements; i++) {
int i1 = rand();
val1.insert(make_pair(i1, rand()));
val1.insert(make_pair(i1, rand()));
}
msgpack::sbuffer sbuf;
msgpack::pack(sbuf, val1);
msgpack::zone z;
msgpack::object obj;
msgpack::unpack_return ret =
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj);
EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret);
tr1::unordered_multimap<int, int> val2;
obj.convert(&val2);
vector<pair<int, int> > v1, v2;
tr1::unordered_multimap<int, int>::const_iterator it;
for (it = val1.begin(); it != val1.end(); ++it)
v1.push_back(make_pair(it->first, it->second));
for (it = val2.begin(); it != val2.end(); ++it)
v2.push_back(make_pair(it->first, it->second));
EXPECT_EQ(val1.size(), val2.size());
EXPECT_EQ(v1.size(), v2.size());
sort(v1.begin(), v1.end());
sort(v2.begin(), v2.end());
EXPECT_TRUE(v1 == v2);
}
}
#endif
#ifdef HAVE_TR1_UNORDERED_SET
#include <tr1/unordered_set>
#include "msgpack/type/tr1/unordered_set.hpp"
TEST(MSGPACK_TR1, simple_buffer_unordered_set)
{
for (unsigned int k = 0; k < kLoop; k++) {
tr1::unordered_set<int> val1;
for (unsigned int i = 0; i < kElements; i++)
val1.insert(rand());
msgpack::sbuffer sbuf;
msgpack::pack(sbuf, val1);
msgpack::zone z;
msgpack::object obj;
msgpack::unpack_return ret =
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj);
EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret);
tr1::unordered_set<int> val2;
obj.convert(&val2);
EXPECT_EQ(val1.size(), val2.size());
tr1::unordered_set<int>::const_iterator it;
for (it = val1.begin(); it != val1.end(); ++it)
EXPECT_TRUE(val2.find(*it) != val2.end());
}
}
TEST(MSGPACK_TR1, simple_buffer_unordered_multiset)
{
for (unsigned int k = 0; k < kLoop; k++) {
tr1::unordered_multiset<int> val1;
for (unsigned int i = 0; i < kElements; i++)
val1.insert(rand());
msgpack::sbuffer sbuf;
msgpack::pack(sbuf, val1);
msgpack::zone z;
msgpack::object obj;
msgpack::unpack_return ret =
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj);
EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret);
tr1::unordered_multiset<int> val2;
obj.convert(&val2);
vector<int> v1, v2;
tr1::unordered_multiset<int>::const_iterator it;
for (it = val1.begin(); it != val1.end(); ++it)
v1.push_back(*it);
for (it = val2.begin(); it != val2.end(); ++it)
v2.push_back(*it);
EXPECT_EQ(val1.size(), val2.size());
EXPECT_EQ(v1.size(), v2.size());
sort(v1.begin(), v1.end());
sort(v2.begin(), v2.end());
EXPECT_TRUE(v1 == v2);
}
}
#endif
// User-Defined Structures
class TestClass
{
public:
TestClass() : i(0), s("kzk") {}
int i;
string s;
MSGPACK_DEFINE(i, s);
};
TEST(MSGPACK_USER_DEFINED, simple_buffer_class)
{
for (unsigned int k = 0; k < kLoop; k++) {
TestClass val1;
msgpack::sbuffer sbuf;
msgpack::pack(sbuf, val1);
msgpack::zone z;
msgpack::object obj;
msgpack::unpack_return ret =
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj);
EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret);
TestClass val2;
val2.i = -1;
val2.s = "";
obj.convert(&val2);
EXPECT_EQ(val1.i, val2.i);
EXPECT_EQ(val1.s, val2.s);
}
}
class TestClass2
{
public:
TestClass2() : i(0), s("kzk") {
for (unsigned int i = 0; i < kElements; i++)
v.push_back(rand());
}
int i;
string s;
vector<int> v;
MSGPACK_DEFINE(i, s, v);
};
TEST(MSGPACK_USER_DEFINED, simple_buffer_class_old_to_new)
{
for (unsigned int k = 0; k < kLoop; k++) {
TestClass val1;
msgpack::sbuffer sbuf;
msgpack::pack(sbuf, val1);
msgpack::zone z;
msgpack::object obj;
msgpack::unpack_return ret =
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj);
EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret);
TestClass2 val2;
val2.i = -1;
val2.s = "";
val2.v = vector<int>();
obj.convert(&val2);
EXPECT_EQ(val1.i, val2.i);
EXPECT_EQ(val1.s, val2.s);
EXPECT_FALSE(val2.s.empty());
}
}
TEST(MSGPACK_USER_DEFINED, simple_buffer_class_new_to_old)
{
for (unsigned int k = 0; k < kLoop; k++) {
TestClass2 val1;
msgpack::sbuffer sbuf;
msgpack::pack(sbuf, val1);
msgpack::zone z;
msgpack::object obj;
msgpack::unpack_return ret =
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj);
EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret);
TestClass val2;
val2.i = -1;
val2.s = "";
obj.convert(&val2);
EXPECT_EQ(val1.i, val2.i);
EXPECT_EQ(val1.s, val2.s);
EXPECT_FALSE(val2.s.empty());
}
}
class TestEnumMemberClass
{
public:
TestEnumMemberClass()
: t1(STATE_A), t2(STATE_B), t3(STATE_C) {}
enum TestEnumType {
STATE_INVALID = 0,
STATE_A = 1,
STATE_B = 2,
STATE_C = 3
};
TestEnumType t1;
TestEnumType t2;
TestEnumType t3;
MSGPACK_DEFINE((int&)t1, (int&)t2, (int&)t3);
};
TEST(MSGPACK_USER_DEFINED, simple_buffer_enum_member)
{
TestEnumMemberClass val1;
msgpack::sbuffer sbuf;
msgpack::pack(sbuf, val1);
msgpack::zone z;
msgpack::object obj;
msgpack::unpack_return ret =
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj);
EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret);
TestEnumMemberClass val2;
val2.t1 = TestEnumMemberClass::STATE_INVALID;
val2.t2 = TestEnumMemberClass::STATE_INVALID;
val2.t3 = TestEnumMemberClass::STATE_INVALID;
obj.convert(&val2);
EXPECT_EQ(val1.t1, val2.t1);
EXPECT_EQ(val1.t2, val2.t2);
EXPECT_EQ(val1.t3, val2.t3);
}
class TestUnionMemberClass
{
public:
TestUnionMemberClass() {}
TestUnionMemberClass(double f) {
is_double = true;
value.f = f;
}
TestUnionMemberClass(int i) {
is_double = false;
value.i = i;
}
union {
double f;
int i;
} value;
bool is_double;
template <typename Packer>
void msgpack_pack(Packer& pk) const
{
if (is_double)
pk.pack(msgpack::type::tuple<bool, double>(true, value.f));
else
pk.pack(msgpack::type::tuple<bool, int>(false, value.i));
}
void msgpack_unpack(msgpack::object o)
{
msgpack::type::tuple<bool, msgpack::object> tuple;
o.convert(&tuple);
is_double = tuple.get<0>();
if (is_double)
tuple.get<1>().convert(&value.f);
else
tuple.get<1>().convert(&value.i);
}
};
TEST(MSGPACK_USER_DEFINED, simple_buffer_union_member)
{
{
// double
TestUnionMemberClass val1(1.0);
msgpack::sbuffer sbuf;
msgpack::pack(sbuf, val1);
msgpack::zone z;
msgpack::object obj;
msgpack::unpack_return ret =
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj);
EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret);
TestUnionMemberClass val2;
obj.convert(&val2);
EXPECT_EQ(val1.is_double, val2.is_double);
EXPECT_TRUE(fabs(val1.value.f - val2.value.f) < kEPS);
}
{
// int
TestUnionMemberClass val1(1);
msgpack::sbuffer sbuf;
msgpack::pack(sbuf, val1);
msgpack::zone z;
msgpack::object obj;
msgpack::unpack_return ret =
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj);
EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret);
TestUnionMemberClass val2;
obj.convert(&val2);
EXPECT_EQ(val1.is_double, val2.is_double);
EXPECT_EQ(val1.value.i, 1);
EXPECT_EQ(val1.value.i, val2.value.i);
}
}
//-----------------------------------------------------------------------------
#define GEN_TEST_VREF(test_type) \
do { \
vector<test_type> v; \
v.push_back(0); \
for (unsigned int i = 0; i < v.size(); i++) { \
test_type val1 = v[i]; \
msgpack::vrefbuffer vbuf; \
msgpack::pack(vbuf, val1); \
msgpack::sbuffer sbuf; \
const struct iovec* cur = vbuf.vector(); \
const struct iovec* end = cur + vbuf.vector_size(); \
for(; cur != end; ++cur) \
sbuf.write((const char*)cur->iov_base, cur->iov_len); \
msgpack::zone z; \
msgpack::object obj; \
msgpack::unpack_return ret = \
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); \
EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); \
test_type val2; \
obj.convert(&val2); \
EXPECT_EQ(val1, val2); \
} \
} while(0);
TEST(MSGPACK, vrefbuffer_short)
{
GEN_TEST_VREF(short);
}
TEST(MSGPACK, vrefbuffer_int)
{
GEN_TEST_VREF(int);
}
TEST(MSGPACK, vrefbuffer_long)
{
GEN_TEST_VREF(long);
}
TEST(MSGPACK, vrefbuffer_long_long)
{
GEN_TEST_VREF(long long);
}
TEST(MSGPACK, vrefbuffer_unsigned_short)
{
GEN_TEST_VREF(unsigned short);
}
TEST(MSGPACK, vrefbuffer_unsigned_int)
{
GEN_TEST_VREF(unsigned int);
}
TEST(MSGPACK, vrefbuffer_unsigned_long)
{
GEN_TEST_VREF(unsigned long);
}
TEST(MSGPACK, vrefbuffer_unsigned_long_long)
{
GEN_TEST_VREF(unsigned long long);
}
TEST(MSGPACK, vrefbuffer_uint8)
{
GEN_TEST_VREF(uint8_t);
}
TEST(MSGPACK, vrefbuffer_uint16)
{
GEN_TEST_VREF(uint16_t);
}
TEST(MSGPACK, vrefbuffer_uint32)
{
GEN_TEST_VREF(uint32_t);
}
TEST(MSGPACK, vrefbuffer_uint64)
{
GEN_TEST_VREF(uint64_t);
}
TEST(MSGPACK, vrefbuffer_int8)
{
GEN_TEST_VREF(int8_t);
}
TEST(MSGPACK, vrefbuffer_int16)
{
GEN_TEST_VREF(int16_t);
}
TEST(MSGPACK, vrefbuffer_int32)
{
GEN_TEST_VREF(int32_t);
}
TEST(MSGPACK, vrefbuffer_int64)
{
GEN_TEST_VREF(int64_t);
}
//-----------------------------------------------------------------------------
#define GEN_TEST_STREAM(test_type) \
for (unsigned int k = 0; k < kLoop; k++) { \
msgpack::sbuffer sbuf; \
msgpack::packer<msgpack::sbuffer> pk(sbuf); \
typedef std::vector<test_type> vec_type; \
vec_type vec; \
for(unsigned int i = 0; i < rand() % kLoop; ++i) { \
vec_type::value_type r = rand(); \
vec.push_back(r); \
pk.pack(r); \
} \
msgpack::unpacker pac; \
vec_type::const_iterator it = vec.begin(); \
const char *p = sbuf.data(); \
const char * const pend = p + sbuf.size(); \
while (p < pend) { \
const size_t sz = std::min<size_t>(pend - p, rand() % 128); \
pac.reserve_buffer(sz); \
memcpy(pac.buffer(), p, sz); \
pac.buffer_consumed(sz); \
while (pac.execute()) { \
if (it == vec.end()) goto out; \
msgpack::object obj = pac.data(); \
msgpack::zone *life = pac.release_zone(); \
EXPECT_TRUE(life != NULL); \
pac.reset(); \
vec_type::value_type val; \
obj.convert(&val); \
EXPECT_EQ(*it, val); \
++it; \
delete life; \
} \
p += sz; \
} \
out: \
; \
}
TEST(MSGPACK, stream_short)
{
GEN_TEST_STREAM(short);
}
TEST(MSGPACK, stream_int)
{
GEN_TEST_STREAM(int);
}
TEST(MSGPACK, stream_long)
{
GEN_TEST_STREAM(long);
}
TEST(MSGPACK, stream_long_long)
{
GEN_TEST_STREAM(long long);
}
TEST(MSGPACK, stream_unsigned_short)
{
GEN_TEST_STREAM(unsigned short);
}
TEST(MSGPACK, stream_unsigned_int)
{
GEN_TEST_STREAM(unsigned int);
}
TEST(MSGPACK, stream_unsigned_long)
{
GEN_TEST_STREAM(unsigned long);
}
TEST(MSGPACK, stream_unsigned_long_long)
{
GEN_TEST_STREAM(unsigned long long);
}
TEST(MSGPACK, stream_uint8)
{
GEN_TEST_STREAM(uint8_t);
}
TEST(MSGPACK, stream_uint16)
{
GEN_TEST_STREAM(uint16_t);
}
TEST(MSGPACK, stream_uint32)
{
GEN_TEST_STREAM(uint32_t);
}
TEST(MSGPACK, stream_uint64)
{
GEN_TEST_STREAM(uint64_t);
}
TEST(MSGPACK, stream_int8)
{
GEN_TEST_STREAM(int8_t);
}
TEST(MSGPACK, stream_int16)
{
GEN_TEST_STREAM(int16_t);
}
TEST(MSGPACK, stream_int32)
{
GEN_TEST_STREAM(int32_t);
}
TEST(MSGPACK, stream_int64)
{
GEN_TEST_STREAM(int64_t);
}

View file

@ -1,424 +0,0 @@
#include "msgpack.h"
#include <math.h>
#include <vector>
#include <limits>
#include <gtest/gtest.h>
using namespace std;
const unsigned int kLoop = 10000;
const double kEPS = 1e-10;
#define GEN_TEST_SIGNED(test_type, func_type) \
do { \
vector<test_type> v; \
v.push_back(0); \
v.push_back(1); \
v.push_back(-1); \
v.push_back(numeric_limits<test_type>::min()); \
v.push_back(numeric_limits<test_type>::max()); \
for (unsigned int i = 0; i < kLoop; i++) \
v.push_back(rand()); \
for (unsigned int i = 0; i < v.size() ; i++) { \
test_type val = v[i]; \
msgpack_sbuffer sbuf; \
msgpack_sbuffer_init(&sbuf); \
msgpack_packer pk; \
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); \
msgpack_pack_##func_type(&pk, val); \
msgpack_zone z; \
msgpack_zone_init(&z, 2048); \
msgpack_object obj; \
msgpack_unpack_return ret = \
msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj); \
EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret); \
if (val < 0) { \
EXPECT_EQ(MSGPACK_OBJECT_NEGATIVE_INTEGER, obj.type); \
EXPECT_EQ(val, obj.via.i64); \
} else { \
EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, obj.type); \
EXPECT_EQ(val, obj.via.u64); \
} \
msgpack_zone_destroy(&z); \
msgpack_sbuffer_destroy(&sbuf); \
} \
} while(0)
#define GEN_TEST_UNSIGNED(test_type, func_type) \
do { \
vector<test_type> v; \
v.push_back(0); \
v.push_back(1); \
v.push_back(2); \
v.push_back(numeric_limits<test_type>::min()); \
v.push_back(numeric_limits<test_type>::max()); \
for (unsigned int i = 0; i < kLoop; i++) \
v.push_back(rand()); \
for (unsigned int i = 0; i < v.size() ; i++) { \
test_type val = v[i]; \
msgpack_sbuffer sbuf; \
msgpack_sbuffer_init(&sbuf); \
msgpack_packer pk; \
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); \
msgpack_pack_##func_type(&pk, val); \
msgpack_zone z; \
msgpack_zone_init(&z, 2048); \
msgpack_object obj; \
msgpack_unpack_return ret = \
msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj); \
EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret); \
EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, obj.type); \
EXPECT_EQ(val, obj.via.u64); \
msgpack_zone_destroy(&z); \
msgpack_sbuffer_destroy(&sbuf); \
} \
} while(0)
TEST(MSGPACKC, simple_buffer_short)
{
GEN_TEST_SIGNED(short, short);
}
TEST(MSGPACKC, simple_buffer_int)
{
GEN_TEST_SIGNED(int, int);
}
TEST(MSGPACKC, simple_buffer_long)
{
GEN_TEST_SIGNED(long, long);
}
TEST(MSGPACKC, simple_buffer_long_long)
{
GEN_TEST_SIGNED(long long, long_long);
}
TEST(MSGPACKC, simple_buffer_unsigned_short)
{
GEN_TEST_UNSIGNED(unsigned short, unsigned_short);
}
TEST(MSGPACKC, simple_buffer_unsigned_int)
{
GEN_TEST_UNSIGNED(unsigned int, unsigned_int);
}
TEST(MSGPACKC, simple_buffer_unsigned_long)
{
GEN_TEST_UNSIGNED(unsigned long, unsigned_long);
}
TEST(MSGPACKC, simple_buffer_unsigned_long_long)
{
GEN_TEST_UNSIGNED(unsigned long long, unsigned_long_long);
}
TEST(MSGPACKC, simple_buffer_uint8)
{
GEN_TEST_UNSIGNED(uint8_t, uint8);
}
TEST(MSGPACKC, simple_buffer_uint16)
{
GEN_TEST_UNSIGNED(uint16_t, uint16);
}
TEST(MSGPACKC, simple_buffer_uint32)
{
GEN_TEST_UNSIGNED(uint32_t, uint32);
}
TEST(MSGPACKC, simple_buffer_uint64)
{
GEN_TEST_UNSIGNED(uint64_t, uint64);
}
TEST(MSGPACKC, simple_buffer_int8)
{
GEN_TEST_SIGNED(int8_t, int8);
}
TEST(MSGPACKC, simple_buffer_int16)
{
GEN_TEST_SIGNED(int16_t, int16);
}
TEST(MSGPACKC, simple_buffer_int32)
{
GEN_TEST_SIGNED(int32_t, int32);
}
TEST(MSGPACKC, simple_buffer_int64)
{
GEN_TEST_SIGNED(int64_t, int64);
}
TEST(MSGPACKC, simple_buffer_float)
{
vector<float> v;
v.push_back(0.0);
v.push_back(1.0);
v.push_back(-1.0);
v.push_back(numeric_limits<float>::min());
v.push_back(numeric_limits<float>::max());
v.push_back(nanf("tag"));
v.push_back(1.0/0.0); // inf
v.push_back(-(1.0/0.0)); // -inf
for (unsigned int i = 0; i < kLoop; i++) {
v.push_back(drand48());
v.push_back(-drand48());
}
for (unsigned int i = 0; i < v.size() ; i++) {
float val = v[i];
msgpack_sbuffer sbuf;
msgpack_sbuffer_init(&sbuf);
msgpack_packer pk;
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
msgpack_pack_float(&pk, val);
msgpack_zone z;
msgpack_zone_init(&z, 2048);
msgpack_object obj;
msgpack_unpack_return ret =
msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj);
EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret);
EXPECT_EQ(MSGPACK_OBJECT_DOUBLE, obj.type);
if (isnan(val))
EXPECT_TRUE(isnan(obj.via.dec));
else if (isinf(val))
EXPECT_TRUE(isinf(obj.via.dec));
else
EXPECT_TRUE(fabs(obj.via.dec - val) <= kEPS);
msgpack_zone_destroy(&z);
msgpack_sbuffer_destroy(&sbuf);
}
}
TEST(MSGPACKC, simple_buffer_double)
{
vector<double> v;
v.push_back(0.0);
v.push_back(-0.0);
v.push_back(1.0);
v.push_back(-1.0);
v.push_back(numeric_limits<double>::min());
v.push_back(numeric_limits<double>::max());
v.push_back(nan("tag"));
v.push_back(1.0/0.0); // inf
v.push_back(-(1.0/0.0)); // -inf
for (unsigned int i = 0; i < kLoop; i++) {
v.push_back(drand48());
v.push_back(-drand48());
}
for (unsigned int i = 0; i < v.size() ; i++) {
double val = v[i];
msgpack_sbuffer sbuf;
msgpack_sbuffer_init(&sbuf);
msgpack_packer pk;
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
msgpack_pack_double(&pk, val);
msgpack_zone z;
msgpack_zone_init(&z, 2048);
msgpack_object obj;
msgpack_unpack_return ret =
msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj);
EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret);
EXPECT_EQ(MSGPACK_OBJECT_DOUBLE, obj.type);
if (isnan(val))
EXPECT_TRUE(isnan(obj.via.dec));
else if (isinf(val))
EXPECT_TRUE(isinf(obj.via.dec));
else
EXPECT_TRUE(fabs(obj.via.dec - val) <= kEPS);
msgpack_zone_destroy(&z);
msgpack_sbuffer_destroy(&sbuf);
}
}
TEST(MSGPACKC, simple_buffer_nil)
{
msgpack_sbuffer sbuf;
msgpack_sbuffer_init(&sbuf);
msgpack_packer pk;
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
msgpack_pack_nil(&pk);
msgpack_zone z;
msgpack_zone_init(&z, 2048);
msgpack_object obj;
msgpack_unpack_return ret =
msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj);
EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret);
EXPECT_EQ(MSGPACK_OBJECT_NIL, obj.type);
msgpack_zone_destroy(&z);
msgpack_sbuffer_destroy(&sbuf);
}
TEST(MSGPACKC, simple_buffer_true)
{
msgpack_sbuffer sbuf;
msgpack_sbuffer_init(&sbuf);
msgpack_packer pk;
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
msgpack_pack_true(&pk);
msgpack_zone z;
msgpack_zone_init(&z, 2048);
msgpack_object obj;
msgpack_unpack_return ret =
msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj);
EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret);
EXPECT_EQ(MSGPACK_OBJECT_BOOLEAN, obj.type);
EXPECT_EQ(true, obj.via.boolean);
msgpack_zone_destroy(&z);
msgpack_sbuffer_destroy(&sbuf);
}
TEST(MSGPACKC, simple_buffer_false)
{
msgpack_sbuffer sbuf;
msgpack_sbuffer_init(&sbuf);
msgpack_packer pk;
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
msgpack_pack_false(&pk);
msgpack_zone z;
msgpack_zone_init(&z, 2048);
msgpack_object obj;
msgpack_unpack_return ret =
msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj);
EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret);
EXPECT_EQ(MSGPACK_OBJECT_BOOLEAN, obj.type);
EXPECT_EQ(false, obj.via.boolean);
msgpack_zone_destroy(&z);
msgpack_sbuffer_destroy(&sbuf);
}
TEST(MSGPACKC, simple_buffer_array)
{
unsigned int array_size = 5;
msgpack_sbuffer sbuf;
msgpack_sbuffer_init(&sbuf);
msgpack_packer pk;
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
msgpack_pack_array(&pk, array_size);
msgpack_pack_nil(&pk);
msgpack_pack_true(&pk);
msgpack_pack_false(&pk);
msgpack_pack_int(&pk, 10);
msgpack_pack_int(&pk, -10);
msgpack_zone z;
msgpack_zone_init(&z, 2048);
msgpack_object obj;
msgpack_unpack_return ret;
ret = msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj);
EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret);
EXPECT_EQ(MSGPACK_OBJECT_ARRAY, obj.type);
EXPECT_EQ(array_size, obj.via.array.size);
for (unsigned int i = 0; i < obj.via.array.size; i++) {
msgpack_object o = obj.via.array.ptr[i];
switch (i) {
case 0:
EXPECT_EQ(MSGPACK_OBJECT_NIL, o.type);
break;
case 1:
EXPECT_EQ(MSGPACK_OBJECT_BOOLEAN, o.type);
EXPECT_EQ(true, o.via.boolean);
break;
case 2:
EXPECT_EQ(MSGPACK_OBJECT_BOOLEAN, o.type);
EXPECT_EQ(false, o.via.boolean);
break;
case 3:
EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, o.type);
EXPECT_EQ(10, o.via.u64);
break;
case 4:
EXPECT_EQ(MSGPACK_OBJECT_NEGATIVE_INTEGER, o.type);
EXPECT_EQ(-10, o.via.i64);
break;
}
}
msgpack_zone_destroy(&z);
msgpack_sbuffer_destroy(&sbuf);
}
TEST(MSGPACKC, simple_buffer_map)
{
unsigned int map_size = 2;
msgpack_sbuffer sbuf;
msgpack_sbuffer_init(&sbuf);
msgpack_packer pk;
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
msgpack_pack_map(&pk, map_size);
msgpack_pack_true(&pk);
msgpack_pack_false(&pk);
msgpack_pack_int(&pk, 10);
msgpack_pack_int(&pk, -10);
msgpack_zone z;
msgpack_zone_init(&z, 2048);
msgpack_object obj;
msgpack_unpack_return ret;
ret = msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj);
EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret);
EXPECT_EQ(MSGPACK_OBJECT_MAP, obj.type);
EXPECT_EQ(map_size, obj.via.map.size);
for (unsigned int i = 0; i < map_size; i++) {
msgpack_object key = obj.via.map.ptr[i].key;
msgpack_object val = obj.via.map.ptr[i].val;
switch (i) {
case 0:
EXPECT_EQ(MSGPACK_OBJECT_BOOLEAN, key.type);
EXPECT_EQ(true, key.via.boolean);
EXPECT_EQ(MSGPACK_OBJECT_BOOLEAN, val.type);
EXPECT_EQ(false, val.via.boolean);
break;
case 1:
EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, key.type);
EXPECT_EQ(10, key.via.u64);
EXPECT_EQ(MSGPACK_OBJECT_NEGATIVE_INTEGER, val.type);
EXPECT_EQ(-10, val.via.i64);
break;
}
}
msgpack_zone_destroy(&z);
msgpack_sbuffer_destroy(&sbuf);
}
TEST(MSGPACKC, simple_buffer_raw)
{
unsigned int raw_size = 7;
msgpack_sbuffer sbuf;
msgpack_sbuffer_init(&sbuf);
msgpack_packer pk;
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
msgpack_pack_raw(&pk, raw_size);
msgpack_pack_raw_body(&pk, "fr", 2);
msgpack_pack_raw_body(&pk, "syuki", 5);
// invalid data
msgpack_pack_raw_body(&pk, "", 0);
msgpack_pack_raw_body(&pk, "kzk", 0);
msgpack_zone z;
msgpack_zone_init(&z, 2048);
msgpack_object obj;
msgpack_unpack_return ret;
ret = msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj);
EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret);
EXPECT_EQ(MSGPACK_OBJECT_RAW, obj.type);
EXPECT_EQ(raw_size, obj.via.raw.size);
EXPECT_EQ(0, memcmp("frsyuki", obj.via.raw.ptr, raw_size));
msgpack_zone_destroy(&z);
msgpack_sbuffer_destroy(&sbuf);
}

View file

@ -1,134 +0,0 @@
#include <msgpack.hpp>
#include <gtest/gtest.h>
struct myclass {
myclass() : num(0), str("default") { }
myclass(int num, const std::string& str) :
num(0), str("default") { }
~myclass() { }
int num;
std::string str;
MSGPACK_DEFINE(num, str);
bool operator==(const myclass& o) const
{
return num == o.num && str == o.str;
}
};
std::ostream& operator<<(std::ostream& o, const myclass& m)
{
return o << "myclass("<<m.num<<",\""<<m.str<<"\")";
}
TEST(object, convert)
{
myclass m1;
msgpack::sbuffer sbuf;
msgpack::pack(sbuf, m1);
msgpack::zone z;
msgpack::object obj;
msgpack::unpack_return ret =
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj);
EXPECT_EQ(ret, msgpack::UNPACK_SUCCESS);
myclass m2;
obj.convert(&m2);
EXPECT_EQ(m1, m2);
}
TEST(object, as)
{
myclass m1;
msgpack::sbuffer sbuf;
msgpack::pack(sbuf, m1);
msgpack::zone z;
msgpack::object obj;
msgpack::unpack_return ret =
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj);
EXPECT_EQ(ret, msgpack::UNPACK_SUCCESS);
EXPECT_EQ(m1, obj.as<myclass>());
}
TEST(object, print)
{
msgpack::object obj;
std::cout << obj << std::endl;
}
TEST(object, is_nil)
{
msgpack::object obj;
EXPECT_TRUE(obj.is_nil());
}
TEST(object, type_error)
{
msgpack::object obj(1);
EXPECT_THROW(obj.as<std::string>(), msgpack::type_error);
EXPECT_THROW(obj.as<std::vector<int> >(), msgpack::type_error);
EXPECT_EQ(1, obj.as<int>());
EXPECT_EQ(1, obj.as<short>());
EXPECT_EQ(1u, obj.as<unsigned int>());
EXPECT_EQ(1u, obj.as<unsigned long>());
}
TEST(object, equal_primitive)
{
msgpack::object obj_nil;
EXPECT_EQ(obj_nil, msgpack::object());
msgpack::object obj_int(1);
EXPECT_EQ(obj_int, msgpack::object(1));
EXPECT_EQ(obj_int, 1);
msgpack::object obj_double(1.2);
EXPECT_EQ(obj_double, msgpack::object(1.2));
EXPECT_EQ(obj_double, 1.2);
msgpack::object obj_bool(true);
EXPECT_EQ(obj_bool, msgpack::object(true));
EXPECT_EQ(obj_bool, true);
}
TEST(object, construct_primitive)
{
msgpack::object obj_nil;
EXPECT_EQ(msgpack::type::NIL, obj_nil.type);
msgpack::object obj_uint(1);
EXPECT_EQ(msgpack::type::POSITIVE_INTEGER, obj_uint.type);
EXPECT_EQ(1u, obj_uint.via.u64);
msgpack::object obj_int(-1);
EXPECT_EQ(msgpack::type::NEGATIVE_INTEGER, obj_int.type);
EXPECT_EQ(-1, obj_int.via.i64);
msgpack::object obj_double(1.2);
EXPECT_EQ(msgpack::type::DOUBLE, obj_double.type);
EXPECT_EQ(1.2, obj_double.via.dec);
msgpack::object obj_bool(true);
EXPECT_EQ(msgpack::type::BOOLEAN, obj_bool.type);
EXPECT_EQ(true, obj_bool.via.boolean);
}

View file

@ -1,123 +0,0 @@
#include <msgpack.hpp>
#include <gtest/gtest.h>
#include <sstream>
TEST(pack, num)
{
msgpack::sbuffer sbuf;
msgpack::pack(sbuf, 1);
}
TEST(pack, vector)
{
msgpack::sbuffer sbuf;
std::vector<int> vec;
vec.push_back(1);
vec.push_back(2);
vec.push_back(3);
msgpack::pack(sbuf, vec);
}
TEST(pack, to_ostream)
{
std::ostringstream stream;
msgpack::pack(stream, 1);
}
struct myclass {
myclass() : num(0), str("default") { }
myclass(int num, const std::string& str) :
num(0), str("default") { }
~myclass() { }
int num;
std::string str;
MSGPACK_DEFINE(num, str);
};
TEST(pack, myclass)
{
msgpack::sbuffer sbuf;
myclass m(1, "msgpack");
msgpack::pack(sbuf, m);
}
TEST(unpack, myclass)
{
msgpack::sbuffer sbuf;
myclass m1(1, "phraser");
msgpack::pack(sbuf, m1);
msgpack::zone z;
msgpack::object obj;
msgpack::unpack_return ret =
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj);
EXPECT_EQ(ret, msgpack::UNPACK_SUCCESS);
myclass m2 = obj.as<myclass>();
EXPECT_EQ(m1.num, m2.num);
EXPECT_EQ(m1.str, m2.str);
}
TEST(unpack, sequence)
{
msgpack::sbuffer sbuf;
msgpack::pack(sbuf, 1);
msgpack::pack(sbuf, 2);
msgpack::pack(sbuf, 3);
size_t offset = 0;
msgpack::unpacked msg;
msgpack::unpack(&msg, sbuf.data(), sbuf.size(), &offset);
EXPECT_EQ(1, msg.get().as<int>());
msgpack::unpack(&msg, sbuf.data(), sbuf.size(), &offset);
EXPECT_EQ(2, msg.get().as<int>());
msgpack::unpack(&msg, sbuf.data(), sbuf.size(), &offset);
EXPECT_EQ(3, msg.get().as<int>());
}
TEST(unpack, sequence_compat)
{
msgpack::sbuffer sbuf;
msgpack::pack(sbuf, 1);
msgpack::pack(sbuf, 2);
msgpack::pack(sbuf, 3);
size_t offset = 0;
msgpack::zone z;
msgpack::object obj;
msgpack::unpack_return ret;
ret = msgpack::unpack(sbuf.data(), sbuf.size(), &offset, &z, &obj);
EXPECT_TRUE(ret >= 0);
EXPECT_EQ(ret, msgpack::UNPACK_EXTRA_BYTES);
EXPECT_EQ(1, obj.as<int>());
ret = msgpack::unpack(sbuf.data(), sbuf.size(), &offset, &z, &obj);
EXPECT_TRUE(ret >= 0);
EXPECT_EQ(ret, msgpack::UNPACK_EXTRA_BYTES);
EXPECT_EQ(2, obj.as<int>());
ret = msgpack::unpack(sbuf.data(), sbuf.size(), &offset, &z, &obj);
EXPECT_TRUE(ret >= 0);
EXPECT_EQ(ret, msgpack::UNPACK_SUCCESS);
EXPECT_EQ(3, obj.as<int>());
}

View file

@ -1,70 +0,0 @@
#include <msgpack.h>
#include <gtest/gtest.h>
#include <stdio.h>
TEST(pack, num)
{
msgpack_sbuffer* sbuf = msgpack_sbuffer_new();
msgpack_packer* pk = msgpack_packer_new(sbuf, msgpack_sbuffer_write);
EXPECT_EQ(0, msgpack_pack_int(pk, 1));
msgpack_sbuffer_free(sbuf);
msgpack_packer_free(pk);
}
TEST(pack, array)
{
msgpack_sbuffer* sbuf = msgpack_sbuffer_new();
msgpack_packer* pk = msgpack_packer_new(sbuf, msgpack_sbuffer_write);
EXPECT_EQ(0, msgpack_pack_array(pk, 3));
EXPECT_EQ(0, msgpack_pack_int(pk, 1));
EXPECT_EQ(0, msgpack_pack_int(pk, 2));
EXPECT_EQ(0, msgpack_pack_int(pk, 3));
msgpack_sbuffer_free(sbuf);
msgpack_packer_free(pk);
}
TEST(unpack, sequence)
{
msgpack_sbuffer* sbuf = msgpack_sbuffer_new();
msgpack_packer* pk = msgpack_packer_new(sbuf, msgpack_sbuffer_write);
EXPECT_EQ(0, msgpack_pack_int(pk, 1));
EXPECT_EQ(0, msgpack_pack_int(pk, 2));
EXPECT_EQ(0, msgpack_pack_int(pk, 3));
msgpack_packer_free(pk);
bool success;
size_t offset = 0;
msgpack_unpacked msg;
msgpack_unpacked_init(&msg);
success = msgpack_unpack_next(&msg, sbuf->data, sbuf->size, &offset);
EXPECT_TRUE(success);
EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, msg.data.type);
EXPECT_EQ(1, msg.data.via.u64);
success = msgpack_unpack_next(&msg, sbuf->data, sbuf->size, &offset);
EXPECT_TRUE(success);
EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, msg.data.type);
EXPECT_EQ(2, msg.data.via.u64);
success = msgpack_unpack_next(&msg, sbuf->data, sbuf->size, &offset);
EXPECT_TRUE(success);
EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, msg.data.type);
EXPECT_EQ(3, msg.data.via.u64);
success = msgpack_unpack_next(&msg, sbuf->data, sbuf->size, &offset);
EXPECT_FALSE(success);
msgpack_sbuffer_free(sbuf);
msgpack_unpacked_destroy(&msg);
}

View file

@ -1,220 +0,0 @@
#include <msgpack.hpp>
#include <gtest/gtest.h>
#include <sstream>
TEST(streaming, basic)
{
msgpack::sbuffer buffer;
msgpack::packer<msgpack::sbuffer> pk(&buffer);
pk.pack(1);
pk.pack(2);
pk.pack(3);
const char* input = buffer.data();
const char* const eof = input + buffer.size();
msgpack::unpacker pac;
msgpack::unpacked result;
int count = 0;
while(count < 3) {
pac.reserve_buffer(32*1024);
// read buffer into pac.buffer() upto
// pac.buffer_capacity() bytes.
size_t len = 1;
memcpy(pac.buffer(), input, len);
input += len;
pac.buffer_consumed(len);
while(pac.next(&result)) {
msgpack::object obj = result.get();
switch(count++) {
case 0:
EXPECT_EQ(1, obj.as<int>());
break;
case 1:
EXPECT_EQ(2, obj.as<int>());
break;
case 2:
EXPECT_EQ(3, obj.as<int>());
return;
}
}
EXPECT_TRUE(input < eof);
}
}
class event_handler {
public:
event_handler(std::istream& input) : input(input) { }
~event_handler() { }
void on_read()
{
while(true) {
pac.reserve_buffer(32*1024);
size_t len = input.readsome(pac.buffer(), pac.buffer_capacity());
if(len == 0) {
return;
}
pac.buffer_consumed(len);
msgpack::unpacked result;
while(pac.next(&result)) {
on_message(result.get(), result.zone());
}
if(pac.message_size() > 10*1024*1024) {
throw std::runtime_error("message is too large");
}
}
}
void on_message(msgpack::object obj, std::auto_ptr<msgpack::zone> z)
{
EXPECT_EQ(expect, obj.as<int>());
}
int expect;
private:
std::istream& input;
msgpack::unpacker pac;
};
TEST(streaming, event)
{
std::stringstream stream;
msgpack::packer<std::ostream> pk(&stream);
event_handler handler(stream);
pk.pack(1);
handler.expect = 1;
handler.on_read();
pk.pack(2);
handler.expect = 2;
handler.on_read();
pk.pack(3);
handler.expect = 3;
handler.on_read();
}
// backward compatibility
TEST(streaming, basic_compat)
{
std::ostringstream stream;
msgpack::packer<std::ostream> pk(&stream);
pk.pack(1);
pk.pack(2);
pk.pack(3);
std::istringstream input(stream.str());
msgpack::unpacker pac;
int count = 0;
while(count < 3) {
pac.reserve_buffer(32*1024);
size_t len = input.readsome(pac.buffer(), pac.buffer_capacity());
pac.buffer_consumed(len);
while(pac.execute()) {
std::auto_ptr<msgpack::zone> z(pac.release_zone());
msgpack::object obj = pac.data();
pac.reset();
switch(count++) {
case 0:
EXPECT_EQ(1, obj.as<int>());
break;
case 1:
EXPECT_EQ(2, obj.as<int>());
break;
case 2:
EXPECT_EQ(3, obj.as<int>());
return;
}
}
}
}
// backward compatibility
class event_handler_compat {
public:
event_handler_compat(std::istream& input) : input(input) { }
~event_handler_compat() { }
void on_read()
{
while(true) {
pac.reserve_buffer(32*1024);
size_t len = input.readsome(pac.buffer(), pac.buffer_capacity());
if(len == 0) {
return;
}
pac.buffer_consumed(len);
while(pac.execute()) {
std::auto_ptr<msgpack::zone> z(pac.release_zone());
msgpack::object obj = pac.data();
pac.reset();
on_message(obj, z);
}
if(pac.message_size() > 10*1024*1024) {
throw std::runtime_error("message is too large");
}
}
}
void on_message(msgpack::object obj, std::auto_ptr<msgpack::zone> z)
{
EXPECT_EQ(expect, obj.as<int>());
}
int expect;
private:
std::istream& input;
msgpack::unpacker pac;
};
TEST(streaming, event_compat)
{
std::stringstream stream;
msgpack::packer<std::ostream> pk(&stream);
event_handler_compat handler(stream);
pk.pack(1);
handler.expect = 1;
handler.on_read();
pk.pack(2);
handler.expect = 2;
handler.on_read();
pk.pack(3);
handler.expect = 3;
handler.on_read();
}

View file

@ -1,57 +0,0 @@
#include <msgpack.h>
#include <gtest/gtest.h>
#include <stdio.h>
TEST(streaming, basic)
{
msgpack_sbuffer* buffer = msgpack_sbuffer_new();
msgpack_packer* pk = msgpack_packer_new(buffer, msgpack_sbuffer_write);
EXPECT_EQ(0, msgpack_pack_int(pk, 1));
EXPECT_EQ(0, msgpack_pack_int(pk, 2));
EXPECT_EQ(0, msgpack_pack_int(pk, 3));
msgpack_packer_free(pk);
const char* input = buffer->data;
const char* const eof = input + buffer->size;
msgpack_unpacker pac;
msgpack_unpacker_init(&pac, MSGPACK_UNPACKER_INIT_BUFFER_SIZE);
msgpack_unpacked result;
msgpack_unpacked_init(&result);
int count = 0;
while(count < 3) {
msgpack_unpacker_reserve_buffer(&pac, 32*1024);
/* read buffer into msgpack_unapcker_buffer(&pac) upto
* msgpack_unpacker_buffer_capacity(&pac) bytes. */
size_t len = 1;
memcpy(msgpack_unpacker_buffer(&pac), input, len);
input += len;
msgpack_unpacker_buffer_consumed(&pac, len);
while(msgpack_unpacker_next(&pac, &result)) {
msgpack_object obj = result.data;
switch(count++) {
case 0:
EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, result.data.type);
EXPECT_EQ(1, result.data.via.u64);
break;
case 1:
EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, result.data.type);
EXPECT_EQ(2, result.data.via.u64);
break;
case 2:
EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, result.data.type);
EXPECT_EQ(3, result.data.via.u64);
return;
}
}
EXPECT_TRUE(input < eof);
}
}

View file

@ -1,13 +0,0 @@
#include <msgpack.hpp>
#include <gtest/gtest.h>
TEST(version, print)
{
printf("MSGPACK_VERSION : %s\n", MSGPACK_VERSION);
printf("MSGPACK_VERSION_MAJOR : %d\n", MSGPACK_VERSION_MAJOR);
printf("MSGPACK_VERSION_MINOR : %d\n", MSGPACK_VERSION_MINOR);
printf("msgpack_version() : %s\n", msgpack_version());
printf("msgpack_version_major() : %d\n", msgpack_version_major());
printf("msgpack_version_minor() : %d\n", msgpack_version_minor());
}

View file

@ -1,78 +0,0 @@
#include <msgpack.hpp>
#include <gtest/gtest.h>
TEST(zone, malloc)
{
msgpack::zone z;
char* buf1 = (char*)z.malloc(4);
memcpy(buf1, "test", 4);
char* buf2 = (char*)z.malloc(4);
memcpy(buf2, "test", 4);
}
class myclass {
public:
myclass() : num(0), str("default") { }
myclass(int num, const std::string& str) :
num(num), str(str) { }
~myclass() { }
int num;
std::string str;
private:
myclass(const myclass&);
};
TEST(zone, allocate)
{
msgpack::zone z;
myclass* m = z.allocate<myclass>();
EXPECT_EQ(m->num, 0);
EXPECT_EQ(m->str, "default");
}
TEST(zone, allocate_constructor)
{
msgpack::zone z;
myclass* m = z.allocate<myclass>(7, "msgpack");
EXPECT_EQ(m->num, 7);
EXPECT_EQ(m->str, "msgpack");
}
static void custom_finalizer_func(void* user)
{
myclass* m = (myclass*)user;
delete m;
}
TEST(zone, push_finalizer)
{
msgpack::zone z;
myclass* m = new myclass();
z.push_finalizer(custom_finalizer_func, (void*)m);
}
TEST(zone, push_finalizer_auto_ptr)
{
msgpack::zone z;
std::auto_ptr<myclass> am(new myclass());
z.push_finalizer(am);
}
TEST(zone, malloc_no_align)
{
msgpack::zone z;
char* buf1 = (char*)z.malloc_no_align(4);
char* buf2 = (char*)z.malloc_no_align(4);
EXPECT_EQ(buf1+4, buf2);
}

22
docker/buildwheel.sh Normal file
View file

@ -0,0 +1,22 @@
#!/bin/bash
DOCKER_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source "$DOCKER_DIR/shared.env"
set -e -x
ARCH=`uname -p`
echo "arch=$ARCH"
ls /opt/python
for V in "${PYTHON_VERSIONS[@]}"; do
PYBIN=/opt/python/$V/bin
rm -rf build/ # Avoid lib build by narrow Python is used by wide python
$PYBIN/python -m build -w
done
cd dist
for whl in *.whl; do
auditwheel repair "$whl"
rm "$whl"
done

17
docker/runtests.sh Executable file
View file

@ -0,0 +1,17 @@
#!/bin/bash
DOCKER_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source "$DOCKER_DIR/shared.env"
set -e -x
for V in "${PYTHON_VERSIONS[@]}"; do
PYBIN=/opt/python/$V/bin
$PYBIN/python setup.py install
rm -rf build/ # Avoid lib build by narrow Python is used by wide python
$PYBIN/pip install pytest
pushd test # prevent importing msgpack package in current directory.
$PYBIN/python -c 'import sys; print(hex(sys.maxsize))'
$PYBIN/python -c 'from msgpack import _cmsgpack' # Ensure extension is available
$PYBIN/pytest -v .
popd
done

7
docker/shared.env Normal file
View file

@ -0,0 +1,7 @@
PYTHON_VERSIONS=(
cp310-cp310
cp39-cp39
cp38-cp38
cp37-cp37m
cp36-cp36m
)

159
docs/Makefile Normal file
View file

@ -0,0 +1,159 @@
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = _build
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -E -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " texinfo to make Texinfo files"
@echo " info to make Texinfo files and run them through makeinfo"
@echo " gettext to make PO message catalogs"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
clean:
-rm -rf $(BUILDDIR)/*
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/msgpack.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/msgpack.qhc"
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/msgpack"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/msgpack"
@echo "# devhelp"
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
texinfo:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
@echo "Run \`make' in that directory to run these through makeinfo" \
"(use \`make info' here to do that automatically)."
info:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo "Running Texinfo files through makeinfo..."
make -C $(BUILDDIR)/texinfo info
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
@echo
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."
serve: html
python3 -m http.server -d _build/html
zip: html
cd _build/html && zip -r ../../../msgpack-doc.zip .

1
docs/_static/README.txt vendored Normal file
View file

@ -0,0 +1 @@
Sphinx will copy the contents of docs/_static/ directory to the build location.

32
docs/advanced.rst Normal file
View file

@ -0,0 +1,32 @@
Advanced usage
===============
Packer
------
autoreset
~~~~~~~~~
When you used ``autoreset=False`` option of :class:`~msgpack.Packer`,
``pack()`` method doesn't return packed ``bytes``.
You can use :meth:`~msgpack.Packer.bytes` or :meth:`~msgpack.Packer.getbuffer` to
get packed data.
``bytes()`` returns ``bytes`` object. ``getbuffer()`` returns some bytes-like
object. It's concrete type is implement detail and it will be changed in future
versions.
You can reduce temporary bytes object by using ``Unpacker.getbuffer()``.
.. code-block:: python
packer = Packer(use_bin_type=True, autoreset=False)
packer.pack([1, 2])
packer.pack([3, 4])
with open('data.bin', 'wb') as f:
f.write(packer.getbuffer())
packer.reset() # reset internal buffer

43
docs/api.rst Normal file
View file

@ -0,0 +1,43 @@
API reference
=============
.. module:: msgpack
.. autofunction:: pack
``dump()`` is an alias for :func:`pack`
.. autofunction:: packb
``dumps()`` is an alias for :func:`packb`
.. autofunction:: unpack
``load()`` is an alias for :func:`unpack`
.. autofunction:: unpackb
``loads()`` is an alias for :func:`unpackb`
.. autoclass:: Packer
:members:
.. autoclass:: Unpacker
:members:
.. autoclass:: ExtType
.. autoclass:: Timestamp
:members:
:special-members: __init__
exceptions
----------
These exceptions are accessible via `msgpack` package.
(For example, `msgpack.OutOfData` is shortcut for `msgpack.exceptions.OutOfData`)
.. automodule:: msgpack.exceptions
:members:
:undoc-members:
:show-inheritance:

283
docs/conf.py Normal file
View file

@ -0,0 +1,283 @@
# msgpack documentation build configuration file, created by
# sphinx-quickstart on Sun Feb 24 14:20:50 2013.
#
# This file is execfile()d with the current directory set to its containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
# import os
# import sys
# sys.path.insert(0, os.path.abspath('..'))
# -- General configuration -----------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
# needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ["sphinx.ext.autodoc", "sphinx.ext.viewcode"]
# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]
# The suffix of source filenames.
source_suffix = ".rst"
# The encoding of source files.
# source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = "index"
# General information about the project.
project = "msgpack"
copyright = "Inada Naoki"
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
# The full version, including alpha/beta/rc tags.
version = release = "1.0"
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
# language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
# today = ''
# Else, today_fmt is used as the format for a strftime call.
# today_fmt = '%B %d, %Y'
today_fmt = "%Y-%m-%d"
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ["_build"]
# The reST default role (used for this markup: `text`) to use for all documents.
# default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
# add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
# add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
# show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = "sphinx"
# A list of ignored prefixes for module index sorting.
# modindex_common_prefix = []
# -- Options for HTML output ---------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = "sphinx_rtd_theme"
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
# html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
# html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
# html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
# html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
# html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
# html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ["_static"]
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
# html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
# html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
# html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
# html_additional_pages = {}
# If false, no module index is generated.
# html_domain_indices = True
# If false, no index is generated.
# html_use_index = True
# If true, the index is split into individual pages for each letter.
# html_split_index = False
# If true, links to the reST sources are added to the pages.
# html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
# html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
# html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
# html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
# html_file_suffix = None
# Output file base name for HTML help builder.
htmlhelp_basename = "msgpackdoc"
# -- Options for LaTeX output --------------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#'preamble': '',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
("index", "msgpack.tex", "msgpack Documentation", "Author", "manual"),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
# latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
# latex_use_parts = False
# If true, show page references after internal links.
# latex_show_pagerefs = False
# If true, show URL addresses after external links.
# latex_show_urls = False
# Documents to append as an appendix to all manuals.
# latex_appendices = []
# If false, no module index is generated.
# latex_domain_indices = True
# -- Options for manual page output --------------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [("index", "msgpack", "msgpack Documentation", ["Author"], 1)]
# If true, show URL addresses after external links.
# man_show_urls = False
# -- Options for Texinfo output ------------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(
"index",
"msgpack",
"msgpack Documentation",
"Author",
"msgpack",
"One line description of project.",
"Miscellaneous",
),
]
# Documents to append as an appendix to all manuals.
# texinfo_appendices = []
# If false, no module index is generated.
# texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
# texinfo_show_urls = 'footnote'
# -- Options for Epub output ---------------------------------------------------
# Bibliographic Dublin Core info.
epub_title = "msgpack"
epub_author = "Author"
epub_publisher = "Author"
epub_copyright = "2013, Author"
# The language of the text. It defaults to the language option
# or en if the language is not set.
# epub_language = ''
# The scheme of the identifier. Typical schemes are ISBN or URL.
# epub_scheme = ''
# The unique identifier of the text. This can be a ISBN number
# or the project homepage.
# epub_identifier = ''
# A unique identification for the text.
# epub_uid = ''
# A tuple containing the cover image and cover page html template filenames.
# epub_cover = ()
# HTML files that should be inserted before the pages created by sphinx.
# The format is a list of tuples containing the path and title.
# epub_pre_files = []
# HTML files shat should be inserted after the pages created by sphinx.
# The format is a list of tuples containing the path and title.
# epub_post_files = []
# A list of files that should not be packed into the epub file.
# epub_exclude_files = []
# The depth of the table of contents in toc.ncx.
# epub_tocdepth = 3
# Allow duplicate toc entries.
# epub_tocdup = True

11
docs/index.rst Normal file
View file

@ -0,0 +1,11 @@
msgpack document
================
`MessagePack <http://msgpack.org>`_ is a efficient format for inter
language data exchange.
.. toctree::
:maxdepth: 1
api
advanced

2
docs/requirements.txt Normal file
View file

@ -0,0 +1,2 @@
sphinx~=7.3.7
sphinx-rtd-theme~=2.0.0

5
erlang/.gitignore vendored
View file

@ -1,5 +0,0 @@
MANIFEST
*.beam
.omakedb*
*.omc
*~

View file

@ -1,51 +0,0 @@
########################################################################
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this file, to deal in the File without
# restriction, including without limitation the rights to use,
# copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the File, and to permit persons to whom the
# File is furnished to do so, subject to the following condition:
#
# THE FILE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE FILE OR
# THE USE OR OTHER DEALINGS IN THE FILE.
########################################################################
# The standard OMakefile.
# You will usually need to modify this file for your project.
########################################################################
# Phony targets are scoped, so you probably want to declare them first.
#
.PHONY: all clean test edoc dialyzer #install
########################################################################
# Subdirectories.
# You may want to include some subdirectories in this project.
# If so, define the subdirectory targets and uncomment this section.
#
.DEFAULT: msgpack.beam
msgpack.beam: msgpack.erl
erlc -Wall +debug_info $<
msgpack.html: msgpack.erl
erl -noshell -run edoc_run file $<
test: msgpack.beam
erl -noshell -s msgpack test -s init stop
edoc: msgpack.erl
erl -noshell -eval 'ok=edoc:files(["msgpack.erl"], [{dir, "edoc"}]).' -s init stop
dialyzer: msgpack.erl
dialyzer --src $<
clean:
-rm -f *.beam *.html

View file

@ -1,45 +0,0 @@
########################################################################
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this file, to deal in the File without
# restriction, including without limitation the rights to use,
# copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the File, and to permit persons to whom the
# File is furnished to do so, subject to the following condition:
#
# THE FILE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE FILE OR
# THE USE OR OTHER DEALINGS IN THE FILE.
########################################################################
# The standard OMakeroot file.
# You will not normally need to modify this file.
# By default, your changes should be placed in the
# OMakefile in this directory.
#
# If you decide to modify this file, note that it uses exactly
# the same syntax as the OMakefile.
#
#
# Include the standard installed configuration files.
# Any of these can be deleted if you are not using them,
# but you probably want to keep the Common file.
#
open build/C
open build/OCaml
open build/LaTeX
#
# The command-line variables are defined *after* the
# standard configuration has been loaded.
#
DefineCommandVars()
#
# Include the OMakefile in this directory.
#
.SUBDIRS: .

View file

@ -1,9 +0,0 @@
MessagePack for Erlang
======================
Binary-based efficient object serialization library.
see wiki ( http://redmine.msgpack.org/projects/msgpack/wiki/QuickStartErlang ) for details
# Status
0.1.0 released.

View file

@ -1,4 +0,0 @@
*.html
*.css
*.png
edoc-info

View file

@ -1,395 +0,0 @@
%%
%% MessagePack for Erlang
%%
%% Copyright (C) 2009-2010 UENISHI Kota
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
%%
%% http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing, software
%% distributed under the License is distributed on an "AS IS" BASIS,
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
%% @doc <a href="http://msgpack.org/">MessagePack</a> codec for Erlang.
%%
%% APIs are almost compatible with <a href="http://redmine.msgpack.org/projects/msgpack/wiki/QuickStartC">C API</a>
%% except for buffering functions (both copying and zero-copying), which are unavailable.
%%
%% <table border="1">
%% <caption>Equivalence between Erlang and <a href="http://msgpack.sourceforge.jp/spec">Msgpack type</a> :</caption>
%% <tr><th> erlang </th><th> msgpack </th></tr>
%% <tr><td> integer() </td><td> pos_fixnum/neg_fixnum/uint8/uint16/uint32/uint64/int8/int16/int32/int64 </td></tr>
%% <tr><td> float() </td><td> float/double </td></tr>
%% <tr><td> nil </td><td> nil </td></tr>
%% <tr><td> boolean() </td><td> boolean </td></tr>
%% <tr><td> binary() </td><td> fix_raw/raw16/raw32 </td></tr>
%% <tr><td> list() </td><td> fix_array/array16/array32 </td></tr>
%% <tr><td> {proplist()} </td><td> fix_map/map16/map32 </td></tr>
%% </table>
%% @end
-module(msgpack).
-author('kuenishi+msgpack@gmail.com').
-export([pack/1, unpack/1, unpack_all/1]).
% @type msgpack_term() = [msgpack_term()]
% | {[{msgpack_term(),msgpack_term()}]}
% | integer() | float() | binary().
% Erlang representation of msgpack data.
-type msgpack_term() :: [msgpack_term()]
| {[{msgpack_term(),msgpack_term()}]}
| integer() | float() | binary().
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% external APIs
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% @doc Encode an erlang term into an msgpack binary.
% Returns {error, {badarg, term()}} if the input is illegal.
% @spec pack(Term::msgpack_term()) -> binary() | {error, {badarg, term()}}
-spec pack(Term::msgpack_term()) -> binary() | {error, {badarg, term()}}.
pack(Term)->
try
pack_(Term)
catch
throw:Exception ->
{error, Exception}
end.
% @doc Decode an msgpack binary into an erlang term.
% It only decodes the first msgpack packet contained in the binary; the rest is returned as is.
% Returns {error, {badarg, term()}} if the input is corrupted.
% Returns {error, incomplete} if the input is not a full msgpack packet (caller should gather more data and try again).
% @spec unpack(Bin::binary()) -> {msgpack_term(), binary()} | {error, incomplete} | {error, {badarg, term()}}
-spec unpack(Bin::binary()) -> {msgpack_term(), binary()} | {error, incomplete} | {error, {badarg, term()}}.
unpack(Bin) when is_binary(Bin) ->
try
unpack_(Bin)
catch
throw:Exception ->
{error, Exception}
end;
unpack(Other) ->
{error, {badarg, Other}}.
% @doc Decode an msgpack binary into an erlang terms.
% It only decodes ALL msgpack packets contained in the binary. No packets should not remain.
% Returns {error, {badarg, term()}} if the input is corrupted.
% Returns {error, incomplete} if the input is not a full msgpack packet (caller should gather more data and try again).
% @spec unpack_all(binary()) -> [msgpack_term()] | {error, incomplete} | {error, {badarg, term()}}
-spec unpack_all(binary()) -> [msgpack_term()] | {error, incomplete} | {error, {badarg, term()}}.
unpack_all(Data)->
try
unpack_all_(Data)
catch
throw:Exception ->
{error, Exception}
end.
unpack_all_(Data)->
case unpack_(Data) of
{ Term, <<>> } ->
[Term];
{ Term, Binary } when is_binary(Binary) ->
[Term|unpack_all_(Binary)]
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% internal APIs
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% pack them all
-spec pack_(msgpack_term()) -> binary() | no_return().
pack_(I) when is_integer(I) andalso I < 0 ->
pack_int_(I);
pack_(I) when is_integer(I) ->
pack_uint_(I);
pack_(F) when is_float(F) ->
pack_double(F);
pack_(nil) ->
<< 16#C0:8 >>;
pack_(true) ->
<< 16#C3:8 >>;
pack_(false) ->
<< 16#C2:8 >>;
pack_(Bin) when is_binary(Bin) ->
pack_raw(Bin);
pack_(List) when is_list(List) ->
pack_array(List);
pack_({Map}) when is_list(Map) ->
pack_map(Map);
pack_(Other) ->
throw({badarg, Other}).
-spec pack_uint_(non_neg_integer()) -> binary().
% positive fixnum
pack_uint_(N) when N < 128 ->
<< 2#0:1, N:7 >>;
% uint 8
pack_uint_(N) when N < 256 ->
<< 16#CC:8, N:8 >>;
% uint 16
pack_uint_(N) when N < 65536 ->
<< 16#CD:8, N:16/big-unsigned-integer-unit:1 >>;
% uint 32
pack_uint_(N) when N < 16#FFFFFFFF->
<< 16#CE:8, N:32/big-unsigned-integer-unit:1 >>;
% uint 64
pack_uint_(N) ->
<< 16#CF:8, N:64/big-unsigned-integer-unit:1 >>.
-spec pack_int_(integer()) -> binary().
% negative fixnum
pack_int_(N) when N >= -32->
<< 2#111:3, N:5 >>;
% int 8
pack_int_(N) when N > -128 ->
<< 16#D0:8, N:8/big-signed-integer-unit:1 >>;
% int 16
pack_int_(N) when N > -32768 ->
<< 16#D1:8, N:16/big-signed-integer-unit:1 >>;
% int 32
pack_int_(N) when N > -16#FFFFFFFF ->
<< 16#D2:8, N:32/big-signed-integer-unit:1 >>;
% int 64
pack_int_(N) ->
<< 16#D3:8, N:64/big-signed-integer-unit:1 >>.
-spec pack_double(float()) -> binary().
% float : erlang's float is always IEEE 754 64bit format.
% pack_float(F) when is_float(F)->
% << 16#CA:8, F:32/big-float-unit:1 >>.
% pack_double(F).
% double
pack_double(F) ->
<< 16#CB:8, F:64/big-float-unit:1 >>.
-spec pack_raw(binary()) -> binary().
% raw bytes
pack_raw(Bin) ->
case byte_size(Bin) of
Len when Len < 6->
<< 2#101:3, Len:5, Bin/binary >>;
Len when Len < 16#10000 -> % 65536
<< 16#DA:8, Len:16/big-unsigned-integer-unit:1, Bin/binary >>;
Len ->
<< 16#DB:8, Len:32/big-unsigned-integer-unit:1, Bin/binary >>
end.
-spec pack_array([msgpack_term()]) -> binary() | no_return().
% list
pack_array(L) ->
case length(L) of
Len when Len < 16 ->
<< 2#1001:4, Len:4/integer-unit:1, (pack_array_(L, <<>>))/binary >>;
Len when Len < 16#10000 -> % 65536
<< 16#DC:8, Len:16/big-unsigned-integer-unit:1, (pack_array_(L, <<>>))/binary >>;
Len ->
<< 16#DD:8, Len:32/big-unsigned-integer-unit:1, (pack_array_(L, <<>>))/binary >>
end.
pack_array_([], Acc) -> Acc;
pack_array_([Head|Tail], Acc) ->
pack_array_(Tail, <<Acc/binary, (pack_(Head))/binary>>).
% Users SHOULD NOT send too long list: this uses lists:reverse/1
-spec unpack_array_(binary(), non_neg_integer(), [msgpack_term()]) -> {[msgpack_term()], binary()} | no_return().
unpack_array_(Bin, 0, Acc) -> {lists:reverse(Acc), Bin};
unpack_array_(Bin, Len, Acc) ->
{Term, Rest} = unpack_(Bin),
unpack_array_(Rest, Len-1, [Term|Acc]).
-spec pack_map(M::[{msgpack_term(),msgpack_term()}]) -> binary() | no_return().
pack_map(M)->
case length(M) of
Len when Len < 16 ->
<< 2#1000:4, Len:4/integer-unit:1, (pack_map_(M, <<>>))/binary >>;
Len when Len < 16#10000 -> % 65536
<< 16#DE:8, Len:16/big-unsigned-integer-unit:1, (pack_map_(M, <<>>))/binary >>;
Len ->
<< 16#DF:8, Len:32/big-unsigned-integer-unit:1, (pack_map_(M, <<>>))/binary >>
end.
pack_map_([], Acc) -> Acc;
pack_map_([{Key,Value}|Tail], Acc) ->
pack_map_(Tail, << Acc/binary, (pack_(Key))/binary, (pack_(Value))/binary>>).
% Users SHOULD NOT send too long list: this uses lists:reverse/1
-spec unpack_map_(binary(), non_neg_integer(), [{msgpack_term(), msgpack_term()}]) ->
{{[{msgpack_term(), msgpack_term()}]}, binary()} | no_return().
unpack_map_(Bin, 0, Acc) -> {{lists:reverse(Acc)}, Bin};
unpack_map_(Bin, Len, Acc) ->
{Key, Rest} = unpack_(Bin),
{Value, Rest2} = unpack_(Rest),
unpack_map_(Rest2, Len-1, [{Key,Value}|Acc]).
% unpack them all
-spec unpack_(Bin::binary()) -> {msgpack_term(), binary()} | no_return().
unpack_(Bin) ->
case Bin of
% ATOMS
<<16#C0, Rest/binary>> -> {nil, Rest};
<<16#C2, Rest/binary>> -> {false, Rest};
<<16#C3, Rest/binary>> -> {true, Rest};
% Floats
<<16#CA, V:32/float-unit:1, Rest/binary>> -> {V, Rest};
<<16#CB, V:64/float-unit:1, Rest/binary>> -> {V, Rest};
% Unsigned integers
<<16#CC, V:8/unsigned-integer, Rest/binary>> -> {V, Rest};
<<16#CD, V:16/big-unsigned-integer-unit:1, Rest/binary>> -> {V, Rest};
<<16#CE, V:32/big-unsigned-integer-unit:1, Rest/binary>> -> {V, Rest};
<<16#CF, V:64/big-unsigned-integer-unit:1, Rest/binary>> -> {V, Rest};
% Signed integers
<<16#D0, V:8/signed-integer, Rest/binary>> -> {V, Rest};
<<16#D1, V:16/big-signed-integer-unit:1, Rest/binary>> -> {V, Rest};
<<16#D2, V:32/big-signed-integer-unit:1, Rest/binary>> -> {V, Rest};
<<16#D3, V:64/big-signed-integer-unit:1, Rest/binary>> -> {V, Rest};
% Raw bytes
<<16#DA, L:16/unsigned-integer-unit:1, V:L/binary, Rest/binary>> -> {V, Rest};
<<16#DB, L:32/unsigned-integer-unit:1, V:L/binary, Rest/binary>> -> {V, Rest};
% Arrays
<<16#DC, L:16/big-unsigned-integer-unit:1, Rest/binary>> -> unpack_array_(Rest, L, []);
<<16#DD, L:32/big-unsigned-integer-unit:1, Rest/binary>> -> unpack_array_(Rest, L, []);
% Maps
<<16#DE, L:16/big-unsigned-integer-unit:1, Rest/binary>> -> unpack_map_(Rest, L, []);
<<16#DF, L:32/big-unsigned-integer-unit:1, Rest/binary>> -> unpack_map_(Rest, L, []);
% Tag-encoded lengths (kept last, for speed)
<<0:1, V:7, Rest/binary>> -> {V, Rest}; % positive int
<<2#111:3, V:5, Rest/binary>> -> {V - 2#100000, Rest}; % negative int
<<2#101:3, L:5, V:L/binary, Rest/binary>> -> {V, Rest}; % raw bytes
<<2#1001:4, L:4, Rest/binary>> -> unpack_array_(Rest, L, []); % array
<<2#1000:4, L:4, Rest/binary>> -> unpack_map_(Rest, L, []); % map
% Invalid data
<<F, R/binary>> when F==16#C1;
F==16#C4; F==16#C5; F==16#C6; F==16#C7; F==16#C8; F==16#C9;
F==16#D4; F==16#D5; F==16#D6; F==16#D7; F==16#D8; F==16#D9 ->
throw({badarg, <<F, R/binary>>});
% Incomplete data (we've covered every complete/invalid case; anything left is incomplete)
_ ->
throw(incomplete)
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% unit tests
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-include_lib("eunit/include/eunit.hrl").
-ifdef(EUNIT).
compare_all([], [])-> ok;
compare_all([], R)-> {toomuchrhs, R};
compare_all(L, [])-> {toomuchlhs, L};
compare_all([LH|LTL], [RH|RTL]) ->
?assertEqual(LH, RH),
compare_all(LTL, RTL).
port_receive(Port) ->
port_receive(Port, <<>>).
port_receive(Port, Acc) ->
receive
{Port, {data, Data}} -> port_receive(Port, <<Acc/binary, Data/binary>>);
{Port, eof} -> Acc
after 1000 -> Acc
end.
test_([]) -> 0;
test_([Term|Rest])->
Pack = msgpack:pack(Term),
?assertEqual({Term, <<>>}, msgpack:unpack( Pack )),
1+test_(Rest).
test_data()->
[true, false, nil,
0, 1, 2, 123, 512, 1230, 678908, 16#FFFFFFFFFF,
-1, -23, -512, -1230, -567898, -16#FFFFFFFFFF,
123.123, -234.4355, 1.0e-34, 1.0e64,
[23, 234, 0.23],
<<"hogehoge">>, <<"243546rf7g68h798j", 0, 23, 255>>,
<<"hoasfdafdas][">>,
[0,42, <<"sum">>, [1,2]], [1,42, nil, [3]],
-234, -40000, -16#10000000, -16#100000000,
42
].
basic_test()->
Tests = test_data(),
Passed = test_(Tests),
Passed = length(Tests).
port_test()->
Tests = test_data(),
?assertEqual({[Tests],<<>>}, msgpack:unpack(msgpack:pack([Tests]))),
Port = open_port({spawn, "ruby ../test/crosslang.rb"}, [binary, eof]),
true = port_command(Port, msgpack:pack(Tests)),
?assertEqual({Tests, <<>>}, msgpack:unpack(port_receive(Port))),
port_close(Port).
test_p(Len,Term,OrigBin,Len) ->
{Term, <<>>}=msgpack:unpack(OrigBin);
test_p(I,_,OrigBin,Len) when I < Len->
<<Bin:I/binary, _/binary>> = OrigBin,
?assertEqual({error,incomplete}, msgpack:unpack(Bin)).
partial_test()-> % error handling test.
Term = lists:seq(0, 45),
Bin=msgpack:pack(Term),
BinLen = byte_size(Bin),
[test_p(X, Term, Bin, BinLen) || X <- lists:seq(0,BinLen)].
long_test()->
Longer = lists:seq(0, 655),
{Longer, <<>>} = msgpack:unpack(msgpack:pack(Longer)).
map_test()->
Ints = lists:seq(0, 65),
Map = {[ {X, X*2} || X <- Ints ] ++ [{<<"hage">>, 324}, {43542, [nil, true, false]}]},
{Map2, <<>>} = msgpack:unpack(msgpack:pack(Map)),
?assertEqual(Map, Map2),
ok.
unknown_test()->
Port = open_port({spawn, "ruby testcase_generator.rb"}, [binary, eof]),
Tests = [0, 1, 2, 123, 512, 1230, 678908,
-1, -23, -512, -1230, -567898,
<<"hogehoge">>, <<"243546rf7g68h798j">>,
123.123,
-234.4355, 1.0e-34, 1.0e64,
[23, 234, 0.23],
[0,42,<<"sum">>, [1,2]], [1,42, nil, [3]],
{[{1,2},{<<"hoge">>,nil}]}, % map
-234, -50000,
42
],
?assertEqual(ok, compare_all(Tests, msgpack:unpack_all(port_receive(Port)))),
port_close(Port).
other_test()->
?assertEqual({error,incomplete},msgpack:unpack(<<>>)).
benchmark_test()->
Data=[test_data() || _ <- lists:seq(0, 10000)],
S=?debugTime(" serialize", msgpack:pack(Data)),
{Data,<<>>}=?debugTime("deserialize", msgpack:unpack(S)),
?debugFmt("for ~p KB test data.", [byte_size(S) div 1024]).
error_test()->
?assertEqual({error,{badarg, atom}}, msgpack:pack(atom)),
Term = {"hoge", "hage", atom},
?assertEqual({error,{badarg, Term}}, msgpack:pack(Term)).
-endif.

Some files were not shown because too many files have changed in this diff Show more