- Notifications
You must be signed in to change notification settings - Fork1
Experimental library for messagepack support in fortran
License
synthfi/fortran-messagepack
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Library forMessagePack support in fortran.
| Build System | Targets | Known Working Versions |
|---|---|---|
| Meson | messagepack | 1.3.2 |
| CMake | messagepack | 3.28.3 |
| FPM | . | 0.10.1, alpha |
Known to work withgfortran 13.3.0 and above.
- Fortran 2008
- OOP utilized heavily
program test use messagepack use iso_fortran_envimplicit none ! buffer filled with MsgPackdata byte, allocatable,dimension(:):: buffer ! base class usedto interact with MsgPack class(mp_value_type), allocatable:: mp_value ! object usedto store various settings class(msgpack), allocatable:: mpinteger:: unpacked_value mp= msgpack()call mp%unpack(buffer, mp_value)if (mp%failed())then ! insert error handling herestop1end ifif (is_int(mp_value))thencall get_int(mp_value, unpacked_value, error)write(*,*)"Unpacked:", unpacked_valueend ifend program
program test use messagepack use iso_fortran_envimplicit none ! bufferto fill with MsgPackdata byte, allocatable,dimension(:):: buffer ! object usedto store various settings class(msgpack), allocatable:: mp mp= msgpack() ! get default settings ! create an array with two elements: ! ["hello world",.false.] class(mp_arr_type), allocatable:: mp_arr mp_arr= mp_arr_type(2_int64) mp_arr%value(1)%obj= mp_str_type("hello world") mp_arr%value(2)%obj= mp_bool_type(.false.) ! pack the value into a dynamically allocated arraycall mp%pack_alloc(buffer, mp_deserialized)if (mp%failed())then ! insert error handling herestop1end if !print the messagepack objectin a pretty waycall mp%print_value(mp_deserialized) deallocate(buffer) deallocate(mp_deserialized)end program
All MsgPack classes extend frommp_value_type. Container types utilizemp_value_type_ptr as a wrapper around the polymorphic type.
type:: mp_value_type_ptr class(mp_value_type), allocatable:: objend type
Themp_value_type contains the following type-bound procedures:
| Procedure | Applies To | Functionality |
|---|---|---|
| numelements | mp_arr_type,mp_map_type,mp_ext_type | Returns number of contained elements. For the map it returns the number of pairs. For non-containers, returns 1 |
| getsize | All | Returns number of bytes taken up by the object |
| pack | All | Internal use only |
A class calledmsgpack handles all unpacking & packing procedures. It also handles custom user extensions and configurable error handling.
Most commonly used functions:
subroutinepack_alloc(this,mpv,buffer) ! Packs a messagepack object into a dynamically ! allocated buffer, returnedto the user. The user ! must handle deallocation. ! @param[in] this- self ! @param[in] mpv- messagepack valueto pack ! @param[out] buffer-contains serializeddataendsubroutinesubroutinepack_prealloc(this,mpv,buffer) ! Packs a messagepack object into a pre-allocated buffer, ! returnedto the user. This function does not check beforehand ! for the array being the correct size, and willreturn an error !if the buffer is too small. ! @param[in] this- self ! @param[in] mpv- messagepack valueto pack ! @param[out] buffer- existing bufferto placedata intoendsubroutinesubroutineunpack(this,buffer,mpv) ! @param[in] this- self ! @param[in] buffer- serialized messagepackdata ! @param[out] mpv- Deserialized valueendsubroutinesubroutineprint_value(this,obj) ! Prints MessagePack object with default options ! @param[in] this- instance ! @param[in] obj- MessagePack objecttoprint ...endsubroutinerecursivesubroutineprint_value_with_args(this,obj,indentation,&sameline,maxelems) ! Prints MessagePack object with a variety of configurability ! @param[in] this- instance ! @param[in] obj- MessagePack objecttoprintin a pretty fashion ! @param[in] indentation- number of levels of indentationtoprint with ! @param[in] sameline-if true, compacts the output ! @param[in] maxelems-if non-negative, limits number of elements printed ! @returns Noneendsubroutinesubroutineprint_version() ! prints version of messagepack
The library exposes the following global subroutines:
subroutineprint_bytes_as_hex(bytes,addhexmark) ! prints a buffer of bytes as the unsigned hex version ! @param[in] bytes- byte buffertoprint ! @param[in] addhexmark-If true,print with0x prepended ! @returns noneendsubroutine
TLDR: please run the tests associated with this library on your system to ensure that this library will work correctly.
Fortran does not support unsigned integers. This library assumes that signed integers are represented with twos-bit complement.
The user must be aware that MessagePack can represent integers larger than what signed 64 bit integers can represent. This is the largest size of integer that the library supports due to portability concerns.fortran-messagepack does recognize this, please see the documentation in theInteger format family on how to deal with this.
MessagePack explicitly does not specify a character encoding.
Fortran does not supply a built in hash table/hash map/red-black tree/etc datatype. Themp_map_type is represented simply as two arrays under the hood, and does not perform key uniqueness checks.
The underlying support class ismp_nil_type.
functionis_nil(obj) result(res)! @returns whether the object is `mp_nil_type`
The underlying support class ismp_int_type.
functionis_int(obj) result(res)! @returns whether the object is a `mp_int_type`subroutineget_int(obj,val,stat)! @param[out] val-integerto store decoded value! @param[out] stat- Returns falseif the object is not `mp_int_type`
If an integer is unpacked that is greater than what a signed 64 bit integer can represent, a special flag will be marked which can be checked for with theis_unsigned function. The library leaves further processing of the value up to the user.
logicalfunctionis_unsigned(obj) ! trueif the value is unsignedsubroutineset_unsigned(obj) ! mark that the stored value is unsigned
The underlying support class ismp_float_type.
functionis_float(obj) result(res)! @returns whether the object is a `mp_float_type`subroutineget_real(obj,val,stat)! @param[out] val- real64to store decoded value! @param[out] stat- Returns falseif the object is not `mp_float_type`
The underlying support class ismp_str_type.
functionis_str(obj) result(res)! @returns whether the object is a `mp_str_type`subroutineget_str(obj,val,stat)! @param[out] val-character(:), allocatable! @param[out] stat- Returns falseif the object is not `mp_str_type`
The underlying support class ismp_bin_type.
The constructor of the same name accepts a length argument.
type, extends(mp_value_type):: mp_bin_type byte, allocatable,dimension(:):: value ...contains ...end type
Related Functions
functionis_bin(obj) result(res)! @returns whether the object is a `mp_bin_type`subroutineget_bin(obj,val,stat)! @param[out] val- byte, allocatable,dimension(:)! @param[out] stat- Returns falseif the object is not `mp_bin_type`
The underlying support class ismp_arr_type.
The constructor of the same name accepts a length argument.
type, extends(mp_value_type):: mp_arr_type class(mp_value_type_ptr), allocatable,dimension(:):: value ...contains ...end type
Related Functions
functionis_arr(obj) result(res)! @returns whether the object is a `mp_arr_type`subroutineget_arr_ref(obj,val,stat)! Turn a generic `mp_value_type` into a `mp_arr_type`! @param[in] obj- class(mp_value_type), allocatable ! @param[out] val- class(mp_arr_type), allocatable! @param[out] stat- Returns falseif the object is not `mp_arr_type`
Example of accessing contained values
mp_arr_type:: arr_objinteger,dimension(3):: decodedlogical:: status! arr_obj is pre-populated with3 intsdo i=1,3 get_int(arr_obj%value(i)%obj, decoded(i), status)if (.not. status)then ! error handlingend ifend doprint*,"Decoded:", decoded
The length restriction of(2^32)-1 is only checked for at pack time.
The underlying support class ismp_map_type.
The constructor of the same name accepts a length argument.
type, extends(mp_value_type):: mp_map_type class(mp_value_type_ptr), allocatable,dimension(:):: keys class(mp_value_type_ptr), allocatable,dimension(:):: values ...contains ...end type
Related Functions
functionis_map(obj) result(res)! @returns whether the object is a `mp_map_type`subroutineget_map_ref(obj,val,stat)! Turn a generic `mp_value_type` into a `mp_map_type`! @param[in] obj- class(mp_value_type), allocatable ! @param[out] val- class(mp_map_type), allocatable! @param[out] stat- Returns falseif the object is not `mp_map_type`
The underlying support class ismp_ext_type.
The constructor of the same name accepts an extension type argument and length argument.
type, extends(mp_value_type):: mp_ext_typeinteger:: exttype ! extension type byte, allocatable,dimension(:):: valuescontains ...end type
Related Functions
functionis_ext(obj) result(res)! @returns whether the object is a `mp_ext_type`subroutineget_ext_ref(obj,val,stat)! Turn a generic `mp_value_type` into a `mp_ext_type`! @param[in] obj- class(mp_value_type), allocatable ! @param[out] val- class(mp_ext_type), allocatable! @param[out] stat- Returns falseif the object is not `mp_ext_type`
The underlying support class ismp_timestamp_type.
The constructor of the same name accepts a seconds & nanoseconds argument. The nanoseconds argument must be positive.
This type does not have any built datetime support. It is merely a vehicle to serialize/deserialize a unix timestamp to/from messagepack.
type, extends(mp_value_type):: mp_timestamp_typeinteger(kind=int64):: secondsinteger(kind=int64):: nanoseconds ! this must be positive ...contains ...end type
Related Functions
functionis_timestamp(obj) result(res)! @returns whether the object is a `mp_timestamp_type`subroutineget_timestamp_ref(obj,val,stat)! Turn a generic `mp_value_type` into a `mp_timestamp_type`! @param[in] obj- class(mp_value_type), allocatable ! @param[out] val- class(mp_timestamp_type), allocatable! @param[out] stat- Returns falseif the object is not `mp_timestamp_type`
Tests integrated into Meson:
| Executable Name | Purpose |
|---|---|
| constructors | Unit test of constructors. Also serves as example |
| packing | Unit testing of packing with checks on the packed buffers |
| unpacking | Unit test of unpacking with known packed buffers |
| roundtrip | Unit test of packing data, and then unpacking |
| Build System | Command |
|---|---|
| meson | meson test |
| cmake | ctest |
| fpm | fpm test |
The executables can also be executed directly.
About
Experimental library for messagepack support in fortran
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.