├── .gitignore ├── .gitmodules ├── test ├── build_utils │ ├── CMakeForLibs │ └── setof_encode_uper.c ├── common │ ├── intTests.cpp │ ├── boolTests.cpp │ ├── enumTests.cpp │ ├── stringTests.cpp │ ├── definitions.asn1 │ ├── nestedTests.cpp │ ├── optionalTests.cpp │ ├── setofTests.cpp │ └── sequenceofTests.cpp └── CMakeLists.txt ├── docstyle ├── footer.html ├── header.html ├── customdoxygen.css └── doxy-boot.js ├── CMakeLists.txt ├── README.md ├── include └── asn1cpp │ ├── SequenceOf.hpp │ ├── Utils.hpp │ ├── Encoding.hpp │ ├── Getter.hpp │ ├── Setter.hpp │ ├── SetOf.hpp │ ├── Seq.hpp │ └── View.hpp ├── .ycm_extra_conf.py └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | build/ 3 | debugbuild/ 4 | html/ 5 | *.pyc 6 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "deps/asn1c"] 2 | path = deps/asn1c 3 | url = https://github.com/vlm/asn1c.git 4 | -------------------------------------------------------------------------------- /test/build_utils/CMakeForLibs: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 3.3) 2 | 3 | project (asn1lib) 4 | 5 | file(GLOB BUILD_FILES "*.c" "*.h") 6 | 7 | include_directories(${PROJECT_SOURCE_DIR}) 8 | add_library(asn1 ${BUILD_FILES}) 9 | -------------------------------------------------------------------------------- /test/build_utils/setof_encode_uper.c: -------------------------------------------------------------------------------- 1 | #include "constr_SEQUENCE_OF.h" 2 | 3 | /* This function is missing and would lead to a compilation error. 4 | * See https://github.com/vlm/asn1c/issues/42 */ 5 | 6 | asn_enc_rval_t 7 | SET_OF_encode_uper(asn_TYPE_descriptor_t *td, 8 | asn_per_constraints_t *constraints, void *sptr, 9 | asn_per_outp_t *po) 10 | { 11 | return SEQUENCE_OF_encode_uper(td, constraints, sptr, po); 12 | } 13 | -------------------------------------------------------------------------------- /docstyle/footer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 3.3) 2 | 3 | project (asn1cpp) 4 | 5 | add_definitions( 6 | -std=c++11 7 | -Wall 8 | -Wextra 9 | ) 10 | 11 | set(ASN_OPTIONS -fwide-types -gen-PER) 12 | 13 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) 14 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) 15 | 16 | # Add library directories 17 | include_directories(${PROJECT_SOURCE_DIR}/include) 18 | 19 | if (NOT DEFINED MAKE_TESTS) 20 | set(MAKE_TESTS 1) 21 | endif() 22 | 23 | # If enabled, add tests 24 | if (MAKE_TESTS) 25 | if (NOT EXISTS ${PROJECT_SOURCE_DIR}/deps/asn1c/.git) 26 | message(FATAL_ERROR "Asn1c repo not initialized, did you run 'git submodule init; git submodule update'?") 27 | endif() 28 | # Add and compile asn1c 29 | include(ExternalProject) 30 | ExternalProject_Add(asn1c 31 | SOURCE_DIR ${PROJECT_SOURCE_DIR}/deps/asn1c 32 | CONFIGURE_COMMAND ${PROJECT_SOURCE_DIR}/deps/asn1c/configure --prefix=${PROJECT_BINARY_DIR} 33 | BUILD_COMMAND ${MAKE} 34 | ) 35 | 36 | ExternalProject_Add_Step(asn1c autoreconf 37 | COMMAND autoreconf -iv 38 | WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/deps/asn1c/ 39 | DEPENDERS configure 40 | ) 41 | 42 | include(CTest) 43 | add_subdirectory (${PROJECT_SOURCE_DIR}/test) 44 | endif() 45 | -------------------------------------------------------------------------------- /test/common/intTests.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE intTests 2 | #define BOOST_TEST_DYN_LINK 3 | #define BOOST_TEST_MAIN 4 | #include 5 | 6 | #include "TestInteger.h" 7 | 8 | #include "asn1cpp/Seq.hpp" 9 | #include "asn1cpp/Getter.hpp" 10 | #include "asn1cpp/Setter.hpp" 11 | #include "asn1cpp/Encoding.hpp" 12 | 13 | BOOST_AUTO_TEST_CASE( construction ) { 14 | auto test = asn1cpp::makeSeq(TestInteger); 15 | } 16 | 17 | BOOST_AUTO_TEST_CASE( assignment ) { 18 | constexpr int value = 5; 19 | 20 | auto test = asn1cpp::makeSeq(TestInteger); 21 | 22 | asn1cpp::setField(test->integer, value); 23 | 24 | auto v = asn1cpp::getField(test->integer, int); 25 | 26 | BOOST_CHECK_EQUAL(value, v); 27 | } 28 | 29 | BOOST_AUTO_TEST_CASE( encoding ) { 30 | constexpr int value = 64; 31 | 32 | auto test = asn1cpp::makeSeq(TestInteger); 33 | 34 | asn1cpp::setField(test->integer, value); 35 | 36 | auto str = asn1cpp::ber::encode(test); 37 | auto recoveredTest = asn1cpp::ber::decode(str, TestInteger); 38 | 39 | BOOST_CHECK(recoveredTest); 40 | 41 | auto v = asn1cpp::getField(recoveredTest->integer, int); 42 | 43 | BOOST_CHECK_EQUAL(value, v); 44 | } 45 | 46 | BOOST_AUTO_TEST_CASE( copy ) { 47 | constexpr int value = 5; 48 | 49 | auto test = asn1cpp::makeSeq(TestInteger); 50 | 51 | asn1cpp::setField(test->integer, value); 52 | 53 | auto copy = asn1cpp::Seq(test); 54 | 55 | auto v = asn1cpp::getField(copy->integer, int); 56 | 57 | BOOST_CHECK_EQUAL(value, v); 58 | BOOST_CHECK_EQUAL(test, copy); 59 | } 60 | -------------------------------------------------------------------------------- /test/common/boolTests.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE boolTests 2 | #define BOOST_TEST_DYN_LINK 3 | #define BOOST_TEST_MAIN 4 | #include 5 | 6 | #include "TestBoolean.h" 7 | 8 | #include "asn1cpp/Seq.hpp" 9 | #include "asn1cpp/Getter.hpp" 10 | #include "asn1cpp/Setter.hpp" 11 | #include "asn1cpp/Encoding.hpp" 12 | 13 | BOOST_AUTO_TEST_CASE( construction ) { 14 | auto test = asn1cpp::makeSeq(TestBoolean); 15 | } 16 | 17 | BOOST_AUTO_TEST_CASE( assignment ) { 18 | constexpr bool value = true; 19 | 20 | auto test = asn1cpp::makeSeq(TestBoolean); 21 | 22 | asn1cpp::setField(test->boolean, value); 23 | 24 | auto v = asn1cpp::getField(test->boolean, bool); 25 | 26 | BOOST_CHECK_EQUAL(value, v); 27 | } 28 | 29 | BOOST_AUTO_TEST_CASE( encoding ) { 30 | constexpr bool value = true; 31 | 32 | auto test = asn1cpp::makeSeq(TestBoolean); 33 | 34 | asn1cpp::setField(test->boolean, value); 35 | 36 | auto str = asn1cpp::ber::encode(test); 37 | auto recoveredTest = asn1cpp::ber::decode(str, TestBoolean); 38 | 39 | BOOST_CHECK(recoveredTest); 40 | 41 | auto v = asn1cpp::getField(recoveredTest->boolean, bool); 42 | 43 | BOOST_CHECK_EQUAL(value, v); 44 | } 45 | 46 | BOOST_AUTO_TEST_CASE( copy ) { 47 | constexpr bool value = true; 48 | 49 | auto test = asn1cpp::makeSeq(TestBoolean); 50 | 51 | asn1cpp::setField(test->boolean, value); 52 | 53 | auto copy = asn1cpp::Seq(test); 54 | 55 | auto v = asn1cpp::getField(copy->boolean, bool); 56 | 57 | BOOST_CHECK_EQUAL(value, v); 58 | BOOST_CHECK_EQUAL(test, copy); 59 | } 60 | -------------------------------------------------------------------------------- /test/common/enumTests.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE enumTests 2 | #define BOOST_TEST_DYN_LINK 3 | #define BOOST_TEST_MAIN 4 | #include 5 | 6 | #include "TestEnum.h" 7 | 8 | #include "asn1cpp/Seq.hpp" 9 | #include "asn1cpp/Getter.hpp" 10 | #include "asn1cpp/Setter.hpp" 11 | #include "asn1cpp/Encoding.hpp" 12 | 13 | BOOST_AUTO_TEST_CASE( construction ) { 14 | auto test = asn1cpp::makeSeq(TestEnum); 15 | } 16 | 17 | BOOST_AUTO_TEST_CASE( assignment ) { 18 | constexpr TestEnumType value = TestEnumType_value0; 19 | 20 | auto test = asn1cpp::makeSeq(TestEnum); 21 | 22 | asn1cpp::setField(test->enm, value); 23 | 24 | auto v = asn1cpp::getField(test->enm, TestEnumType); 25 | 26 | BOOST_CHECK_EQUAL(value, v); 27 | } 28 | 29 | BOOST_AUTO_TEST_CASE( encoding ) { 30 | constexpr TestEnumType value = TestEnumType_value2; 31 | 32 | auto test = asn1cpp::makeSeq(TestEnum); 33 | 34 | asn1cpp::setField(test->enm, value); 35 | 36 | auto str = asn1cpp::ber::encode(test); 37 | auto recoveredTest = asn1cpp::ber::decode(str, TestEnum); 38 | 39 | BOOST_CHECK(recoveredTest); 40 | 41 | auto v = asn1cpp::getField(recoveredTest->enm, TestEnumType); 42 | 43 | BOOST_CHECK_EQUAL(value, v); 44 | } 45 | 46 | BOOST_AUTO_TEST_CASE( copy ) { 47 | constexpr TestEnumType value = TestEnumType_value1; 48 | 49 | auto test = asn1cpp::makeSeq(TestEnum); 50 | 51 | asn1cpp::setField(test->enm, value); 52 | 53 | auto copy = asn1cpp::Seq(test); 54 | 55 | auto v = asn1cpp::getField(copy->enm, TestEnumType); 56 | 57 | BOOST_CHECK_EQUAL(value, v); 58 | BOOST_CHECK_EQUAL(test, copy); 59 | } 60 | -------------------------------------------------------------------------------- /test/common/stringTests.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE stringTests 2 | #define BOOST_TEST_DYN_LINK 3 | #define BOOST_TEST_MAIN 4 | #include 5 | 6 | #include "TestPrintableString.h" 7 | 8 | #include "asn1cpp/Seq.hpp" 9 | #include "asn1cpp/Getter.hpp" 10 | #include "asn1cpp/Setter.hpp" 11 | #include "asn1cpp/Encoding.hpp" 12 | 13 | BOOST_AUTO_TEST_CASE( construction ) { 14 | auto test = asn1cpp::makeSeq(TestPrintableString); 15 | } 16 | 17 | BOOST_AUTO_TEST_CASE( assignment ) { 18 | const std::string value = "abcd"; 19 | 20 | auto test = asn1cpp::makeSeq(TestPrintableString); 21 | 22 | asn1cpp::setField(test->string, value); 23 | 24 | auto v = asn1cpp::getField(test->string, std::string); 25 | 26 | BOOST_CHECK_EQUAL(value, v); 27 | } 28 | 29 | BOOST_AUTO_TEST_CASE( encoding ) { 30 | const std::string value = "qwerty"; 31 | 32 | auto test = asn1cpp::makeSeq(TestPrintableString); 33 | 34 | asn1cpp::setField(test->string, value); 35 | 36 | auto str = asn1cpp::ber::encode(test); 37 | auto recoveredTest = asn1cpp::ber::decode(str, TestPrintableString); 38 | 39 | BOOST_CHECK(recoveredTest); 40 | 41 | auto v = asn1cpp::getField(recoveredTest->string, std::string); 42 | 43 | BOOST_CHECK_EQUAL(value, v); 44 | } 45 | 46 | BOOST_AUTO_TEST_CASE( copy ) { 47 | const std::string value = "asdfgh"; 48 | 49 | auto test = asn1cpp::makeSeq(TestPrintableString); 50 | 51 | asn1cpp::setField(test->string, value); 52 | 53 | auto copy = asn1cpp::Seq(test); 54 | 55 | auto v = asn1cpp::getField(copy->string, std::string); 56 | 57 | BOOST_CHECK_EQUAL(value, v); 58 | BOOST_CHECK_EQUAL(test, copy); 59 | } 60 | -------------------------------------------------------------------------------- /test/common/definitions.asn1: -------------------------------------------------------------------------------- 1 | TEST DEFINITIONS AUTOMATIC TAGS ::= BEGIN 2 | 3 | TestInteger ::= SEQUENCE 4 | { 5 | integer INTEGER 6 | } 7 | 8 | TestBoolean ::= SEQUENCE 9 | { 10 | boolean BOOLEAN 11 | } 12 | 13 | TestPrintableString ::= SEQUENCE 14 | { 15 | string PrintableString 16 | } 17 | 18 | TestEnumType ::= ENUMERATED 19 | { 20 | value0 (0), 21 | value1 (1), 22 | value2 (2) 23 | } 24 | 25 | TestEnum ::= SEQUENCE 26 | { 27 | enm TestEnumType 28 | } 29 | 30 | TestNested ::= SEQUENCE 31 | { 32 | nested TestInteger 33 | } 34 | 35 | TestOptional ::= SEQUENCE 36 | { 37 | integer INTEGER OPTIONAL, 38 | string PrintableString OPTIONAL, 39 | boolean BOOLEAN OPTIONAL, 40 | sequence SEQUENCE OF INTEGER OPTIONAL, 41 | nested SEQUENCE OF TestInteger OPTIONAL 42 | } 43 | 44 | TestSequenceOf ::= SEQUENCE 45 | { 46 | integer SEQUENCE OF INTEGER, 47 | string SEQUENCE OF PrintableString, 48 | boolean SEQUENCE OF BOOLEAN, 49 | nested SET OF TestInteger 50 | } 51 | 52 | -- Unfortunately even if SEQUENCE OF depends on the SET OF code, we have an 53 | -- inverse dependency since the asn1 compiler does not produce the 54 | -- SET_OF_encode_uper function, and we use the SEQUENCE OF one to fix this 55 | -- and allow compilation of the generated sources. 56 | TestSetOf ::= SEQUENCE 57 | { 58 | integer SET OF INTEGER, 59 | string SET OF PrintableString, 60 | boolean SET OF BOOLEAN, 61 | nested SET OF TestInteger 62 | } 63 | 64 | END 65 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | asn1cpp: A memory-safe C++ wrapper on top of asn1c 2 | ================================================== 3 | 4 | This project tries to create a memory-safe and easy to use modern C++ wrapper 5 | around the code generated by the [asn1c project](https://github.com/vlm/asn1c). 6 | 7 | The project is completely header-only: just include the headers in your project 8 | and you're ready to use it. 9 | 10 | Feel free to explore the `test` folder in order to see examples on how the 11 | library is used. 12 | 13 | Requirements 14 | ------------ 15 | 16 | This library only requires that you have a C++11 compliant compiler, and nothing 17 | else. 18 | 19 | Building the tests 20 | ------------------ 21 | 22 | The repository includes a series of tests. The tests are not necessary if you 23 | just wish to use the library. 24 | 25 | If you wish to build and run them, you need first to install the [Boost 26 | Test](http://www.boost.org/doc/libs/1_64_0/libs/test/doc/html/index.html) 27 | library. 28 | 29 | Then you can simply follow the following instructions from the repository's 30 | root folder: 31 | 32 | ``` 33 | git submodule init 34 | git submodule update 35 | mkdir build 36 | cd build 37 | cmake .. 38 | make 39 | ``` 40 | 41 | This will build all the tests. To run the tests, run: 42 | 43 | ``` 44 | ctest -V 45 | ``` 46 | 47 | from the `build` folder you have created. 48 | 49 | To run the tests with `valgrind`, run: 50 | 51 | ``` 52 | ctest -D ExperimentalMemCheck -V 53 | ``` 54 | 55 | Documentation 56 | ------------- 57 | 58 | The asn1cpp library is fully documented. 59 | 60 | The Doxygen documentation will export only the API of the library, so to avoid 61 | providing you with unnecessary text to read. To generate the Doxygen 62 | documentation simply run 63 | 64 | ``` 65 | doxygen 66 | ``` 67 | 68 | Within the project's folder. It will automatically create an `html` folder which 69 | contains the generated documentation. Detailed informations on the library's 70 | usage can be found under the `Related Pages` section. 71 | 72 | In order to have more information about the internals feel free to read the 73 | documentation in the code itself. This should be unnecessary in order to simply 74 | use the library, and should be needed only if you need to extend some particular 75 | functionality. 76 | -------------------------------------------------------------------------------- /docstyle/header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | $projectname: $title 15 | $title 16 | 17 | 18 | $treeview 19 | $search 20 | $mathjax 21 | 22 | $extrastylesheet 23 | 24 | 25 | 26 | 27 | 28 | 29 | 36 |
37 |
38 |
39 |
40 |
41 |
42 | 43 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 3.3) 2 | 3 | set(GEN_FOLDER ${PROJECT_BINARY_DIR}/gen) 4 | set(ASN_CMAKE ${PROJECT_SOURCE_DIR}/test/build_utils/CMakeForLibs) 5 | set(ADDITIONAL_SOURCES ${PROJECT_SOURCE_DIR}/test/build_utils/setof_encode_uper.c) 6 | 7 | function (SetupSuite SUITE) 8 | set(ASN1_FILE ${PROJECT_SOURCE_DIR}/test/${SUITE}/definitions.asn1) 9 | set(SUITE_FOLDER ${GEN_FOLDER}/${SUITE}) 10 | 11 | # Generating asn1 C files for this suite 12 | add_custom_command(OUTPUT ${SUITE_FOLDER} 13 | COMMAND rm -rf ${SUITE_FOLDER} 14 | COMMAND mkdir -p ${SUITE_FOLDER} 15 | COMMAND cd ${SUITE_FOLDER} && ${PROJECT_BINARY_DIR}/bin/asn1c ${ASN_OPTIONS} ${ASN1_FILE} 16 | COMMAND rm -f ${SUITE_FOLDER}/converter-sample.c 17 | COMMAND cp ${ADDITIONAL_SOURCES} ${SUITE_FOLDER} 18 | COMMAND cp ${ASN_CMAKE} ${SUITE_FOLDER}/CMakeLists.txt 19 | WORKING_DIRECTORY ${PROJECT_BINARY_DIR} 20 | DEPENDS asn1c ${ASN1_FILE} ${ASN_CMAKE} 21 | ) 22 | add_custom_target(gen_${SUITE} DEPENDS ${SUITE_FOLDER}) 23 | 24 | # Building library on the fly 25 | add_custom_command(OUTPUT ${SUITE_FOLDER}/build/libasn1.a 26 | COMMAND mkdir -p build 27 | COMMAND cd build && cmake .. && make 28 | WORKING_DIRECTORY ${SUITE_FOLDER} 29 | DEPENDS gen_${SUITE} 30 | ) 31 | add_custom_target(libasn1 DEPENDS ${SUITE_FOLDER}/build/libasn1.a) 32 | 33 | # Export the library so it can be used 34 | add_library(${SUITE}_lib STATIC IMPORTED GLOBAL) 35 | add_dependencies(${SUITE}_lib libasn1) 36 | set_target_properties(${SUITE}_lib PROPERTIES 37 | IMPORTED_LOCATION ${SUITE_FOLDER}/build/libasn1.a) 38 | endfunction (SetupSuite) 39 | 40 | function (AddTest SUITE TEST) 41 | set(SUITE_FOLDER ${GEN_FOLDER}/${SUITE}) 42 | set(EXE ${SUITE}_${TEST}) 43 | add_executable(${EXE}Tests ./${SUITE}/${TEST}Tests.cpp) 44 | target_link_libraries(${EXE}Tests ${SUITE}_lib ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) 45 | target_include_directories(${EXE}Tests PRIVATE ${SUITE_FOLDER}) 46 | add_test(NAME ${EXE} WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} COMMAND $) 47 | endfunction (AddTest) 48 | 49 | find_package(Boost 1.53 COMPONENTS unit_test_framework REQUIRED) 50 | include_directories(${Boost_INCLUDE_DIRS}) 51 | 52 | SetupSuite(common) 53 | AddTest(common int) 54 | AddTest(common bool) 55 | AddTest(common string) 56 | AddTest(common enum) 57 | AddTest(common optional) 58 | AddTest(common nested) 59 | AddTest(common setof) 60 | AddTest(common sequenceof) 61 | -------------------------------------------------------------------------------- /include/asn1cpp/SequenceOf.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ASN1CPP_SEQUENCEOF_HEADER_FILE 2 | #define ASN1CPP_SEQUENCEOF_HEADER_FILE 3 | 4 | #include "asn1cpp/SetOf.hpp" 5 | 6 | namespace asn1cpp { 7 | namespace sequenceof { 8 | template 9 | int getSize(const T& field) { 10 | return setof::getSize(field); 11 | } 12 | 13 | template 14 | R getterField(const T& field, int id, bool *ok = nullptr) { 15 | return setof::getterField(field, id, ok); 16 | } 17 | 18 | template 19 | Seq::type> getterSeq(const T& field, asn_TYPE_descriptor_t * def, int id, bool *ok = nullptr) { 20 | return setof::getterSeq(field, def, id, ok); 21 | } 22 | 23 | template 24 | View::type> getterView(const T& field, asn_TYPE_descriptor_t * def, int id, bool *ok = nullptr) { 25 | return setof::getterView(field, def, id, ok); 26 | } 27 | 28 | template 29 | View::type> getterView(T& field, asn_TYPE_descriptor_t * def, int id, bool *ok = nullptr) { 30 | return setof::getterView(field, def, id, ok); 31 | } 32 | 33 | template 34 | bool setterField(T & field, const V & value, int id) { 35 | return setof::setterField(field, value, id); 36 | } 37 | 38 | template 39 | bool adderElement(T & field, const V & value) { 40 | return setof::adderElement(field, value); 41 | } 42 | 43 | template 44 | bool removerElement(T & field, int id, asn_TYPE_descriptor_t * def) { 45 | if (id < 0 || id >= getSize(field)) 46 | return false; 47 | 48 | auto p = field.list.array[id]; 49 | // Note that here we use the sequence del, not the set 50 | asn_sequence_del(&field, id, 0); 51 | def->free_struct(def, p, 0); 52 | return true; 53 | } 54 | 55 | template 56 | bool removerElement(T *& field, int id, asn_TYPE_descriptor_t * def) { 57 | if (!field) return false; 58 | 59 | return removerElement(*field, id, def); 60 | } 61 | 62 | template 63 | void clearerField(T & field, asn_TYPE_descriptor_t * def) { 64 | setof::clearerField(field, def); 65 | } 66 | } 67 | } 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /test/common/nestedTests.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE nestedTests 2 | #define BOOST_TEST_DYN_LINK 3 | #define BOOST_TEST_MAIN 4 | #include 5 | 6 | #include "TestNested.h" 7 | 8 | #include "asn1cpp/Seq.hpp" 9 | #include "asn1cpp/View.hpp" 10 | #include "asn1cpp/Getter.hpp" 11 | #include "asn1cpp/Setter.hpp" 12 | #include "asn1cpp/Encoding.hpp" 13 | 14 | BOOST_AUTO_TEST_CASE( construction ) { 15 | auto test = asn1cpp::makeSeq(TestNested); 16 | } 17 | 18 | BOOST_AUTO_TEST_CASE( assignment ) { 19 | constexpr unsigned value = 98; 20 | 21 | auto test = asn1cpp::makeSeq(TestNested); 22 | 23 | asn1cpp::setField(test->nested.integer, value); 24 | 25 | auto v = asn1cpp::getField(test->nested.integer, unsigned); 26 | 27 | BOOST_CHECK_EQUAL(v, value); 28 | } 29 | 30 | BOOST_AUTO_TEST_CASE( view_assignment ) { 31 | constexpr unsigned value = 44; 32 | auto test = asn1cpp::makeSeq(TestNested); 33 | 34 | auto view = asn1cpp::getView(test->nested, TestInteger); 35 | 36 | asn1cpp::setField(view->integer, value); 37 | 38 | auto v = asn1cpp::getField(test->nested.integer, unsigned); 39 | 40 | BOOST_CHECK_EQUAL(v, value); 41 | } 42 | 43 | BOOST_AUTO_TEST_CASE( view_copy ) { 44 | constexpr unsigned value = 44; 45 | auto test = asn1cpp::makeSeq(TestNested); 46 | 47 | auto view = asn1cpp::getView(test->nested, TestInteger); 48 | 49 | asn1cpp::setField(view->integer, value); 50 | 51 | auto copy = asn1cpp::Seq(view); 52 | 53 | auto v = asn1cpp::getField(copy->integer, unsigned); 54 | 55 | BOOST_CHECK_EQUAL(v, value); 56 | BOOST_CHECK_EQUAL(view, copy); 57 | } 58 | 59 | BOOST_AUTO_TEST_CASE( view_const ) { 60 | constexpr unsigned value = 44; 61 | auto test = asn1cpp::makeSeq(TestNested); 62 | asn1cpp::setField(test->nested.integer, value); 63 | 64 | asn1cpp::View view = asn1cpp::getView(test->nested, TestInteger); 65 | 66 | auto testValue = asn1cpp::getField(test->nested.integer, unsigned); 67 | auto viewValue = asn1cpp::getField(view->integer, unsigned); 68 | 69 | BOOST_CHECK_EQUAL(testValue, viewValue); 70 | 71 | const auto const_view = asn1cpp::getView(test->nested, TestInteger); 72 | asn1cpp::View internal_const_view = const_view; 73 | 74 | auto v1 = asn1cpp::getField(const_view->integer, unsigned); 75 | auto v2 = asn1cpp::getField(internal_const_view->integer, unsigned); 76 | 77 | BOOST_CHECK_EQUAL(testValue, v1); 78 | BOOST_CHECK_EQUAL(v1, v2); 79 | } 80 | 81 | BOOST_AUTO_TEST_CASE( to_view_assignment ) { 82 | constexpr unsigned value = 897; 83 | auto test = asn1cpp::makeSeq(TestNested); 84 | 85 | auto view = asn1cpp::getView(test->nested, TestInteger); 86 | 87 | asn1cpp::setField(view->integer, value); 88 | 89 | auto v = asn1cpp::getField(test->nested.integer, unsigned); 90 | 91 | BOOST_CHECK_EQUAL(v, value); 92 | 93 | constexpr unsigned otherValue = 777; 94 | auto other = asn1cpp::makeSeq(TestInteger); 95 | asn1cpp::setField(other->integer, otherValue); 96 | 97 | view = other; 98 | auto vv = asn1cpp::getField(test->nested.integer, unsigned); 99 | auto otherv = asn1cpp::getField(other->integer, unsigned); 100 | 101 | BOOST_CHECK_EQUAL(vv, otherValue); 102 | BOOST_CHECK_EQUAL(otherv, otherValue); 103 | } 104 | 105 | BOOST_AUTO_TEST_CASE( encoding ) { 106 | constexpr unsigned value = 98; 107 | auto test = asn1cpp::makeSeq(TestNested); 108 | 109 | asn1cpp::setField(test->nested.integer, value); 110 | 111 | auto str = asn1cpp::ber::encode(test); 112 | auto recoveredTest = asn1cpp::ber::decode(str, TestNested); 113 | 114 | BOOST_CHECK_EQUAL(test, recoveredTest); 115 | } 116 | -------------------------------------------------------------------------------- /include/asn1cpp/Utils.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ASN1CPP_UTILS_HEADER_FILE 2 | #define ASN1CPP_UTILS_HEADER_FILE 3 | 4 | #include 5 | 6 | #include "asn_application.h" 7 | 8 | // This macro is used in order to be able to access an asn1c struct definition 9 | // just by the type name. 10 | #define ASN1CPP_ASN1C_DEF(T) asn_DEF_##T 11 | 12 | namespace asn1cpp { 13 | /** 14 | * @brief This struct represents whether a particular class fulfills our asn1c wrapped interface. 15 | * 16 | * This is used in order to enable template constructors from classes that 17 | * fulfill the asn1c wrapped interface we use in this library. 18 | * 19 | * Note that simply implementing the interface is not a guarantee that 20 | * everything will work right: if your interface breaks any invariants we 21 | * assume it will break (for example, we assume that getTypeDescriptor() 22 | * never returns nullptr). 23 | */ 24 | template 25 | struct is_asn1_wrapper { 26 | enum { value = false }; 27 | }; 28 | 29 | template