openinterfaces 0.5.4__tar.gz → 0.6.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/CMakeLists.txt +19 -1
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/PKG-INFO +15 -27
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/README.md +14 -26
- openinterfaces-0.6.2/cmake-build-debug/_deps/cwpack-src/LICENSE +21 -0
- openinterfaces-0.6.2/cmake-build-debug/_deps/cwpack-src/README.md +102 -0
- openinterfaces-0.6.2/cmake-build-debug/_deps/cwpack-src/example/README.md +14 -0
- openinterfaces-0.6.2/cmake-build-debug/_deps/cwpack-src/goodies/README.md +17 -0
- openinterfaces-0.6.2/cmake-build-debug/_deps/cwpack-src/goodies/basic-contexts/README.md +16 -0
- openinterfaces-0.6.2/cmake-build-debug/_deps/cwpack-src/goodies/dump/README.md +53 -0
- openinterfaces-0.6.2/cmake-build-debug/_deps/cwpack-src/goodies/numeric-extensions/README.md +21 -0
- openinterfaces-0.6.2/cmake-build-debug/_deps/cwpack-src/goodies/objC/README.md +98 -0
- openinterfaces-0.6.2/cmake-build-debug/_deps/cwpack-src/goodies/objC/obsolete/README.md +40 -0
- openinterfaces-0.6.2/cmake-build-debug/_deps/cwpack-src/goodies/swift/README.md +126 -0
- openinterfaces-0.6.2/cmake-build-debug/_deps/cwpack-src/goodies/utils/README.md +52 -0
- openinterfaces-0.6.2/cmake-build-debug/_deps/cwpack-src/src/README.md +28 -0
- openinterfaces-0.6.2/cmake-build-debug/_deps/cwpack-src/test/README.md +17 -0
- openinterfaces-0.6.2/cmake-build-debug/_deps/cwpack-subbuild/CMakeLists.txt +42 -0
- openinterfaces-0.6.2/cmake-build-debug/_deps/googletest-src/CMakeLists.txt +39 -0
- openinterfaces-0.6.2/cmake-build-debug/_deps/googletest-src/LICENSE +28 -0
- openinterfaces-0.6.2/cmake-build-debug/_deps/googletest-src/README.md +117 -0
- openinterfaces-0.6.2/cmake-build-debug/_deps/googletest-src/googlemock/CMakeLists.txt +218 -0
- openinterfaces-0.6.2/cmake-build-debug/_deps/googletest-src/googlemock/README.md +40 -0
- openinterfaces-0.6.2/cmake-build-debug/_deps/googletest-src/googlemock/docs/README.md +4 -0
- openinterfaces-0.6.2/cmake-build-debug/_deps/googletest-src/googlemock/include/gmock/internal/custom/README.md +18 -0
- openinterfaces-0.6.2/cmake-build-debug/_deps/googletest-src/googletest/CMakeLists.txt +338 -0
- openinterfaces-0.6.2/cmake-build-debug/_deps/googletest-src/googletest/README.md +217 -0
- openinterfaces-0.6.2/cmake-build-debug/_deps/googletest-src/googletest/docs/README.md +4 -0
- openinterfaces-0.6.2/cmake-build-debug/_deps/googletest-src/googletest/include/gtest/internal/custom/README.md +44 -0
- openinterfaces-0.6.2/cmake-build-debug/_deps/googletest-subbuild/CMakeLists.txt +34 -0
- openinterfaces-0.6.2/cmake-build-debug/_deps/hashmap-src/CMakeLists.txt +120 -0
- openinterfaces-0.6.2/cmake-build-debug/_deps/hashmap-src/LICENSE +21 -0
- openinterfaces-0.6.2/cmake-build-debug/_deps/hashmap-src/README.md +155 -0
- openinterfaces-0.6.2/cmake-build-debug/_deps/hashmap-src/examples/CMakeLists.txt +7 -0
- openinterfaces-0.6.2/cmake-build-debug/_deps/hashmap-src/test/CMakeLists.txt +10 -0
- openinterfaces-0.6.2/cmake-build-debug/_deps/hashmap-subbuild/CMakeLists.txt +42 -0
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/common/CMakeLists.txt +1 -1
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/common/oif_config_dict.c +31 -17
- openinterfaces-0.6.2/common/util.c +231 -0
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/dispatch/dispatch.c +87 -62
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/examples/call_ivp_from_python.py +1 -1
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/examples/call_ivp_from_python_burgers_eq.py +18 -11
- openinterfaces-0.6.2/examples/call_ivp_from_python_vdp.py +133 -0
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/examples/call_linsolve_from_python.py +5 -1
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/examples/call_qeq_from_python.py +1 -1
- openinterfaces-0.6.2/include/oif/_platform.h +30 -0
- openinterfaces-0.6.2/include/oif/_platform.h.gch +0 -0
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/include/oif/api.h +29 -3
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/include/oif/c_bindings.h +6 -4
- openinterfaces-0.6.2/include/oif/util.h +111 -0
- openinterfaces-0.6.2/lang_julia/CMakeLists.txt +22 -0
- openinterfaces-0.6.2/lang_python/CMakeLists.txt +10 -0
- openinterfaces-0.6.2/lang_python/oif/CMakeLists.txt +1 -0
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/lang_python/oif/openinterfaces/CMakeLists.txt +4 -1
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/lang_python/oif/openinterfaces/core.py +84 -20
- openinterfaces-0.6.2/lang_python/oif/openinterfaces/version.py +1 -0
- openinterfaces-0.6.2/lang_python/oif_impl/CMakeLists.txt +38 -0
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/lang_python/oif_impl/_callback.c +13 -1
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/lang_python/oif_impl/_serialization.py +7 -1
- openinterfaces-0.5.4/lang_python/oif_impl/dispatch_python.c → openinterfaces-0.6.2/lang_python/oif_impl/bridge_python.c +188 -62
- openinterfaces-0.6.2/lang_python/oif_impl/openinterfaces/CMakeLists.txt +1 -0
- openinterfaces-0.6.2/lang_python/oif_impl/openinterfaces/_impl/CMakeLists.txt +14 -0
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/lang_python/oif_impl/openinterfaces/_impl/ivp/scipy_ode/scipy_ode.py +2 -2
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/lang_python/oif_impl/openinterfaces/_impl/linsolve/numpy/linsolve.py +2 -0
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/lang_python/oif_impl/openinterfaces/callback.py +5 -1
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/pyproject.toml +1 -1
- openinterfaces-0.6.2/tests/CMakeLists.txt +27 -0
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/tests/lang_c/CMakeLists.txt +15 -6
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/tests/lang_python/test_ivp.py +65 -10
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/tests/lang_python/test_linsolve.py +12 -1
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/tests/lang_python/test_qeq.py +12 -1
- openinterfaces-0.5.4/common/util.c +0 -55
- openinterfaces-0.5.4/examples/call_ivp_from_python_vdp.py +0 -114
- openinterfaces-0.5.4/include/oif/_platform.h +0 -14
- openinterfaces-0.5.4/include/oif/util.h +0 -43
- openinterfaces-0.5.4/lang_python/CMakeLists.txt +0 -2
- openinterfaces-0.5.4/lang_python/oif/CMakeLists.txt +0 -4
- openinterfaces-0.5.4/lang_python/oif/openinterfaces/version.py +0 -1
- openinterfaces-0.5.4/lang_python/oif_impl/CMakeLists.txt +0 -32
- openinterfaces-0.5.4/tests/CMakeLists.txt +0 -6
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/.pytest_cache/README.md +0 -0
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/LICENSE +0 -0
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/dispatch/CMakeLists.txt +0 -0
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/examples/compare_performance_ivp_burgers_eq.py +0 -0
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/examples/compare_performance_ivp_burgers_eq_pure_comparison.py +0 -0
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/examples/compare_performance_ivp_cvode_gray_scott.py +0 -0
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/include/oif/config_dict.h +0 -0
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/include/oif/internal/bridge_api.h +0 -0
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/include/oif/internal/dispatch.h +0 -0
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/lang_python/oif/_convert.c +0 -0
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/lang_python/oif/openinterfaces/_conversion.c +0 -0
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/lang_python/oif/openinterfaces/util.py +0 -0
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/lang_python/oif_impl/openinterfaces/_impl/interfaces/ivp.py +0 -0
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/lang_python/oif_impl/openinterfaces/_impl/interfaces/linsolve.py +0 -0
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/lang_python/oif_impl/openinterfaces/_impl/interfaces/qeq.py +0 -0
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/lang_python/oif_impl/openinterfaces/_impl/ivp/scipy_ode/scipy_ode.conf +0 -0
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/lang_python/oif_impl/openinterfaces/_impl/linsolve/numpy/numpy.conf +0 -0
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/lang_python/oif_impl/openinterfaces/_impl/qeq/py_qeq_solver/py_qeq_solver.conf +0 -0
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/lang_python/oif_impl/openinterfaces/_impl/qeq/py_qeq_solver/qeq_solver.py +0 -0
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/lang_python/oif_interfaces/openinterfaces/interfaces/ivp.py +0 -0
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/lang_python/oif_interfaces/openinterfaces/interfaces/linsolve.py +0 -0
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/lang_python/oif_interfaces/openinterfaces/interfaces/qeq.py +0 -0
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/tests/lang_python/test_util.py +0 -0
- {openinterfaces-0.5.4 → openinterfaces-0.6.2}/vendor/CMakeLists.txt +0 -0
|
@@ -3,15 +3,32 @@ cmake_minimum_required(VERSION 3.18)
|
|
|
3
3
|
project(
|
|
4
4
|
oif-toy-example
|
|
5
5
|
LANGUAGES C CXX
|
|
6
|
-
VERSION 0.
|
|
6
|
+
VERSION 0.6.2)
|
|
7
|
+
|
|
8
|
+
option(OIF_OPTION_VERBOSE_DEBUG_INFO
|
|
9
|
+
"Enable verbose debug info in Debug builds" OFF)
|
|
10
|
+
|
|
11
|
+
option(OIF_OPTION_SANITIZE "Enable sanitizers in Debug builds" OFF)
|
|
7
12
|
|
|
8
13
|
# Enforce using `-std=c11`, without any extensions like `gnu11`.
|
|
9
14
|
set(CMAKE_C_STANDARD 11)
|
|
10
15
|
set(CMAKE_C_STANDARD_REQUIRED ON)
|
|
11
16
|
|
|
17
|
+
# Enforce using `-std=c++11`, without any extensions like `gnu++11`.
|
|
18
|
+
set(CMAKE_CXX_STANDARD 11)
|
|
19
|
+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
20
|
+
set(CMAKE_CXX_EXTENSIONS OFF)
|
|
21
|
+
|
|
12
22
|
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|
13
23
|
message("Disable optimizations for Debug build type")
|
|
14
24
|
string(PREPEND CMAKE_C_FLAGS_DEBUG "-O0 ")
|
|
25
|
+
if(OIF_OPTION_VERBOSE_DEBUG_INFO)
|
|
26
|
+
add_compile_definitions(OIF_OPTION_VERBOSE_DEBUG_INFO)
|
|
27
|
+
endif()
|
|
28
|
+
if(OIF_OPTION_SANITIZE)
|
|
29
|
+
add_compile_options(-fno-omit-frame-pointer -fsanitize=address)
|
|
30
|
+
add_link_options(-fno-omit-frame-pointer -fsanitize=address)
|
|
31
|
+
endif()
|
|
15
32
|
endif()
|
|
16
33
|
|
|
17
34
|
# Incorporate additions by X/Open 7, that includes POSIX 17 additions and allow
|
|
@@ -43,6 +60,7 @@ add_subdirectory(vendor)
|
|
|
43
60
|
add_subdirectory(common)
|
|
44
61
|
add_subdirectory(dispatch)
|
|
45
62
|
|
|
63
|
+
add_subdirectory(lang_julia)
|
|
46
64
|
add_subdirectory(lang_python)
|
|
47
65
|
|
|
48
66
|
if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/oif")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openinterfaces
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.2
|
|
4
4
|
Summary: Open Interfaces for improving Interoperability in Scientific Computing
|
|
5
5
|
Author-Email: "Dmitry I. Kabanov" <dmitry.kabanov@uni-muenster.de>, Stephan Rave <stephan.rave@uni-muenster.de>, Mario Ohlberger <mario.ohlberger@uni-muenster.de>
|
|
6
6
|
License-File: LICENSE
|
|
@@ -54,38 +54,26 @@ marshalling between different languages and a set of interfaces for typical
|
|
|
54
54
|
numerical problems such as integration of differential equations and
|
|
55
55
|
optimization.
|
|
56
56
|
|
|
57
|
+
| Traditional pairwise bindings-----| | Decoupled bindings via _Open Interfaces_ |
|
|
58
|
+
|:----------------------------------|---|-----------------------------------------:|
|
|
59
|
+
|  | |  |
|
|
60
|
+
|
|
57
61
|
This project is the part of the [_Mathematical Research Data Initiative
|
|
58
62
|
(MaRDI)_](https://mardi4nfdi.de).
|
|
59
63
|
|
|
60
|
-
##
|
|
61
|
-
|
|
62
|
-

|
|
63
|
-
|
|
64
|
-
This figure shows the software architecture of the _MaRDI Open Interfaces_.
|
|
65
|
-
There are two principal decoupled parts. The left part is user-facing
|
|
66
|
-
and allows a user to request an implementation of some numerical procedure
|
|
67
|
-
and then invoke different functions in this implementation to conduct
|
|
68
|
-
computations using a unified interface (Gateway)
|
|
69
|
-
that hides discrepancies between different implementations.
|
|
70
|
-
The other part (on the right) is completely hidden from the user
|
|
71
|
-
and works with an implementation of the interface.
|
|
72
|
-
Particularly, it loads the implementation and its adapter and converts
|
|
73
|
-
user data to the native data for the implementation.
|
|
74
|
-
|
|
75
|
-
## Installation of Python bindings and implementations
|
|
64
|
+
## Installation and Documentation
|
|
76
65
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
pip install openinterfaces
|
|
82
|
-
```
|
|
66
|
+
Please refer to the documentation at
|
|
67
|
+
<https://mardi4nfdi.github.io/open-interfaces/>
|
|
68
|
+
for deeper view on the goals and implementation details
|
|
69
|
+
as well as installation instructions, tutorials, and API reference.
|
|
83
70
|
|
|
84
|
-
##
|
|
71
|
+
## Support and Contact
|
|
85
72
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
73
|
+
_MaRDI Open Interfaces_ is an open source academic project.
|
|
74
|
+
Please use the
|
|
75
|
+
[issue tracker](https://github.com/MaRDI4NFDI/open-interfaces/issues)
|
|
76
|
+
for bug reports and feature requests and asking questions.
|
|
89
77
|
|
|
90
78
|
|
|
91
79
|
## Funding
|
|
@@ -25,38 +25,26 @@ marshalling between different languages and a set of interfaces for typical
|
|
|
25
25
|
numerical problems such as integration of differential equations and
|
|
26
26
|
optimization.
|
|
27
27
|
|
|
28
|
+
| Traditional pairwise bindings-----| | Decoupled bindings via _Open Interfaces_ |
|
|
29
|
+
|:----------------------------------|---|-----------------------------------------:|
|
|
30
|
+
|  | |  |
|
|
31
|
+
|
|
28
32
|
This project is the part of the [_Mathematical Research Data Initiative
|
|
29
33
|
(MaRDI)_](https://mardi4nfdi.de).
|
|
30
34
|
|
|
31
|
-
##
|
|
32
|
-
|
|
33
|
-

|
|
34
|
-
|
|
35
|
-
This figure shows the software architecture of the _MaRDI Open Interfaces_.
|
|
36
|
-
There are two principal decoupled parts. The left part is user-facing
|
|
37
|
-
and allows a user to request an implementation of some numerical procedure
|
|
38
|
-
and then invoke different functions in this implementation to conduct
|
|
39
|
-
computations using a unified interface (Gateway)
|
|
40
|
-
that hides discrepancies between different implementations.
|
|
41
|
-
The other part (on the right) is completely hidden from the user
|
|
42
|
-
and works with an implementation of the interface.
|
|
43
|
-
Particularly, it loads the implementation and its adapter and converts
|
|
44
|
-
user data to the native data for the implementation.
|
|
45
|
-
|
|
46
|
-
## Installation of Python bindings and implementations
|
|
35
|
+
## Installation and Documentation
|
|
47
36
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
pip install openinterfaces
|
|
53
|
-
```
|
|
37
|
+
Please refer to the documentation at
|
|
38
|
+
<https://mardi4nfdi.github.io/open-interfaces/>
|
|
39
|
+
for deeper view on the goals and implementation details
|
|
40
|
+
as well as installation instructions, tutorials, and API reference.
|
|
54
41
|
|
|
55
|
-
##
|
|
42
|
+
## Support and Contact
|
|
56
43
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
44
|
+
_MaRDI Open Interfaces_ is an open source academic project.
|
|
45
|
+
Please use the
|
|
46
|
+
[issue tracker](https://github.com/MaRDI4NFDI/open-interfaces/issues)
|
|
47
|
+
for bug reports and feature requests and asking questions.
|
|
60
48
|
|
|
61
49
|
|
|
62
50
|
## Funding
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2017 Claes Wihlborg
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# CWPack
|
|
2
|
+
|
|
3
|
+
CWPack is a lightweight and yet complete implementation of the
|
|
4
|
+
[MessagePack](http://msgpack.org) serialization format
|
|
5
|
+
[version 5](https://github.com/msgpack/msgpack/blob/master/spec.md).
|
|
6
|
+
It also supports the Timestamp extension type.
|
|
7
|
+
|
|
8
|
+
## Excellent Performance
|
|
9
|
+
|
|
10
|
+
Together with [MPack](https://github.com/ludocode/mpack), CWPack is the fastest open-source messagepack implementation. Both totally outperform
|
|
11
|
+
[CMP](https://github.com/camgunz/cmp) and [msgpack-c](https://github.com/msgpack/msgpack-c)
|
|
12
|
+
|
|
13
|
+
## Design
|
|
14
|
+
|
|
15
|
+
CWPack does no memory allocations and no file handling in its basic setup. All that is done outside of CWPack. Example extensions are included.
|
|
16
|
+
|
|
17
|
+
CWPack is working against memory buffers. User defined handlers are called when buffers are filled up (packing) or needs refill (unpack).
|
|
18
|
+
|
|
19
|
+
Containers (arrays, maps) are read/written in parts, first the item containing the size and then the contained items one by one. Exception to this is the `cw_skip_items` function which skip whole containers.
|
|
20
|
+
|
|
21
|
+
## Example
|
|
22
|
+
|
|
23
|
+
Pack and unpack example from the MessagePack home page:
|
|
24
|
+
|
|
25
|
+
```c
|
|
26
|
+
void example (void)
|
|
27
|
+
{
|
|
28
|
+
cw_pack_context pc;
|
|
29
|
+
char buffer[20];
|
|
30
|
+
cw_pack_context_init (&pc, buffer, 20, 0);
|
|
31
|
+
|
|
32
|
+
cw_pack_map_size (&pc, 2);
|
|
33
|
+
cw_pack_str (&pc, "compact", 7);
|
|
34
|
+
cw_pack_boolean (&pc, true);
|
|
35
|
+
cw_pack_str (&pc, "schema", 6);
|
|
36
|
+
cw_pack_unsigned (&pc, 0);
|
|
37
|
+
|
|
38
|
+
if (pc.return_code != CWP_RC_OK) ERROR;
|
|
39
|
+
int length = pc.current - pc.start;
|
|
40
|
+
if (length != 18) ERROR;
|
|
41
|
+
|
|
42
|
+
cw_unpack_context uc;
|
|
43
|
+
cw_unpack_context_init (&uc, pc.start, length, 0);
|
|
44
|
+
|
|
45
|
+
if (cw_unpack_next_map_size(&uc) != 2) ERROR;
|
|
46
|
+
if (cw_unpack_next_str_lengh(&uc) != 7) ERROR;
|
|
47
|
+
if (strncmp("compact", uc.item.as.str.start, 7)) ERROR;
|
|
48
|
+
if (cw_unpack_next_boolean(&uc) != true) ERROR;
|
|
49
|
+
if (cw_unpack_next_str_lengh(&uc) != 6) ERROR;
|
|
50
|
+
if (strncmp("schema", uc.item.as.str.start, 6)) ERROR;
|
|
51
|
+
if (cw_unpack_next_signed32(&uc) != 0) ERROR;
|
|
52
|
+
|
|
53
|
+
if (uc.return_code != CWP_RC_OK) ERROR;
|
|
54
|
+
cw_unpack_next(&uc);
|
|
55
|
+
if (uc.return_code != CWP_RC_END_OF_INPUT) ERROR;
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
In the examples folder there are more examples.
|
|
60
|
+
|
|
61
|
+
## Backward compatibility
|
|
62
|
+
|
|
63
|
+
CWPack may be run in compatibility mode. It affects only packing; EXT & TIMESTAMP is considered illegal, BIN are transformed to STR and generation of STR8 is supressed.
|
|
64
|
+
|
|
65
|
+
## Error handling
|
|
66
|
+
|
|
67
|
+
When an error is detected in a context, the context is stopped and all future calls to that context are immediatly returned without any actions. Thus it is possible to make some calls and delay error checking until all calls are done.
|
|
68
|
+
|
|
69
|
+
CWPack does not check for illegal values (e.g. in STR for illegal unicode characters).
|
|
70
|
+
|
|
71
|
+
## Build
|
|
72
|
+
|
|
73
|
+
CWPack consists of a single src file and three header files. It is written in strict ansi C and the files are together ~ 1.4K lines. No separate build is neccesary, just include the files in your own build.
|
|
74
|
+
|
|
75
|
+
CWPack has no dependencies to other libraries.
|
|
76
|
+
|
|
77
|
+
## Test
|
|
78
|
+
|
|
79
|
+
Included in the test folder are a module test and a performance test and shell scripts to run them.
|
|
80
|
+
|
|
81
|
+
# Objective-C
|
|
82
|
+
|
|
83
|
+
CWPack also contains an Objective-C interface. The MessagePack home page example would look like:
|
|
84
|
+
|
|
85
|
+
```C
|
|
86
|
+
CWPackContext *pc = [CWPackContext newWithContext:my_cw_pack_context];
|
|
87
|
+
[pc packObject:@{@"compact":@YES, @"schema":@0}];
|
|
88
|
+
|
|
89
|
+
CWUnpackContext *uc = [CWUnpackContext newWithContext:my_cw_unpack_context];
|
|
90
|
+
NSDictionary *dict = [uc unpackNextObject];
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
# Swift
|
|
94
|
+
|
|
95
|
+
CWPack also contains a Swift interface. The MessagePack home page example would pack like:
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
let packer = CWDataPacker()
|
|
99
|
+
packer + DictionaryHeader(2) + "compact" + true + "schema" + 0
|
|
100
|
+
let data = packer.data
|
|
101
|
+
|
|
102
|
+
```
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# CWPack / Example
|
|
2
|
+
|
|
3
|
+
The example contains a program that takes a json file and converts it to a messagePack file, then converts the latter back to json.
|
|
4
|
+
|
|
5
|
+
In the script runExample.sh the 2 json files are also diffed.
|
|
6
|
+
|
|
7
|
+
The files `item.*` contains a memory tree representation of json data and the conversion routines:
|
|
8
|
+
|
|
9
|
+
- Item Tree To Json File
|
|
10
|
+
- Item Tree To MessagePack File
|
|
11
|
+
- Json File To Item Tree
|
|
12
|
+
- MessagePack File To Item Tree
|
|
13
|
+
|
|
14
|
+
The conversion routines are just examples and not of production quality.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# CWPack / Goodies
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
Goodies contains the following:
|
|
5
|
+
|
|
6
|
+
**basic_contexts** has contexts for dynamic memory contexts and a set of file contexts.
|
|
7
|
+
|
|
8
|
+
**dump** presents a msgpack file in human readable form.
|
|
9
|
+
|
|
10
|
+
**numeric_extensions** use when your Ext data is integer or real.
|
|
11
|
+
|
|
12
|
+
**objC** Objective-C wrapper.
|
|
13
|
+
|
|
14
|
+
**swift** Swift wrapper.
|
|
15
|
+
|
|
16
|
+
**utils** convenience calls and expect api for CWPack.
|
|
17
|
+
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# CWPack / Goodies / Basic Contexts
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
Basic contexts contains 5 contexts that meet most demands:
|
|
5
|
+
|
|
6
|
+
- **Dynamic Memory Pack Context** is used when you want to pack to a malloc´d memory buffer. At buffer overflow the context handler tries to reallocate the buffer to a larger size.
|
|
7
|
+
|
|
8
|
+
- **Stream Pack Context** is used when you pack to a C stream. At buffer overflow the context handler writes the buffer out and then reuses it. If an item is larger than the buffer, the handler tries to reallocate the buffer so the item would fit.
|
|
9
|
+
|
|
10
|
+
- **Stream Unpack Context** is used when you unpack from a C stream. As with Stream Pack Context, the handler asserts that an item will always fit in the buffer.
|
|
11
|
+
|
|
12
|
+
- **File Pack Context** is used when you pack to a file descriptor. At buffer overflow the context handler writes the buffer out and then reuses it. However, if the barrier is active, the subsequent content is kept in the buffer. If an item is larger than the buffer, the handler tries to reallocate the buffer so the item would fit.
|
|
13
|
+
|
|
14
|
+
- **File Unpack Context** is used when you unpack from a file descriptor. If the barrier is active, the subsequent content is always kept in buffer. The handler asserts that an item will always fit in the buffer.
|
|
15
|
+
|
|
16
|
+
With the stream/file contexts, it is assumed that the stream/file has been opened before the context is initialized. Before a packed stream/file is closed, the corresponding terminate context should be called so the last buffer is saved.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# CWPack / Goodies / Dump
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
Dump is a small program taking a msgpack file as input and produces a human readable file as output. The output is not json as msgpack is more feature-rich.
|
|
5
|
+
|
|
6
|
+
Syntax:
|
|
7
|
+
cwpack_dump [-t 9] [-v][-r] [-h] < msgpackFile > humanReadableFile
|
|
8
|
+
-t 9 Tab size
|
|
9
|
+
-v Version
|
|
10
|
+
-r Recognize records
|
|
11
|
+
-h Help
|
|
12
|
+
|
|
13
|
+
Each topmost msgpack item in the file starts on a new line. Each line starts with a file offset (hex) of the first item on the line.
|
|
14
|
+
If Tab size isn't given, structures are written on a single line.
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
`cwpack_dump < testdump.msgpack` prints:
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
0 [10000000 3.14 "åäöÅÄÖ"]
|
|
21
|
+
1c {"binary": <62696e617279> "extension": (-5,<68656c6c6f>) "time": '2020-05-20 18:40:00'}
|
|
22
|
+
49
|
|
23
|
+
```
|
|
24
|
+
and `cwpack_dump -t 4 < testdump.msgpack` prints:
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
0 [
|
|
28
|
+
1 10000000
|
|
29
|
+
6 3.14
|
|
30
|
+
f "åäöÅÄÖ"
|
|
31
|
+
1c ]
|
|
32
|
+
1c {
|
|
33
|
+
1d "binary": <62696e617279>
|
|
34
|
+
2c "extension": (-5,<68656c6c6f>)
|
|
35
|
+
3e "time": '2020-05-20 18:40:00'
|
|
36
|
+
49 }
|
|
37
|
+
49
|
|
38
|
+
```
|
|
39
|
+
The -r option makes dump recognize Objective-C objects. `cwpack_dump < testdump2.msgpack` prints:
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
0 [(127,<ff>) [[(127,<ff>)]]]
|
|
43
|
+
9 [(127,<01>) "MyClass" 10 [(127,<02>) "MyClass" 20 [(127,<01>)]]]
|
|
44
|
+
27
|
|
45
|
+
```
|
|
46
|
+
and `cwpack_dump -r < testdump2.msgpack` prints
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
0 -1->[->-1]
|
|
50
|
+
9 1->MyClass(10 2->MyClass(20 ->1))
|
|
51
|
+
27
|
|
52
|
+
```
|
|
53
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# CWPack / Goodies / Numeric Extensions
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
Numeric Extensions solves the byte order problem when the value of an extension item is a numeric entity. It uses the same byte order as `cw_pack_signed` and `cw_pack_double`.
|
|
5
|
+
|
|
6
|
+
## Pack
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
void cw_pack_ext_integer (cw_pack_context* pack_context, int8_t type, int64_t i);
|
|
10
|
+
void cw_pack_ext_float (cw_pack_context* pack_context, int8_t type, float f);
|
|
11
|
+
void cw_pack_ext_double (cw_pack_context* pack_context, int8_t type, double d);
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Unpack
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
int64_t get_ext_integer (cw_unpack_context* unpack_context);
|
|
18
|
+
float get_ext_float (cw_unpack_context* unpack_context);
|
|
19
|
+
double get_ext_double (cw_unpack_context* unpack_context);
|
|
20
|
+
```
|
|
21
|
+
The `get_ext_...` functions assume that the user first has done a successful `cw_unpack_next` call. They return error if the unpacked item isn't an ext item or if the item has wrong length.
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# CWPack / Goodies / ObjC
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
ObjC contains a pack and an unpack context to enable Objective-C objects in the MessagePack stream. The implementation also has the capability to keep the references between objects.
|
|
5
|
+
|
|
6
|
+
## Contexts
|
|
7
|
+
|
|
8
|
+
ObjC contains 2 contexts `CWPackContext` and `CWPUnpackContext`.
|
|
9
|
+
|
|
10
|
+
#### Pack
|
|
11
|
+
|
|
12
|
+
`CWPackContext` is layered on top of a `cw_pack_context`, which it receives at initiation.
|
|
13
|
+
The `cw_pack_context` is then accessible through the property `context`.
|
|
14
|
+
|
|
15
|
+
The other property on `CWPackContext` is the boolean property `useLabels`. It is defaulted to NO, but should be set to YES if you want references between objects to be kept. This makes the MessagePack stream more verbose so don't use it if you don't have to.
|
|
16
|
+
|
|
17
|
+
To pack an object you just call: `[myPackContext packObject:anObject]`.
|
|
18
|
+
|
|
19
|
+
#### Unpack
|
|
20
|
+
|
|
21
|
+
`CWUnpackContext` is layered on top of a `cw_unpack_context`, which it receives at initiation.
|
|
22
|
+
The `cw_unpack_context` is then accessible through the property `context`.
|
|
23
|
+
|
|
24
|
+
To retreive an object you call `[myUnpackContext unpackNextObject]`.
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
## Packable objects
|
|
28
|
+
|
|
29
|
+
When choosing if the packing should be automatic by inspection or explicit, we have chosen the latter, as it gives better control over the (un)packing, which can be important when communicating with others. For that reason, to be packable, objects need to fulfill the protocol `CWPackable`.
|
|
30
|
+
|
|
31
|
+
##### @property (readonly) int persistentAttributeCount
|
|
32
|
+
|
|
33
|
+
This is the number of MessagePack items that the description of the object take. If you have a long prefix chain you normally defines it as
|
|
34
|
+
|
|
35
|
+
```C
|
|
36
|
+
- (int) persistentAttributeCount {
|
|
37
|
+
return myAttributeCount + super.persistentAttributeCount;}
|
|
38
|
+
```
|
|
39
|
+
On the next outermost level, where NSObject is the prefix class, you must not call `super`.
|
|
40
|
+
|
|
41
|
+
##### - (void) cwPackSub:(CWPackContext*)ctx
|
|
42
|
+
|
|
43
|
+
This is the routine where you pack. Let´s take an example:
|
|
44
|
+
|
|
45
|
+
```C
|
|
46
|
+
@interface MyClass: SomeOtherClass <CWPackable>
|
|
47
|
+
@property int level;
|
|
48
|
+
@property MyClass *link;
|
|
49
|
+
- (instancetype) initWithLevel:(int)level link:(MyClass*)link;
|
|
50
|
+
@end
|
|
51
|
+
```
|
|
52
|
+
Note first, one attribute is a link to another instance, so here we should set useLabels to YES. Our pack method could be like this:
|
|
53
|
+
|
|
54
|
+
```C
|
|
55
|
+
- (void) cwPackSub:(CWPackContext*)ctx {
|
|
56
|
+
[super cwPackSub:ctx];
|
|
57
|
+
cw_pack_signed(ctx.context, level);
|
|
58
|
+
[ctx packObject:link];
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
If the immediate ancestor to MyClass is NSObject, then super must not be called.
|
|
62
|
+
|
|
63
|
+
Unpacking can be a little more tangled due to the possibility of circular references, that is a referenced object has a reference back to the root object. Unpacking happens in two steps: first the object is allocated and in the next step the attributes are set.
|
|
64
|
+
|
|
65
|
+
Step 1: Allocation & Initiating
|
|
66
|
+
|
|
67
|
+
##### - (instancetype) cwUnpackSubInit:(CWUnpackContext*)ctx remainingAttributes:(int)remainingAttributes
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
When `cwUnpackSubInit` is called, self is allocated but not inited. The sole purpose of the method is to return a suitable inited object. It is not neccesary to be the same object as self. If it is sufficient to sent init to the preallocated object (self), this method could be skipped, it's optional.
|
|
71
|
+
|
|
72
|
+
Step 2: Fetching attributes.
|
|
73
|
+
|
|
74
|
+
##### - (void) cwUnpackSub:(CWUnpackContext*)ctx remainingAttributes:(int)remainingAttributes
|
|
75
|
+
|
|
76
|
+
In the pack example an unpack method could be:
|
|
77
|
+
|
|
78
|
+
```C
|
|
79
|
+
- (void) cwUnpackSub:(CWUnpackContext*)ctx remainingAttributes:(int)remainingAttributes {
|
|
80
|
+
[super cwUnpackSub:ctx remainingAttributes:remainingAttributes - 2]
|
|
81
|
+
level = cw_unpack_next_signed32 (ctx.context);
|
|
82
|
+
link = [ctx unpackNextObject];
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
As usual, don't call super on NSObject.
|
|
86
|
+
|
|
87
|
+
### Packable system objects
|
|
88
|
+
(Un)packing of the following system classes is predefined in ObjC:
|
|
89
|
+
NSArray, NSDictionary, NSData, NSDate, NSNull, NSNumber, NSSet, NSCountableSet and NSString. In most cases they are mapped at their corresponding MessagePack item. !WARNING! MessagePack has an arbitrary type as key in map. Objective-C demands a string key in the corresponding NSDictionary.
|
|
90
|
+
|
|
91
|
+
Of those who have both mutable and immutable versions, NSData and NSString are created immutable, and NSArray, NSDictionary and NSSet are created mutable at unpack.
|
|
92
|
+
|
|
93
|
+
### Special
|
|
94
|
+
There are two special cases.
|
|
95
|
+
|
|
96
|
+
First, when the MessagePack item is of an unknown EXT type, it will be unpacked as an instance of the `CWPackExternalItem` class.
|
|
97
|
+
|
|
98
|
+
Second, when the object to be unpacked is of unknown user class, it is unpacked as an instance of the class `CWPackGenericClass`.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# CWPack / Goodies / ObjC
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
ObjC contains a wrapper for objective-C in the form of a category to NSObject.
|
|
5
|
+
The category contains two methods:
|
|
6
|
+
|
|
7
|
+
```C
|
|
8
|
+
/* *********************** P A C K *****************************/
|
|
9
|
+
- (void) packIn:(cw_pack_context*) buff;
|
|
10
|
+
|
|
11
|
+
/* *********************** U N P A C K *************************/
|
|
12
|
+
+ (instancetype) unpackFrom:(cw_unpack_context*) buff;
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
The methods are defined for the standard classes NSString, NSData, NSNumber, NSDate, NSNull, NSDictionary, NSArray and NSSet.
|
|
16
|
+
|
|
17
|
+
For other classes you need to define the methods yourself. E.g.
|
|
18
|
+
|
|
19
|
+
```C
|
|
20
|
+
@interface myClass: NSObject {
|
|
21
|
+
int theInt;
|
|
22
|
+
NSMutableSet theSet;
|
|
23
|
+
}
|
|
24
|
+
@end
|
|
25
|
+
|
|
26
|
+
@implementation myClass
|
|
27
|
+
- (void) packIn:(cw_pack_context*) buff
|
|
28
|
+
{
|
|
29
|
+
cw_pack_signed( buff, theInt );
|
|
30
|
+
[theSet packIn:buff];
|
|
31
|
+
}
|
|
32
|
+
+ (instancetype) unpackFrom:(cw_unpack_context*) buff
|
|
33
|
+
{
|
|
34
|
+
int anInt = cw_unpack_next_signed32( buff );
|
|
35
|
+
NSMutableSet aSet = [NSMutableSet unpackFrom:buff];
|
|
36
|
+
return [[self alloc] initWithInt:anInt set:aSet];
|
|
37
|
+
}
|
|
38
|
+
@end
|
|
39
|
+
```
|
|
40
|
+
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# CWPack / Goodies / Swift
|
|
2
|
+
|
|
3
|
+
This folder contains a pack and an unpack context and a packable protocol to enable Swift items in the MessagePack stream.
|
|
4
|
+
|
|
5
|
+
## Contexts
|
|
6
|
+
|
|
7
|
+
The swift interface contains 4 contexts `CWDataPacker`, `CWFilePacker`, `CWDataUnpacker` and `CWFileUnpacker`. All are layered on the corresponding c structures accessable though the property `p`.
|
|
8
|
+
|
|
9
|
+
The file packer/unpacker comes in 2 flavours, inited with an URL or with a file descriptor.
|
|
10
|
+
|
|
11
|
+
#### Pack
|
|
12
|
+
|
|
13
|
+
`CWDataPacker` is layered on top of a `dynamic_memory_pack_context` and `CWFilePacker` is layerd on top of a `file_pack_context`.
|
|
14
|
+
|
|
15
|
+
To pack an item you call: `item.cwPack(packer)`
|
|
16
|
+
|
|
17
|
+
After packing you can check the result by inspecting the packer property `OK`.
|
|
18
|
+
|
|
19
|
+
The packers have a property `optimizeReal`. When true, a check is performed to see if real items losslessly could be casted to a shorter representation, e.g. 0.0 is saved as an (1 byte) integer and Double 0.5 is saved as a Float.
|
|
20
|
+
|
|
21
|
+
#### Unpack
|
|
22
|
+
|
|
23
|
+
`CWDataUnpacker` is layered on top of a `cw_unpack_context` and
|
|
24
|
+
`CWFileUnpacker` is layered on `file_unpack_context`.
|
|
25
|
+
|
|
26
|
+
To retreive items you call the init(_ unpacker: CWUnpacker) initializer e.g:
|
|
27
|
+
`let i = Int(unpacker)` and
|
|
28
|
+
`let ar: [String] = Array(unpacker)`
|
|
29
|
+
|
|
30
|
+
If the messagepack stream doesn't contain the expected item, an exception is thrown.
|
|
31
|
+
|
|
32
|
+
Doubles accept both Float and Integer as valid values at unpack.
|
|
33
|
+
|
|
34
|
+
## Conveniance operators '+' and '-'
|
|
35
|
+
|
|
36
|
+
To simplify packing and unpacking two operators are defined for packers/unpackers. When packing you can write:
|
|
37
|
+
|
|
38
|
+
`packer + value1 + value2 ...` (think of it as adding values to the packer stream) and when unpacking you can write:
|
|
39
|
+
|
|
40
|
+
`unpacker - variable1 - variable2...`
|
|
41
|
+
|
|
42
|
+
Note however, this has limited usage in inits, as the variables are handled as `inout` parameters and if they are properties, they are considered used before assigned by the compiler.
|
|
43
|
+
|
|
44
|
+
## Packable items
|
|
45
|
+
|
|
46
|
+
When choosing if the packing should be automatic by inspection or explicit, we have chosen the latter, as it gives better control over the (un)packing, which can be important when communicating with others. For that reason, to be packable, objects need to fulfill the protocol `CWPackable`.
|
|
47
|
+
|
|
48
|
+
To fulfill the `CWPackable` protocol, an item must implement 2 methods:
|
|
49
|
+
|
|
50
|
+
- `init(_ unpacker:CWUnpacker) throws` and
|
|
51
|
+
- `cwPack(_ packer:CWPacker)`
|
|
52
|
+
|
|
53
|
+
The file CWPackable.swift contains CWPackable exstensions of some system types.
|
|
54
|
+
|
|
55
|
+
### MessagePack items
|
|
56
|
+
|
|
57
|
+
MessagePack has some types that don't have exact match in Swift. To simplify usage they are defined in CWPack.swift. They are:
|
|
58
|
+
|
|
59
|
+
- `CWNil` to be able to handle nil items.
|
|
60
|
+
- `ArrayHeader` and
|
|
61
|
+
- `DictionaryHeader` to be able to pack/unpack structures in an incremental fashion.
|
|
62
|
+
- `MsgPackExt` to handle extension types. However, the standard extension type Timestamp is mapped to Swift type Date.
|
|
63
|
+
|
|
64
|
+
## Installation
|
|
65
|
+
|
|
66
|
+
The interface is delivered as source files that you include in your project. The following source files (and corresponding header files) must be included:
|
|
67
|
+
|
|
68
|
+
- CWPack/src/cwpack.c
|
|
69
|
+
- CWPack/goodies/basic-contexts/basic_contexts.c
|
|
70
|
+
- CWPack/goodies/utils/cwpack_utils.c
|
|
71
|
+
- CWPack/goodies/swift/CWPack.swift
|
|
72
|
+
- CWPack/goodies/swift/CWPackable.swift
|
|
73
|
+
|
|
74
|
+
If you use XCode you should place this snippet in the file xxx-Bridging-Header.h
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
#include "cwpack.h"
|
|
78
|
+
#include "cwpack_utils.h"
|
|
79
|
+
#include "basic_contexts.h"
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Example
|
|
83
|
+
|
|
84
|
+
When you write pack code it's a good routine to contain struct and class properties in an array. This way it works if you in turn put those structures in other containers (Arrays and Dictionaries)
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
struct RGB {
|
|
88
|
+
let r,g,b: UInt8
|
|
89
|
+
cwPack(_ packer:CWPacker) {
|
|
90
|
+
packer + ArrayHeader(3) + r + g + b
|
|
91
|
+
}
|
|
92
|
+
init(_ unpacker:CWUnpacker) throws {
|
|
93
|
+
guard try ArrayHeader(unpacker).count == 3 else {throw some error}
|
|
94
|
+
r = try UInt8(unpacker)
|
|
95
|
+
g = try UInt8(unpacker)
|
|
96
|
+
b = try UInt8(unpacker)
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
The packing line above could also be written as:
|
|
101
|
+
`packer + [r,g,b]` with the same result.
|
|
102
|
+
|
|
103
|
+
Now you can use this struct in another struct:
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
struct palette {
|
|
107
|
+
colors: [RGB]
|
|
108
|
+
alpha: UInt8
|
|
109
|
+
cwPack(_ packer:CWPacker) {
|
|
110
|
+
packer + ArrayHeader(2) + colors + alpha
|
|
111
|
+
}
|
|
112
|
+
init(_ unpacker:CWUnpacker) throws {
|
|
113
|
+
guard try ArrayHeader(unpacker).count == 2 else {throw some error}
|
|
114
|
+
colors = try Array(unpacker)
|
|
115
|
+
alpha = try UInt8(unpacker)
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Failings
|
|
121
|
+
|
|
122
|
+
I'm sorry for this section but one has to face the facts. To be able to unpack (at least with this library), you must know the type of the next item. So if you have a definition like:
|
|
123
|
+
`var ar: [Any]`, you can't write:
|
|
124
|
+
`ar = try Array(unpacker)`
|
|
125
|
+
|
|
126
|
+
The same problem arises with subclasses. In both cases one can often solv the dilemma with incremental unpacking and intelligent lookahead of what's coming next.
|