--- /dev/null
+PROJECT(asn1)
+
+SET(ASN1_VERSION_MAJOR 1)
+SET(ASN1_VERSION_MINOR 0)
+SET(ASN1_VERSION_PATCH 2)
+SET(ASN1_VERSION "${ASN1_VERSION_MAJOR}.${ASN1_VERSION_MINOR}.${ASN1_VERSION_PATCH}")
+
+OPTION(WITH_CMIP "Build Asn1 CMIP test directory" OFF)
+OPTION(WITH_CSTA "Build Asn1 CSTA v2 test directory" ON)
+OPTION(WITH_CSTAV1 "Build Asn1 CSTA v1 test directory" ON)
+OPTION(WITH_GSM "Build Asn1 GSM test directory" ON)
+OPTION(WITH_H323 "Build Asn1 H323 test directory" ON)
+OPTION(WITH_ASN1_GEN_UML "Build UML Code Generator library" OFF)
+OPTION(WITH_ASN1_GEN_JS "Build Javascript Code Generator library" ON)
+OPTION(WITH_ASN1_GEN_CPP "Build C++ Code Generator library" ON)
+OPTION(WITH_ASN1_GEN_LDS "Build Lds Code Generator library" OFF)
+
+IF(CMAKE_CROSSCOMPILING)
+ SET(IMPORT_EXECUTABLES "IMPORTFILE-NOTFOUND" CACHE FILEPATH "Point to the
+ export file from native build")
+ INCLUDE(${IMPORT_EXECUTABLES})
+ENDIF(CMAKE_CROSSCOMPILING)
+
+IF (NOT CMAKE_BUILD_TYPE)
+ SET(CMAKE_BUILD_TYPE Debug)
+ENDIF(NOT CMAKE_BUILD_TYPE)
+
+ADD_DEFINITIONS(-DBUILD_VERSION=\"${ASN1_VERSION}\")
+ADD_DEFINITIONS(-DBUILD_TYPE=\"${CMAKE_BUILD_TYPE}\")
+# Only for Linux not MAC
+IF(APPLE)
+ SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG ")
+ELSEIF(WIN32)
+ SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG ")
+ELSE(APPLE)
+ SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG -std=c++0x")
+ SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++0x")
+ENDIF(APPLE)
+
+#
+# Set VARIABLES used by subdirs
+# eg: fltk, cppunit, expat, pcap, winpcap
+
+#
+# Libraries first. Process sub dirs
+#
+IF(NOT CMAKE_CROSSCOMPILING)
+SUBDIRS(rtasn1 adt libparser libgen tests pkix cstav1 ledger csta gsm h323 megaco h248
+ cmip)
+ELSE(NOT CMAKE_CROSSCOMPILING)
+SUBDIRS(rtasn1 pkix cstav1 ledger csta gsm h323 megaco h248)
+ENDIF(NOT CMAKE_CROSSCOMPILING)
+
+INCLUDE(${rules_SOURCE_DIR}/flex.cmake)
+
+IF(NOT WIN32)
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__FILENAME__='\"$(subst ${CMAKE_CURRENT_SOURCE_DIR}/,,$<)\"'")
+ENDIF(NOT WIN32)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/libgen)
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/adt)
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+INCLUDE_DIRECTORIES(${aebutils_SOURCE_DIR})
+
+#
+# MAC specific addon files for target
+#
+IF(APPLE)
+ SET(ASN1PADDONS
+ ${CMAKE_CURRENT_SOURCE_DIR}/../Resources/squarelogo.jpg
+ ${CMAKE_CURRENT_SOURCE_DIR}/../Resources/cstainsight.icns
+ )
+ELSE(APPLE)
+ SET(ASN1PADDONS "")
+ENDIF(APPLE)
+#
+# EXECUTALBE
+#
+IF (NOT CMAKE_CROSSCOMPILING)
+
+ ADD_EXECUTABLE(asn1p
+ main.cpp
+ ${ASN1PADDONS}
+ )
+ IF (WIN32)
+ SET_TARGET_PROPERTIES(asn1p PROPERTIES LINK_FLAGS_DEBUG "/SUBSYSTEM:console")
+ SET_TARGET_PROPERTIES(asn1p PROPERTIES COMPILE_DEFINITIONS_DEBUG "_CONSOLE")
+ SET_TARGET_PROPERTIES(asn1p PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:console")
+ SET_TARGET_PROPERTIES(asn1p PROPERTIES COMPILE_DEFINITIONS_RELEASE "_CONSOLE")
+ ENDIF(WIN32)
+ MESSAGE("Export Executables to ${CMAKE_BINARY_DIR}")
+ EXPORT(TARGETS asn1p FILE ${CMAKE_BINARY_DIR}/ImportExecutables.cmake
+ NAMESPACE native-)
+ TARGET_LINK_LIBRARIES(asn1p asn1adt libgen libasn1p)
+ENDIF(NOT CMAKE_CROSSCOMPILING)
+
+#
+# Cross compiling ...
+#
+IF(CMAKE_CROSSCOMPILING)
+ SET(asn1p_EXE native-asn1p)
+ GET_TARGET_PROPERTY(test ${asn1p_EXE} IMPORTED_LOCATION_DEBUG)
+ SET(asn1p_EXE ${test})
+ELSE(CMAKE_CROSSCOMPILING)
+ SET(asn1p_EXE ${CMAKE_CURRENT_BINARY_DIR}/asn1p)
+ENDIF(CMAKE_CROSSCOMPILING)
+
+#
+# Install Stuff
+#
+IF(APPLE)
+ ADD_EXECUTABLE(Smartasn1
+ main.cpp
+ ${ASN1PADDONS}
+ )
+ TARGET_LINK_LIBRARIES(Smartasn1 asn1adt libgen libasn1p)
+
+ SET(MACOSX_RESOURCE_FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/../Resources/cstainsight.icns
+ )
+ SET_TARGET_PROPERTIES(Smartasn1 PROPERTIES
+ MACOSX_BUNDLE TRUE
+ MACOSX_BUNDLE_STARTUP_COMMAND betfan.sh
+ MACOSX_BUNDLE_BUNDLE_NAME ${PROJECT_NAME}
+ MACOSX_BUNDLE_BUNDLE_VERSION ${ASN1_VERSION}
+ MACOSX_BUNDLE_LONG_VERSION_STRING "${ASN1_VERSION}"
+ MACOSX_BUNDLE_SHORT_VERSION_STRING "${ASN1_VERSION}"
+ MACOSX_BUNDLE_GUI_IDENTIFIER "fr.ebersold.Smartasn1"
+ # MACOSX_BUNDLE_ICON_FILE "betfan.icns"
+ MACOSX_BUNDLE_ICON_FILE "cstainsight.icns"
+ )
+ SET_SOURCE_FILES_PROPERTIES(
+ ${CMAKE_CURRENT_SOURCE_DIR}/../Resources/squarelogo.icns
+ PROPERTIES MACOSX_PACKAGE_LOCATION Resources
+ )
+ SET_SOURCE_FILES_PROPERTIES(
+ ${CMAKE_CURRENT_SOURCE_DIR}/../Resources/cstainsight.icns
+ PROPERTIES MACOSX_PACKAGE_LOCATION Resources
+ )
+ SET(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_BINARY_DIR})
+ SET(APPS "\$ENV{DESTDIR}/Smartasn1.app")
+ SET(DIRS "")
+ENDIF(APPLE)
+IF(WIN32)
+ SET_TARGET_PROPERTIES(asn1p PROPERTIES WIN32_EXECUTABLE TRUE)
+ENDIF(WIN32)
+
+IF (NOT CMAKE_CROSSCOMPILING)
+ IF(APPLE)
+ INSTALL(TARGETS Smartasn1
+ BUNDLE DESTINATION .
+ COMPONENT Asn1
+ RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin/
+ LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/
+ )
+ INSTALL(TARGETS asn1p
+ COMPONENT Asn1
+ DESTINATION Smartasn1.app/Contents/bin/
+ RUNTIME DESTINATION Smartasn1.app/Contents/bin/
+ LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/
+ )
+
+ #INSTALL(CODE "
+ # include(BundleUtilities)
+ # fixup_bundle(\"${APP}\" \"\" \"${DIRS}\")
+ # " COMPONENT Asn1)
+ ELSE(APPLE)
+ #
+ # Unix Install
+ #
+ INSTALL(TARGETS asn1p
+ COMPONENT Asn1
+ DESTINATION bin/)
+ ENDIF(APPLE)
+ENDIF(NOT CMAKE_CROSSCOMPILING)
+
+
--- /dev/null
+2012/01/27 : Solve the issue with type identifier
+2012/01/27 : Solve the issue with parameterized types
+
+SIGNED{ToBeSigned} ::= SEQUENCE {
+ tobeSigned ToBeSigned;
+}
+
+2012/07/27 : Codec for Enum is needed specificaly when there is an explicit
+tag
+2012/07/27 : ANY IDENTIFY BY See If I can replace it by something else.
+
+2012/07/27 : Choice should have set/get operation as inline. Default
+constructors for each choice. !!! might be an issue when several choices have
+the same type.
+
+2012/07/31 : ObjectSet code generation is missing
+2012/07/31 : Constraint management, for sized elements
+2012/07/31 : Better support for Optional values in codec
+2012/07/31 : asn1::error class / codes for error management in codec
+2012/07/31 : Log results in file, Logger class
+
+2012/08/01 : Tags in attributes for sequence
+2012/08/01 : Tags in attributes for choice
+2012/08/01 : Tags in attributes for set
+
+2012/08/13 : Decoders have a problem with [0] IMPLICIT BOOLEAN. The issue is
+linked to tag checks.
+
+2014/10/02 : Size of csta_insight has increased 7934911 to 8662504
+8662504
+7934911
+8810664 2017/04/28
+8175720 2017/07/21
+8115936 2017/07/28
+
+2014/11/02 : First version of cstav1 with optional and new choice.
+ - URGENT printf of new choice.
+ - remove attributes from choice.
+ - remplace code in choice_codec
+ - review the way to initialize defaults. New Constructor prototype ?
+ - review decode of optionnal. Maybe destroy existing value if one.
+ - Write tests : SEQUENCE OF, SEQUENCE with defaults that are tagged.
+ - purge traces in parser (generator.cpp) all std::cout should be put under log
+ - add log traces filter at generation level. (DEBUG_CTOR, DEBUG_CODEC, DEBUG_COMMENT)
+ * a flag that will remove all comments from source code.
+ * a flag that will remove debug traces
+ * a flag that will even remove ERROR traces.
+ - ENUMRATED, put implementation in cpp file.
+ - BIT_STRING, if there is a size contraint, I should use it.
+
+ 2014/11/18: ASN1 spec 2008
+ --------------------------
+ Take into account the news introduced in X.680 2008 there are changes
+ -> new reserved keywords : DATE / DATE-TIME / DURATION / ENCODING-CONTROL /
+ INSTRUCTIONS / NOT-A-NUMBER / OID-IRI / RELATIVE-OID-IRI / SETTINGS / TIME /
+ TIME-OF-DAY
+ new tags:
+ TIME tag UNIVERSAL 14
+ DATE tag UNIVERSAL 31
+ TIME-OF-DAY tag 32
+ DATE-TIME tag UNIVERSAL 33
+ DURATION tag UNIVERSAL 34
+
+ add ENCODING-CONTROL part
+ in definition, rule encoding_instruction_defaults
+
+2015/08/19:
+-----------
+Move files abstract datatypes to adt directory and make a library out of it.
+create a new version 2 for asn1.l asn1.y to use common project of parser.
+
+Also solve asn1p issues with gsm and H323
+-------------
+
+Generaration of CODE SEQUENCE_OF<primitivetype>
+ leads to duplicate codecs
+
+Generation of CODEC for private CHOICE in sequence
+ missing codec for private choice
+
+Issue with CODEC generation with SEQUENCE OF SEQUENCE
+
+2016/01/20:
+-----------
+ - Finalize helper generator for cpp et hpp
+ - Finalize flatten option. or unested code generation.
+ - Add prefix option
+ - Add namespace option
+ - Put all asn1 file and definition name in a file to allow the parser to resolve imports.
+ - OER encoded needs to be added.
+ - Solve issue with duplicated name types in nested environments specially in h248.
+ - Issue with BIT_STRING primitive class. should not be an array needs to be rewritten
+ - Rework handling of reference generation as I got a better understanding
+ - Add a resolver class in adt. The purpose is to find the type for a given reference.
+ - Better handling of struct name assignment
+ - BIT STRING types are not defined in header. compilation of gsm fails
+
+2016/04/06:
+-----------
+ - Fixed parsing objects and checking against class
+ - Fixed nested issue
+ - Fixed SELECTION TYPE
+ - Fixed COMPONENTS OF for sequence / set. Missing one check
+ - Fixed Duplicate Types in h248
+ - Fixed encoding for object classes
+ - Fixed resolver added in adt.
+ - Fixed ROS syntax with parameter generation. Missing Init of object sets
+
+2017/01/10:
+-----------
+ - remove begin / end for all calls where it is not required
+ - handling of values to be aligned. valuetype class should be used. Clarify
+ valuetype and value class !!! seems to have the same purpose
+
+2017/04/28:
+-----------
+ - Fixed H323 generation. Compiles again ... Was broken during source reworking
+ - Improved Asn1 Object data types to facilitate parsing and understanding.
+ - Better distinction in generator between actual parameter and parameter.
+ - Optimizer, Added processing of SELECTION Type
+ - Reworked Codec classes .... added dummy per and oer codecs. Seems to be promissing
+ - Tests have still 5 failures.
+ - DONE move asn1 folder to rtasn1 meaning : asn1 runtime to avoid confusion with root
+ directory.
+ - In choice, add parameter handling for Types like Invoke...
+
+2017/05/14:
+-----------
+ - make a clear separation between typenodes and assignments
+ * move m_reference and its API from node to typeref
+ * move m_type and its API from node to assignment and field
+ * remove node iterator, and introduce assignement iterator and field iterator
+
+2017/06/20:
+-----------
+ - TODO For typeref add methods like get_canonical() return the primivite type
+ - TODO For typeref add get_prev_typeref which will return preview declaration. It's useful
+ to build tag list chaine.
+ - TODO For typeref also add method get_prev_typenode()
+ - TODO Before optimization, I should built the type map and resolve the references.
+ this would save me a lot of time during processing where is often use lookup
+ - TODO Attribute-ASN1Module uses class typeref. I do not generate code for this type :-(
+
+2018/05/19:
+-----------
+
+Generator | BER | BER | JER | OER | PER | XER | ctors | print | equal |Â copy
+cpp/Type | Old | Codec | Codec | Codec | Codec | | | | |
+
+Typeref | | 30% | 40% | | | | | | |
+BOOLEAN | 100% | 50% | 50% | 20% | | | DONE |Â DONE |Â DONE |Â DONE
+INTEGER | 70% | 30% | 30% | 20% | 20% | | | | |
+ENUMERATED | 70% | 30% | 30% | 20% | 20% | | | | |
+NULL | 100% | 20% | 50% | 20% | 20% | | | | |
+REAL | 5% | | 20% | | | | | | |
+OCTET_STRING | 80% | 30% | 40% | 20% | 20% | | | | |
+BIT_STRING | 70% | 20% | 30% | 20% | 20% | | | | |
+SEQUENCE | 60% | 20% | 40% | | | | | | |
+SET | 50% | | 0% | | | | | | |
+CHOICE | 70% | 20% | 30% | | | | | | |
+SEQUENCE OF | 60% | 20% | 40% | 20% | 20% | | | | |
+SET OF | 60% | 20% | 20% | 20% | | | | | |
+CLASSDEF | 60% | | 0% | | | | | | |
+OBJECT | 60% | | 0% | | | | | | |
+OID | 60% | 20% | 20% | 20% | | | | | |
+ROID | 0% | | 0% | | | | | | |
+TIME | 0% | | 0% | | | | | | |
+TIME-OF-DAY | 0% | | 0% | | | | | | |
+GeneralizeUTC | 0% | | 0% | | | | | | |
+DATA-TIME | 0% | | 0% | | | | | | |
+DURATION | 0% | | 0% | | | | | | |
+STRING | 60% | | 20% | | | | | | |
+EXTERNAL | 0% | | 0% | | | | | | |
+EMBEDDED-PDV | 0% | | 0% | | | | | | |
+
+ - TODO JER start decoding implementation.
+ - TODO move encode/decode BER to BER codec way. Goal : remove Old BER style.
+ - TODO update helpers to be more unified. encode/decode into generate_ber
+ - TODO set/sequence equal
+ - TODO BIT_STRING or ENUMERATED with constraint in SEQUENCE or SET should lead to a new type!
+ - TODO disable default ber in generator.
+ - TODO improve ber generation so that switch --codecs will work. Either codec or embeded enc/dec
+ - TODO I think there is a constrcutor missing with OID. ASN1 speficitation use a lot of OID value
+ - TODO Provide allocator class to allocate asn1 objects. Might be easier with codec.
--- /dev/null
+PROJECT(libasn1adt)
+
+ADD_LIBRARY(asn1adt
+ asn1_node.cpp
+ asn1_node_typenode.cpp
+ asn1_node_sequence.cpp
+ asn1_node_choice.cpp
+ asn1_node_classdef.cpp
+ asn1_node_object.cpp
+ asn1_node_parameters.cpp
+ asn1_node_assignment.cpp
+ asn1_node_constructed.cpp
+ asn1_node_field.cpp
+ asn1_node_typeref.cpp
+ asn1_node_primitive.cpp
+ asn1_node_imports.cpp
+ asn1_constraint.cpp
+ asn1_value.cpp
+ asn1_resolver.cpp
+ asn1_reference.cpp
+ asn1_node_valuetype.cpp
+ asn1_module.cpp
+ )
+
--- /dev/null
+#include <iostream>
+#include <string>
+#include <sstream>
+#include <list>
+#include <vector>
+
+#include "asn1_value.h"
+#include "asn1_constraint.h"
+#include "asn1_node.h"
+
+namespace asn1 {
+
+std::string
+constraint::name()
+{
+ std::ostringstream os;
+ switch(type())
+ {
+ case asn1::constraint::EL_TYPE: /* T (contained subtype ) */
+ os<<" type("<<m_value->name();
+ os<<")";
+ break;
+ case asn1::constraint::EL_VALUE: /* 123, "X" (elementary value) */
+ os<<" value("<<m_value->name();
+ os<<")";
+ break;
+ case asn1::constraint::EL_RANGE: /* 1..5 (basic range) */
+ case asn1::constraint::EL_LLRANGE: /* 1<..3 */
+ case asn1::constraint::EL_RLRANGE: /* 1..<4 */
+ case asn1::constraint:: EL_ULRANGE: /* 1<..<3 (basic range) */
+ {
+ asn1::constraint_range *cr = as_constraint_range();
+ os<<" range(";
+ if (cr && cr->get_min())
+ {
+ os<<cr->get_min()->name();
+ os<<" .."<<cr->get_max()->name();
+ }
+ os<<")";
+ }
+ break;
+ case asn1::constraint::EL_EXT: /* ... (extensible mark) */
+ os<<" extensible ";
+ break;
+
+ /*Constraint type */
+ case asn1::constraint::CT_SIZE:
+ os<<" !!! size(";
+ if ((! m_elements.empty()) && m_elements.front() != NULL)
+ os<<((m_elements.front()))->name();
+ os<<")";
+ break;
+ case asn1::constraint::CT_FROM:
+ default:
+ os<<" constraint not handled "<<type();
+ };
+
+ return os.str();
+}
+
+/**
+ *
+ */
+std::string
+constraint_type::name()
+{
+ std::ostringstream os;
+ switch(type())
+ {
+ case asn1::constraint::CT_SIZE:
+ os<<" size(";
+ if ( (! m_elements.empty()) && (m_elements.front() != NULL))
+ os<<((m_elements.front()))->name();
+ os<<")";
+ break;
+ case asn1::constraint::CT_FROM:
+ os<<"from ";
+ if (m_elements.front() != NULL)
+ os<<((m_elements.front()))->name()<<" ";
+ break;
+ case asn1::constraint::CT_WCOMP:
+ {
+ os<<"with component ";
+ iterator it = m_elements.begin();
+ os<<(*it)->name();
+ }
+ break;
+ case asn1::constraint::CT_WCOMPS:
+ {
+ os<<"with components ";
+ for (iterator it = m_elements.begin()
+ ; it != m_elements.end()
+ ; ++it)
+ os<<" "<<(*it)->name()<<" ";
+ }
+ break;
+ case asn1::constraint::CT_CTDBY:
+ os<<"constrained by ";
+ if (m_value)
+ os<<m_value->name();
+ break;
+ case asn1::constraint::CT_CTNG:
+ os<<"constaining ";
+ if (m_value)
+ os<<m_value->name();
+ break;
+ default:
+ os<<" constraint not handled ";
+ }
+ return os.str();
+}
+
+std::string
+constraint_array::name()
+{
+ std::ostringstream os;
+ switch(type())
+ {
+ case asn1::constraint::CA_SET:
+ os<<"set ";
+ for (iterator it = m_elements.begin()
+ ; it != m_elements.end()
+ ; ++it)
+ os<<"("<<(*it)->name()<<")";
+ os<<"";
+ break;
+ case asn1::constraint::CA_CRC:
+ {
+ os<<"crc ";
+ iterator it = m_elements.begin();
+ os<<"{"<<(*it)->name()<<"}";
+ ++it;
+ os<<"{@ ? "<<(*it)->name()<<"}";
+ }
+ break;
+ case asn1::constraint::CA_CSV:
+ os<<"csv";
+ break;
+ case asn1::constraint::CA_UNI:
+ os<<"union";
+ break;
+ case asn1::constraint::CA_INT:
+ os<<"intersection";
+ break;
+ case asn1::constraint::CA_EXC:
+ os<<"except";
+ break;
+ case asn1::constraint::CA_AEX:
+ {
+ os<<"all except ";
+ iterator it = m_elements.begin();
+ os<<(*it)->name();
+ }
+ break;
+
+ default:
+ os<<"array constraint";
+ }
+ return os.str();
+}
+
+asn1::constraint_type *
+constraint::as_constraint_type()
+{
+ return dynamic_cast<asn1::constraint_type *>(this);
+}
+
+asn1::constraint_element *
+constraint::as_constraint_element()
+{
+ return dynamic_cast<asn1::constraint_element *>(this);
+}
+
+
+asn1::ctype_size *
+constraint::as_constraint_size()
+{
+ return dynamic_cast<asn1::ctype_size *>(this);
+}
+
+
+/**
+ * constraint_element
+ */
+
+asn1::valuetype *
+constraint_element::get_valuetype() const
+{
+ return (m_value?m_value->as_value_type():NULL);
+}
+
+
+/**
+ * celt_type specificities
+ */
+celt_type::celt_type(asn1::typeref *t)
+ : constraint_element(EL_TYPE)
+{
+ value(t) ;
+}
+
+//
+asn1::typeref *
+celt_type::get_type() const
+{
+ return value()->as_typeref();
+}
+
+/**
+ * ctype_size object type
+ * subelement constraint is either value or range.
+ * range is of type constraint_range
+ * value is of type constraint_element or
+ */
+asn1::celt_value *
+ctype_size::get_value() const
+{
+ asn1::constraint_element *subelem = (*m_elements.begin())->as_constraint_element();
+ return (subelem?subelem->as_celt_value():NULL);
+}
+
+asn1::constraint_range*
+ctype_size::get_range() const
+{
+ asn1::constraint_element *subelem = (*m_elements.begin())->as_constraint_element();
+ return (subelem?subelem->as_constraint_range():NULL);
+}
+
+/**
+ *
+ */
+constraint_range *
+constraint::as_constraint_range()
+{
+ return dynamic_cast<asn1::constraint_range *>(this);
+}
+
+#define ELEMENT_CONSTRAINT(elt,cls,parent) \
+cls * \
+constraint::as_##cls() \
+{ \
+ return dynamic_cast<asn1::cls *>(this); \
+}
+
+#include "asn1_constraint.inc"
+
+/**
+ * constraint_range code
+ */
+
+constraint_range::constraint_range(types_type t,asn1::node *_min,asn1::node *_max)
+ : m_min(_min),m_max(_max),constraint_element(t)
+{
+}
+
+constraint_range::~constraint_range()
+{
+}
+
+
+void
+constraint_range::set_min(asn1::node *s)
+{
+ m_min = s;
+ //m_elements.push_back(new constraint("value",s,EL_VALUE));
+}
+
+void
+constraint_range::set_max(asn1::node *s)
+{
+ m_max = s;
+ //m_elements.push_back(new constraint("value",s,EL_VALUE));
+}
+
+void
+constraint_range::set_min_max(asn1::node *_min,asn1::node *_max )
+{
+ m_min = _min;
+ m_max = _max;
+}
+
+bool
+constraint_range::get_min_max(long &min,long &max)
+{
+ asn1::valuetype *_min_type = (m_min != NULL)?m_min->as_value_type(): NULL;
+ asn1::valuetype *_max_type = (m_max != NULL)?m_max->as_value_type(): NULL;
+ min = (_min_type)?_min_type->value_long():0;
+ max = (_max_type)?_max_type->value_long():0;
+ return ( (_min_type != NULL) && ( _max_type != NULL));
+}
+
+
+}
--- /dev/null
+#ifndef ASN1_CONSTRAINT_H__
+#define ASN1_CONSTRAINT_H__
+
+namespace asn1 {
+class node;
+class typeref;
+class valuetype;
+class constraint_element;
+class constraint_range;
+class constraint_type;
+class ctype_size;
+class ctype_from;
+
+#define ELEMENT_CONSTRAINT(elt,cls,parent) \
+ class cls ;
+
+#include "asn1_constraint.inc"
+
+class constraint
+{
+ public:
+
+ typedef std::list<constraint *> contraints;
+
+ typedef contraints::iterator iterator;
+ typedef contraints::const_iterator const_iterator;
+
+ typedef enum {
+ EL_INVALID,
+ /* Element type */
+ EL_TYPE, /* T (contained subtype ) */
+ EL_VALUE, /* 123, "X" (elementary value) */
+ EL_RANGE, /* 1..5 (basic range) */
+ EL_LLRANGE, /* 1<..3 */
+ EL_RLRANGE, /* 1..<4 */
+ EL_ULRANGE, /* 1<..<3 (basic range) */
+ EL_ENCODEDBY, /* encoded by type */
+ EL_EXT, /* ... (extensible mark) */
+
+ /*Constraint type */
+ CT_SIZE, /* SIZE Constraint type */
+ CT_FROM, /* */
+ CT_WCOMP, /* WITH COMPONENT */
+ CT_WCOMPS, /* WITH COMPONENTS*/
+ CT_CTDBY, /* CONSTRAINED BY */
+ CT_CTNG, /* CONTAINING */
+ /* Array Constraints */
+ CA_SET, /* A set of constraints: (c1)(c2) */
+ CA_CRC, /* Comp. relation c-t: ({a}{@b}) */
+ CA_CSV, /* Comma-separated constraints array */
+ CA_UNI, /* UNION (|) */
+ CA_INT, /* INTERSECTION (^) */
+ CA_EXC, /* EXCEPT */
+ CA_AEX /* ALL EXCEPT */
+ } types_type;
+
+ inline bool is_constraint_array() { return m_type>= CA_SET && m_type <= CA_AEX ; }
+ inline bool is_constraint_type() { return m_type>= CT_SIZE && m_type <= CT_CTNG ; }
+ inline bool is_constraint_elem() { return m_type>= EL_TYPE && m_type <= EL_EXT ; }
+
+ typedef enum {
+ DEFAULT,
+ PRESENT,
+ ABSENT,
+ OPTIONAL_
+ } presence_type;
+
+ constraint(const char *name,types_type t = EL_INVALID) :m_type(t),m_value(NULL) {}
+ constraint(const char *name,asn1::node *n,types_type t = EL_INVALID) :m_type(t),m_value(n) {}
+ constraint(const constraint &c) : m_type(c.m_type),m_value(c.m_value) {};
+ ~constraint() {};
+
+ virtual std::string name();
+ /* Avoid using iterator. Not all constraints use containers */
+ iterator begin() {return m_elements.begin();}
+ const_iterator begin() const {return m_elements.begin();}
+ iterator end() {return m_elements.end();}
+ const_iterator end() const {return m_elements.end();}
+
+ void append(constraint *c) {m_elements.push_back(c);};
+
+ /* Value associated with the constraint */
+ inline void value(asn1::node *n) {m_value = n;};
+
+ inline asn1::node* value() const {return m_value;};
+
+ inline void presence(presence_type p) {m_presence = p;};
+
+ inline size_t size() const { return m_elements.size();};
+ /* Cast opertors */
+ constraint_type *as_constraint_type();
+ constraint_element *as_constraint_element();
+ constraint_range *as_constraint_range() ;
+ ctype_size *as_constraint_size() ;
+
+#define ELEMENT_CONSTRAINT(elt,cls,parent) \
+ cls *as_##cls() ;
+#include "asn1_constraint.inc"
+
+ // Type of constraint
+ inline types_type type() const {return m_type;};
+ inline void type(types_type t) {m_type = t;};
+ protected:
+ contraints m_elements;
+ asn1::node *m_value;
+ types_type m_type;
+ presence_type m_presence;
+};
+
+
+/**
+ *
+ */
+class constraint_element : public constraint
+{
+ public:
+ constraint_element(types_type t) :constraint("ELEMENT",t) {} ;
+ ~constraint_element() {};
+ /**
+ * valuetype is asn1 value some how.
+ * Here, we leave the constraint syntax
+ */
+ asn1::valuetype *get_valuetype() const ;
+};
+
+/**
+ * A range is composed of two values.
+ * min .. max
+ */
+class constraint_range : public constraint_element
+{
+ asn1::node *m_min;
+ asn1::node *m_max;
+ public:
+ constraint_range(types_type t,asn1::node *_min = NULL,asn1::node *_max = NULL);
+
+ ~constraint_range() ;
+
+ void set_min(asn1::node *s);
+
+ void set_max(asn1::node *s);
+
+ asn1::node *get_min() const { return m_min ; }
+
+ asn1::node *get_max() const { return m_max ; }
+
+ void set_min_max(asn1::node *_min,asn1::node *_max );
+
+ bool get_min_max(long &min,long &max);
+};
+
+/**
+ *
+ */
+class constraint_type : public constraint
+{
+ public:
+ constraint_type(types_type t) : constraint("TYPE",t) {};
+ ~constraint_type() {};
+ std::string name();
+};
+
+/**
+ *
+ */
+class constraint_array : public constraint
+{
+ public:
+ constraint_array(types_type t) : constraint( "ARRAY",t) {} ;
+ ~constraint_array() {} ;
+
+ std::string name();
+};
+/* Element type */
+#define ELEMENT_CONSTRAINT_EXTEND_celt_type \
+ celt_type(asn1::typeref *t); \
+ asn1::typeref *get_type() const;
+#define ELEMENT_CONSTRAINT_EXTEND_celt_value ;
+#define ELEMENT_CONSTRAINT_EXTEND_celt_range ;
+#define ELEMENT_CONSTRAINT_EXTEND_celt_llrange ;
+#define ELEMENT_CONSTRAINT_EXTEND_celt_rlrange ;
+#define ELEMENT_CONSTRAINT_EXTEND_celt_ulrange ;
+#define ELEMENT_CONSTRAINT_EXTEND_celt_encodedby ;
+#define ELEMENT_CONSTRAINT_EXTEND_celt_ext ;
+
+/*Constraint type */
+#define ELEMENT_CONSTRAINT_EXTEND_ctype_size \
+ asn1::celt_value *get_value() const; \
+ asn1::constraint_range *get_range() const; \
+
+#define ELEMENT_CONSTRAINT_EXTEND_ctype_from ;
+#define ELEMENT_CONSTRAINT_EXTEND_ctype_wcomp ;
+#define ELEMENT_CONSTRAINT_EXTEND_ctype_wcomps ;
+#define ELEMENT_CONSTRAINT_EXTEND_ctype_ctdby ;
+#define ELEMENT_CONSTRAINT_EXTEND_ctype_ctng ;
+
+/* Array Constraints */
+#define ELEMENT_CONSTRAINT_EXTEND_ca_set ;
+#define ELEMENT_CONSTRAINT_EXTEND_ca_crc ;
+#define ELEMENT_CONSTRAINT_EXTEND_ca_csv ;
+#define ELEMENT_CONSTRAINT_EXTEND_ca_uni ;
+#define ELEMENT_CONSTRAINT_EXTEND_ca_int ;
+#define ELEMENT_CONSTRAINT_EXTEND_ca_exc ;
+#define ELEMENT_CONSTRAINT_EXTEND_ca_aex ;
+
+
+#define ELEMENT_CONSTRAINT_GEN(elt,cls,parent) \
+ class cls : public parent \
+ {\
+ public:\
+ cls() : parent(elt) {}; \
+ ~cls() {} \
+
+// };
+
+#define ELEMENT_CONSTRAINT(elt,cls,parent) \
+ ELEMENT_CONSTRAINT_GEN(elt,cls,parent) ELEMENT_CONSTRAINT_EXTEND_##cls };
+
+#include "asn1_constraint.inc"
+
+}
+
+/*
+vim:et:sw=2:ts=2
+ */
+#endif
--- /dev/null
+#ifndef ELEMENT_CONSTRAINT
+#define ELEMENT_CONSTRAINT(elt,cls,parent)
+#endif
+/* Element type */
+ELEMENT_CONSTRAINT(EL_TYPE,celt_type,constraint_element) /* t (contained subtype ) */
+ELEMENT_CONSTRAINT(EL_VALUE,celt_value,constraint_element) /* 123, "x" (elementary value) */
+ELEMENT_CONSTRAINT(EL_RANGE,celt_range,constraint_range) /* 1..5 (basic range) */
+ELEMENT_CONSTRAINT(EL_LLRANGE,celt_llrange,constraint_range) /* 1<..3 */
+ELEMENT_CONSTRAINT(EL_RLRANGE,celt_rlrange,constraint_range) /* 1..<4 */
+ELEMENT_CONSTRAINT(EL_ULRANGE,celt_ulrange,constraint_range) /* 1<..<3 (basic range) */
+ELEMENT_CONSTRAINT(EL_ENCODEDBY,celt_encodedby,constraint_range) /* encoded by type */
+ELEMENT_CONSTRAINT(EL_EXT,celt_ext,constraint_element) /* ... (extensible mark) */
+
+/*Constraint type */
+#ifndef ELEMENT_CONSTRAINT_TYPE
+#define ELEMENT_CONSTRAINT_TYPE(elt,cls,parent) ELEMENT_CONSTRAINT(elt,cls,parent)
+#endif
+ELEMENT_CONSTRAINT_TYPE(CT_SIZE,ctype_size,constraint_type) /* size constraint type */
+ELEMENT_CONSTRAINT_TYPE(CT_FROM,ctype_from,constraint_type) /* */
+ELEMENT_CONSTRAINT_TYPE(CT_WCOMP,ctype_wcomp,constraint_type) /* with component */
+ELEMENT_CONSTRAINT_TYPE(CT_WCOMPS,ctype_wcomps,constraint_type) /* with components */
+ELEMENT_CONSTRAINT_TYPE(CT_CTDBY,ctype_ctdby,constraint_type) /* constrained by */
+ELEMENT_CONSTRAINT_TYPE(CT_CTNG,ctype_ctng,constraint_type) /* containing */
+
+/* Array Constraints */
+#ifndef ELEMENT_CONSTRAINT_ARRAY
+#define ELEMENT_CONSTRAINT_ARRAY(elt,cls,parent) ELEMENT_CONSTRAINT(elt,cls,parent)
+#endif
+ELEMENT_CONSTRAINT_ARRAY(CA_SET,ca_set,constraint_array) /* a set of constraints: (c1)(c2) */
+ELEMENT_CONSTRAINT_ARRAY(CA_CRC,ca_crc,constraint_array) /* comp. relation c-t: ({a}{@b}) */
+ELEMENT_CONSTRAINT_ARRAY(CA_CSV,ca_csv,constraint_array) /* comma-separated constraints array */
+ELEMENT_CONSTRAINT_ARRAY(CA_UNI,ca_uni,constraint_array) /* union (|) */
+ELEMENT_CONSTRAINT_ARRAY(CA_INT,ca_int,constraint_array) /* intersection (^) */
+ELEMENT_CONSTRAINT_ARRAY(CA_EXC,ca_exc,constraint_array) /* except */
+ELEMENT_CONSTRAINT_ARRAY(CA_AEX,ca_aex,constraint_array) /* all except */
+
+#undef ELEMENT_CONSTRAINT
+#undef ELEMENT_CONSTRAINT_TYPE
+#undef ELEMENT_CONSTRAINT_ARRAY
--- /dev/null
+#ifndef ASN1_META_H__
+#define ASN1_META_H__
+#include <iostream>
+
+namespace asn1
+{
+
+ class meta
+ {
+ public:
+ typedef enum {
+ INVALID = 0 ,
+ TYPEREF, /* Type2 := Type1 */
+ TYPE, /* Type1 := INTEGER */
+ VALUE, /* value Type1 := 1 */
+ VALUESET, /* Vset Type1 := {value 1} */
+ OBJECT, /* object CLASS := {...} */
+ OBJECTCLASS, /* FCT := CLASS {} */
+ OBJECTSET, /* objref DefinedObject := {set } */
+ OBJECTFIELD,
+ MAX
+ } id;
+ inline meta(meta::id id = INVALID) : m_id(id) {};
+ inline meta(const meta &m) : m_id(m.m_id) {};
+ inline meta &operator =( const meta &m) {m_id = m.m_id; return *this;};
+ inline meta &operator =( const id i) {m_id = i; return *this;};
+ inline ~meta() {};
+ inline bool operator >(const meta &a) {return m_id > a.m_id; };
+ inline bool operator <(const meta &a) {return m_id < a.m_id; };
+ inline bool operator ==(const meta &a) {return m_id == a.m_id; };
+ inline bool operator ==(const meta::id a) {return m_id == a; };
+
+ friend std::ostream & operator <<(std::ostream &os, const meta &m)
+ {
+ os<<m.m_id;
+ return os;
+ }
+ inline id operator()()
+ {
+ return m_id;
+ }
+ protected:
+ id m_id;
+ };
+}
+#endif
--- /dev/null
+#ifndef ASSIGNMENT
+#define ASSIGNMENT(tp,class,parent)
+#endif
+
+ASSIGNMENT(TYPEREF,typeref,assignment)
+ASSIGNMENT(TYPE,type,assignment)
+ASSIGNMENT(VALUE,value,assignment)
+ASSIGNMENT(VALUESET,valueset,assignment)
+ASSIGNMENT(OBJECT,object,assignment)
+ASSIGNMENT(OBJECTCLASS,objectclass,assignment)
+ASSIGNMENT(OBJECTSET,objectset,assignment)
+ASSIGNMENT(OBJECTFIELD,objectfield,assignment)
+
+#undef ASSIGNMENT
--- /dev/null
+#include <iostream>
+#include <list>
+#include <algorithm>
+#include <sstream>
+#include <string.h>
+#include <assert.h>
+
+#include "asn1_meta.h"
+#include "asn1_type.h"
+#include "asn1_value.h"
+#include "asn1_constraint.h"
+#include "aeb/pointer/intrusive_ptr.h"
+#include "asn1_node.h"
+#include "asn1_module.h"
+
+
+namespace asn1
+{
+
+/**
+ * Useful method to resolve references. before
+ * optimization.
+ */
+void
+module::resolve(asn1::resolver &r)
+{
+ struct do_resolve {
+ do_resolve(asn1::resolver &_r) : m_resolver(_r) {};
+
+ void operator () (std::pair<const std::string ,asn1::assignment *> &p)
+ {
+ p.second->get_type()->resolve(m_resolver);
+ }
+ asn1::resolver &m_resolver;
+ } ;
+
+ std::cerr<<__FUNCTION__<<" TODO"<<std::endl;
+
+ std::for_each( m_symbols.begin()
+ , m_symbols.end()
+ ,do_resolve(r));
+}
+
+/**
+ * retrieve assignment initialy declared in asn1 file.
+ * not those reparented through optimization
+ */
+asn1::assignment *
+module::get_assignment(const std::string &n)
+{
+ symt_iterator it = m_symbols.find(n);
+ if (it != m_symbols.end())
+ return it->second;
+ return NULL;
+}
+
+
+
+asn1::assignment *
+module::lookup(asn1::node *reference)
+{
+ asn1::node::iterator nit = std::find_if(begin(),
+ end(),
+ asn1::find_node(reference->name()));
+ if ( nit != end() )
+ {
+ return dynamic_cast<asn1::assignment *>(*nit);
+ }
+ return NULL;
+}
+
+/**
+ * All assignments added through this function are
+ * in m_symbols map.
+ * -> Those reworked by optimize will not be
+ * seen in the map. That allows a distinction between
+ * reparented structures and declared types.
+ */
+void
+module::add_type(asn1::assignment *n)
+{
+ assert((n != NULL) && "add_type parameter assignment must not be NULL");
+ append(n);
+ if ( n && n->meta_id()() == asn1::meta::OBJECT)
+ {
+ m_has_objects = true;
+ }
+ symt_iterator it = m_symbols.find(n->name());
+ if ( it == m_symbols.end())
+ m_symbols[n->name()] = n;
+}
+
+//
+void
+module::enter_symbol(asn1::node *n,asn1::type::id id)
+{
+ if (!m_context.empty())
+ {
+ if (n->get_parent() == NULL)
+ {
+ n->set_parent(m_context.top());
+ } else
+ {
+ std::cerr<<"module::enter_symbol the node already has a parent"<<std::endl;
+ }
+ m_context.top()->append(n);
+ } else
+ {
+ std::cerr<<"module::enter_symbol "<<n->name()<<" can't add on empty context"<<std::endl;
+ }
+}
+
+
+//
+void
+module::enter_context(asn1::constructed *_n)
+{
+ m_context.push(_n);
+}
+
+//
+asn1::constructed *
+module::current_context()
+{
+ if (m_context.empty())
+ return reinterpret_cast<asn1::constructed *>(this);
+ return m_context.top() ;
+}
+//
+asn1::constructed *
+module::leave_context()
+{
+ asn1::constructed *r = m_context.top();
+ m_context.pop();
+ return r;
+}
+
+
+
+
+asn1::import *
+module::get_import(const std::string &imp) const
+{
+ // pre condition, m_imports != NULL
+ if ( ! m_imports)
+ return NULL;
+
+ asn1::node::iterator found = std::find_if( m_imports->begin()
+ , m_imports->end()
+ , asn1::find_node(imp));
+ if (found != m_imports->end())
+ return dynamic_cast<asn1::import *>(*found);
+ return NULL;
+}
+
+}
+/**
+ * vim: et sw=2 ts=2 list:
+ */
--- /dev/null
+#ifndef ASN1_MODULE_H__
+#define ASN1_MODULE_H__
+
+#include <vector>
+#include <stack>
+#include <map>
+
+#include "asn1_node.h"
+
+namespace asn1 {
+
+ class import_list;
+ class import;
+ class module;
+ class resolver ;
+ struct find_module
+ {
+ find_module(const std::string &s) : m_s(s) {}
+ bool operator ()(asn1::module *n);
+ std::string m_s;
+ };
+
+/**
+ * A module contains all definitions. When we start a new definition,
+ * the parser shall call enter context and at the end, it shall call
+ * leave_context
+ */
+class module : public asn1::constructed
+{
+ public:
+ typedef std::map<std::string ,asn1::assignment *> symtable_type;
+ typedef symtable_type::iterator symt_iterator;
+ typedef std::vector<asn1::module *> modules_type;
+ typedef std::stack<asn1::constructed *> context_stack_type;
+
+ public:
+
+ module(const char *name ) : asn1::constructed(name,type::INVALID)
+ ,m_root(NULL)
+ ,m_has_objects(false)
+ ,m_imports(NULL)
+ ,m_exports(NULL) {};
+
+ module(const module &m)
+ : asn1::constructed(m)
+ , m_has_objects(m.m_has_objects)
+ {
+ std::cerr<<"module::module(const module &m)"<<std::endl;
+ };
+ // Default destructor
+ virtual ~module() {};
+
+ inline bool has_objects() const {return m_has_objects; } ;
+ /**
+ * The parser uses this function to add assignment tp
+ * the module.
+ */
+ void add_type(asn1::assignment *a);
+ //
+ void enter_symbol(asn1::node *n,asn1::type::id id) ;
+ //
+ void enter_context(asn1::constructed *_n) ;
+ //
+ asn1::constructed *current_context() ;
+ //
+ asn1::constructed *leave_context() ;
+
+ /**
+ * Useful method to resolve references. before
+ * optimization.
+ */
+ void resolve(asn1::resolver &r);
+ /**
+ * retrieve assignment initialy declared in asn1 file.
+ * not those reparented through optimization
+ */
+ asn1::assignment *get_assignment(const std::string &n);
+ /**
+ *
+ */
+ asn1::assignment *lookup(asn1::node *reference);
+
+ inline void exports(asn1::exports *exp) { m_exports = exp; };
+ inline asn1::exports *exports(void ) { return m_exports; };
+
+ inline void imports(asn1::import_list *exp) { m_imports = exp; };
+ inline asn1::import_list *imports(void ) { return m_imports; };
+ inline asn1::import_list *imports(void ) const { return m_imports; };
+ /**
+ * lookup if we import elements from module imp.
+ */
+ asn1::import *get_import(const std::string &imp) const;
+ protected:
+ context_stack_type m_context;
+ symtable_type m_symbols;
+ bool m_has_objects;
+ asn1::node *m_root;
+ asn1::exports *m_exports;
+ asn1::import_list *m_imports;
+};
+
+
+ inline bool find_module::operator ()(asn1::module *n)
+ {
+ return !m_s.compare(n->name());
+ };
+
+}
+
+/**
+vim:et:sw=2:ts=2
+ */
+#endif
--- /dev/null
+#include <iostream>
+#include <list>
+#include <algorithm>
+#include <sstream>
+#include <string.h>
+#include <assert.h>
+
+#include "asn1_meta.h"
+#include "asn1_type.h"
+#include "asn1_value.h"
+#include "asn1_constraint.h"
+#include "aeb/pointer/intrusive_ptr.h"
+#include "asn1_node.h"
+#include "asn1_reference.h"
+#include "asn1_module.h"
+
+namespace asn1 {
+// Counter to help computing an unique identifier for each node.
+static long g_counter = 0;
+
+static
+char lop_substitute(char c)
+{
+ return (c == '&')?'_':c;
+}
+/**
+ *
+ *
+ */
+node::node(const std::string name, meta m ) : m_is_generated(CL_GREEN) ,
+ m_ref(0),m_name(name),m_meta(m),
+ m_next(NULL)
+ , m_constraints("VIDE")
+ , m_identifier(NULL)
+ ,m_parameters(NULL)
+ ,m_value(NULL)
+ ,m_type(NULL)
+ ,m_parent(NULL)
+ ,m_marker(marker_type::FL_NONE)
+{
+ m_tag.m_mode = tag_type::TM_DEFAULT;
+ m_tag.m_class = tag_type::TC_NOCLASS;
+ m_tag.m_value = -1;
+ m_tag.m_set = false;
+ std::ostringstream oss;
+ std::string cppname;
+ cppname.resize(m_name.size());
+ std::transform(m_name.begin(),m_name.end(),cppname.begin(),asn1::lop_substitute);
+ oss<<cppname<<"_"<<g_counter;
+ m_uid = oss.str();
+ g_counter++;
+}
+
+node *
+node::clone()
+{
+ std::cerr<<"node::clone Should not happend "<<name()<< "type:"<<type_id()()<<std::endl;
+ return new node(*this);
+};
+
+/**
+ *
+ *
+ */
+node::node(const std::string name, type t ,meta m ) : m_is_generated(CL_GREEN),
+ m_ref(0),m_meta(m),m_type_id(t),m_name(name),
+ m_next(NULL)
+ ,m_constraints("VIDE")
+ ,m_identifier(NULL)
+ ,m_parameters(NULL)
+ ,m_parent(NULL)
+ ,m_value(NULL)
+ ,m_type(NULL)
+ ,m_marker(marker_type::FL_NONE)
+{
+ m_marker.m_flags = marker_type::FL_NONE;
+ m_tag.m_mode = tag_type::TM_DEFAULT;
+ m_tag.m_class = tag_type::TC_NOCLASS;
+ m_tag.m_value = -1;
+ m_tag.m_set = false;
+ std::ostringstream oss;
+ std::string cppname;
+ cppname.resize(m_name.size());
+ std::transform(m_name.begin(),m_name.end(),cppname.begin(),asn1::lop_substitute);
+ oss<<cppname<<"_"<<g_counter;
+ m_uid = oss.str();
+ g_counter++;
+ switch (t())
+ {
+ case asn1::type::ASN1_REFERENCE:
+ break;
+ case asn1::type::ASN1_EXPORTVAR:
+ break;
+ // case asn1::type::ASN1_UNIVERSAL: break;
+ // case asn1::type::ASN1_BITVECTOR: break;
+ case asn1::type::ASN1_EXTENSIBLE:
+ break;
+ case asn1::type::ASN1_COMPONENTS_OF:
+ break;
+ case asn1::type::ASN1_VALUESET:
+ break;
+ case asn1::type::ASN1_CLASSDEF:
+ break;
+ // case asn1::type::ASN1_INSTANCE: break;
+
+ /**
+ * Class Field type
+ */
+ case asn1::type::ASN1_CLASSFIELD_TF:
+ break; /* Type Field */
+ case asn1::type::ASN1_CLASSFIELD_FTVF:
+ break; /* Fixed Type Value Field */
+ case asn1::type::ASN1_CLASSFIELD_VTVF:
+ break; /* Variable Type Value Field */
+ case asn1::type::ASN1_CLASSFIELD_FTVSF:
+ break; /* Fixed Type Value Set Field */
+ case asn1::type::ASN1_CLASSFIELD_VTVSF:
+ break; /* Variable Type Value Set Field*/
+ case asn1::type::ASN1_CLASSFIELD_OF:
+ break; /* Object Field */
+ case asn1::type::ASN1_CLASSFIELD_OSF:
+ break; /* Object Set Field */
+ /* Constructed Types
+ */
+ case asn1::type::ASN1_SEQUENCE:
+ m_tag.m_value = 16;
+ break; /* 17 */
+ case asn1::type::ASN1_CHOICE:
+ break;
+ case asn1::type::ASN1_SET:
+ m_tag.m_value = 17;
+ break;
+ case asn1::type::ASN1_SEQUENCE_OF:
+ m_tag.m_value = 16;
+ break;
+ case asn1::type::ASN1_SET_OF:
+ m_tag.m_value = 17;
+ break;
+ case asn1::type::ASN1_SELECTION:
+ break;
+ /* Basic Types
+ */
+ case asn1::type::ASN1_ANY:
+ break;
+ case asn1::type::ASN1_BOOLEAN:
+ m_tag.m_value = 1;
+ break;
+ case asn1::type::ASN1_INTEGER:
+ m_tag.m_value = 2;
+ break;
+ case asn1::type::ASN1_BIT_STRING:
+ m_tag.m_value = 3;
+ break;
+ case asn1::type::ASN1_OCTET_STRING:
+ m_tag.m_value = 4;
+ break;
+ case asn1::type::ASN1_NULL:
+ m_tag.m_value = 5;
+ break;
+ case asn1::type::ASN1_OBJECT_IDENTIFIER:
+ m_tag.m_value = 6;
+ break;
+ case asn1::type::ASN1_OBJECT_DESCRIPTOR:
+ break;
+ case asn1::type::ASN1_REAL:
+ m_tag.m_value = 9;
+ break;
+ case asn1::type::ASN1_ENUMERATED:
+ m_tag.m_value = 10;
+ break;
+ case asn1::type::ASN1_RELATIVE_OID:
+ break;
+ case asn1::type::ASN1_EXTERNAL:
+ m_tag.m_value = 8;
+ break;
+ case asn1::type::ASN1_EMBEDDED_PDV:
+ break;
+ case asn1::type::ASN1_CHARACTER_STRING:
+ break;
+ case asn1::type::ASN1_UTCTime:
+ m_tag.m_value = 23;
+ break;
+ case asn1::type::ASN1_GeneralizedTime:
+ m_tag.m_value = 24;
+ break;
+ /* String Types
+ */
+
+ case asn1::type::ASN1_STRING:
+ break;
+ case asn1::type::ASN1_STRING_IA5String:
+ m_tag.m_value = 22;
+ break;
+ case asn1::type::ASN1_STRING_PrintableString:
+ m_tag.m_value = 19;
+ break;
+ case asn1::type::ASN1_STRING_VisibleString:
+ m_tag.m_value = 26;
+ break;
+ case asn1::type::ASN1_STRING_ISO646String:
+ break; /* aka VisibleString */
+ case asn1::type::ASN1_STRING_NumericString:
+ m_tag.m_value = 18;
+ break;
+ case asn1::type::ASN1_STRING_UniversalString:
+ m_tag.m_value = 29;
+ break;
+ case asn1::type::ASN1_STRING_BMPString:
+ m_tag.m_value = 30;
+ break;
+ case asn1::type::ASN1_STRING_UTF8String :
+ m_tag.m_value = 12;
+ break;
+ case asn1::type::ASN1_STRING_GeneralString:
+ m_tag.m_value = 27;
+ break;
+ case asn1::type::ASN1_STRING_GraphicString:
+ m_tag.m_value = 25;
+ break;
+ case asn1::type::ASN1_STRING_TeletexString:
+ m_tag.m_value = 20;
+ break;
+ case asn1::type::ASN1_STRING_T61String:
+ break;
+ case asn1::type::ASN1_STRING_VideotexString:
+ m_tag.m_value = 21;
+ break;
+ case asn1::type::ASN1_STRING_ObjectDescriptor:
+ break;
+ default:
+ ;
+ }
+}
+
+/**
+ * copy constructor
+ *
+ */
+node::node(const node &n) : m_is_generated(n.m_is_generated),m_meta(n.m_meta),m_type_id(n.m_type_id),
+ m_name(n.m_name), m_next(n.m_next)
+ ,m_constraints(n.m_constraints)
+ ,m_marker(n.m_marker)
+ ,m_identifier(NULL)
+ ,m_tag(n.m_tag)
+ ,m_parameters(NULL)
+ ,m_value(n.m_value)
+ ,m_type(n.m_type)
+ ,m_uid(n.m_uid)
+ ,m_parent(n.m_parent)
+{
+}
+
+/**
+ *
+ *
+ */
+node::node(const char *name) :m_is_generated(CL_GREEN) , m_ref(0), m_name(name)
+ ,m_next(NULL)
+ ,m_constraints("")
+ ,m_identifier(NULL)
+ ,m_parameters(NULL)
+ ,m_value(NULL)
+ ,m_type(NULL)
+ ,m_parent(NULL)
+ ,m_marker(marker_type::FL_NONE)
+{
+#ifdef DEBUG
+// std::cout<<"New Node:"<<m_name<<std::endl;
+#endif
+ if ((name == NULL) || (strlen(name)==0))
+ {
+ std::cout<<"ERROR not goof"<<std::endl;
+ exit(1);
+ }
+ m_tag.m_mode = tag_type::TM_DEFAULT;
+ m_tag.m_class = tag_type::TC_NOCLASS;
+ m_tag.m_value = -1;
+ std::ostringstream oss;
+ std::string cppname;
+ cppname.resize(m_name.size());
+ std::transform(m_name.begin(),m_name.end(),cppname.begin(),asn1::lop_substitute);
+ oss<<cppname<<"_"<<g_counter;
+ m_uid = oss.str();
+ g_counter++;
+}
+
+
+//
+//
+//
+const std::string
+node::name() const
+{
+ std::string ref_name("error");
+ if (const asn1::selection *sel = dynamic_cast<const asn1::selection *>(this))
+ {
+ return m_name;
+ }
+
+ if (const asn1::typeref *tref = as_typeref())
+ {
+
+ ref_name = "error-ref";
+ if ( tref->get_reference() &&
+ (*(tref->get_reference()->begin()) ).m_identifier.compare("TYPE-IDENTIFIER") == 0)
+ {
+ ref_name = "error-ref-type-identifier";
+ if (m_constraints.begin() != m_constraints.end())
+ {
+ ref_name = "error-ref-type-identifier-has-constraint";
+ asn1::constraint::const_iterator cit = m_constraints.begin();
+ if ( (*cit)->type() == asn1::constraint::EL_TYPE )
+ {
+ asn1::node *value = (*cit)->value();
+ ref_name = value->name();//+"/*CTY*/";
+ }
+ }
+ } else
+ {
+ if (tref->get_reference())
+ ref_name = tref->get_reference()->name();
+ }
+ } else
+ ref_name = m_name;
+#if 0
+ // Does not work.
+ if (meta_id() == meta::VALUE
+ && m_value)
+ {
+ ref_name = m_value->cpp_name();
+ }
+#endif
+ return ref_name;
+}
+
+
+//
+//
+//
+const std::string
+node::cpp_name()
+{
+std::string lname = name();
+#if 0
+std::string s;
+s.resize(name().size());
+std::transform(lname.begin(),lname.end(),s.begin(),op_substitute);
+if (lname.compare("private") == 0) {
+ return std::string("_private");
+} else if (lname.compare("operator") == 0) {
+ return std::string("_operator");
+} else if (lname.compare("...") == 0) {
+ return std::string("_treedot");
+} else if (lname.compare("bool") == 0) {
+ return std::string("_bool");
+} else if (lname.compare("true") == 0) {
+ return std::string("_true");
+} else if (lname.compare("false") == 0) {
+ return std::string("_false");
+} else if (lname.compare("auto") == 0) {
+ return std::string("_auto");
+} else if (lname.compare("explicit") == 0) {
+ return std::string("_explicit");
+} else if (lname.compare("continue") == 0) {
+ return std::string("_continue");
+} else if (lname.compare("default") == 0) {
+ return std::string("_default");
+} else if (lname.compare("NULL") == 0) {
+ return std::string("Null");
+} else
+return s;
+#else
+ return asn1::cpp_name(lname);
+#endif
+}
+
+const std::string
+cpp_name(const std::string &lname)
+{
+ std::string s;
+ s.resize(lname.size());
+ std::transform(lname.begin(),lname.end(),s.begin(),op_substitute);
+ if (lname.compare("private") == 0) {
+ return std::string("_private");
+ } else if (lname.compare("operator") == 0) {
+ return std::string("_operator");
+ } else if (lname.compare("...") == 0) {
+ return std::string("_treedot");
+ } else if (lname.compare("bool") == 0) {
+ return std::string("_bool");
+ } else if (lname.compare("true") == 0) {
+ return std::string("_true");
+ } else if (lname.compare("false") == 0) {
+ return std::string("_false");
+ } else if (lname.compare("auto") == 0) {
+ return std::string("_auto");
+ } else if (lname.compare("explicit") == 0) {
+ return std::string("_explicit");
+ } else if (lname.compare("continue") == 0) {
+ return std::string("_continue");
+ } else if (lname.compare("default") == 0) {
+ return std::string("_default");
+ } else if (lname.compare("NULL") == 0) {
+ return std::string("Null");
+ } else
+ return s;
+}
+
+//
+//
+//
+const std::string
+node::identifier_name()
+{
+ if (m_identifier !=NULL) {
+ return m_identifier->name();
+ } else {
+ std::cerr<<"Identifier is NULL"<<std::endl;
+ assert(0 && "node::identifier_name is NULL not good");
+ return std::string("null");
+ }
+}
+
+//
+//
+//
+const std::string
+node::identifier_cpp_name()
+{
+//std::cerr<<__FUNCTION__<<" HERE 1 "<<m_name<<std::endl;
+if (this->m_identifier == NULL) {
+ std::cerr<<"ERROR indentifier == NULL"<<std::endl;
+}
+//std::cerr<<"HERE 25 "<<std::endl;
+const std::string &name = m_identifier->name();
+//std::cerr<<"HERE 2 "<<std::endl;
+std::string s("unknown");
+//std::cerr<<"HERE"<<std::endl;
+if (name.size()>0) {
+ s.resize(name.size());
+ std::transform(name.begin(),name.end(),s.begin(),op_substitute);
+}
+if (name.compare("private") == 0) {
+ return std::string("_private");
+} else if (name.compare("...") == 0) {
+ return std::string("_treedot");
+} else if (name.compare("bool") == 0) {
+ return std::string("_bool");
+} else if (name.compare("true") == 0) {
+ return std::string("_true");
+} else if (name.compare("false") == 0) {
+ return std::string("_false");
+} else if (name.compare("default") == 0) {
+ return std::string("_default");
+} else
+return s;
+}
+
+
+// Generated stuff
+void node::set_generated(bool b)
+{
+ if (b == false) {
+ m_is_generated = CL_GREEN;
+ } else {
+ if (m_is_generated != CL_RED)
+ m_is_generated = color(m_is_generated + 1);
+ }
+
+}
+
+//
+//
+//
+bool node::is_generated()
+{
+ switch(m_type_id())
+ {
+ case asn1::type::ASN1_INTEGER:
+ case asn1::type::ASN1_OCTET_STRING:
+ return true;
+ break;
+ default:
+ return m_is_generated == CL_RED;
+ };
+}
+
+//
+//
+//
+void
+node::path2module(std::list<asn1::node *> &l) const
+{
+ long depth = 0;
+ asn1::node *p = m_parent;
+ if ( p == NULL)
+ {
+ std::cerr<<"node::path2module p (parent ) is NULL for node "<<name()<<" "<<std::endl;
+ assert(0);
+ }
+ // Parent must be set.
+ assert(m_parent != NULL);
+ if (dynamic_cast<asn1::module *>(p))
+ {
+ l.push_front(const_cast<asn1::node *>(this));
+ return;
+ }
+ do
+ {
+ if ( p == NULL)
+ {
+ std::cerr<<"node::path2module p is NULL "<<name()<<" "<<std::endl;
+ assert(0);
+ }
+ switch (p->type_id()())
+ {
+ case asn1::type::ASN1_SEQUENCE_OF:
+ case asn1::type::ASN1_SET_OF:
+ p = p->get_parent();
+ break;
+ case asn1::type::ASN1_SEQUENCE:
+ case asn1::type::ASN1_CHOICE:
+ case asn1::type::ASN1_SET:
+ if ( p->identifier() == NULL)
+ {
+ std::cerr<<"node::path2module ASSERT "<<name()<<" "<<p->name()<<std::endl;
+ // assert(0);
+ if (asn1::module *nm = dynamic_cast<asn1::module *>( p->get_parent()))
+ {
+ std::cerr<<"node::path2module ASSERT return "<<name()<<" "<<p->name()<<std::endl;
+ l.push_front(p);
+ return;
+ } else
+ {
+ std::cerr<<"node::path2module ASSERT parent not module "<<name()<<" "<<p->name()<<std::endl;
+ }
+ }
+ l.push_front(p);
+ p = p->get_parent();
+ break;
+ default:
+ l.push_front(p);
+ p = p->get_parent();
+ depth++;
+ }
+ } while( (p != NULL) && (dynamic_cast<asn1::module *>(p) == NULL) && depth < 20) ;
+ assert((depth < 20) && (p != NULL));
+}
+
+/**
+ *
+ */
+asn1::module *node::from_module() const
+{
+ asn1::node *p = m_parent;
+ node_list nl;
+
+ if (asn1::module *mo = dynamic_cast<asn1::module *>(p))
+ {
+ return mo;
+ }
+ path2module(nl);
+
+
+ asn1::module *t_module = dynamic_cast<asn1::module *>(nl.front()->get_parent());
+ return t_module;
+}
+
+//
+//
+//
+bool
+node::is_private() const
+{
+ int depth = 0;
+ if (dynamic_cast<module *>(m_parent) != NULL )
+ return false;
+ asn1::node *p = m_parent;
+ do
+ {
+ if ( p == NULL)
+ {
+ std::cerr<<"is_private p is NULL no parent for type "<<name()<<" "<<std::endl;
+ assert(0);
+ }
+ switch (p->type_id()())
+ {
+ case asn1::type::ASN1_SEQUENCE_OF:
+ case asn1::type::ASN1_SET_OF:
+ p = p->get_parent();
+ break;
+ case asn1::type::ASN1_SEQUENCE:
+ case asn1::type::ASN1_CHOICE:
+ case asn1::type::ASN1_SET:
+ if ( p->identifier() == NULL)
+ {
+ std::cerr<<"is_private ASSERT "<<name()<<" "<<p->name()<<std::endl;
+ assert(0);
+ } else
+ return true;
+ break;
+ default:
+ p = p->get_parent();
+ depth++;
+ }
+ } while( (p != NULL) && (dynamic_cast<asn1::module *>(p) == NULL) && depth < 20) ;
+ assert((depth < 20) && (p != NULL));
+ return false;
+}
+
+
+asn1::valuetype *
+node::as_value_type()
+{
+ return dynamic_cast<asn1::valuetype *>(this);
+}
+
+asn1::typenode *
+node::as_typenode()
+{
+ return dynamic_cast<asn1::typenode *>(this);
+}
+
+asn1::enumerated *
+node::as_enumerated()
+{
+ return dynamic_cast<asn1::enumerated *>(this);
+}
+
+
+asn1::typeref *
+node::as_typeref()
+{
+ return dynamic_cast<asn1::typeref *>(this);
+}
+const asn1::typeref *
+node::as_typeref() const
+{
+ return dynamic_cast<const asn1::typeref *>(this);
+}
+
+asn1::constructed *
+node::as_constructed()
+{
+ return dynamic_cast<asn1::constructed *>(this);
+}
+
+asn1::sequence *
+node::as_sequence()
+{
+ return dynamic_cast<asn1::sequence *>(this);
+}
+asn1::choice *
+node::as_choice()
+{
+ return dynamic_cast<asn1::choice *>(this);
+}
+
+asn1::set *
+node::as_set()
+{
+ return dynamic_cast<asn1::set *>(this);
+}
+
+asn1::object *
+node::as_object()
+{
+ return dynamic_cast<asn1::object *>(this);
+}
+
+asn1::integer *
+node::as_integer()
+{
+ return dynamic_cast<asn1::integer *>(this);
+}
+
+asn1::assignment *
+node::as_assignment()
+{
+ return dynamic_cast<asn1::assignment *>(this);
+}
+
+asn1::object_identifier *
+node::as_object_identifier()
+{
+ return dynamic_cast<asn1::object_identifier *>(this);
+}
+
+asn1::parameters *
+node::as_parameters()
+{
+ return dynamic_cast<asn1::parameters *>(this);
+}
+asn1::parameter *
+node::as_parameter()
+{
+ return dynamic_cast<asn1::parameter *>(this);
+}
+
+
+asn1::act_parameters *
+node::as_act_parameters()
+{
+ return dynamic_cast<asn1::act_parameters *>(this);
+}
+
+asn1::parameters *node::parameters() const
+{
+ return m_parameters->as_parameters() ;
+}
+
+asn1::act_parameters *node::act_parameters() const
+{
+ return m_parameters->as_act_parameters() ;
+}
+
+const char *
+type::name() const
+{
+ switch (m_id)
+ {
+
+#define ASN1_TYPE(cls,parent,id) \
+ case ASN1_##id : return #id;
+
+#define ASN1_STRING_TYPE(cls,parent,id) \
+ case ASN1_STRING_##id : return #id;
+
+#include "adt/asn1_type.inc"
+ default:
+ {
+ std::cerr<<"type::name ERROR unknow : "<<m_id<<std::endl;
+ return "unknown type ";
+ }
+ }
+
+}
+
+}
+/*
+vim:et:sw=2:ts=2:
+ */
--- /dev/null
+#ifndef ASN1_NODE_H__
+#define ASN1_NODE_H__
+#ifndef GCC_VERSION
+#define GCC_VERSION (__GNUC__ *10000 \
+ + __GNUC_MINOR__ * 100 \
+ + __GNUC_PATCHLEVEL__ )
+#endif
+#include <iostream>
+#include <list>
+#include <set>
+#include <map>
+#include <vector>
+#include <algorithm>
+#include <memory> // std::shared_ptr
+#include <stdexcept> // exception
+#include "asn1_meta.h"
+#include "asn1_type.h"
+#include "asn1_value.h"
+#include "asn1_constraint.h"
+#include "aeb/sys/log.h"
+#include "aeb/pointer/intrusive_ptr.h"
+
+namespace asn1
+{
+ class object_identifier;
+ class parameters;
+ class parameter;
+ class act_parameters;
+ class typeref;
+ class integer;
+ class sequence;
+ class assignment;
+ class enumerated;
+ class choice;
+ class set;
+ class object;
+
+ inline char op_substitute(char c)
+ {
+ return (c == '-')?'_':c;
+ }
+ class node;
+ class reference;
+ class simple_reference;
+ class objectclass_reference;
+ class module;
+ class constructed;
+ class valuetype;
+ class typenode;
+ /**
+ *
+ */
+ struct find_node {
+ find_node(const std::string &s) : m_s(s){}
+ bool operator ()(asn1::node *n) ;
+ std::string m_s;
+ };
+ /**
+ *
+ */
+ struct find_type {
+ find_type(const std::string &s) : m_s(s){}
+ bool operator ()(asn1::node *n) ;
+ std::string m_s;
+ };
+ /**
+ *
+ */
+ struct find_value {
+ find_value(const std::string &s) : m_s(s){}
+ bool operator ()(asn1::node *n) ;
+ std::string m_s;
+ };
+
+ /**
+ * This is a generic class for all kind of elements that can
+ * be found in an ASN1 definition. In terme, this class shall
+ * become an asbstract class so that it cannot be instantiated.
+ *
+ */
+ class node
+ {
+ INTRUSIVE_DECLARATION(node)
+ public:
+ typedef std::list<node *> node_list;
+ typedef std::list<node *>::iterator iterator;
+ typedef std::list<node *>::const_iterator const_iterator;
+
+ public:
+ // Constructor , Destructors
+ node(const std::string name, meta m = meta::INVALID);
+
+ node(const std::string name, type t = type::INVALID,meta m = meta::INVALID);
+
+ node(const node &n) ;
+
+ node(const char *name) ;
+
+ virtual ~node() {};
+ // Deep copy
+ virtual node *clone() ;
+
+ enum color {
+ CL_GREEN = 0,
+ CL_ORANGE = 1,
+ CL_REENTRANT = 2,
+ CL_RED = 3
+ };
+
+ // Generated stuff
+ void set_generated(bool b) ;
+
+ color get_color(void)const
+ {return m_is_generated;};
+
+ void set_color(asn1::node::color c)
+ {m_is_generated = c;};
+
+ bool is_generated() ;
+
+ // Name stuff
+ const std::string name() const;
+
+ const void name(const std::string &n)
+ {m_name = n;};
+
+ const std::string cpp_name() ;
+ // Casts
+ asn1::integer *as_integer();
+ asn1::valuetype *as_value_type();
+ const asn1::typeref *as_typeref() const;
+ asn1::typeref *as_typeref() ;
+ asn1::typenode *as_typenode();
+
+ asn1::constructed *as_constructed();
+
+ asn1::choice *as_choice();
+ asn1::sequence *as_sequence();
+ asn1::enumerated *as_enumerated();
+ asn1::set *as_set();
+ asn1::object *as_object();
+
+ asn1::object_identifier *as_object_identifier();
+
+ asn1::parameters *as_parameters();
+ asn1::parameter *as_parameter();
+ asn1::act_parameters *as_act_parameters();
+ asn1::assignment *as_assignment();
+ // Iterators ...
+#define NODE_REMOVE_ITERATORS
+ //
+ inline bool is_primitive() const
+ { return m_type_id() >= type::ASN1_BOOLEAN
+ && m_type_id() <= type::ASN1_STRING_ObjectDescriptor ;
+ }
+ inline bool is_constructed() const
+ { return (m_type_id() >= type::ASN1_SEQUENCE
+ && m_type_id() <= type::ASN1_SELECTION )
+ || m_type_id() == type::ASN1_ENUMERATED;
+ }
+
+ inline bool is_object_identifier() const
+ { return m_type_id() == type::ASN1_OBJECT_IDENTIFIER ; };
+
+ inline bool is_asn1() const
+ { return is_primitive() || is_constructed() || is_object_identifier(); }
+
+ inline bool is_choice() const
+ { return m_type_id() == type::ASN1_CHOICE ; };
+
+ inline bool is_reference() const
+ { return m_type_id() == type::ASN1_REFERENCE ; };
+
+ inline bool is_extensible() const
+ { return m_type_id() == type::ASN1_EXTENSIBLE ; };
+
+ virtual bool equals(const node &_n ) const { return false; };
+ // str Type, type_id
+ inline void type_node(node *t) { m_type = t; }
+
+ inline node *type_node() const { return m_type; }
+
+ // parameter stuff does not apply to all nodes
+ // see if this can be moved to another place
+ asn1::parameters *parameters() const;
+
+ inline void parameters(asn1::constructed *n)
+ { m_parameters = n; };
+
+ asn1::act_parameters *act_parameters() const;
+
+ inline void act_parameters(asn1::constructed *n)
+ { m_parameters = n; };
+
+
+ // str Identifier
+ inline void identifier(node *t) { m_identifier = t; }
+
+ inline node *identifier() const { return m_identifier; }
+
+ const std::string identifier_name( ) ;
+
+ const std::string identifier_cpp_name( ) ;
+
+ inline std::string uid(void) {return m_uid;};
+
+ // Type_id stuff
+ inline void type_id(asn1::type::id t) { m_type_id = t; }
+
+ inline type type_id() const {return m_type_id;};
+
+ inline asn1::value *value() const { return m_value;};
+
+ inline void value(asn1::value *v) {m_value =v;};
+ // Meta stuff
+ inline void meta_id(asn1::meta::id m) {m_meta = m;}
+
+ inline meta meta_id() const {return m_meta ;}
+
+ inline bool operator >(const node &n) {return m_meta > n.m_meta;};
+ /**
+ * two nodes are equal if, they are of the same type,
+ * have the same tagging,
+ * have the same contraints
+ * have the same elements
+ *
+ */
+ bool operator ==(const node &_n) { return equals(_n) ;};
+ static bool op_sort(asn1::node *n1,asn1::node *n2)
+ {
+#if 0
+ std::cout<<"Compare : "<<n1->meta_id()<<" "<<n2->meta_id()<<std::endl;
+#endif
+ return (n1->meta_id()) > (n2->meta_id());
+ }
+
+ /// Tag stuff
+ struct tag_type {
+ //inline tag_type() : m_class(TC_NOCLASS),m_mode(TM_DEFAULT) {};
+ enum {
+ TC_NOCLASS ,
+ TC_UNIVERSAL = 0,
+ TC_APPLICATION = 1,
+ TC_CONTEXT_SPECIFIC = 2,
+ TC_PRIVATE = 3
+ } m_class;
+
+ enum {
+ TM_DEFAULT,
+ TM_IMPLICIT,
+ TM_EXPLICIT,
+ TM_AUTOMATIC
+ } m_mode;
+ inline long byte() const { return m_class<<6 | m_value; };
+ inline long get_tag() const { return m_value<<2 | m_class; };
+ long m_value;
+ bool m_set;
+ };
+ // Do not set -1 tags
+ inline void tag(tag_type &t)
+ { if (t.m_value != -1 ) {m_tag = t; m_tag.m_set = true;} };
+
+ inline tag_type tag() const {return m_tag;};
+ inline tag_type &tag() {return m_tag;};
+ inline bool tagged() const
+ { return m_tag.m_set && m_tag.m_value>=0 && m_tag.m_class>= 0; };
+ // Marker flags
+ struct marker_type
+ {
+ inline bool is_omitable() const
+ { return (m_flags & FL_OMITABLE) == FL_OMITABLE; };
+
+ inline bool is_optional() const
+ { return (m_flags & FL_OPTIONAL) == FL_OPTIONAL; };
+
+ inline bool is_default() const
+ { return m_flags == FL_DEFAULT; };
+
+ enum eFlag {
+ FL_NONE = 0,
+ FL_OMITABLE = 0x02, /* 00010 can be absente in encoding */
+ FL_OPTIONAL = 0x07, /* 00111 default value */
+ FL_DEFAULT = 0x0F /* 01111*/
+ } m_flags;
+
+ marker_type(eFlag t = FL_NONE) : m_flags(t), m_value1(NULL)
+ {};
+
+ marker_type(const marker_type &m)
+ : m_flags(m.m_flags) ,m_value1(m.m_value1)
+ {};
+ marker_type & operator = (const marker_type &m)
+ {
+ m_value1 = m.m_value1;
+ m_flags = m.m_flags;
+ m_value = m.m_value; return *this;
+ };
+ //TODO Should also check value BUG
+ bool operator ==(const marker_type &m) const
+ {
+ return m_flags == m.m_flags;
+ };
+ int m_value; /* When default value
+ I would like it to be of type asn1::value::ptr */
+ asn1::value::ptr m_value1;
+ };
+
+ marker_type flags() const {
+ // std::cout<<"node::flags() "<<m_marker.m_flags<<std::endl;
+ return m_marker;
+ };
+
+ inline void flags(marker_type *f) {if (f) m_marker = *f;};
+ // Traversal of nodes
+ inline void set_parent(node *p) { m_parent = p ; }
+ inline node * get_parent () const { return m_parent ; };
+
+ // This function computes the nodes between module and node
+ // example : SEQUENCE { e1 SEQUENCE { e2 SET OF SEQUENCE { } } }
+ void path2module(std::list<asn1::node *> &l) const;
+ asn1::module *from_module() const;
+ bool is_private() const;
+
+ protected:
+ node *m_parent;
+ asn1::meta m_meta;
+ asn1::type m_type_id;
+ std::string m_name;
+ node *m_next;
+
+ node *m_type; // 2011/05/03 must be deprecated
+ asn1::value *m_value; // Should become part of valuetype
+ node *m_identifier;
+ asn1::constructed *m_parameters;
+ asn1::constraint m_constraints;
+ tag_type m_tag;
+ marker_type m_marker;
+ union {
+ long long m_value_long;
+ double m_value_double;
+ } ;
+ color m_is_generated;
+ std::string m_uid;
+ };
+ // Helper function for code generation
+ const std::string
+ cpp_name(const std::string &lname);
+
+ inline bool find_node::operator ()(asn1::node *n)
+ {
+ if (n == NULL) return false;
+ //std::cout<<" mds as:"<<n->name()<<std::endl;
+ return !m_s.compare(n->name());
+ };
+ inline bool find_type::operator ()(asn1::node *type)
+ {
+ if (type == NULL) return false;
+ //std::cout<<" mds as:"<<n->name()<<std::endl;
+ return !m_s.compare(type->identifier_name());
+ };
+
+ inline bool find_value::operator ()(asn1::node *type)
+ {
+ if (type == NULL) return false;
+ //std::cout<<" mds as:"<<n->name()<<std::endl;
+ return !(type->meta_id()() == asn1::meta::VALUE) && !m_s.compare(type->name());
+ };
+
+/* Add a container class here */
+
+/* ALL asn1 Datatypes that can be instantiated */
+#include "asn1_node_typenode.h"
+#include "asn1_node_constructed.h"
+#include "asn1_node_imports.h"
+#include "asn1_node_exports.h"
+#include "asn1_node_parameters.h"
+#include "asn1_node_typeref.h"
+#include "asn1_node_selection.h"
+#include "asn1_node_field.h"
+#include "asn1_node_alternative_choice.h"
+#include "asn1_node_primitive.h"
+#include "asn1_node_choice.h"
+#include "asn1_node_sequence.h"
+#include "asn1_node_sequence_of.h"
+#include "asn1_node_set.h"
+#include "asn1_node_set_of.h"
+#include "asn1_node_classdef.h"
+#include "asn1_node_valuetype.h"
+#include "asn1_node_object.h"
+#include "asn1_node_assignment.h"
+
+}
+#include "asn1_reference.h"
+/*
+ * vim:et:sw=2:ts=2
+ */
+#endif
--- /dev/null
+#ifndef ASN1_NODE_ALTERNATIVE_CHOICE_H
+#define ASN1_NODE_ALTERNATIVE_CHOICE_H
+
+
+class alternative_choice : public node
+{
+ public:
+
+ alternative_choice() ;
+ ~alternative_choice() ;
+
+ protected:
+};
+
+
+#endif
--- /dev/null
+#include <iostream>
+#include <list>
+#include <algorithm>
+#include <sstream>
+#include <string.h>
+#include <assert.h>
+
+#include "asn1_meta.h"
+#include "asn1_type.h"
+#include "asn1_value.h"
+#include "asn1_constraint.h"
+#include "aeb/pointer/intrusive_ptr.h"
+#include "asn1_node.h"
+#include "asn1_module.h"
+
+
+namespace asn1
+{
+
+assignment::assignment(const std::string &s)
+ : node(s,type::INVALID,meta::INVALID)
+{
+}
+
+assignment::assignment(const std::string &s,asn1::type t,asn1::meta m)
+ : node(s,t,m)
+{
+}
+
+void assignment::set_type(asn1::node *type)
+{
+ type_node(type);
+}
+
+typenode *
+assignment::get_type() const
+{
+ return reinterpret_cast<typenode *>(type_node());
+}
+
+objectset *
+assignment::get_objectset() const
+{
+ return reinterpret_cast<objectset *>(type_node());
+}
+
+parameter *
+assignment::have_parameter(asn1::node *actp,long &idx)
+{
+ idx = 0;
+ if (actp && m_parameters)
+ {
+ for (asn1::node::iterator pit = parameters()->begin();
+ pit != parameters()->end();
+ ++pit,++idx)
+ {
+ asn1::parameter *p = (*pit)->as_parameter();
+ if (p && p->get_typeref()->name() == actp->name())
+ return p;
+ }
+
+ }
+ return NULL;
+}
+}
+
+/**
+ * vim: et sw=2 ts=2:
+ */
--- /dev/null
+#ifndef ASN1_NODE_ASSIGNMENT_H
+#define ASN1_NODE_ASSIGNMENT_H
+
+
+/**
+ * This class represents an
+ * asn1 assignment examples :
+ * Type ::= SEQUENCE ...
+ * OBJECTSET ::= {} and so on
+ *
+ */
+class assignment : public node
+{
+ public:
+ assignment(const std::string &s) ;
+
+ assignment(const assignment &a)
+ : node(a)
+ {}
+
+ assignment(const std::string &s,asn1::type t,asn1::meta m) ;
+
+ assignment *clone() { return new assignment (*this); }
+ // Should replace node with typenode
+ void set_type(asn1::node *n);
+
+ typenode *get_type() const;
+ objectset *get_objectset() const;
+ /**
+ * node is an act_parameter ...
+ */
+ parameter *have_parameter(asn1::node *,long &idx);
+ protected:
+};
+
+#define ASSIGNMENT(tp,cls,parent) \
+ class cls ## _assignment : public parent \
+ {\
+ public:\
+ cls ## _assignment (const std::string &s) \
+ : parent( s,asn1::type::INVALID,asn1::meta::tp) {} ; \
+ cls ## _assignment (const cls ## _assignment &a) \
+ : parent(a) \
+ {}; \
+ ~cls ## _assignment () {}; \
+ cls ## _assignment *clone() { return new cls ## _assignment(*this);}; \
+ };
+
+#include "asn1_meta.inc"
+
+#endif /*ASN1_NODE_ASSIGNMENT_H*/
+/**
+ * vim: et sw=2 ts=2:
+ */
--- /dev/null
+#include <iostream>
+#include <list>
+#include <vector>
+#include <algorithm>
+#include <sstream>
+#include <string.h>
+#include <assert.h>
+
+#include "asn1_meta.h"
+#include "asn1_type.h"
+#include "asn1_value.h"
+#include "asn1_constraint.h"
+#include "aeb/pointer/intrusive_ptr.h"
+#include "asn1_node.h"
+#include "asn1_module.h"
+#include "asn1_resolver.h"
+
+
+namespace asn1
+{
+
+choice::choice() : constructed("CHOICE",type::ASN1_CHOICE)
+{
+}
+
+choice::choice(const choice &c) : constructed(c.name(),type::ASN1_CHOICE)
+{
+ std::cerr<<"choice::choice copy "<<c.size()<<" "<<name()<<" "<<c.name()<<std::endl;
+ if (this != &c)
+ {
+ // duplicate elements in vector
+ for ( asn1::node::const_iterator it = c.begin()
+ ; it != c.end()
+ ; ++it)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*it);
+ std::cerr<<"choice::choice"<<name()<<" clone "<<(*it)->name()<<std::endl;
+ asn1::field *nn = f->clone();
+ nn->set_parent(this);
+ nn->get_type()->set_parent(this);
+ append(nn);
+ std::cerr<<"choice::choice end "<<name()<<" clone "<<(*it)->name()<<std::endl;
+ }
+ std::cerr<<"choice::choice clone identidier "<<size()<<" "<<name()<<"\n"<<std::endl;
+ set_parent(c.identifier()->get_parent());
+ }
+ std::cerr<<"choice::choice copy end "<<size()<<" "<<name()<<"\n"<<std::endl;
+}
+
+/**
+ *
+ */
+asn1::node::tag_type
+choice::get_tag(asn1::resolver &r) const
+{
+ asn1::node *ftype = dynamic_cast<asn1::field *>(*begin()) -> get_type();
+
+ // std::cerr<<"choice::"<<__FUNCTION__<<" Begin type "<<name()<<" \n";
+loopref:
+ if (ftype->tagged())
+ {
+ //std::cerr<<"choice::"<<__FUNCTION__<<" tagged type "<<ftype->name()<<" \n";
+ return ftype->tag();
+ }
+ // Untagged reference,
+ // Check realtype
+ if (asn1::typeref *ref = ftype->as_typeref())
+ {
+ std::cerr<<"choice::"<<__FUNCTION__<<" type "<<name()<<" ";
+ std::cerr<<" got ref :"<<ref->name()<<std::endl;
+ if (asn1::node *rtype = ref->get_real_type())
+ {
+ // tagged realtype
+ if (rtype->tagged())
+ {
+ std::cerr<<"choice::"<<__FUNCTION__<<" tagged type "<<rtype->name()<<" \n";
+ assert(rtype->tag().m_value != -1);
+ return rtype->tag();
+ }
+ if (asn1::choice *c = dynamic_cast<asn1::choice *>(rtype))
+ {
+ return c->get_tag(r);
+ }
+ // Not a tagged type , Not Choice
+ if (rtype->tag().m_value != -1)
+ return rtype->tag();
+ // Still a reference, dig deeper,
+ if (rtype->as_typeref())
+ {
+ ftype = rtype;
+ goto loopref;
+ }
+ // tag is -1 assert an error I don't know what to do
+ std::cerr<<"choice::"<<__FUNCTION__<<" type "<<name()<<" ";
+ std::cerr<<" Can't find valid tag for choice init :"<<rtype->name()<<std::endl;
+ assert(0 && "Could not find valid tag for choice");
+
+ }
+ asn1::module *m = ref->from_module();
+ std::cerr<<"choice::"<<__FUNCTION__<<" type "<<m->name()<<"::"<<name()<<" ";
+ std::cerr<<" no real type Aieee :"<<ref->name()<<std::endl;
+ ftype = r.resolve(*ref);
+ std::cerr<<" new:"<<ftype->name()<<std::endl;
+ assert((ftype != NULL) && "Still tag not found");
+ goto loopref;
+ }
+
+ // Not a tagged, Not Choice
+ if (ftype->tag().m_value != -1)
+ return ftype->tag();
+ if (asn1::choice *nc = dynamic_cast<asn1::choice *>(ftype))
+ {
+ return nc->get_tag(r);
+ }
+ std::cerr<<"choice::"<<__FUNCTION__<<" type "<<name()<<" ";
+ std::cerr<<" Can't find valid tag for choice init :"<<ftype->name()<<std::endl;
+ assert(0 && "Still tag not found");
+}
+
+void
+choice::add_alternative(asn1::node *c)
+{
+ append(c);
+}
+
+}
+/**
+ * vim: et sw=2 ts=2 list:
+ */
--- /dev/null
+#ifndef ASN1_NODE_CHOICE_H
+#define ASN1_NODE_CHOICE_H
+
+
+class choice : public constructed
+{
+ protected:
+ choice(const choice &c) ;
+ public:
+
+ //choice() : constructed("CHOICE",asn1::type::ASN1_CHOICE) { } ;
+ choice() ;
+
+ virtual ~choice() {};
+
+ virtual choice *clone() { return new choice(*this); };
+ /**
+ * @brief retrieve the appropriate tag for
+ * first node. if it's a choice, lookup further
+ * until I get a valide tag.
+ * Example: PDU ::= CHOICE {
+ * aarq Arq
+ * rl Rrq
+ * }
+ * Arq ::= CHOICE {
+ * invoke [ 1 ] IMPLICIT Invoke
+ * }
+ */
+ asn1::node::tag_type get_tag(asn1::resolver &r) const;
+ // alternative_choice_iterator
+ void add_alternative(asn1::node *);
+ protected:
+ int test;
+};
+
+
+#endif
+/*
+ * vim: et sw=2 ts=2 :
+ */
--- /dev/null
+#include <iostream>
+#include <list>
+#include <algorithm>
+#include <sstream>
+#include <string.h>
+#include <assert.h>
+
+#include "asn1_meta.h"
+#include "asn1_type.h"
+#include "asn1_value.h"
+#include "asn1_constraint.h"
+#include "aeb/pointer/intrusive_ptr.h"
+#include "asn1_node.h"
+#include "asn1_module.h"
+
+
+namespace asn1
+{
+namespace internal
+{
+
+/**
+ * Abstract state ...
+ */
+state::state()
+{
+}
+
+void state::visit(visitor *v) const
+{
+ ;
+}
+/**
+ * transition state
+ */
+transition::transition(transition_type t) : m_type(t),m_next(NULL)
+{
+}
+
+void transition::visit(visitor *v) const
+{
+ v->visit_transition(dynamic_cast<const transition &>(*this));
+}
+
+/**
+ * split state
+ */
+split::split(state *start,state *end)
+ : m_first(start),m_second(end)
+{
+}
+
+void split::visit(visitor *v) const
+{
+ ;
+ v->visit_split(dynamic_cast<const split &>(*this));
+}
+
+/**
+ * match state
+ */
+match::match()
+{
+}
+
+void match::visit(visitor *v) const
+{
+ v->visit_match(dynamic_cast<const match &>(*this));
+}
+
+} /* end namespace internal */
+
+/**
+ * CLASS classdef_nfa
+ */
+classdef_nfa::classdef_nfa(state *start,state *end,std::shared_ptr<state_pool> pool)
+ : m_start(start),m_end(end), m_pool(pool)
+{
+}
+
+
+void
+classdef_nfa::visit(visitor *v) const
+{
+ v->visit(*m_start,*m_end);
+}
+
+/**
+ * CLASS syntax_parser
+ */
+
+syntax_parser::fragment::fragment(std::shared_ptr<state_pool> pool)
+ : m_pool(pool),m_start(NULL)
+{
+}
+
+syntax_parser::fragment::fragment( asn1::node *n
+ , std::shared_ptr<state_pool> pool)
+ : m_pool(pool)
+{
+
+ transition *trans = NULL;
+ if (n->type_id()() == asn1::type::INVALID)
+ {
+ trans = m_pool->make_transition(transition::eToken);
+ } else
+ trans = m_pool->make_transition(transition::eType);
+ trans->m_node_type = n;
+ m_out_edges.push_back(&(trans->m_next));
+ m_start = trans;
+}
+
+std::string
+syntax_parser::fragment::name() const
+{
+ if (m_start)
+ {
+ if (transition *t = dynamic_cast<transition *>(m_start))
+ {
+ std::string s("<transition frag ");
+ s = s + t->m_node_type->name() +">";
+ return s;
+ }
+ if (dynamic_cast<split *>(m_start))
+ {
+ return std::string("<split fragment>");
+ }
+ if (dynamic_cast<match *>(m_start))
+ {
+ return std::string("<match fragment>");
+ }
+ }
+ return std::string("<empty fragment>");
+}
+
+/**
+ *
+ * .-------. .-------.
+ * --->| frag1 |--->| frag2 |--->
+ * '-------' '-------'
+ */
+void
+syntax_parser::fragment::concat(const fragment &frag)
+{
+ for (size_t i = 0 ; i < m_out_edges.size() ; i++)
+ {
+ *m_out_edges[i] = frag.m_start;
+ }
+ m_out_edges = frag.m_out_edges;
+}
+
+
+/**
+ *
+ *
+ * .-------.
+ * .------->| frag2 |--->
+ * | '-------'
+ * .-------.
+ * --->| split |
+ * '-------'
+ * | .-------.
+ * '--------| frag1 |--->
+ * '-------'
+ */
+void
+syntax_parser::fragment::_split(const fragment &frag)
+{
+ m_start = m_pool->make_split(m_start,frag.m_start);
+ // Append outgoing edges from frag
+ for ( size_t i = 0 ; i < frag.m_out_edges.size() ; i++)
+ {
+ m_out_edges.push_back(frag.m_out_edges[i]);
+ }
+}
+
+/**
+ *
+ *
+ * .------.
+ * .------->| frag |--->
+ * | '------'
+ * .-------.
+ * --->| split |
+ * '-------'
+ * |
+ * '------------------->
+ */
+void
+syntax_parser::fragment::zero_or_one()
+{
+ split *s = m_pool->make_split(m_start,NULL);
+ // Append outgoing edges from frag
+ m_out_edges.push_back(&(s->m_second));
+ m_start = s;
+}
+
+
+/**
+ *
+ */
+std::shared_ptr<classdef_nfa >
+syntax_parser::fragment::to_nfa()
+{
+ match *m = m_pool->make_match();
+
+ for ( size_t i = 0 ; i < m_out_edges.size() ; i++)
+ {
+ *m_out_edges[i] = m ;
+ }
+ return std::shared_ptr<classdef_nfa>(
+ new classdef_nfa(m_start,m,m_pool) );
+}
+
+
+
+
+
+/**
+ * CLASS thomson_algorithm
+ */
+
+thomson_algorithm::thomson_algorithm()
+ : m_matched(false)
+ , m_object(NULL)
+ , m_start(NULL), m_end(NULL)
+ , m_current() , m_next()
+{
+}
+
+
+bool
+thomson_algorithm::accept(object *o,const std::shared_ptr<classdef_nfa> nfa)
+{
+ m_object = o;
+ m_current_it = o->begin();
+ nfa->visit(this);
+#if 0
+ std::cerr<<"thomson_algorithm::accept( matched "<<m_matched;
+ std::cerr<<" or end == end = "<<(m_current.find(m_end) != m_current.end());
+ std::cerr<<") and end="<<(m_current_it == o->end());
+ if (m_current_it != o->end())
+ std::cerr<<" cur_it="<<(*m_current_it)->name();
+ std::cerr<<std::endl;
+#endif
+ return (m_matched || m_current.find(m_end) != m_current.end()) && m_current_it == o->end();
+}
+
+
+void
+thomson_algorithm::visit(const state &start,const state &end)
+{
+ m_start = &start;
+ m_end = &end;
+ m_current.clear();
+ m_current.insert(m_start);
+
+ asn1::node *field = *m_current_it;
+ //std::cerr<<"visite_nfa "<<field->name()<<std::endl;
+
+ while ( (m_current_it != m_object->end()) && (m_current.size() != 0))
+ {
+ m_matched = false;
+#if 0
+ std::cerr<<"\nSTART NODE "<<" matched: "<<m_matched;
+ std::cerr<<" current.size "<<m_current.size()<<std::endl;
+#endif
+ // visit all states
+ for (state_const_iterator i = m_current.begin() ;
+ i != m_current.end(); ++i)
+ {
+ (*i)->visit(this);
+ }
+ ++m_current_it; // advance
+ m_current.swap(m_next);
+ m_next.clear();
+#if 0
+ if (m_current_it == m_object->end())
+ {
+ std::cerr<<"NEXT NODE "<<" previous matched: "<<m_matched<<std::endl;
+ } else
+ std::cerr<<"NEXT NODE "<<(*m_current_it)->name()<<" previous matched: "<<m_matched<<std::endl;
+#endif
+ }
+ // May be it's a match. If next is a split and second contains end.
+ const split *_next = dynamic_cast<const split *>(*(m_current.begin()));
+ if (_next)
+ {
+ _next->visit(this);
+ }
+}
+
+
+void
+thomson_algorithm::visit_transition(const transition &trans)
+{
+ asn1::node *field = *m_current_it;
+ // Check if there is a match
+ if (m_current_it != m_object->end())
+ {
+ if ( trans.is_token()
+ && !field->name().compare(trans.m_node_type->name()) )
+ {
+ // Ok, got expected token
+ m_next.insert(trans.m_next);
+ } else if (trans.is_type() )
+ { // Check type
+ //std::cerr<<"visite_transition MATCH "<<field->name();
+ //std::cerr<<" nd:"<<trans.m_node_type->name()<<std::endl;
+ m_object->parsed_field(trans.m_node_type->name(),field);
+ m_next.insert(trans.m_next);
+ } else
+ {
+ //std::cerr<<"visite_transition no match "<<field->name();
+ //std::cerr<<" nd:"<<trans.m_node_type->name()<<std::endl;
+ }
+ }
+
+}
+
+
+void
+thomson_algorithm::visit_split(const split &s)
+{
+ asn1::node *field = *m_current_it;
+#if 0
+ if (m_current_it != m_object->end())
+ std::cerr<<"visite_split "<<field->name()<<std::endl;
+#endif
+ s.m_first->visit(this);
+ s.m_second->visit(this);
+}
+
+
+void
+thomson_algorithm::visit_match(const match &trans)
+{
+ asn1::node *field = *m_current_it;
+#if 0
+ if (m_current_it != m_object->end())
+ std::cerr<<"visite_match "<<field->name()<<std::endl;
+#endif
+ m_matched = true;
+}
+
+
+/**
+ * CLASS classdef
+ */
+classdef::classdef()
+ : constructed("OBJECT_CLASS",type::ASN1_CLASSDEF,meta::OBJECTCLASS)
+{
+}
+
+void
+classdef::start_syntax()
+{
+ m_pool = std::make_shared<state_pool>();
+}
+
+//
+classdef::~classdef()
+{
+}
+
+//
+bool
+classdef::check_object_syntax(object *_o)
+{
+ thomson_algorithm algo;
+ bool result = algo.accept(_o,m_nfa);
+ return result;
+}
+
+//
+classdef::fragment *
+classdef::parse_token(asn1::node *t)
+{
+ fragment *frag = new fragment(t,m_pool);
+ return frag;
+}
+
+//
+classdef::fragment *
+classdef::parse_optional(fragment *frag)
+{
+ assert(frag != NULL);
+ frag->zero_or_one();
+ return frag;
+}
+//
+classdef::fragment *
+classdef::parse_append(fragment *f1,fragment *f2)
+{
+ assert(f1 != NULL && f2!=NULL);
+ f1->concat(*f2);
+ return f1;
+}
+//
+classdef::fragment *
+classdef::parse_new()
+{
+ fragment *frag = new fragment(m_pool);
+ return frag;
+}
+//
+void
+classdef::set_nfa(fragment *f)
+{
+ assert(f != NULL);
+ m_nfa = f->to_nfa();
+}
+
+//
+void
+classdef::add_field(asn1::classfield *c)
+{
+ append(c);
+ if (c->type_node() && c->type_node()->flags().is_optional())
+ {
+ m_optionals.push_back(c);
+ }
+}
+
+asn1::classfield *
+classdef::get_classfield(const std::string &name)
+{
+ asn1::node::iterator found = std::find_if( begin()
+ , end()
+ , asn1::find_node(name));
+ if (found != end() )
+ return dynamic_cast<asn1::classfield *>(*found);
+
+ return NULL;
+}
+
+struct fieldcmp
+{
+ bool operator()(asn1::node *a,asn1::node *b)
+ {
+ return a->type_id()() < b->type_id()();
+ }
+};
+//
+void
+classdef::sort_fields()
+{
+ //std::sort(begin(),end(),fieldcmp());
+ m_nodes.sort(fieldcmp());
+}
+
+} /* end namespace asn1 */
--- /dev/null
+#ifndef ASN1_NODE_CLASSDEF_H
+#define ASN1_NODE_CLASSDEF_H
+#if defined(_WIN32)
+/* MSDN Visual Studion 14 exception handling ... */
+#pragma warning(disable : 4290)
+#endif
+
+class object;
+namespace internal {
+ struct state;
+ struct transition;
+ struct split;
+ struct match;
+
+ class visitor
+ {
+ public:
+ virtual void visit(const state &start,const state &end) = 0;
+
+ virtual void visit_transition(const transition &trans) = 0;
+
+ virtual void visit_split(const split &trans) = 0;
+
+ virtual void visit_match(const match &trans) = 0;
+ };
+
+ /**
+ *
+ */
+ struct state
+ {
+ state();
+
+ virtual void visit(visitor *) const;
+ };
+
+ /**
+ *
+ */
+ struct transition : public state
+ {
+ typedef enum { eToken,eType} transition_type;
+ transition(transition_type);
+
+ inline bool is_token() const { return m_type == eToken; };
+ inline bool is_type() const { return m_type == eType; };
+
+ virtual void visit(visitor *) const;
+
+ transition_type m_type;
+ node *m_node_type;
+ state *m_next;
+ };
+
+ /**
+ *
+ */
+ struct split : public state
+ {
+ split(state *first,state*second);
+
+ virtual void visit(visitor *) const;
+ state *m_first;
+ state *m_second;
+ };
+ /**
+ *
+ */
+ struct match : public state
+ {
+ match();
+
+ virtual void visit(visitor *) const;
+ };
+
+ /**
+ * StatePool stack
+ */
+class state_pool {
+
+ //! \brief state_pool memory representation.
+ //!
+ //! No data alignement is performed when a Chunk
+ //! allocates memory, i.e. it can't be used in a
+ //! general case.
+ template <unsigned int chunk_size>
+ struct Chunk {
+ public:
+ //! \brief Default constructor.
+ //! \post The next pointer is NULL
+ //! \post The data_index is set to 0.
+ Chunk(): next(NULL), data_index(0) {}
+
+ //! \brief Reserve N bytes in this chunk.
+ //! \param nbytes Number of bytes to allocate/reserve.
+ //! \pre The requested number of bytes (nbytes) must be
+ //! smaller or equal (<=) to the chunk_size.
+ //! \return A raw pointer to the begining of the reserved
+ //! memory space.
+ void* reserve(size_t nbytes) throw(std::logic_error) {
+
+ // Make sure that a Chunk can really
+ // serve a request of this size.
+ if (nbytes > chunk_size)
+ throw std::logic_error("state_pool::Chunk::reserve(): the "
+ "requested number of bytes is bigger "
+ "than a chunk_size.");
+
+ // Make sure that we have enough room serve
+ // the request. If not return NULL. The pool
+ // will handle this by allocating a new chunk.
+ if (chunk_size - data_index >= nbytes) {
+ void* dptr = &data[data_index];
+ data_index += nbytes;
+ return dptr;
+ }
+
+ return NULL;
+ }
+
+ Chunk* next; /**< A pointer to the next chunk. */
+ unsigned int data_index; /**< Current position in the data array. */
+ char data[chunk_size]; /**< Allocation array containing chunk_size bytes. */
+ };
+
+ typedef Chunk<64> MemoryChunk;
+
+public:
+
+ //! \brief Default constructor.
+ state_pool() {
+ root_chunk = last_chunk = new MemoryChunk;
+ }
+
+ //! \brief Destructor.
+ //!
+ //! Free all memory associated to the states allocated from
+ //! this pool. Beware that it won't call the destructor on
+ //! those objects.
+ ~state_pool() {
+ while (root_chunk) {
+ MemoryChunk* temp_chunk = root_chunk;
+ root_chunk = root_chunk->next;
+ delete temp_chunk;
+ }
+ }
+
+ //! \brief Construct a split state from the pool.
+ //! \param[in] first The first neighbor State.
+ //! \param[in] second The second neighbor State.
+ //! \return A pointer to the newly constructed split state.
+ split* make_split(state* first, state* second) {
+ void* _split = reserve(sizeof(split));
+ new (static_cast<void*>(_split)) split(first, second);
+ return reinterpret_cast<split*>(_split);
+ }
+
+ //! \brief Construct a transition state from the pool.
+ //! \param label The transition label.
+ //! \return A pointer to the newly constructed transition state.
+ transition* make_transition(transition::transition_type label) {
+ void* trans = reserve(sizeof(transition));
+ new (static_cast<void*>(trans)) transition(label);
+ return reinterpret_cast<transition*>(trans);
+ }
+
+ //! \brief Construct a match state from the pool.
+ //! \return A pointer to the newly constructed match state.
+ match* make_match() {
+ void* _match = reserve(sizeof(match));
+ new (static_cast<void*>(_match)) match();
+ return reinterpret_cast<match*>(_match);
+ }
+
+protected:
+
+ //! \brief Reserve N bytes from this pool.
+ //! \param nbytes Number of bytes to allocate/reserve.
+ //! \return A raw pointer to the begining of the reserved
+ //! memory space.
+ void* reserve(size_t nbytes) {
+ // Try to reserve N bytes from the last
+ // allocated memory chunk.
+ void* data = last_chunk->reserve(nbytes);
+
+ // Check if it's a miss. If so, we'll
+ // need to allocate a new chunk.
+ if (!data) {
+ last_chunk->next = new MemoryChunk;
+ last_chunk = last_chunk->next;
+ data = last_chunk->reserve(nbytes);
+ }
+
+ return data;
+ }
+
+ state_pool(const state_pool&) {}
+ void operator=(const state_pool&) {}
+
+ MemoryChunk* root_chunk; /**< First allocated chunk. */
+ MemoryChunk* last_chunk; /**< Last allocated chunk. */
+};
+
+} /* end namespace internal */
+
+class syntax_parser;
+class classdef_nfa
+{
+ protected:
+ friend class syntax_parser;
+ typedef internal::state state;
+ typedef internal::state_pool state_pool;
+ typedef internal::visitor visitor;
+ classdef_nfa(state *start,state *end,std::shared_ptr<state_pool> pool);
+ public:
+
+ void visit(visitor *v) const;
+ protected:
+ state *m_start;
+ state *m_end;
+ std::shared_ptr<state_pool> m_pool;
+};
+
+/**
+ * fragments must be visible to the asn1 parser
+ * as it is the one the builds the parsing tree
+ */
+class syntax_parser
+{
+ public:
+ typedef internal::state state;
+ typedef internal::transition transition;
+ typedef internal::split split;
+ typedef internal::match match;
+ typedef internal::state_pool state_pool;
+ /**
+ * \brief Class representing a partial fragment of the nfa
+ */
+ class fragment
+ {
+ public:
+ /**
+ * Build an empty fragment
+ */
+ fragment(std::shared_ptr<state_pool> pool);
+ /**
+ * Build an transition framgent
+ */
+ fragment(asn1::node *,std::shared_ptr<state_pool> pool);
+
+ void concat(const fragment &frag);
+
+ void _split(const fragment &frag);
+
+ std::string name() const;
+
+ void zero_or_one();
+
+ std::shared_ptr<classdef_nfa > to_nfa();
+ protected:
+ state *m_start;
+ std::vector<state **> m_out_edges;
+ std::shared_ptr<state_pool> m_pool;
+ };
+
+ protected:
+ std::shared_ptr<state_pool> m_pool;
+
+};
+
+
+/**
+ *
+ */
+class thomson_algorithm : public internal::visitor
+{
+ typedef internal::state state;
+ typedef internal::transition transition;
+ typedef internal::split split;
+ typedef internal::match match;
+ protected:
+
+ public:
+ typedef std::set<const state *>::const_iterator state_const_iterator;
+ thomson_algorithm() ;
+
+ bool accept(object *o,const std::shared_ptr<classdef_nfa> nfa);
+
+ void visit(const state &start,const state &end);
+
+ void visit_transition(const transition &trans);
+
+ void visit_split(const split &trans);
+
+ void visit_match(const match &trans);
+ protected:
+ bool m_matched;
+ node::iterator m_current_it;
+ object *m_object; // token to go through are in object
+ const state *m_start;
+ const state *m_end;
+ std::set<const state *> m_current;
+ std::set<const state *> m_next;
+};
+
+/**
+ * class definition. This object can be followed with syntax
+ * it should have code to build the parser for the defined syntax
+ * and check if the object defined respects the defined syntax
+ *
+ * in order to parser the tokens properly, I should passe the object as
+ * reference. The object contains the token, the parser will set
+ * the appropriate fields according to the tokens and the defined parser
+ */
+class classdef : public constructed
+{
+ public:
+ typedef syntax_parser::fragment fragment;
+ typedef syntax_parser::state_pool state_pool;
+
+ typedef std::vector<asn1::node *> OptionalArrayType;
+ typedef OptionalArrayType::iterator OptionalIterator;
+
+ classdef() ;
+ ~classdef() ;
+ /**
+ * At a given time, the with syntax must have been used.
+ * parse all token and build a simple automaton.
+ *
+ */
+ fragment *parse_token(asn1::node *t);
+ //
+ fragment *parse_optional(fragment *f);
+ //
+ fragment *parse_append(fragment *f1,fragment *f2);
+ //
+ fragment *parse_new();
+ //
+ void set_nfa(fragment *f);
+ //
+ void start_syntax();
+
+ bool check_object_syntax(object *_o);
+ //
+ void add_field(asn1::classfield *);
+
+ asn1::classfield *get_classfield(const std::string &name) ;
+ // Order fields
+ void sort_fields();
+
+ OptionalIterator opt_begin() { return m_optionals.begin() ; }
+ OptionalIterator opt_end() { return m_optionals.end() ; }
+
+ size_t opt_size( ) const { return m_optionals.size(); }
+
+ protected:
+ OptionalArrayType m_optionals;
+ std::shared_ptr<state_pool> m_pool;
+ std::shared_ptr<classdef_nfa> m_nfa;
+ // Should own a list of tokens
+};
+
+
+#endif
--- /dev/null
+#include <iostream>
+#include <list>
+#include <algorithm>
+#include <sstream>
+#include <string.h>
+#include <assert.h>
+
+#include "asn1_meta.h"
+#include "asn1_type.h"
+#include "asn1_value.h"
+#include "asn1_constraint.h"
+#include "aeb/pointer/intrusive_ptr.h"
+#include "asn1_node.h"
+#include "asn1_module.h"
+
+
+namespace asn1
+{
+
+/**
+ *
+ */
+constructed::constructed(const constructed &c)
+ : typenode(c)
+{
+
+}
+
+asn1::constructed *
+constructed::clone()
+{
+ asn1::constructed *nc = new constructed(*this);
+ std::cerr<<"constructed::clone "<<name()<<std::endl;
+ return nc;
+}
+
+
+bool
+constructed::equals(const node &_nn) const
+{
+ const asn1::constructed &_n = dynamic_cast<const asn1::constructed &>(_nn);
+ bool eq = (type_id()() == _n.type_id()());
+ if ( ! is_empty() && eq)
+ {
+ const_iterator field_it,nfield_it;
+ for (field_it = begin() , nfield_it =_n.begin()
+ ; field_it != end() && nfield_it != end()
+ ; ++field_it, ++nfield_it )
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*field_it);
+ asn1::field *nf = dynamic_cast<asn1::field *>(*nfield_it);
+ if ( f->get_type() != NULL
+ && nf->get_type() != NULL)
+ {
+ asn1::node *t = f->get_type();
+ asn1::node *nt = nf->get_type();
+ eq = eq && (*t == *nt) ;
+ if (! eq )
+ return false; // Don't continue looking
+ }
+ }
+ if ( (field_it == end() ) && (nfield_it == _n.end()) )
+ {
+ return flags() == _n.flags();
+ }
+ return false;
+ } else
+ return ( eq );
+}
+
+// Lookup for field name in node list
+asn1::field *
+constructed::get_field(const std::string &name)
+{
+ asn1::node::iterator found = std::find_if( begin()
+ , end()
+ , asn1::find_node(name));
+ if (found != end() )
+ return dynamic_cast<asn1::field *>(*found);
+
+ return NULL;
+}
+
+}
--- /dev/null
+#ifndef ASN1_NODE_CONSTRUCTED_H
+#define ASN1_NODE_CONSTRUCTED_H
+
+/**
+ *
+ * Container class. All types that contain elements must
+ * ibherit from this class. Example:
+ * bit_string, enumerate,integer
+ * sequence,set,choice,object,objectclass
+ * imports,exports,paramters,act_parameters
+ */
+class constructed : public typenode
+{
+ public:
+ typedef node::iterator field_iterator;
+ typedef node::const_iterator const_field_iterator;
+
+ // constructed(const std::string s,type _t) : node(s,_t) { } ;
+
+ constructed(const std::string name, type t = type::INVALID,meta m = meta::TYPE)
+ : typenode(name,t,m) {};
+
+ constructed(const constructed &c) ;
+
+ constructed *clone() ;
+
+ virtual ~constructed() {};
+
+ virtual bool equals(const node &_n) const ;
+
+ node::iterator begin() {return m_nodes.begin();}
+ node::const_iterator begin() const {return m_nodes.begin();}
+
+ node::iterator end() {return m_nodes.end();}
+ node::const_iterator end() const {return m_nodes.end();}
+
+ size_t size() const {return m_nodes.size();}
+
+ bool is_empty() const { return m_nodes.begin() == m_nodes.end(); };
+ // alternative_constructed_iterator
+ node::node_list &nodes() { return m_nodes; }
+ // Lookup for field name in node list
+ asn1::field *get_field(const std::string &name);
+
+ inline void sort_childs()
+ {
+ m_nodes.sort(node::op_sort);
+ };
+
+ void append(node *n)
+ {
+ if (n)
+ {
+ m_nodes.push_back(n);
+ if (n->get_parent() == NULL ) n->set_parent(this);
+ } else
+ {
+ std::cerr<<"node::append NULL node is wierd"<<std::endl;
+ }
+ }
+ protected:
+ node::node_list m_nodes;
+};
+
+
+#endif
--- /dev/null
+#ifndef ASN1_NODE_EXPORTS_H
+#define ASN1_NODE_EXPORTS_H
+
+/**
+ * List items exported by module.
+ */
+class exports : public constructed
+{
+ public:
+
+ exports(const std::string &n = std::string("exports"))
+ : m_all(false), constructed(n,type::INVALID) { } ;
+
+ ~exports() {} ;
+
+ typeref *get_item( const std::string &item) ;
+
+ bool all() const { return m_all; } ;
+ void all(bool a) { m_all = a; } ;
+ protected:
+ bool m_all;
+};
+
+
+#endif
--- /dev/null
+#include <iostream>
+#include <list>
+#include <algorithm>
+#include <sstream>
+#include <string.h>
+#include <assert.h>
+
+#include "asn1_meta.h"
+#include "asn1_type.h"
+#include "asn1_value.h"
+#include "asn1_constraint.h"
+#include "aeb/pointer/intrusive_ptr.h"
+#include "asn1_node.h"
+#include "asn1_module.h"
+
+
+namespace asn1
+{
+
+/**
+ *
+ */
+field::field(const field &f)
+ : node(f)
+{
+ std::cerr<<"field::field copy - "<<name()<<" "<<f.name()<< std::endl;
+ if (&f != this)
+ {
+ asn1::typenode *nt = f.get_type()->clone();
+ nt->identifier(this);
+ type_node(nt);
+#if 0
+ if (nt->type_id()() != asn1::type::ASN1_REFERENCE)
+ {
+ nt->name(name()+"_t");
+ }
+#endif
+ }
+}
+
+/**
+ *
+ */
+field::field(const std::string _s,asn1::node *_type)
+ : node(_s,asn1::type::INVALID)
+{
+ type_node(_type);
+ if (_type != NULL)
+ _type->identifier(this);
+};
+
+typenode *
+field::get_type() const
+{
+ return reinterpret_cast<typenode *>(type_node());
+}
+
+void
+field::set_type(asn1::typenode *t)
+{
+ type_node(t);
+}
+
+/**
+ *
+ */
+field *
+field::clone()
+{
+ return new field(*this);
+}
+
+/**
+ * extension field class
+ */
+extension_field::extension_field(const extension_field &ef)
+ : field("...",NULL)
+{
+}
+
+extension_field *
+extension_field::clone()
+{
+ return new extension_field(*this);
+}
+
+extension_field::extension_field()
+ : field("...",NULL)
+{
+ type_id(asn1::type::ASN1_EXTENSIBLE);
+}
+
+/**
+ *
+ */
+classfield::classfield(const std::string &_s,type t)
+ : node(_s,t,meta::OBJECTFIELD)
+ , m_reference(NULL)
+{
+}
+typenode *
+classfield::get_type() const
+{
+ assert( 0 && "Should not be called");
+ return NULL;
+}
+
+/**
+ * CLASSFIELD FTVSF
+ */
+classfield_ftvf::classfield_ftvf( const std::string &n,asn1::typenode *t,type _t)
+ : classfield(n,_t)
+{
+ type_node(t);
+}
+typenode *
+classfield_ftvf::get_type() const
+{
+ return reinterpret_cast<typenode *>(type_node());
+}
+
+classfield_ftvsf::classfield_ftvsf( const std::string &n,asn1::typenode *t,type _t)
+ : classfield(n,_t)
+{
+ type_node(t);
+}
+typenode *
+classfield_ftvsf::get_type() const
+{
+ return reinterpret_cast<typenode *>(type_node());
+}
+/**
+ * CLASSFIELD OSF
+ */
+classfield_osf::classfield_osf( const std::string &n,asn1::typeref *t,type _t)
+ : classfield(n,_t)
+{
+ type_node(t);
+}
+typeref *
+classfield_osf::get_typeref() const
+{
+ return reinterpret_cast<typeref *>(type_node());
+}
+
+typenode *
+classfield_osf::get_type() const
+{
+ return reinterpret_cast<typenode *>(type_node());
+}
+
+
+}
--- /dev/null
+#ifndef ASN1_NODE_FIELD_H
+#define ASN1_NODE_FIELD_H
+
+/**
+ * This class represents the componentType in ASN1 definition
+ * -> It's most lickely that "components of" will also be handled
+ * by this class.
+ * -> SEQUENCE AND SET contained elements are fields
+ */
+class field : public node
+{
+ field(const field &f);
+ public:
+ field *clone();
+
+ field(const std::string _s,asn1::node *_type) ;
+ ~field() {};
+
+ typenode *get_type() const;
+ void set_type(asn1::typenode *t);
+ // a field in set or sequence, use same type for choice as well
+ protected:
+};
+
+/**
+ * @brief represents the ... in ASN1 specification
+ * still missing the possible exception value.
+ */
+class extension_field : public field
+{
+ protected:
+ extension_field(const extension_field &ef);
+ public:
+ extension_field *clone();
+ extension_field();
+ protected:
+ // Exception should be added here
+};
+
+
+/**
+ *
+ * It would have been good to have function like get
+ * components this would return the list of components
+ */
+class components_of : public field
+{
+ public:
+ components_of(asn1::node *_typeref)
+ : field("components_of",_typeref)
+ {
+ type_node(_typeref);
+ _typeref->identifier(this);
+ type_id(asn1::type::ASN1_COMPONENTS_OF);
+ }
+ asn1::typeref *get_typeref()
+ {
+ return dynamic_cast<asn1::typeref *>(type_node());
+ }
+ protected:
+};
+
+/**
+ * Classfield classes
+ */
+/**
+ *
+ */
+class classfield : public node
+{
+ public:
+
+ classfield(const std::string &_s,type t);
+
+ ~classfield() {};
+
+ // a field in set or sequence
+ // 2017/05/17 does not work yet !!! 15 errors in hpp
+ inline reference *get_reference() const { return m_reference;};
+ inline void set_reference(reference *r) {m_reference =r;};
+ virtual typenode *get_type() const;
+ protected:
+ asn1::reference *m_reference;
+};
+
+
+#define ASN1_CLASSFIELD_GEN(cls,parent,tp) \
+ class cls : public parent \
+ {\
+ public:\
+ cls(const std::string &s) : parent( s,tp) {} ; \
+ ~cls() {}; \
+
+
+#define ASN1_CLASSFIELD_ADD_classfield_tf ;
+#define ASN1_CLASSFIELD_ADD_classfield_ftvf \
+ classfield_ftvf( const std::string &n \
+ , asn1::typenode *t \
+ , type _t = asn1::type::ASN1_CLASSFIELD_FTVF) ; \
+ typenode *get_type() const;
+#define ASN1_CLASSFIELD_ADD_classfield_vtvf ;
+#define ASN1_CLASSFIELD_ADD_classfield_ftvsf \
+ classfield_ftvsf( const std::string &n \
+ , asn1::typenode *t \
+ , type _t = asn1::type::ASN1_CLASSFIELD_FTVSF) ; \
+ typenode *get_type() const;
+#define ASN1_CLASSFIELD_ADD_classfield_vtvsf ;
+#define ASN1_CLASSFIELD_ADD_classfield_of ;
+#define ASN1_CLASSFIELD_ADD_classfield_osf \
+ classfield_osf( const std::string &n \
+ , asn1::typeref *t \
+ , type _t = asn1::type::ASN1_CLASSFIELD_OSF) ; \
+ typeref *get_typeref() const; \
+ typenode *get_type() const;
+
+#define ASN1_CLASSFIELD_TYPE(cls,parent,tp) \
+ ASN1_CLASSFIELD_GEN(cls,parent,asn1::type::ASN1_##tp) ASN1_CLASSFIELD_ADD_##cls };
+
+#endif
+
--- /dev/null
+#include <iostream>
+#include <list>
+#include <algorithm>
+#include <sstream>
+#include <string.h>
+#include <assert.h>
+
+#include "asn1_meta.h"
+#include "asn1_type.h"
+#include "asn1_value.h"
+#include "asn1_constraint.h"
+#include "aeb/pointer/intrusive_ptr.h"
+#include "asn1_node.h"
+#include "asn1_module.h"
+
+
+namespace asn1
+{
+
+bool
+import_list::get_item(const std::string &type_name,import *&imp,typeref *&ref)
+{
+ bool ret = false;
+
+ asn1::node::iterator it = begin();
+// GEN_LOG_DEBUG("lookup for type %s\n",type.c_str());
+ for (; it != end() ;it++)
+ {
+ asn1::import *import = dynamic_cast<asn1::import *>(*it);
+
+ if (asn1::typeref *_ref = import->get_item(type_name))
+ {
+
+// GEN_LOG_DEBUG("found %s in %s\n",type_name.c_str(),import->identifier()->name().c_str());
+ imp = import;
+ ref = _ref;
+ ret = true;
+ break;
+ }
+ }
+ return ret;
+}
+
+asn1::typeref *
+import::get_item(const std::string &item)
+{
+
+ asn1::node::iterator found = std::find_if( begin()
+ , end()
+ , asn1::find_node(item));
+ if (found != end() )
+ return (*found)->as_typeref();
+ return NULL;
+}
+
+}
+/**
+ * vim: et sw=2 ts=2 list:
+ */
--- /dev/null
+#ifndef ASN1_NODE_IMPORTS_H
+#define ASN1_NODE_IMPORTS_H
+
+class import;
+/**
+ * import_list class contains a list
+ * of import.
+ *
+ */
+class import_list : public constructed
+{
+ public:
+
+ import_list()
+ : constructed("IMPORTS",type::INVALID) {};
+ ~import_list() {};
+
+ /**
+ * @brief find type_name in import_list of current module.
+ * if found return true. ref and imp will be initialized
+ * if not found ref and imp are unchanged.
+ */
+ bool get_item(const std::string &type_name,import *&imp,typeref *&ref);
+ // alternative_imports_iterator
+ protected:
+};
+
+/**
+ * import class contains the elements imported.
+ *
+ */
+class import :public constructed
+{
+ public:
+ import(const std::string &n)
+ : constructed(n,type::INVALID) { } ;
+ ~import() { };
+ /**
+ * lookup for item in this import
+ */
+ typeref *get_item( const std::string &item) ;
+};
+
+/**
+ * vim: et sw=2 ts=2 list:
+ */
+#endif
--- /dev/null
+#include <iostream>
+#include <list>
+#include <algorithm>
+#include <sstream>
+#include <string.h>
+#include <assert.h>
+
+#include "asn1_meta.h"
+#include "asn1_type.h"
+#include "asn1_value.h"
+#include "asn1_constraint.h"
+#include "aeb/pointer/intrusive_ptr.h"
+#include "asn1_node.h"
+#include "asn1_module.h"
+
+
+namespace asn1
+{
+
+/**
+ *
+ */
+object::object()
+ : constructed("OBJECT",type::INVALID)
+ , m_classdef(NULL)
+{
+}
+
+/**
+ */
+object::~object()
+{
+}
+
+void
+object::parsed_field(const std::string &fname,asn1::node *t)
+{
+ m_fields[fname] = t;
+}
+
+void object::update_field(const std::string &fname,asn1::node *t)
+{
+ m_fields[fname] = t;
+}
+
+// defined fields
+asn1::node *
+object::get_field(const std::string &fname)
+{
+ iterator it = m_fields.find(fname);
+ if (it != m_fields.end())
+ {
+ return it->second;
+ } else
+ {
+ return NULL;
+ }
+}
+
+asn1::objectset *
+object::get_objectset(const std::string &fname)
+{
+ return dynamic_cast<asn1::objectset *>(get_field(fname));
+}
+
+}
--- /dev/null
+#ifndef ASN1_NODE_OBJECT_H
+#define ASN1_NODE_OBJECT_H
+
+class classdef;
+class valuetype;
+/**
+ * object that containes
+ */
+class object : public constructed
+{
+ typedef std::map<std::string,asn1::node * > fieldmap_type;
+ typedef fieldmap_type::iterator iterator;
+ typedef fieldmap_type::const_iterator const_iterator;
+ public:
+
+ object() ;
+ ~object() ;
+
+ void parsed_field(const std::string &fname,asn1::node *t);
+ // defined fields
+ asn1::node *get_field(const std::string &fname);
+ asn1::valuetype *get_ftvf(const std::string &fname)
+ { return dynamic_cast<asn1::valuetype *>(get_field(fname)); }
+ asn1::objectset *get_objectset(const std::string &fname);
+
+ void update_field(const std::string &fname,asn1::node *t);
+ // Once parsed, keep a pointer to the classdef. We will need
+ // it for each processing This avoids calls to resolver
+ inline classdef *get_classdef() const { return m_classdef; }
+ inline void set_classdef(classdef *cd) { m_classdef = cd; }
+ protected:
+ classdef *m_classdef;
+ fieldmap_type m_fields;
+};
+
+
+#endif
--- /dev/null
+#include <iostream>
+#include <list>
+#include <algorithm>
+#include <sstream>
+#include <string.h>
+#include <assert.h>
+
+#include "asn1_meta.h"
+#include "asn1_type.h"
+#include "asn1_value.h"
+#include "asn1_constraint.h"
+#include "aeb/pointer/intrusive_ptr.h"
+#include "asn1_node.h"
+#include "asn1_module.h"
+
+
+namespace asn1
+{
+
+parameters::parameters(const parameters &p)
+ : constructed(p)
+{
+ if (this != &p)
+ {
+ // duplicate elements in vector
+ for ( asn1::node::const_iterator it = p.begin()
+ ; it != p.end()
+ ; ++it)
+ {
+ asn1::parameter *param = dynamic_cast<asn1::parameter *>(*it);
+ asn1::parameter *nn = param->clone();
+ nn->set_parent(this);
+ if (nn->type_node())
+ nn->type_node()->set_parent(this);
+ append(nn);
+ }
+ identifier(p.identifier());
+ }
+}
+
+parameters*
+parameters::clone()
+{
+ return new parameters(*this);
+}
+
+bool
+parameters::have_reference(const std::string &name,node::iterator &it)
+{
+ it = std::find_if(begin(),end(),find_node(name));
+ return it != end();
+}
+
+void
+parameters::add_parameter(parameter *p)
+{
+ append(p);
+}
+
+asn1::parameter *
+parameters::operator [](int l)
+{
+ asn1::node *result = *(begin());
+ int i = 0;
+ for (asn1::node::const_iterator it = begin();
+ (it !=end() ) && (i != l + 1)
+ ; ++it,++i)
+ {
+ result = *it;
+ }
+ return dynamic_cast<parameter *>(result);
+}
+
+
+/**
+ *
+ */
+
+act_parameters::act_parameters(const act_parameters &p)
+ : constructed(p)
+{
+ if (this != &p)
+ {
+ // duplicate elements in vector
+ for ( asn1::node::const_iterator it = p.begin()
+ ; it != p.end()
+ ; ++it)
+ {
+ asn1::node *nn = (*it)->clone();
+ nn->set_parent(this);
+ if (nn->type_node())
+ nn->type_node()->set_parent(this);
+ append(nn);
+ }
+ identifier(p.identifier());
+ }
+}
+
+act_parameters*
+act_parameters::clone()
+{
+ return new act_parameters(*this);
+}
+
+asn1::node *
+act_parameters::operator [](int l)
+{
+ asn1::node *result = *(begin());
+ int i = 0;
+ for (asn1::node::const_iterator it = begin();
+ (it !=end() ) && (i != l + 1)
+ ; ++it,++i)
+ {
+ result = *it;
+ }
+ return result;
+}
+
+/*
+ * parameter class implementation
+ */
+parameter::parameter(asn1::node *_gov,asn1::typeref *_ref)
+ : node(_ref->name(),_ref->type_id()(),_ref->meta_id())
+ , m_param_ref(_ref)
+ , m_governor(_gov)
+{
+ type_node(_gov);
+ //set_reference(_ref->get_reference());
+ // To stay compatible with the existing code
+}
+
+
+}
--- /dev/null
+#ifndef ASN1_NODE_PARAMETERS_H
+#define ASN1_NODE_PARAMETERS_H
+
+class typeref ;
+class parameter;
+/**
+ * Instead of creating nodes in the parser,
+ * It's better to build specialized classes with better
+ * services.
+ * - parmeters class is a container of parameters
+ * SHOULD inherit from something like node_container or container
+ */
+class parameters : public constructed
+{
+ parameters(const parameters &p);
+ public:
+ parameters()
+ : constructed("",type::INVALID) {}
+ ~parameters() {}
+ parameters *clone();
+ // Provide some function to find reference according to name
+ // will return the appropriate parameter
+ bool have_reference(const std::string &name,node::iterator &it) ;
+
+ void add_parameter(asn1::parameter *n);
+
+ asn1::parameter *operator [](int l);
+ protected:
+};
+
+/**
+ * Instead of creating nodes in the parser,
+ * It's better to build specialized classes with better
+ * services.
+ * this class contains the actual parameters of a type.
+ * not to mix with parameters.
+ * typeref {parameters} ::= SEQ {
+ * toto Toto {act_parameters}
+ * }
+ */
+class act_parameters : public constructed
+{
+ act_parameters(const act_parameters &ap);
+ public:
+ act_parameters()
+ : constructed("",type::INVALID) {}
+ ~act_parameters() {}
+
+ act_parameters *clone();
+ // Provide some function to find reference according to name
+ // will return the appropriate parameter
+ bool have_reference(const std::string &name,node::iterator &it)
+ {
+ it = std::find_if(begin(),end(),find_node(name));
+ return it != end();
+ }
+
+ void add_parameter(asn1::node *n)
+ {
+ append(n);
+ }
+
+ asn1::node *operator [](int l);
+ protected:
+};
+
+
+/**
+ * A parameter is contained in parameters
+ * a parameter is either a dummyReference -> reference
+ * or governor : dummyReference
+ * governor
+ * reference
+ * a parameter can be a typeref, a value or valueSet or even ObjectSet
+ */
+class parameter : public node
+{
+ parameter(const parameter &p)
+ : node(p) , m_param_ref(p.m_param_ref),m_governor(p.m_governor)
+ {
+ }
+ public:
+ parameter(asn1::node *_gov,asn1::typeref *_ref) ;
+
+ ~parameter() {};
+
+ parameter *clone() { return new parameter(*this); };
+
+ asn1::node *get_governor() const { return m_governor; } ;
+
+ asn1::typeref * get_typeref() const { return m_param_ref; }
+ protected:
+ // Shall own two nodes.
+ asn1::typeref *m_param_ref;
+ // governor and reference.
+ asn1::node *m_governor;
+};
+
+/*
+ * vim:et:sw=2
+ */
+#endif
--- /dev/null
+#include <iostream>
+#include <list>
+#include <vector>
+#include <algorithm>
+#include <sstream>
+#include <string.h>
+#include <assert.h>
+
+#include "asn1_meta.h"
+#include "asn1_type.h"
+#include "asn1_value.h"
+#include "asn1_constraint.h"
+#include "aeb/pointer/intrusive_ptr.h"
+#include "asn1_node.h"
+#include "asn1_module.h"
+
+
+namespace asn1
+{
+#undef DEBUG
+
+
+/*********************************************
+ * integer type specific methods for generator
+ */
+bool integer::is_unsigned() const
+{
+ long min,max;
+ if (get_range(min,max) && (min >= 0))
+ {
+ return true;
+ }
+ return false;
+}
+
+/**
+ * @brief asn1 integers most often have range
+ * constraints.
+ * @return false if no constraint or no real MAX
+ *
+ */
+bool integer::get_range(long &_min,long &_max) const
+{
+ if (has_constraints())
+ {
+ asn1::constraint_range *cr =( *constraint_begin())->as_constraint_range() ;
+ if (cr)
+ {
+ return cr->get_min_max(_min,_max);
+ } else
+ {
+ //GEN_LOG_ERROR("integer::%s not a range constraint",__FUNCTION__);
+ std::cerr<<"integer::"<<__FUNCTION__<<" not a range constraint"<<std::endl;
+ }
+ }
+ return false;
+}
+
+
+/**
+ * This is only valid for OID where we use 7 bits for each octet.
+ * OUTPUT:
+ * v will contain the result. A 7 bit encoded array
+ */
+void object_identifier::encode_integer( long value
+ , arcsType &v)
+{
+ long integer = value;
+ long intsize = 4;
+ long mask = 0x1FF <<23; // Shift 8 *3 - 1 ? 0xFF800000
+#ifdef DEBUG
+ GEN_LOG_DEBUG("generator::encode_integer %ld %lx",value,value);
+#endif
+ while ( (((integer & mask) == 0) || ((integer & mask) == mask))
+ && (intsize > 1)) {
+ intsize--;
+ integer <<=8;
+#ifdef DEBUG
+ GEN_LOG_DEBUG("generator::encode_integer step 1 %lx",integer);
+#endif
+ }
+ mask = (0x7f << ((intsize-1)*7));
+ long decal = (intsize -1)*7;
+#ifdef DEBUG
+ GEN_LOG_DEBUG("generator::encode_integer step 1 intsize=%ld mask=0x%lx decal=%ld",intsize,mask,decal);
+#endif
+ while ((value & mask ) != 0)
+ {
+ long treat = ((value & mask)>>decal);
+ v.push_back (( treat & 0x7F) |0x80 );
+#ifdef DEBUG
+ std::cout<<"\tpushed :";
+ std::cout<<std::hex<<(int)v.back()<<" integer was:"<<value;
+ std::cout<<" Mask=0x"<<mask<<" treat="<<treat;
+ std::cout<<std::dec<<std::endl;
+#endif
+ value<<=7;
+ }
+ v.back() = v.back() & 0x7F;
+}
+
+
+
+void
+object_identifier::oid_value(long *pos,arcsType *v)
+{
+ int first2 = 0;
+#ifdef DEBUG
+ GEN_LOG_DEBUG( "object_identifier::oid_value type_name=%s pos=%d v.size=%ld"
+ , name().c_str(),*pos,v->size());
+#endif
+ if (type_id()() != asn1::type::ASN1_OBJECT_IDENTIFIER)
+ {
+ std::cerr<<__FUNCTION__<<" BAD TYPE SHOULD be OBJECT IDENTIFIER\n";
+ assert(0);
+ }
+ for (asn1::node::iterator lit = begin(); lit != end() ; lit++)
+ {
+//#ifdef DEBUG
+#if 0
+ std::cout<<"object_identifier::"<<__FUNCTION__<<" "<<(*lit)->name()<<" pos="<<*pos;
+ std::cout<<" v.size="<<v->size()<<std::endl;
+#endif
+ if ((*lit)->type_id() == asn1::type::ASN1_INTEGER)
+ {
+ asn1::valuetype *vt = (*lit)->as_value_type();
+ long long l = vt->value_long();
+ if (*pos == 0) {
+ first2 = 40 * vt->value_long();
+ } else if (*pos == 1){
+ first2 = first2 + vt->value_long();
+ v->push_back(first2);
+ } else
+ encode_integer(l,*v);
+ (*pos)++;
+ } else
+ {
+ asn1::node *id = from_module()->lookup((*lit));
+ if (id )
+ {
+ if (asn1::object_identifier *roid = id->type_node()
+ ->as_object_identifier())
+ roid->oid_value(pos,v);
+ } else
+ {
+ // Probaly I have value
+ asn1::valuetype *vt = (*lit)->as_value_type();
+ if (*pos == 0 && vt) {
+ first2 = 40 * vt->value_long();
+ } else if (*pos == 1 && vt) {
+ first2 = first2 + vt->value_long();
+ v->push_back(first2);
+ } else if (vt) {
+ encode_integer(vt->value_long(),*v);
+ } else {
+ std::cerr<<"object_identifier::oid_value vt==NULL";
+ std::cerr<<" tyeid="<<(*lit)->type_id()();
+ std::cerr<<" cpp_name="<<(*lit)->cpp_name()<<std::endl;
+ assert(0);
+ }
+ (*pos)++;
+
+ }
+ }
+
+ }
+#if 0
+ std::cout<<"object_identifier::"<<__FUNCTION__<<" end "<<name()<<" pos="<<*pos;
+ std::cout<<" v.size="<<v->size()<<std::endl;
+#endif
+}
+
+void object_identifier::arcs(arcsType &v)
+{
+ long pos = 0;
+ oid_value(&pos,&v);
+}
+
+void object_identifier::print_strhex( std::ostream &os,const arcsType &v)
+{
+ os<<"\"";
+ for (arcsConstIterator it = v.begin(); it!=v.end() ; it++)
+ {
+ os<<"\\x"<<std::hex<<(int)(*it);
+ }
+ os<<"\"";
+ os<<std::dec;
+}
+
+void object_identifier::print_strhex( std::ostream &os)
+{
+ arcsType v;
+ long pos = 0;
+ oid_value(&pos,&v);
+ //
+ print_strhex(os,v);
+}
+
+long object_identifier::hash()
+{
+ arcsType v;
+ long size = 0;
+ oid_value(&size,&v);
+ size = 0;
+ for (arcsIterator it = v.begin()
+ ; it!=v.end()
+ ; it++)
+ {
+ size += (*it);
+ }
+ return size;
+}
+
+
+};
+/**
+ * vim: et sw=2 ts=2 list:
+ */
--- /dev/null
+#ifndef ASN1_NODE_PRIMITIVE_H
+#define ASN1_NODE_PRIMITIVE_H
+
+
+class primitive : public typenode
+{
+ public:
+
+ primitive(const std::string s, type _t)
+ : typenode(s,_t,meta::TYPE) , m_primitive_tag(m_tag.m_value)
+ { } ;
+
+ primitive(const primitive &p)
+ : m_primitive_tag(p.m_primitive_tag), typenode(p) {}
+ virtual ~primitive() {};
+
+ primitive *clone() { return new primitive(*this);}
+ int primitive_tag() const
+ { return m_primitive_tag; }
+ virtual bool equals(const node&_n) const
+ {
+ return ( type_id()() == _n.type_id()() );
+ }
+ // alternative_primitive_iterator
+ protected:
+ int m_primitive_tag;
+};
+#ifdef NULL
+#ifndef _MSC_VER
+#pragma warn "NULL defined"
+#endif
+#endif
+
+#define ASN1_PRIMITIVE_GEN(cls,parent,stp,tp) \
+ class cls : public parent \
+ {\
+ public:\
+ cls() : parent( stp,tp) {} ; \
+ cls(const cls &c) : parent( c ) {} ; \
+ cls *clone() { return new cls(*this);} \
+ ~cls() {};
+
+
+#define ASN1_PRIMITIVE_ADD_any ;
+#define ASN1_PRIMITIVE_ADD_boolean ;
+#define ASN1_PRIMITIVE_ADD_integer \
+ bool is_unsigned() const; \
+ bool get_range(long &_min,long &_max) const; \
+
+#define ASN1_PRIMITIVE_ADD_bit_string ;
+#define ASN1_PRIMITIVE_ADD_octet_string ;
+#define ASN1_PRIMITIVE_ADD_null ;
+#define ASN1_PRIMITIVE_ADD_object_identifier \
+ int primitive_tag() const { return m_primitive_tag; } ; \
+ typedef std::vector<unsigned char> arcsType; \
+ typedef arcsType::iterator arcsIterator; \
+ typedef arcsType::const_iterator arcsConstIterator; \
+ void arcs(arcsType &v ); \
+ long hash( ); \
+ void encode_integer( long value , arcsType &v); \
+ void print_strhex( std::ostream &os); \
+ void print_strhex( std::ostream &os,const arcsType &v); \
+ protected: \
+ void oid_value(long *pos,arcsType *v);\
+ int m_primitive_tag;
+#define ASN1_PRIMITIVE_ADD_object_descriptor ;
+#define ASN1_PRIMITIVE_ADD_real ;
+#define ASN1_PRIMITIVE_ADD_enumerated ;
+#define ASN1_PRIMITIVE_ADD_relative_oid ;
+#define ASN1_PRIMITIVE_ADD_external ;
+#define ASN1_PRIMITIVE_ADD_embedded_pdv ;
+#define ASN1_PRIMITIVE_ADD_character_string ;
+#define ASN1_PRIMITIVE_ADD_utctime ;
+#define ASN1_PRIMITIVE_ADD_generalizedtime ;
+
+
+#define ASN1_PRIMITIVE_TYPE(cls,parent,tp) \
+ ASN1_PRIMITIVE_GEN(cls,parent,#tp,asn1::type::ASN1_##tp) ASN1_PRIMITIVE_ADD_##cls };
+
+#define ASN1_STRING_TYPE(cls,parent,tp) \
+ class cls : public parent \
+ {\
+ public:\
+ cls() : parent( #tp,asn1::type::ASN1_STRING_##tp) {} ; \
+ cls(const cls &c) : parent( c ) {} ; \
+ cls *clone() { return new cls(*this); } \
+ ~cls() {}; \
+ };
+
+#include "adt/asn1_type.inc"
+
+class extensible : public node
+{
+ public:
+ extensible()
+ : node("...",type::ASN1_EXTENSIBLE) {}
+};
+
+class exportvar : public node
+{
+ public:
+ exportvar()
+ : node("...",type::ASN1_EXPORTVAR) {}
+};
+
+#endif
--- /dev/null
+#ifndef ASN1_NODE_SELECTION_H
+#define ASN1_NODE_SELECTION_H
+
+/**
+ * selection type object is a typeref where get_reference
+ * will return NULL !!!!!
+ *
+ * -> Solver might have a problem with this.
+ */
+class selection : public typeref
+{
+ protected:
+ selection(const selection &s)
+ : typeref(s)
+ {};
+ public:
+
+ selection(const std::string &s,asn1::node *_n = NULL)
+ : typeref(s,NULL,meta::TYPEREF)
+ {
+ type_id(asn1::type::ASN1_SELECTION);
+ meta_id(asn1::meta::TYPEREF);
+ type_node(_n);
+ };
+
+ selection *clone() { return new selection(*this);};
+ ~selection() {};
+
+ protected:
+};
+
+
+#endif
--- /dev/null
+#include <iostream>
+#include <list>
+#include <vector>
+#include <algorithm>
+#include <sstream>
+#include <string.h>
+#include <assert.h>
+
+#include "asn1_meta.h"
+#include "asn1_type.h"
+#include "asn1_value.h"
+#include "asn1_constraint.h"
+#include "aeb/pointer/intrusive_ptr.h"
+#include "asn1_node.h"
+#include "asn1_module.h"
+
+
+namespace asn1
+{
+
+sequence::sequence() : constructed("SEQUENCE",type::ASN1_SEQUENCE)
+{
+}
+
+sequence::sequence(const sequence &s)
+ : constructed("SEQUENCE",type::ASN1_SEQUENCE)
+{
+ std::cerr<<"sequence::sequence copy "<<s.size()<<std::endl;
+ if (this != &s)
+ {
+ // duplicate elements in vector
+ for ( asn1::node::const_iterator it = s.begin()
+ ; it != s.end()
+ ; ++it)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*it);
+ asn1::field *nn = f->clone();
+ nn->set_parent(this);
+ nn->get_type()->set_parent(this);
+ nn->get_type()->identifier(nn);
+ add_component(nn);
+ }
+ set_parent(s.get_parent());
+ //identifier(s.identifier());
+ }
+}
+
+void
+sequence::add_component(asn1::node *c)
+{
+ append(c);
+ if (c && c->flags().is_optional())
+ {
+ m_optionals.push_back(c);
+ }
+}
+
+}
+
--- /dev/null
+#ifndef ASN1_NODE_SEQUENCE_H
+#define ASN1_NODE_SEQUENCE_H
+
+/**
+ * adt sequence type. contains the fields in the sequence.
+ * add methodes to collect optional fields. This will help
+ * in code generation.
+ * component items should also be added through an API from
+ * this class. The goal is to remove container from node class.
+ */
+class sequence : public constructed
+{
+ protected:
+ sequence(const sequence &s);
+ public:
+ typedef std::vector<asn1::node *> OptionalArrayType;
+ typedef OptionalArrayType::iterator OptionalIterator;
+ sequence();
+ ~sequence() {};
+
+ sequence *clone() {return new sequence(*this); }
+
+ OptionalIterator opt_begin() { return m_optionals.begin() ; }
+ OptionalIterator opt_end() { return m_optionals.end() ; }
+
+ size_t opt_size( ) const { return m_optionals.size(); }
+
+ /**
+ * Add a component. the type should be more specific
+ */
+ void add_component(asn1::node *);
+ protected:
+ std::vector<asn1::node *> m_optionals;
+};
+
+
+#endif
--- /dev/null
+#ifndef ASN1_NODE_SEQUENCE_OF_H
+#define ASN1_NODE_SEQUENCE_OF_H
+
+
+class sequence_of : public typenode
+{
+ public:
+
+ sequence_of(asn1::node *_type)
+ : typenode("SEQUENCE_OF",type::ASN1_SEQUENCE_OF)
+ {
+ type_node(_type);
+ _type->set_parent(this);
+ };
+ ~sequence_of() {};
+
+ protected:
+};
+
+
+#endif
--- /dev/null
+#ifndef ASN1_NODE_SET_H
+#define ASN1_NODE_SET_H
+
+
+class set : public constructed
+{
+ public:
+
+ set() : constructed("SET",type::ASN1_SET) {};
+ ~set() {};
+
+ // alternative_set_iterator
+ protected:
+};
+
+
+#endif
--- /dev/null
+#ifndef ASN1_NODE_SET_OF_H
+#define ASN1_NODE_SET_OF_H
+
+
+class set_of : public typenode
+{
+ public:
+
+ set_of(asn1::node *_type)
+ : typenode("SET_OF",type::ASN1_SET_OF) { type_node(_type); };
+ ~set_of() {};
+
+ // alternative_set_iterator
+ protected:
+};
+
+
+#endif
--- /dev/null
+#include <iostream>
+#include <list>
+#include <algorithm>
+#include <sstream>
+#include <string.h>
+#include <assert.h>
+
+#include "asn1_meta.h"
+#include "asn1_type.h"
+#include "asn1_value.h"
+#include "asn1_constraint.h"
+#include "aeb/pointer/intrusive_ptr.h"
+#include "asn1_node.h"
+#include "asn1_reference.h"
+#include "asn1_module.h"
+#include "asn1_node_assignment.h"
+#include "asn1_node_typenode.h"
+
+
+namespace asn1 {
+
+
+
+// copy constructor
+typenode::typenode(const typenode &t)
+ : node (t)
+{
+}
+typenode::typenode(const std::string name
+ , type _t
+ , meta _m )
+ : node(name,_t,_m)
+{
+}
+
+typenode *
+typenode::clone()
+{
+ return new typenode(*this);
+}
+
+// Return the assignment the type is part of
+asn1::assignment *
+typenode::get_assignment( ) const
+{
+ assert(0 && "typenode::get_assignment TODO");
+ return NULL;
+}
+
+// Return the field the is type is part of
+asn1::field *
+typenode::get_field( ) const
+{
+ assert(0 && "typenode::get_field TODO");
+ return NULL;
+}
+
+asn1::typenode *
+typenode::get_eltype( ) const
+{
+ //assert(0 && "typenode::get_eltype TODO");
+ return dynamic_cast<asn1::typenode *>(type_node());
+}
+
+// Need to solve mess with objectset / valueset before
+// Constraints on a node type
+bool typenode::has_constraints() const
+{
+ return m_constraints.begin() != m_constraints.end();
+}
+
+
+}
+
+/**
+ * vim: et sw=2 ts=2 list:
+ */
--- /dev/null
+#ifndef _TYPENODE_H__
+#define _TYPENODE_H__
+
+class field;
+class assignment;
+class resolver;
+/**
+ * Base class for types. It is own by an assignment or field
+ * in constructed type.
+ * This class should be the parent class for all types (primitive
+ * and contructed).
+ * The idea is to move some features from node to type node.
+ * A type does not have a name.
+ */
+class typenode : public node
+{
+ public:
+ typenode(const std::string s, type _t)
+ : node(s,_t,meta::TYPE)
+ { } ;
+
+ typenode(const std::string name
+ , type _t
+ , meta _m );
+ // copy constructor
+ typenode(const typenode &t);
+
+ typenode *clone();
+
+ // Return the assignment the type is part of
+ asn1::assignment * get_assignment( ) const;
+ // Return the field the is type is part of
+ asn1::field * get_field( ) const;
+ // For set_of and sequence_of ...
+ asn1::typenode * get_eltype( ) const;
+
+ inline void constraint(asn1::constraint *c)
+ { m_constraints.append(c); };
+ // Constraints on a node type
+ bool has_constraints() const;
+ // iterators
+ inline asn1::constraint::iterator constraint_begin()
+ { return m_constraints.begin(); };
+
+ //
+ inline asn1::constraint::const_iterator constraint_begin() const
+ { return m_constraints.begin(); };
+
+ //
+ inline asn1::constraint::iterator constraint_end()
+ { return m_constraints.end();};
+
+ //
+ inline asn1::constraint::const_iterator constraint_end() const
+ { return m_constraints.end();};
+ /**
+ * For recursive typeref resolution
+ */
+ virtual void resolve(asn1::resolver &r) {};
+ protected:
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <list>
+#include <algorithm>
+#include <sstream>
+#include <string.h>
+#include <assert.h>
+
+#include "asn1_meta.h"
+#include "asn1_type.h"
+#include "asn1_value.h"
+#include "asn1_constraint.h"
+#include "aeb/pointer/intrusive_ptr.h"
+#include "asn1_node.h"
+#include "asn1_module.h"
+#include "asn1_resolver.h"
+
+
+namespace asn1
+{
+
+/**
+ * May ben
+ */
+typeref::typeref(const typeref &r)
+ : typenode(r)
+ , m_real_type(r.m_real_type)
+ , m_reference(r.m_reference)
+{
+ //set_reference(r.get_reference());
+ if (r.parameters())
+ {
+ std::cerr<<"typeref::typeref copy "<<r.name()<<std::endl;
+ parameters(r.parameters()->clone());
+ }
+}
+
+typeref *
+typeref::clone()
+{
+ return new typeref(*this);
+}
+
+bool typeref::is_complex() const
+{
+ return (get_reference()->size() >1);
+}
+
+bool typeref::is_simple() const
+{
+ return dynamic_cast<simple_reference *>(get_reference()) != NULL;
+}
+//
+bool typeref::is_external() const
+{
+ return dynamic_cast<external_type_reference *>(get_reference()) != NULL;
+}
+//
+bool typeref::is_objectclass() const
+{
+ return dynamic_cast<objectclass_reference *>(get_reference()) != NULL;
+}
+
+bool typeref::is_type_identifier() const
+{
+ try
+ {
+ objectclass_reference &_ref = get_objectclass();
+ return ! std::string("TYPE-IDENTIFIER::&Type").compare(_ref.name());
+ } catch (std::exception &e)
+ {
+ return false;
+ }
+}
+
+objectclass_reference &
+typeref::get_objectclass() const
+{
+ return dynamic_cast<objectclass_reference &>(*get_reference());
+}
+
+simple_reference &
+typeref::get_simple() const
+{
+return dynamic_cast<simple_reference &>(*get_reference());
+}
+
+/**
+ *
+ */
+bool
+typeref::is_imported(std::string &m) const
+{
+ asn1::module *_module = from_module();
+ bool ret = false;
+ asn1::import_list *imports = _module->imports();
+ if (imports == NULL)
+ {
+#if 0
+ GEN_LOG_ERROR("%s type %s not in imports no imports\n"
+ , __FUNCTION__
+ , name().c_str());
+#endif
+ return ret;
+ }
+ asn1::node::iterator it = imports->begin();
+#if 0
+ GEN_LOG_DEBUG("%s lookup for type %s\n"
+ , __FUNCTION__
+ , name().c_str());
+#endif
+ for (; it != imports->end();it++)
+ {
+ asn1::import *import = dynamic_cast<asn1::import *>(*it);
+ asn1::node::iterator found = std::find_if( import->begin()
+ , import->end()
+ , asn1::find_node(name()));
+ if (found != import->end() )
+ {
+#if 0
+ GEN_LOG_DEBUG("%s found %s in %s\n"
+ , __FUNCTION__
+ , name().c_str()
+ , import->identifier()->name().c_str());
+#endif
+ m = import->identifier()->name();
+ ret = true;
+ break;
+ }
+ }
+ return ret;
+
+}
+
+/**
+ *
+ */
+bool
+typeref::equals(const node &_n ) const
+{
+ if (asn1::typeref *tref = const_cast<node &>(_n).as_typeref())
+ {
+ return ! get_reference()->name().compare(tref->get_reference()->name());
+ } else
+ return false;
+};
+
+
+asn1::node::tag_type
+typeref::otag(asn1::resolver &resolver) const
+{
+ asn1::node *t = m_real_type;
+ if (!t)
+ {
+ std::cerr<<"typeref::"<<__FUNCTION__<<" START ";
+ std::cerr<<"have real type: "<<((t != NULL)?1:0);
+ std::cerr<<" "<<from_module()->name()<<"::"<<name()<<std::endl;
+ assert(0 && "typeref::otag must have m_real_type");
+ }
+ if ( tagged())
+ return tag();
+ if ( ! t )
+ t = resolver.resolve(*this);
+ while (t && !t->tagged() && t->as_typeref())
+ {
+ if (t->as_typeref() )
+ {
+ asn1::node *nt = t->as_typeref()->get_real_type();
+ if (! nt)
+ {
+ std::cerr<<"typeref::"<<__FUNCTION__<<" should have real type ";
+ std::cerr<<t->from_module()->name()<<"::"<<t->name()<<std::endl;
+ // if (is_complex())
+ nt = resolver.resolve(*t->as_typeref());
+ if (nt)
+ {
+ std::cerr<<__FUNCTION__<<" got "<<nt->from_module()->name();
+ std::cerr<<"::"<<nt->name()<<std::endl;
+ }
+ }
+ t = nt;
+ } else
+ break;
+ }
+#if 0
+ /* Debug traces */
+ std::cerr<<"typeref::"<<__FUNCTION__<<" END LOOP"<<std::endl;
+#endif
+ if ( t && t->tagged())
+ return t->tag();
+
+ if (asn1::choice *c = dynamic_cast<asn1::choice *>(t))
+ {
+ std::cerr<<"typeref::"<<__FUNCTION__<<" "<<name()<<" t is choice"<<std::endl;
+ return c->get_tag(resolver);
+ }
+ /* What does this mean ? */
+ std::cerr<<"typeref::"<<__FUNCTION__<<" ERROR "<<from_module()->name();
+ std::cerr<<"::"<<name()<<" no tag!";
+ std::cerr<<std::endl;
+ if (is_complex())
+ {
+ return t->tag();
+ }
+ assert((t != NULL) && "otag no tag in reference chaine !");
+ if (t->tag().m_value == -1)
+ std::cerr<<"typeref::"<<__FUNCTION__<<" "<<t->name()<<std::endl;
+ if (t->name().compare("ANY"))
+ assert((t->tag().m_value != -1) && "Tag must have a value");
+ return t->tag();
+}
+
+void
+typeref::resolve(asn1::resolver &_resolver)
+{
+ asn1::node *pi = NULL;
+ asn1::assignment *p = NULL;
+
+ if ( get_parent() )
+ {
+ if (asn1::module *m = dynamic_cast<asn1::module *>(get_parent()))
+ {
+ //std::cerr<<" typeref="<<name()<<" Parent is module identi="<<identifier()->cpp_name()<<std::endl;
+ p = identifier()->as_assignment();
+ } else
+ {
+ pi = get_parent()->identifier();
+ p = pi->as_assignment();
+ }
+ } else {
+ std::cerr<<"typeref::"<<__FUNCTION__<<"pi is NULL not good ";
+ std::cerr<<" parent= NULL";
+ std::cerr<<" typeref="<<name()<<std::endl;
+ }
+ assert(get_parent() != NULL && "Parent is NULL not good");
+ assert(p != NULL && "p is NULL type is ");
+
+ // std::cerr<<"typeref::"<<__FUNCTION__<<" Typeref nore ref "<<name();
+ // std::cerr<<" parent="<<p->name()<<std::endl;
+ if (p && p->parameters())
+ {
+ long pos;
+ m_real_type = p->have_parameter(this,pos);
+ }
+ if (m_real_type == NULL)
+ {
+ //std::cerr<<"typeref::"<<__FUNCTION__<<" call resolve on this "<<name()<<"\n";
+ m_real_type = _resolver.resolve(*this);
+#if 0
+ std::cerr<<"typeref::"<<__FUNCTION__<<" "<<name();
+ std::cerr<<" rt_name "<<m_real_type->cpp_name();
+ std::cerr<<" m_real_type= "<<m_real_type<<"\n";
+#endif
+ }
+#if 0
+ // Leave for debug 02/04/2017
+ std::cerr<<"Before resolve reference "<<name();
+ std::cerr<<" meta="<<meta_id()();
+ std::cerr<<" Is objectclass= "<<is_objectclass()<<std::endl;
+#endif
+ if (m_real_type == NULL)
+ {
+ std::cerr<<"Unable to resolve reference "<<name()<<std::endl;
+ assert(0 && "typeref::resolve should always resolve!!!");
+ return;
+ }
+ assert((m_real_type != NULL) && "typeref::resolve real type not found ");
+ if ( ( m_real_type->is_primitive()
+ || m_real_type->is_constructed())
+ && (is_objectclass() && ! is_complex()))
+ {
+ asn1::reference *ref = get_reference();
+ set_reference( new asn1::simple_reference(ref->name()));
+
+ std::cerr<<"typeref::"<<__FUNCTION__<<" Issue with "<<name();
+ std::cerr<<" Fixed"<<std::endl;
+ delete ref;
+ }
+ // If real_type is reference, I should resolve it too !! or not !
+ asn1::typeref *oref = m_real_type->as_typeref();
+ if (oref)
+ {
+ // std::cerr<<"typeref::"<<__FUNCTION__<<" !! recursif call resolve real_type "<<oref->name()<<std::endl;
+ oref->resolve(_resolver);
+ }
+}
+//
+asn1::typenode *
+typeref::get_canonical_typenode() const
+{
+ assert( (m_real_type != NULL) && "typeref::get_canonical_typenode must have m_real_type");
+ if (asn1::typeref *lr = m_real_type->as_typeref() )
+ {
+ while ( lr && lr->get_real_type()->as_typeref())
+ lr = lr->get_real_type()->as_typeref();
+ assert((lr != NULL) && "typeref::get_canonical_typenode should not have NULL for lr");
+ return lr->as_typenode();
+ } else
+ return m_real_type->as_typenode();
+}
+
+}
--- /dev/null
+#ifndef ASN1_NODE_TYPEREF_H
+#define ASN1_NODE_TYPEREF_H
+
+/**
+ * Helper node that deals with all kind of references.
+ * value reference, typerefence, objectclass and
+ * so one.
+ * This class will be used by resolver to find the
+ * primary type
+ *
+ */
+class resolver;
+class typeref : public typenode
+{
+ protected:
+ typeref(const typeref &r);
+ public:
+
+ typeref(asn1::reference *_ref,meta _m = meta::TYPE)
+ : typenode("TYPEREF",type::ASN1_REFERENCE,_m)
+ , m_real_type(NULL)
+ , m_reference(_ref)
+ {
+ set_reference(_ref);
+ };
+
+ typeref(const std::string &name,asn1::reference *_ref,meta _m = meta::TYPE)
+ : typenode(name,type::ASN1_REFERENCE,_m)
+ , m_real_type(NULL)
+ , m_reference(_ref)
+ {
+ } ;
+
+ typeref *clone();
+
+ ~typeref() {};
+ // from node
+ inline reference *get_reference() const { return m_reference;};
+ inline void set_reference(reference *r) {m_reference =r;};
+ // get_canonical_typenode() return the primitive asn1::typenode
+ // in case of multiple typereference lists
+ // Str3 ::= [ 1] Str2 Str2 ::= [4] IMPLICIT Str1 Str1 ::= VisibleString
+ // canonical typenode will be VisibleString Typenode
+ asn1::typenode *get_canonical_typenode() const;
+
+ // Yes for references like OPERATION.&Id
+ bool is_complex() const;
+ //
+ bool is_simple() const;
+ //
+ bool is_external() const;
+ //
+ bool is_objectclass() const;
+
+ bool is_type_identifier() const;
+
+ objectclass_reference &get_objectclass() const ;
+
+ simple_reference &get_simple() const ;
+ /**
+ * Check if reference is imported. If so
+ * return the module it's imported from.
+ */
+ bool is_imported(std::string &m) const;
+ //
+ virtual bool equals(const node &_n ) const ;
+ // alternative_typeref_iterator
+
+ // The idea here is to save the real type
+ // and fix objectclass that are pointing
+ // to primitive types. Example H323 TBCD-STRING
+ // Which is a IA5String
+ //
+ void resolve(asn1::resolver &_resolver);
+ // Return real type. Null if resolve has
+ // not been called.
+ asn1::node *get_real_type() const
+ { return m_real_type; }
+ /// Return outer most tag
+ asn1::node::tag_type otag(asn1::resolver &r) const;
+ protected:
+ asn1::reference *m_reference;
+ asn1::node *m_real_type;
+};
+
+
+#endif
--- /dev/null
+#include <iostream>
+#include <list>
+#include <algorithm>
+#include <sstream>
+#include <string.h>
+#include <assert.h>
+
+#include "asn1_meta.h"
+#include "asn1_type.h"
+#include "asn1_value.h"
+#include "asn1_constraint.h"
+#include "aeb/pointer/intrusive_ptr.h"
+#include "asn1_node.h"
+#include "asn1_module.h"
+
+
+namespace asn1
+{
+
+valuetype::valuetype(asn1::value *_val,meta _m )
+ : node("VALUE",type::INVALID,_m)
+{
+ value(_val);
+}
+
+valuetype::valuetype( const std::string &name
+ , asn1::value *_ref
+ , meta _m )
+ : node(name,type::INVALID,_m)
+{
+ value(_ref);
+}
+
+valuetype::~valuetype() {};
+
+//TODO Macro to debug an work on value_long that needs to be changed
+//#define WVAL
+//
+// Value ...
+void
+valuetype::value_long(long long l)
+{
+#ifdef WVAL
+ std::cerr<<"ERR valuetype::value_long called with value_long "<<l<<std::endl;
+#endif
+ type_id(type::ASN1_INTEGER);
+ m_value_long = l;
+}
+
+long long
+valuetype::value_long() const
+{
+ if (m_value)
+ {
+ return m_value->m_integer;
+ }
+#ifdef WVAL
+// std::cerr<<"ERROR value_type called with value_long "<<std::endl;
+#endif
+ return m_value_long;
+}
+
+
+
+asn1::typeref *
+valueset::get_typeref()
+{
+ if (m_constraints.size() >= 1)
+ {
+ if (asn1::celt_type *ct = dynamic_cast<asn1::celt_type *>(*m_constraints.begin()))
+ {
+ if (ct->value())
+ return ct->value()->as_typeref();
+ }
+ }
+ return NULL;
+}
+
+/**
+ * objectset
+ */
+objectset_assignment *
+objectset::get_assignment() const
+{
+ return dynamic_cast<objectset_assignment *>(identifier());
+}
+
+void
+objectset::set_classref(asn1::typeref *ref)
+{
+ //TODO needs to be removed
+ type_node(ref);
+ // Final place
+ m_classref = ref;
+}
+
+}
--- /dev/null
+#ifndef ASN1_NODE_VALUETYPE_H
+#define ASN1_NODE_VALUETYPE_H
+
+class objectset_assignment;
+/**
+ * Helper node that deals with all kind of value.
+ * Possible meta
+ * -> VALUE
+ * -> VALUESET
+ * -> OBJECTSET
+ * details about the value are given in asn1_value structure
+ * VT_MIN, VT_MAX, VT_TRUE, VT_FALSE
+ * if VT is CT_COLON, type should be CHOICE
+ * if VT is TRUE or FALSE, type should be BOOLEAN
+ * if VT is MIN,MAX,NUMBER it should be INTEGER
+ * if VT is string, OCTET_STRING
+ * this could allow better correlation between type and
+ * value at the first place
+ * if VT REFERENCED, type could be OBJECT, OBJECTSET,VALUESET
+ */
+class valuetype : public node
+{
+ public:
+
+ valuetype(asn1::value *_val,meta _m = meta::VALUE);
+
+ valuetype( const std::string &name
+ , asn1::value *_ref
+ , meta _m = meta::VALUE) ;
+
+ ~valuetype();
+ //
+ // Value ...
+ void value_long(long long l) ;
+
+ long long value_long() const ;
+ protected:
+};
+
+/**
+ *
+ */
+class valueset : public typenode
+{
+ public:
+ valueset(asn1::constraint *_val) :
+ typenode("valueset",type::ASN1_VALUESET,meta::VALUE)
+ {
+ type_id(type::ASN1_VALUESET);
+ constraint(_val);
+ }
+ ~valueset() {};
+ /*
+ * Specific for Rose ....
+ */
+ asn1::typeref *get_typeref();
+ protected:
+
+};
+
+/**
+ *
+ */
+class objectset : public typenode
+{
+ public:
+ objectset(asn1::constraint *_val) :
+ typenode("objectset",type::ASN1_OBJECTSET,meta::VALUE)
+ {
+ type_id(type::ASN1_VALUESET);
+ constraint(_val);
+ }
+ ~objectset() {};
+
+ objectset_assignment *get_assignment() const;
+
+ void set_classref(asn1::typeref *);
+
+ asn1::typeref *get_classref() const
+ { return m_classref; }
+ protected:
+ asn1::typeref *m_classref;
+
+};
+
+
+#endif
--- /dev/null
+#ifndef ASN1_RECURSIVE_VISITOR_H__
+#define ASN1_RECURSIVE_VISITOR_H__
+
+namespace asn1
+{
+
+
+//std::cout<<"TRY_TO FAILED calling "<< #f<<std::endl;
+
+#define TRY_TO(f) do { \
+ if (! getDerived().f ) { \
+ return false; \
+ } \
+ } while(0)
+
+template <typename Derived >
+class recursive_visitor
+{
+ public:
+ Derived &getDerived() {
+ return *static_cast<Derived *>(this);
+ };
+
+ bool traverse_module(asn1::module *);
+ bool traverse_assignment(asn1::node *);
+ // Assignment traversal
+#define ASSIGNMENT(tp,CLASS,PARENT) bool traverse_assign_##CLASS(CLASS##_assignment *S);
+#include "asn1_meta.inc"
+
+ bool walkup_from_assignment(asn1::node *s)
+ { return getDerived().visit_assignment(s);}
+
+ bool visit_assignment(asn1::node *s) {return true;}
+
+#define ASSIGNMENT(tp,CLASS,PARENT) \
+ bool walkup_from_assign_##CLASS(CLASS##_assignment *S) { \
+ TRY_TO(walkup_from_##PARENT(S)); \
+ TRY_TO(visit_assign_##CLASS(S)); \
+ return true; \
+ } \
+ bool visit_assign_##CLASS(CLASS##_assignment *S) {return true; }
+
+#include "asn1_meta.inc"
+
+ // Type traversal
+ bool traverse_type(asn1::node *);
+#if 0
+#define ASN1_TYPE(CLASS,PARENT,ID) \
+ bool traverse_##CLASS(asn1::node *S);
+#define ASN1_CONSTRUCTED_TYPE(CLASS,PARENT,ID) \
+ bool traverse_##CLASS(asn1::node *S);
+#define ASN1_PRIMITIVE_TYPE(CLASS,PARENT,ID) \
+ bool traverse_##CLASS(asn1::node *S);
+#else
+#define ASN1_TYPE(CLASS,PARENT,ID) \
+ bool traverse_##CLASS(CLASS *S);
+#define ASN1_CONSTRUCTED_TYPE(CLASS,PARENT,ID) \
+ bool traverse_##CLASS(CLASS *S);
+#define ASN1_PRIMITIVE_TYPE(CLASS,PARENT,ID) \
+ bool traverse_##CLASS(CLASS *S);
+#endif
+
+#define ASN1_CLASSFIELD_TYPE(CLASS,PARENT,ID) \
+ bool traverse_##CLASS(CLASS *S); \
+ bool traverse_object_##CLASS(CLASS *S,asn1::node *field ); \
+
+ bool traverse_object_field(asn1::classfield *S,asn1::node *field);
+
+
+#include "adt/asn1_type.inc"
+ bool walkup_from_node(asn1::node *s)
+ { return getDerived().visit_node(s);}
+
+ bool visit_node(asn1::node *s) {return true;}
+ //
+ bool walkup_from_typenode(asn1::node *s)
+ { return getDerived().visit_typenode(s);}
+
+ bool visit_typenode(asn1::node *s) {return true;}
+ //
+ bool walkup_from_typeref(asn1::node *s)
+ { return getDerived().visit_typeref(s);}
+
+ bool visit_typeref(asn1::node *s) {return true;}
+ //
+ bool walkup_from_primitive(asn1::node *s)
+ { return getDerived().visit_primitive(s);}
+
+ bool visit_primitive(asn1::node *s) {return true;}
+ //
+ bool walkup_from_constructed(asn1::node *s)
+ { return getDerived().visit_constructed(s);}
+
+ bool visit_constructed(asn1::node *s) {return true;}
+ //
+ bool walkup_from_object_classfield(asn1::classfield *s,asn1::node *f)
+ { return getDerived().visit_object_classfield(s,f);}
+
+ bool visit_object_classfield(asn1::classfield *s,asn1::node *f)
+ {return true;}
+#if 0
+#define ASN1_TYPE(CLASS,PARENT,ID) \
+ bool walkup_from_##CLASS(asn1::node *S) { \
+ TRY_TO(walkup_from_##PARENT(S)); \
+ TRY_TO(visit_##CLASS(S)); \
+ return true; \
+ } \
+ bool visit_##CLASS(asn1::node *S) {return true; }
+#else
+#define ASN1_TYPE(CLASS,PARENT,ID) \
+ bool walkup_from_##CLASS(CLASS *S) { \
+ TRY_TO(walkup_from_##PARENT(S)); \
+ TRY_TO(visit_##CLASS(S)); \
+ return true; \
+ } \
+ bool visit_##CLASS(CLASS *S) {return true; }
+
+#endif
+#define ASN1_CLASSFIELD_TYPE(CLASS,PARENT,ID) \
+ bool walkup_from_##CLASS(asn1::node *S) { \
+ TRY_TO(walkup_from_##PARENT(S)); \
+ TRY_TO(visit_##CLASS(S)); \
+ return true; \
+ } \
+ bool visit_##CLASS(asn1::node *S) {return true; } \
+ \
+ bool walkup_from_object_##CLASS(CLASS *S,asn1::node *f) { \
+ TRY_TO(walkup_from_##PARENT(S)); \
+ TRY_TO(visit_object_##CLASS(S,f)); \
+ return true; \
+ } \
+ bool visit_object_##CLASS(CLASS *S,asn1::node *f) {return true; }
+
+
+
+#include "adt/asn1_type.inc"
+ // CONSTRAINT traversal
+ //
+ bool traverse_constraint(constraint *S) ;
+ bool traverse_constraint_element(constraint_element *S) ;
+ bool traverse_constraint_type(constraint_type *S) ;
+ bool traverse_constraint_array(constraint_array *S) ;
+#define ELEMENT_CONSTRAINT(tp,CLASS,PARENT) bool traverse_##CLASS(CLASS *S);
+#include "asn1_constraint.inc"
+ // constraint
+ bool walkup_from_constraint(asn1::constraint *s)
+ { return getDerived().visit_constraint(s);}
+
+ bool visit_constraint(asn1::constraint *s) {return true;}
+ // constraint_array
+
+ // constraint_element
+ bool walkup_from_constraint_element(asn1::constraint_element *s)
+ {
+ TRY_TO(walkup_from_constraint(s));
+ return getDerived().visit_constraint_element(s);
+ }
+
+ bool visit_constraint_element(asn1::constraint_element *s) {return true;}
+
+ // constraint_range
+ bool walkup_from_constraint_range(asn1::constraint_range *s)
+ {
+ TRY_TO(walkup_from_constraint(s));
+ return getDerived().visit_constraint_range(s);
+ }
+
+ bool visit_constraint_range(asn1::constraint_range *s) {return true;}
+
+
+
+ // constraint_type
+ bool walkup_from_constraint_type(asn1::constraint_type *s)
+ {
+ TRY_TO(walkup_from_constraint(s));
+ return getDerived().visit_constraint_type(s);
+ }
+
+ bool visit_constraint_type(asn1::constraint_type *s) {return true;}
+ // constraint_array
+ bool walkup_from_constraint_array(asn1::constraint_array *s)
+ {
+ TRY_TO(walkup_from_constraint(s));
+ return getDerived().visit_constraint_array(s);
+ }
+
+ bool visit_constraint_array(asn1::constraint_array *s) {return true;}
+
+
+
+#define ELEMENT_CONSTRAINT(tp,CLASS,PARENT) \
+ bool walkup_from_##CLASS(CLASS *S) { \
+ TRY_TO(walkup_from_##PARENT(S)); \
+ TRY_TO(visit_##CLASS(S)); \
+ return true; \
+ } \
+ bool visit_##CLASS(CLASS *S) {return true; }
+
+#include "asn1_constraint.inc"
+
+
+ // Actual_choice
+ bool traverse_alternative_choice(asn1::field *);
+
+ bool walkup_from_alternative_choice(asn1::field *s)
+ { return getDerived().visit_alternative_choice(s);}
+
+ bool visit_alternative_choice(asn1::field *s) {return true;}
+ // Component type
+ bool traverse_component_type(asn1::field *);
+
+ bool walkup_from_component_type(asn1::field *s)
+ { return getDerived().visit_component_type(s);}
+
+ bool visit_component_type(asn1::field *s) {return true;}
+
+ protected:
+ asn1::module::iterator m_module_iterator;
+};
+
+/**
+ * Implementation part
+ */
+template <typename Derived>
+bool recursive_visitor<Derived>::traverse_module(asn1::module *S) {
+ if (! S)
+ return true;
+ for ( m_module_iterator = S->begin()
+ ; m_module_iterator != S->end()
+ ; ++m_module_iterator)
+ {
+ // I should probably stop if traverse return false
+ // std::cerr<<"recursive_visitor traverse "<<(*m_module_iterator)->name()<<std::endl;
+ traverse_assignment((*m_module_iterator));
+ // std::cerr<<"recursive_visitor traverse end "<<(*m_module_iterator)->name()<<std::endl;
+ }
+ return true;
+}
+
+template <typename Derived>
+bool recursive_visitor<Derived>::traverse_alternative_choice(asn1::field *S)
+{
+ TRY_TO(walkup_from_alternative_choice(S));
+ return traverse_type(S->get_type());
+}
+
+
+
+template <typename Derived>
+bool recursive_visitor<Derived>::traverse_component_type(asn1::field *S)
+{
+ TRY_TO(walkup_from_component_type(S));
+ return traverse_type(S->get_type());
+}
+// -- Assignment Traversal
+
+#define DEF_TRAVERSE_ASSIGN(STAMT,CODE) \
+ template <typename Derived> \
+ bool recursive_visitor<Derived>::traverse_assign_##STAMT(STAMT##_assignment *S) { \
+ TRY_TO(walkup_from_assign_##STAMT(S)); \
+ { CODE ; } \
+ /* Traverse Children to be done*/ \
+ return traverse_type(S->get_type()); \
+ /*return true; */ \
+ } \
+
+#if 0
+#define DISPATCH(NAME,CLASS,VAR) \
+ return getDerived().traverse_##NAME(static_cast<asn1::node *>(VAR))
+#else
+#define DISPATCH(NAME,CLASS,VAR) \
+ return getDerived().traverse_##NAME(static_cast<CLASS *>(VAR))
+#endif
+
+#define DISPATCH_CLS(NAME,CLASS,VAR) \
+ return getDerived().traverse_##NAME(static_cast<CLASS *>(VAR))
+
+template <typename Derived>
+bool recursive_visitor<Derived>::traverse_assignment(asn1::node *S)
+{
+#define DISPATCH_ASSIGN(NAME,CLASS,VAR) \
+ return getDerived().traverse_assign_##NAME(static_cast<CLASS##_assignment *>(VAR))
+ if (! S)
+ return true;
+ // Dispatch according to statement
+ switch (S->meta_id()()) {
+ case asn1::meta::MAX:
+ case asn1::meta::INVALID:
+ break;
+#define ASSIGNMENT(TP,CLASS,PARENT) \
+ case asn1::meta::TP : \
+ DISPATCH_ASSIGN(CLASS,CLASS,S);
+#include "asn1_meta.inc"
+ }
+ return true;
+}
+
+template <typename Derived>
+bool recursive_visitor<Derived>::traverse_type(asn1::node *S)
+{
+ if (! S)
+ return true;
+#define DISPATCH_TYPE(NAME,CLASS,VAR) DISPATCH(NAME,CLASS,VAR)
+ // Dispatch according to statement
+ switch (S->type_id()()) {
+ case asn1::type::INVALID:
+ break;
+#define ASN1_TYPE(CLASS,PARENT,TP) \
+ case asn1::type::ASN1_##TP : \
+ DISPATCH_TYPE(CLASS,CLASS,S);
+
+#define ASN1_CLASSFIELD_TYPE(CLASS,PARENT,TP) \
+ case asn1::type::ASN1_##TP : \
+ DISPATCH_CLS(CLASS,CLASS,S);
+
+#define ASN1_STRING_TYPE(CLASS,PARENT,TP) \
+ case asn1::type::ASN1_STRING_##TP : \
+ DISPATCH_TYPE(CLASS,CLASS,S);
+
+
+#include "adt/asn1_type.inc"
+ default:
+ ;
+ }
+ return true;
+}
+
+template <typename Derived>
+bool recursive_visitor<Derived>::traverse_object_field(asn1::classfield *S
+ ,asn1::node *field)
+{
+ if (! S)
+ return true;
+#define DISPATCH_OBJF(NAME,CLASS,VAR) \
+ return getDerived().traverse_object_##NAME(static_cast<CLASS *>(VAR),field)
+ // Dispatch according to statement
+ switch (S->type_id()()) {
+ case asn1::type::INVALID:
+ break;
+#define ASN1_TYPE(CLASS,PARENT,TP)
+#define ASN1_PRIMITIVE_TYPE(CLASS,PARENT,TP)
+#define ASN1_CONSTRUCTED_TYPE(CLASS,PARENT,TP)
+#define ASN1_STRING_TYPE(CLASS,PARENT,TP)
+
+#define ASN1_CLASSFIELD_TYPE(CLASS,PARENT,TP) \
+ case asn1::type::ASN1_##TP : \
+ DISPATCH_OBJF(CLASS,CLASS,S);
+
+
+#include "adt/asn1_type.inc"
+ default:
+ ;
+ }
+ return true;
+}
+
+/* Implementation Traverse assignment */
+DEF_TRAVERSE_ASSIGN(typeref,{})
+DEF_TRAVERSE_ASSIGN(type,{})
+DEF_TRAVERSE_ASSIGN(value,{})
+DEF_TRAVERSE_ASSIGN(valueset,{
+ if ( asn1::value *v = S->value())
+ {
+ traverse_constraint(v->m_constraint);
+ }
+})
+DEF_TRAVERSE_ASSIGN(object,{
+ asn1::object *obj = dynamic_cast<asn1::object *>(S->type_node()->type_node());
+ // Now, Get classdef and visit the fields
+ if (asn1::classdef *cdef = obj->get_classdef())
+ {
+ for ( asn1::node::iterator it = cdef->begin()
+ ; it != cdef->end()
+ ; ++it)
+ {
+ if (asn1::node *field = obj->get_field((*it)->name()))
+ {
+ traverse_object_field(static_cast<asn1::classfield *>(*it),field);
+ }
+ }
+ }
+})
+DEF_TRAVERSE_ASSIGN(objectclass,{})
+DEF_TRAVERSE_ASSIGN(objectset,{
+})
+DEF_TRAVERSE_ASSIGN(objectfield,{})
+
+/* Implementation Traverse type */
+
+
+#define DEF_TRAVERSE_TYPE(STAMT,CODE) \
+ template <typename Derived> \
+ bool recursive_visitor<Derived>::traverse_##STAMT(STAMT *S) { \
+ TRY_TO(walkup_from_##STAMT(S)); \
+ { CODE ; } \
+ /* Traverse Children to be done*/ \
+ /*return traverse_type(S->todo()); */ \
+ return true; \
+ } \
+
+
+DEF_TRAVERSE_TYPE(reference,{})
+DEF_TRAVERSE_TYPE(exportvar,{})
+//DEF_TRAVERSE_TYPE(universal,{})
+//DEF_TRAVERSE_TYPE(bitvector,{})
+DEF_TRAVERSE_TYPE(extensible,{})
+DEF_TRAVERSE_TYPE(components_of,{})
+DEF_TRAVERSE_TYPE(valueset,{
+ if ( asn1::value *v = S->value())
+ {
+ traverse_constraint(v->m_constraint);
+ }
+})
+
+DEF_TRAVERSE_TYPE(objectset,{
+ if ( asn1::value *v = S->value())
+ {
+ traverse_constraint(v->m_constraint);
+ }
+})
+
+DEF_TRAVERSE_TYPE(classdef,{
+ for (asn1::node::iterator it = S->begin()
+ ; it != S->end()
+ ; ++it)
+ traverse_component_type(reinterpret_cast<asn1::field *>(*it));
+})
+//DEF_TRAVERSE_TYPE(instance,{})
+DEF_TRAVERSE_TYPE(classfield,{})
+/**
+ * CLASS FIELD TYPE
+ */
+#define DEF_TRAVERSE_CLASSFIELD(STAMT,CODE,CODE1) \
+ template <typename Derived> \
+ bool recursive_visitor<Derived>::traverse_##STAMT(STAMT *S) { \
+ TRY_TO(walkup_from_classfield(S)); \
+ TRY_TO(visit_##STAMT(S)); \
+ { CODE ; } \
+ /* Traverse Children to be done*/ \
+ /*return traverse_type(S->todo()); */ \
+ return true; \
+ } \
+ template <typename Derived> \
+ bool recursive_visitor<Derived>::traverse_object_##STAMT \
+ (STAMT *S,asn1::node *f) { \
+ TRY_TO(walkup_from_object_classfield(S,f)); \
+ TRY_TO(visit_object_##STAMT(S,f)); \
+ { CODE1; } \
+ /* Traverse Children to be done*/ \
+ /*return traverse_type(S->todo()); */ \
+ return true; \
+ } \
+
+DEF_TRAVERSE_CLASSFIELD(classfield_tf,{},{})
+DEF_TRAVERSE_CLASSFIELD(classfield_ftvf,{},{})
+DEF_TRAVERSE_CLASSFIELD(classfield_vtvf,{},{})
+DEF_TRAVERSE_CLASSFIELD(classfield_ftvsf,{},{})
+DEF_TRAVERSE_CLASSFIELD(classfield_vtvsf,{},{})
+DEF_TRAVERSE_CLASSFIELD(classfield_of,{},{})
+DEF_TRAVERSE_CLASSFIELD(classfield_osf,{
+},
+{
+ if (f)
+ {
+ if ( asn1::value *v = f->value())
+ {
+ traverse_constraint(v->m_constraint);
+ }
+ }
+ }
+)
+
+/*
+ * CONSTRUCTED TYPES
+ */
+#define DEF_TRAVERSE_CONSTRUCTED DEF_TRAVERSE_TYPE
+DEF_TRAVERSE_CONSTRUCTED(sequence,{
+ for (asn1::node::iterator it = S->begin()
+ ; it != S->end()
+ ; ++it)
+ traverse_component_type(reinterpret_cast<asn1::field *>(*it));
+})
+DEF_TRAVERSE_CONSTRUCTED(choice,{
+ for (asn1::node::iterator it = S->begin()
+ ; it != S->end()
+ ; ++it)
+ traverse_alternative_choice(reinterpret_cast<asn1::field *>(*it));
+})
+DEF_TRAVERSE_CONSTRUCTED(set,{
+ for (asn1::node::iterator it = S->begin()
+ ; it != S->end()
+ ; ++it)
+ traverse_component_type(reinterpret_cast<asn1::field *>(*it));
+})
+DEF_TRAVERSE_CONSTRUCTED(sequence_of,{
+ traverse_type(S->get_eltype());
+})
+DEF_TRAVERSE_CONSTRUCTED(set_of,{
+ traverse_type(S->get_eltype());
+})
+DEF_TRAVERSE_CONSTRUCTED(selection,{})
+/*
+ * PRIMITIVE TYPES
+ */
+#define DEF_TRAVERSE_PRIMITIVE DEF_TRAVERSE_TYPE
+DEF_TRAVERSE_PRIMITIVE(any,{})
+DEF_TRAVERSE_PRIMITIVE(boolean,{})
+DEF_TRAVERSE_PRIMITIVE(integer,{})
+DEF_TRAVERSE_PRIMITIVE(bit_string,{})
+DEF_TRAVERSE_PRIMITIVE(octet_string,{})
+DEF_TRAVERSE_PRIMITIVE(null,{})
+DEF_TRAVERSE_PRIMITIVE(object_identifier,{})
+DEF_TRAVERSE_PRIMITIVE(object_descriptor,{})
+DEF_TRAVERSE_PRIMITIVE(real,{})
+DEF_TRAVERSE_PRIMITIVE(enumerated,{})
+DEF_TRAVERSE_PRIMITIVE(relative_oid,{})
+DEF_TRAVERSE_PRIMITIVE(external,{})
+DEF_TRAVERSE_PRIMITIVE(embedded_pdv,{})
+DEF_TRAVERSE_PRIMITIVE(character_string,{})
+DEF_TRAVERSE_PRIMITIVE(utctime,{})
+DEF_TRAVERSE_PRIMITIVE(generalizedtime,{})
+/*
+ * STRING TYPES
+ */
+/*
+ASN1_STRING_TYPE(string,primitive,STRING)
+*/
+#define DEF_TRAVERSE_STRING DEF_TRAVERSE_TYPE
+DEF_TRAVERSE_STRING(ia5string,{})
+DEF_TRAVERSE_STRING(printablestring,{})
+DEF_TRAVERSE_STRING(visiblestring,{})
+DEF_TRAVERSE_STRING(iso646string,{})
+DEF_TRAVERSE_STRING(numericstring,{})
+DEF_TRAVERSE_STRING(universalstring,{})
+DEF_TRAVERSE_STRING(bmpstring,{})
+DEF_TRAVERSE_STRING(utf8string,{})
+DEF_TRAVERSE_STRING(generalstring,{})
+DEF_TRAVERSE_STRING(graphicstring,{})
+DEF_TRAVERSE_STRING(teletexstring,{})
+DEF_TRAVERSE_STRING(t61string,{})
+DEF_TRAVERSE_STRING(videotexstring,{})
+DEF_TRAVERSE_STRING(objectdescriptor_string,{})
+
+/**
+ * VISITE CONSTRAINTS
+ */
+template <typename Derived>
+bool recursive_visitor<Derived>::traverse_constraint(asn1::constraint *S)
+{
+ if (! S)
+ return true;
+#define DISPATCH_CONSTRAINT(NAME,CLASS,VAR) DISPATCH_CLS(NAME,CLASS,VAR)
+ // Dispatch according to statement
+ switch (S->type()) {
+ case asn1::constraint::EL_INVALID:
+ break;
+#define ELEMENT_CONSTRAINT(TP,CLASS,PARENT) \
+ case asn1::constraint::TP : \
+ DISPATCH_CONSTRAINT(CLASS,CLASS,S);
+
+#include "asn1_constraint.inc"
+ default:
+ std::cout<<"UNKNOWN CONSTRAINT"<<std::endl;
+ ;
+ }
+ return true;
+}
+
+/* Implementation Traverse type */
+#define DEF_TRAVERSE_CONSTRAINT(STAMT,CODE) \
+ template <typename Derived> \
+ bool recursive_visitor<Derived>::traverse_##STAMT(STAMT *S) { \
+ TRY_TO(walkup_from_##STAMT(S)); \
+ { CODE ; } \
+ /* Traverse Children to be done*/ \
+ /*return traverse_type(S->todo()); */ \
+ return true; \
+ } \
+
+DEF_TRAVERSE_CONSTRAINT(constraint_element,{})
+DEF_TRAVERSE_CONSTRAINT(constraint_type,{})
+DEF_TRAVERSE_CONSTRAINT(constraint_array,{})
+/* Element type */
+DEF_TRAVERSE_CONSTRAINT(celt_type,{})
+DEF_TRAVERSE_CONSTRAINT(celt_value,{})
+DEF_TRAVERSE_CONSTRAINT(celt_range,{})
+DEF_TRAVERSE_CONSTRAINT(celt_llrange,{})
+DEF_TRAVERSE_CONSTRAINT(celt_rlrange,{})
+DEF_TRAVERSE_CONSTRAINT(celt_ulrange,{})
+DEF_TRAVERSE_CONSTRAINT(celt_encodedby,{})
+DEF_TRAVERSE_CONSTRAINT(celt_ext,{})
+
+/*Constraint type */
+#define DEF_TRAVERSE_CONSTRAINT_TYPE(elt,code) DEF_TRAVERSE_CONSTRAINT(elt,code)
+DEF_TRAVERSE_CONSTRAINT_TYPE(ctype_size,{})
+DEF_TRAVERSE_CONSTRAINT_TYPE(ctype_from,{})
+DEF_TRAVERSE_CONSTRAINT_TYPE(ctype_wcomp,{})
+DEF_TRAVERSE_CONSTRAINT_TYPE(ctype_wcomps,{})
+DEF_TRAVERSE_CONSTRAINT_TYPE(ctype_ctdby,{})
+DEF_TRAVERSE_CONSTRAINT_TYPE(ctype_ctng,{})
+
+/* Array Constraints */
+#define DEF_TRAVERSE_CONSTRAINT_ARRAY(elt,code) DEF_TRAVERSE_CONSTRAINT(elt,code)
+DEF_TRAVERSE_CONSTRAINT_ARRAY(ca_set,{
+ for (asn1::constraint::iterator it = S->begin()
+ ; it != S->end()
+ ; ++it)
+ {
+ traverse_constraint(*it);
+ }
+})
+DEF_TRAVERSE_CONSTRAINT_ARRAY(ca_crc,{})
+DEF_TRAVERSE_CONSTRAINT_ARRAY(ca_csv,{})
+DEF_TRAVERSE_CONSTRAINT_ARRAY(ca_uni,{
+ for (asn1::constraint::iterator it = S->begin()
+ ; it != S->end()
+ ; ++it)
+ {
+ traverse_constraint(*it);
+ }
+
+})
+DEF_TRAVERSE_CONSTRAINT_ARRAY(ca_int,{})
+DEF_TRAVERSE_CONSTRAINT_ARRAY(ca_exc,{})
+DEF_TRAVERSE_CONSTRAINT_ARRAY(ca_aex,{})
+
+
+/**
+ * END
+ */
+#undef DEF_TRAVERSE_STRING
+#undef DEF_TRAVERSE_TYPE
+#undef DEF_TRAVERSE_CONSTRUCTED
+#undef DEF_TRAVERSE_PRIMITIVE
+#undef DEF_TRAVERSE_CLASSFIELD
+
+/* END NAMESPACE ASN1 */
+}
+
+#endif
--- /dev/null
+
+#include <iostream>
+#include <list>
+#include <algorithm>
+#if defined(_WIN32)
+#include <iterator>
+#endif
+#include "asn1_node.h"
+#include "asn1_reference.h"
+
+namespace asn1 {
+
+static
+char lop_substitute(char c)
+{
+ return (c == '-')?'_':c;
+}
+
+reference::reference()
+ : node ("",type::ASN1_REFERENCE)
+{
+}
+
+reference::reference(const asn1::reference::component &c)
+ : node("",type::ASN1_REFERENCE)
+{
+ add_component(c);
+}
+
+reference::reference(const asn1::reference::component_list &c)
+ : node("",type::ASN1_REFERENCE)
+{
+ add_components(c);
+}
+
+reference::reference(const reference &ref)
+ : node(ref)
+{
+ std::copy( ref.m_components.begin()
+ , ref.m_components.end()
+ , std::back_inserter(m_components));
+}
+
+reference::~reference()
+{
+}
+
+void
+reference::add_component(const struct component &c)
+{
+ m_components.push_back(c);
+}
+
+void
+reference::add_components(const component_list &c)
+{
+ std::copy(c.begin(),c.end(),std::back_inserter(m_components));
+}
+
+
+std::string
+reference::name() const
+{
+ std::string s;
+ if (m_components.size() > 0)
+ {
+ for (component_const_iterator it = m_components.begin();
+ it != m_components.end();
+ ++it)
+ {
+ if (s.size() > 0)
+ s = s + "::";
+ s = s + (*it).m_identifier;
+ }
+ }
+ return s;
+}
+
+void
+reference::replace_objectclass(const std::string &o)
+{
+ component n(o,component::CAPITALS);
+ m_components.pop_front();
+ m_components.push_front(n);
+}
+
+std::string
+reference::cpp_name() const
+{
+ std::string n = name();
+ std::string cppname;
+ cppname.resize(n.size());
+
+ std::transform(n.begin(),n.end(),cppname.begin(),asn1::lop_substitute);
+ return cppname;
+}
+
+
+
+reference::component::component(const std::string &n ,component::eType _t) : type(_t), m_identifier(n) {}
+
+bool
+reference::component::operator ==(const struct component &c)
+{
+return (!m_identifier.compare(c.m_identifier) && type == c.type);
+}
+
+
+
+
+
+reference::component_iterator
+reference::begin() { return m_components.begin();};
+
+reference::component_iterator
+reference::end() { return m_components.end();};
+
+reference::component_const_iterator
+reference::begin() const { return m_components.begin();};
+
+reference::component_const_iterator
+reference::end() const { return m_components.end();};
+
+reference::component
+reference::back() { return m_components.back();};
+
+reference::component
+reference::front() const { return m_components.front();};
+
+size_t
+reference::size() const { return m_components.size();} ;
+
+reference::component_list &
+reference::get_components() { return m_components; };
+
+const
+reference::component_list &
+reference::get_components() const { return m_components; };
+
+bool
+reference::equals(const reference &) const { return false; } ;
+
+bool
+reference::operator ==(const reference &r) const{ return equals(r); };
+
+
+
+/** **/
+bool simple_reference::equals(const reference &r)
+{
+ return (size() == r.size())
+ && (front() == r.front());
+}
+/** **/
+external_type_reference::external_type_reference(const std::string &module,const std::string &tp)
+ : reference(component(module,component::Uppercase))
+{
+ component c(tp,component::Uppercase);
+ add_component(c);
+}
+
+external_type_reference::external_type_reference(const std::string &module,const reference::component_list &tp)
+ : reference(component(module,component::Uppercase))
+{
+ add_components(tp);
+}
+
+external_type_reference::external_type_reference(const std::string &module,const reference &tp)
+ : reference(component(module,component::Uppercase))
+{
+ add_components(tp.get_components());
+}
+
+
+bool external_type_reference::equals(const reference &r)
+{
+ return (size() == r.size())
+ && (front() == r.front());
+}
+
+/** **/
+
+external_value_reference::external_value_reference(const std::string &module,const std::string &val)
+: reference(component(module,component::Uppercase))
+{
+ component c(val,component::Lowercase);
+ add_component(c);
+}
+
+external_value_reference::~external_value_reference() {}
+
+bool external_value_reference::equals(const reference &r)
+{
+ return (size() == r.size())
+ && (front() == r.front());
+}
+
+
+}
--- /dev/null
+#ifndef ASN1_REFERENCE_H
+#define ASN1_REFERENCE_H
+
+namespace asn1 {
+
+class node;
+
+class reference : public node {
+ public:
+ struct component;
+
+ typedef std::list<component> component_list;
+ typedef std::list<component>::iterator component_iterator;
+ typedef std::list<component>::const_iterator component_const_iterator;
+
+ reference();
+
+ reference(const struct component &c) ;
+
+ reference(const reference &_r) ;
+
+ reference(const component_list &cl);
+
+ ~reference();
+
+ /**
+ *
+ */
+ struct component
+ {
+ enum eType {
+ UNKNOWN,
+ CAPITALS,
+ Uppercase,
+ Lowercase,
+ AmpUppercase,
+ AmpLowercase
+
+ } type;
+
+ std::string m_identifier;
+
+ inline std::string name() const { return m_identifier; };
+
+ component(const std::string &n = "" ,eType _t = UNKNOWN) ;
+
+ bool operator ==(const struct component &c);
+
+ };
+
+
+ void add_component(const struct component &c);
+
+ void add_components(const component_list &cl);
+
+ std::string name() const;
+
+ std::string cpp_name() const;
+
+ component_iterator begin() ;
+
+ component_iterator end();
+
+ component_const_iterator begin() const;
+
+ component_const_iterator end() const;
+
+ component back();
+ component front() const ;
+ size_t size() const ;
+
+ component_list &get_components() ;
+
+ const component_list &get_components() const;
+
+ virtual bool equals(const reference &) const;
+
+ bool operator ==(const reference &r) const ;
+
+ void replace_objectclass(const std::string &o);
+ protected:
+ component_list m_components;
+};
+
+/**
+ *
+ */
+class simple_reference : public reference
+{
+ public:
+ simple_reference(const struct component &c) : reference()
+ {
+ }
+
+ simple_reference(const std::string &n,component::eType _t = component::Uppercase)
+ : reference(component(n,_t) )
+ {
+ }
+
+ ~simple_reference() {}
+
+ virtual bool equals(const reference &r) ;
+ protected:
+};
+
+/**
+ *
+ */
+class external_type_reference : public reference
+{
+ public:
+ external_type_reference(const std::string &module,const std::string &tp) ;
+
+ external_type_reference(const std::string &module,const reference::component_list &tp) ;
+
+ external_type_reference(const std::string &module,const reference &tp);
+
+ ~external_type_reference() {}
+
+ virtual bool equals(const reference &r) ;
+ protected:
+};
+
+
+/**
+ *
+ */
+class external_value_reference : public reference
+{
+ public:
+ external_value_reference(const std::string &module,const std::string &val) ;
+ ~external_value_reference() ;
+
+ virtual bool equals(const reference &r) ;
+ protected:
+};
+
+
+/**
+ * objectclass reference can contain
+ * typefield reference
+ * valuefied reference
+ * type referece
+ * I think that this is the only class that needs a list of fields
+ */
+class objectclass_reference : public reference
+{
+ public:
+ objectclass_reference(const std::string &n)
+ : reference(component(n,component::CAPITALS))
+ {
+ } ;
+ ~objectclass_reference() {} ;
+
+ std::string objectclass()
+ {
+ return m_components.front().m_identifier;
+ }
+
+ std::string field() const
+ { return m_components.back().m_identifier; }
+};
+
+
+/**
+ *
+ */
+class typefield_reference : public reference
+{
+ public:
+ typefield_reference(const std::string &n)
+ : reference(component(n,component::AmpUppercase))
+ {
+ } ;
+ ~typefield_reference() {} ;
+};
+
+
+/**
+ *
+ */
+class valuefield_reference : public reference
+{
+ public:
+ valuefield_reference(const std::string &n)
+ : reference(component(n,component::AmpLowercase))
+ {
+ } ;
+ ~valuefield_reference() {} ;
+};
+
+
+
+
+}
+#endif
+
--- /dev/null
+#include <iostream>
+#include <list>
+#include <algorithm>
+#include <sstream>
+#include <string.h>
+#include <assert.h>
+
+#include "asn1_meta.h"
+#include "asn1_type.h"
+#include "asn1_value.h"
+#include "asn1_constraint.h"
+#include "aeb/pointer/intrusive_ptr.h"
+#include "asn1_module.h" //includes nodes.
+
+#include "asn1_resolver.h"
+#if defined(_WIN32)
+#define GEN_LOG_DEBUG(fmt,...)
+#define GEN_LOG_INFO(fmt,...)
+#define GEN_LOG_ERROR(fmt,...)
+#define GEN_LOG_WARN(fmt,...)
+#else
+#define GEN_LOG_DEBUG(fmt,args...)
+#define GEN_LOG_INFO(fmt,args...)
+#define GEN_LOG_ERROR(fmt,args...) fprintf(stderr,fmt,args)
+#define GEN_LOG_WARN(fmt,args...)
+#endif
+namespace asn1 {
+
+/**
+ *
+ */
+resolver::resolver( const asn1::module &_m
+ , const asn1::module::modules_type &_mods)
+ : m_module(_m),m_module_list(_mods)
+{
+}
+
+/**
+ *
+ */
+resolver::~resolver()
+{
+}
+
+/**
+ * Resolve with reference
+ * Simple references should be found in the current module
+ */
+asn1::node * resolver::resolve(const typeref &_ref)
+{
+ asn1::node *nr = NULL;
+ if ( _ref.is_simple())
+ {
+ asn1::node::const_iterator it = std::find_if(m_module.begin()
+ , m_module.end()
+ , asn1::find_node(_ref.name()));
+ if (it != m_module.end())
+ {
+#if 0
+ // 2017/05/10 Issue with H323 and typeref resolve !! Fails with ClearToken
+ // Found Here null in caller. Looks like a stack overflow
+ std::cerr<<"resolver::resolve type "<<_ref.name()<<" Found in module\n";
+ std::cerr<<"resolver::resolve "<<(*it)->as_assignment()->get_type()->name()<<" Found in module ";
+ std::cerr<<(*it)->as_assignment()->get_type()<<"\n";
+#endif
+ return (*it)->as_assignment()->get_type();
+ }else
+ {
+ // Node not found in module, try other modules from imports
+ asn1::node *ns;
+ if (type_in_imports(_ref.name(),&ns))
+ {
+ if ( !get_type_in_module(ns->name(),_ref.name(),&nr) )
+ {
+ std::cerr<<"resolver::resolve type <"<<_ref.name();
+ std::cerr<<"> Not Found in module "<<ns->name()<<std::endl;
+ std::cerr<<"modules size : "<<m_module_list.size()<<std::endl;
+ assert(0);
+ } else
+ {
+#if 0
+ /* No console trace when OK */
+ std::cerr<<"resolver::resolve type in import "<<_ref.name();
+ std::cerr<<" in module "<<nr->from_module()->name()<<" Found\n";
+#endif
+ GEN_LOG_WARN("resolver::resolve tye %s found in imports %s\n"
+ , _ref.name().c_str()
+ , ns->name().c_str()
+ );
+ nr = nr->as_assignment()->get_type();
+ }
+ } else
+ {
+ std::string modname("");
+ if (! _ref.is_imported(modname))
+ modname = _ref.from_module()->name();
+ // Type not in imports.
+ std::cerr<<"resolver::resolve type <"<<_ref.name()<<" not in imports"<<std::endl;
+ GEN_LOG_WARN("resolver::resolve type %s not found in imports\n"
+ , _ref.name().c_str()
+ );
+ std::cerr<<"resolver::resolve try in module "<<modname<<std::endl;
+ if ( !get_type_in_module(modname,_ref.name(),&nr) )
+ {
+ std::cerr<<"resolver::resolve type "<<_ref.name()<<" not in module =";
+ std::cerr<<modname<<std::endl;
+ } else {
+ nr = nr->as_assignment()->get_type();
+ }
+ }
+ }
+
+ } else if (_ref.is_objectclass())
+ {
+ asn1::objectclass_reference & ocr = _ref.get_objectclass();
+ asn1::node::const_iterator it = std::find_if(m_module.begin()
+ , m_module.end()
+ , asn1::find_node(ocr.objectclass()));
+ if (it != m_module.end()
+ && (*it)->meta_id()() == asn1::meta::TYPEREF )
+ {
+ std::cerr<<"resolver::resolve warning object class reference "<<(*it)->name();
+ std::cerr<<" meta="<<(*it)->meta_id()()<<std::endl;
+ asn1::typenode *nt = (*it)->as_assignment()->get_type();
+ it = std::find_if(m_module.begin()
+ , m_module.end()
+ , asn1::find_node(nt->name()));
+ std::cerr<<"resolver::resolve warning object class reference "<<nt->name()<<std::endl;
+ if (it == m_module.end())
+ {
+ } else
+ std::cerr<<"resolver::resolve warning object class reference "<<(*it)->name()<<std::endl;
+ asn1::objectclass_reference rr(ocr);
+ rr.replace_objectclass(nt->name());
+ asn1::node *n = resolve_objcls(_ref,rr);
+ return n;
+ } else
+ {
+ asn1::node *n = resolve_objcls(_ref,ocr);
+ if (! n)
+ {
+ std::cerr<<"resolver::resolve unable to resolve "<<_ref.name()<<std::endl;
+ //assert(0 && "resolver::resolve_objcls failed");
+ }
+ if (n && n->type_node())
+ {
+ std::cerr<<"resolver::resolve result from resolve_objcls "<<_ref.name()<<std::endl;
+ if (!n->as_typenode())
+ n = n->type_node();
+ }
+ return n;
+ }
+ } else if (_ref.is_external())
+ {
+ asn1::reference::component_const_iterator it = _ref.get_reference()->begin();
+ asn1::module *m = module((*it).name());
+ assert(0 && " external ref should never occur, it's transformed at parsing level");
+ } else
+ {
+ // Loop over components.
+ asn1::reference::component_const_iterator it = _ref.get_reference()->begin();
+ std::cerr<<"resolver::resolve Not Yet Supported " <<_ref.name()<<"\n";
+ }
+ return nr;
+}
+
+/** Resolve with parameters
+ * parameter can be a typereference.
+ * typeref contains act_parameters,
+ * lookup in _params, in module, in imports
+ */
+
+bool resolver::resolve(typeref &_ref,parameters _params,asn1::node &type)
+{
+ return false;
+}
+
+/**
+ *
+ */
+asn1::node *
+resolver::resolve_objcls(const asn1::typeref &tref,asn1::objectclass_reference &ref)
+{
+ asn1::node *nr = NULL;
+ if (ref.size() <= 1)
+ {
+ asn1::node::const_iterator it = std::find_if(m_module.begin()
+ , m_module.end()
+ , asn1::find_node(ref.name()));
+ if (it != m_module.end())
+ {
+ nr = (*it)->as_assignment()->get_type();
+ } else
+ {
+ // Node not found in module, try other modules
+ asn1::node *ns;
+ if (type_in_imports(ref.name(),&ns))
+ {
+ if ( !get_type_in_module(ns->name(),ref.name(),&nr) )
+ {
+ std::cerr<<"Object "<<ns->name();
+ std::cerr<<" Not Found in module "<<ref.name()<<std::endl;
+ } else
+ {
+ nr = nr->as_assignment()->get_type();
+ }
+ }
+ }
+
+ } else if (std::string("TYPE-IDENTIFIER::&Type").compare(ref.name()) == 0)
+ {
+ asn1::constraint::const_iterator c = tref.constraint_begin();
+ if ((*c)->type() == asn1::constraint::EL_TYPE)
+ {
+ asn1::typeref *ctype = dynamic_cast<asn1::typeref *>((*c)->value());
+ assert(ctype != NULL);
+ std::cerr<<__FUNCTION__<<" GOT TYPE-IDENTIFIER&Type "<<ctype->name()<<std::endl;
+ nr = resolve(*ctype);
+ std::cerr<<__FUNCTION__<<" After resolve in resolve Issue here "<<nr->name()<<std::endl;
+ //nr = nr->type_node();
+ }
+ } else
+ {
+ asn1::classdef *current_cls = NULL;
+ asn1::reference::component_const_iterator it = ref.begin();
+ do
+ {
+ asn1::node *cident = NULL;
+ std::string cname = (*it).m_identifier;
+ if ( (cname[0] != '&') )
+ {
+ asn1::node *ns;
+ if (get_type_in_module(m_module.name(),cname,&cident))
+ {
+ current_cls = dynamic_cast<asn1::classdef *>(cident->as_assignment()->get_type());
+ } else if (type_in_imports(cname,&ns)
+ && get_type_in_module(ns->name(),cname,&cident)
+ )
+ {
+ current_cls = dynamic_cast<asn1::classdef *>(cident->as_assignment()->get_type());
+ } else
+ {
+ assert(0);
+ }
+ } else if (cname[0] == '&' && current_cls)
+ {
+ //asn1::node::iterator cls_attribute = std::find_if(current_cls->begin(),
+ // current_cls->end(),
+ // asn1::find_node((*it).m_identifier));
+ asn1::classfield *cls_attribute = current_cls->get_classfield((*it).m_identifier);
+ if (cls_attribute != NULL)
+ {
+ //std::cerr<<"Found "<<(*cls_attribute)->name()<<" In class\n";
+ // Wow attribute found in class Now I can decide what to do
+ switch( cls_attribute->type_id()())
+ {
+ case asn1::type::ASN1_CLASSFIELD_TF:
+ GEN_LOG_DEBUG("resolver::Found typefield %s in class %s\n"
+ , (*it).m_identifier.c_str()
+ , current_class->name().c_str());
+
+ break;
+ case asn1::type::ASN1_CLASSFIELD_FTVF:
+ {
+ GEN_LOG_DEBUG("resolver::Found typefield FTVF %s in class %s\n"
+ , (*it).m_identifier.c_str()
+ , current_class->name().c_str());
+ }
+ break;
+ case asn1::type::ASN1_CLASSFIELD_OSF:
+ {
+ asn1::typeref *rnode =
+ dynamic_cast<asn1::typeref *>(cls_attribute->get_type());
+ std::cerr<<"PRBL "<<(*it).m_identifier<<" CLS:"<<rnode->name()<<"\n";
+ asn1::node *n = resolve(*rnode);
+ if (n)
+ {
+ std::cerr<<"Got N"<<" CLS:"<<n->name()<<"\n";
+ current_cls = dynamic_cast<asn1::classdef *>(n);
+ }
+
+ }
+ break;
+ default:
+ GEN_LOG_ERROR("resolver::Found typefield %s in class %s NOT HANDLED\n"
+ , (*it).m_identifier.c_str()
+ , current_cls->name().c_str());
+ break;
+ } /* end switch */
+ //TODO not good, nr should not be classfield
+ std::cerr<<__FUNCTION__<<" nr should not be class field "<<cls_attribute->name()<<std::endl;
+ nr = cls_attribute;
+ } else
+ {
+ std::cerr<<"NOT Found "<<(*it).m_identifier<<" In current class ";
+ std::cerr<<current_cls->identifier()->name()<<"\n";
+ assert(0);
+ }
+ } else
+ {
+ std::cerr<<"NOT Found "<<cname<<" In module TODO check other modules\n";
+ assert(0);
+ break;
+ }
+ ++it;
+ } while (it != ref.end());
+
+ }
+ return nr;
+}
+
+
+
+
+
+
+
+
+
+bool resolver::type_in_imports( asn1::node *type
+ , asn1::node **ns) const
+{
+ return type_in_imports(type->name(),ns);
+}
+
+bool resolver::type_in_imports(const std::string &type
+ , asn1::node **ns) const
+{
+ bool ret = false;
+ asn1::import_list *imports = m_module.imports();
+ if (imports == NULL)
+ {
+ GEN_LOG_ERROR("type %s not in imports no imports\n",type.c_str());
+ return ret;
+ }
+ asn1::node::iterator it = imports->begin();
+ GEN_LOG_DEBUG("lookup for type %s\n",type.c_str());
+ for (; it != imports->end();it++)
+ {
+ asn1::import *import = dynamic_cast<asn1::import *>(*it);
+ asn1::node::iterator found = std::find_if( import->begin()
+ , import->end()
+ , asn1::find_node(type));
+ if (found != import->end() )
+ {
+ GEN_LOG_DEBUG("found %s in %s\n",type.c_str(),import->identifier()->name().c_str());
+ *ns = import->identifier();
+ ret = true;
+ break;
+ }
+ }
+ return ret;
+}
+
+/**
+ *
+ *
+ */
+asn1::module *
+resolver::module(const std::string &mod_name) const
+{
+ modules_const_iterator mit = std::find_if(m_module_list.begin()
+ , m_module_list.end()
+ , asn1::find_module(mod_name));
+ if (mit != m_module_list.end())
+ {
+ return *mit;
+ } else
+ return NULL;
+}
+
+/**
+ *
+ */
+bool
+resolver::get_type_in_module( const std::string &mod_name
+ , const std::string &typ_name
+ , asn1::node **n) const
+{
+ GEN_LOG_INFO("resolver::get_type_in_module module=%s current_module=%s name=%s modules=%lu\n"
+ , mod_name.c_str()
+ , m_module->name().c_str()
+ , typ_name.c_str()
+ , m_modules.size());
+
+ modules_const_iterator mit = std::find_if(m_module_list.begin()
+ , m_module_list.end()
+ , asn1::find_module(mod_name));
+
+ if (mit != m_module_list.end())
+ {
+ asn1::node::iterator nit =
+ std::find_if( (*mit)->begin()
+ , (*mit)->end()
+ , asn1::find_node(typ_name));
+ if (nit != (*mit)->end())
+ {
+ *n = (*nit);
+ return true;
+ } else
+ {
+ std::cerr<<"resolver::get_type_in_module "<<mod_name;
+ std::cerr<<" real module name:"<<(*mit)->name()<<std::endl;
+ std::cerr<<" tp:"<<typ_name<<" mod size="<<(*mit)->size()<<std::endl;
+ GEN_LOG_ERROR("get_type_in_module type %s not in module %s M size=%d\n"
+ , typ_name.c_str()
+ , mod_name.c_str()
+ , (*mit)->size()
+ );
+ return false;
+ }
+ } else
+ {
+ std::cerr<<"resolver::get_type_in_module did not find module "<<mod_name<<std::endl;
+ GEN_LOG_ERROR("get_type_in_module did not find module %s\n",mod_name.c_str());
+ return false;
+ }
+}
+
+bool
+resolver::get_type_in_module( asn1::module &mod
+ , const std::string &typ_name
+ , asn1::assignment **n) const
+{
+ asn1::node::iterator nit =
+ std::find_if( mod.begin()
+ , mod.end()
+ , asn1::find_node(typ_name));
+ if (nit != mod.end())
+ {
+ *n = (*nit)->as_assignment();
+ return true;
+ } else
+ {
+ std::cerr<<"resolver::get_type_in_module "<<mod.name();
+ std::cerr<<" real module name:"<<mod.name()<<std::endl;
+ std::cerr<<" tp:"<<typ_name<<" mod size="<<mod.size()<<std::endl;
+ GEN_LOG_ERROR("get_type_in_module type %s not in module %s M size=%d\n"
+ , typ_name.c_str()
+ , mod.name().c_str()
+ , mod.size()
+ );
+ return false;
+ }
+}
+
+/**
+* check if typename is in imports of module
+* if so, return module that contains the type.
+*/
+bool
+resolver::get_type_in_module_import( const asn1::module &mod
+ , const std::string &typ_name
+ , asn1::module **in_module) const
+{
+ bool ret = false;
+ asn1::import_list *imports = mod.imports();
+ if (imports == NULL)
+ {
+ GEN_LOG_ERROR( "type %s not in imports no imports\n"
+ , typ_name.c_str());
+ return ret;
+ }
+ asn1::node::iterator it = imports->begin();
+ GEN_LOG_DEBUG( "%s lookup for type %s\n"
+ , __FUNCTION__
+ , typ_name.c_str());
+ for (; it != imports->end();it++)
+ {
+ asn1::import *import = dynamic_cast<asn1::import *>(*it);
+ asn1::node::iterator found = std::find_if( import->begin()
+ , import->end()
+ , asn1::find_node(typ_name));
+ if (found != import->end() )
+ {
+ GEN_LOG_DEBUG( "%s found %s in %s\n"
+ , __FUNCTION__
+ , type.c_str()
+ , import->identifier()->name().c_str());
+ *in_module = module(import->identifier()->name());
+ ret = true;
+ break;
+ }
+ }
+ return ret;
+}
+
+
+
+
+
+
+
+}
--- /dev/null
+#ifndef ASN1_RESOLVER_H
+#define ASN1_RESOLVER_H
+
+namespace asn1 {
+/**
+ * The purpose of the class is to resolve
+ * references. Example : given a reference,
+ * the resolver will find the correponding type.
+ * T1 ::= SEQUENE { }
+ * T2 ::= CHOICE { t1 T1 }
+ * resolve T1 returns type SEQUENCE T1.
+ */
+class resolver
+{
+ public:
+ typedef asn1::module::modules_type modules_type;
+ typedef asn1::module::modules_type::iterator modules_iterator;
+ typedef asn1::module::modules_type::const_iterator modules_const_iterator;
+ typedef asn1::node::iterator node_iterator;
+
+ /// constructor
+ resolver( const asn1::module &_m
+ , const asn1::module::modules_type &_mods);
+ /// copy constructor
+ resolver( const resolver &_r)
+ : m_module(_r.m_module), m_module_list(_r.m_module_list) {}
+ ///
+ virtual ~resolver();
+ // Resolve with reference
+ // If found return type node of found reference
+ asn1::node *resolve(const typeref &_ref);
+ // Resolve with parameters
+ // parameter can be a typereference.
+ // typeref contains act_parameters,
+ // lookup in _params, in module, in imports
+ bool resolve(typeref &_ref,parameters _params,asn1::node &type);
+
+ asn1::module *module(const std::string &mn) const;
+ protected:
+ asn1::node *resolve_objcls(const typeref &tref, asn1::objectclass_reference &ref);
+
+ bool get_type_in_module( const std::string &mod_name
+ , const std::string &typ_name
+ , asn1::node **n) const;
+ /**
+ * New way ...
+ */
+ bool get_type_in_module( asn1::module &mod
+ , const std::string &typ_name
+ , asn1::assignment **n) const;
+ /**
+ * check if typename is in imports of module
+ * if so, return module that contains the type.
+ */
+ bool get_type_in_module_import( const asn1::module &mod
+ , const std::string &typ_name
+ , asn1::module **in_module) const;
+
+ bool type_in_imports(asn1::node *type,asn1::node **ns) const;
+
+ bool type_in_imports(const std::string &type,asn1::node **ns)const ;
+ protected:
+ const asn1::module &m_module; // Current module
+ const asn1::module::modules_type &m_module_list;
+};
+
+}
+#endif /*ASN1_RESOLVER_H*/
--- /dev/null
+#ifndef ASN1_TYPE_H__
+#define ASN1_TYPE_H__
+
+
+namespace asn1
+{
+
+ class type
+ {
+ public:
+ typedef enum {
+ INVALID = 0 ,
+#if 1
+#define ASN1_TYPE(cls,parent,id) ASN1_##id ,
+#define ASN1_STRING_TYPE(cls,parent,id) ASN1_STRING_##id ,
+#define ASN1_ABSTRACT_STRING_TYPE(cls,parent,id) ASN1_##id ,
+#include "adt/asn1_type.inc"
+#else
+ ASN1_REFERENCE,
+ ASN1_EXPORTVAR,
+ ASN1_UNIVERSAL,
+ ASN1_BITVECTOR,
+ ASN1_EXTENSIBLE,
+ ASN1_COMPONENTS_OF,
+ ASN1_VALUESET,
+ ASN1_CLASSDEF,
+ ASN1_INSTANCE,
+
+ /**
+ * Class Field type
+ */
+ ASN1_CLASSFIELD, /* */
+ ASN1_CLASSFIELD_TF, /* Type Field 10 */
+ ASN1_CLASSFIELD_FTVF, /* Fixed Type Value Field */
+ ASN1_CLASSFIELD_VTVF, /* Variable Type Value Field */
+ ASN1_CLASSFIELD_FTVSF, /* Fixed Type Value Set Field */
+ ASN1_CLASSFIELD_VTVSF, /* Variable Type Value Set Field*/
+ ASN1_CLASSFIELD_OF, /* Object Field */
+ ASN1_CLASSFIELD_OSF, /* Object Set Field */
+ /* Constructed Types
+ */
+ ASN1_SEQUENCE, /* 18 */
+ ASN1_CHOICE,
+ ASN1_SET,
+ ASN1_SEQUENCE_OF,
+ ASN1_SET_OF,
+ ASN1_SELECTION,
+ /* Basic Types
+ */
+ ASN1_ANY,
+ ASN1_BOOLEAN,
+ ASN1_INTEGER,
+ ASN1_BIT_STRING,
+ ASN1_OCTET_STRING,
+ ASN1_NULL,
+ ASN1_OBJECT_IDENTIFIER,
+ ASN1_OBJECT_DESCRIPTOR,
+ ASN1_REAL,
+ ASN1_ENUMERATED,
+ ASN1_RELATIVE_OID,
+ ASN1_EXTERNAL,
+ ASN1_EMBEDDED_PDV,
+ ASN1_CHARACTER_STRING,
+ ASN1_UTCTime,
+ ASN1_GeneralizedTime,
+ /* String Types
+ */
+ ASN1_STRING,
+ ASN1_STRING_IA5String,
+ ASN1_STRING_PrintableString,
+ ASN1_STRING_VisibleString,
+ ASN1_STRING_ISO646String, /* aka VisibleString */
+ ASN1_STRING_NumericString,
+ ASN1_STRING_UniversalString,
+ ASN1_STRING_BMPString,
+ ASN1_STRING_UTF8String ,
+ ASN1_STRING_GeneralString,
+ ASN1_STRING_GraphicString,
+ ASN1_STRING_TeletexString,
+ ASN1_STRING_T61String,
+ ASN1_STRING_VideotexString,
+ ASN1_STRING_ObjectDescriptor,
+#endif
+ ASN1_TYPE_MAX
+ } id;
+
+ inline type(type::id id = INVALID) : m_id(id) {};
+ inline type(const type &m) : m_id(m.m_id) {};
+ inline type &operator =( const type &m) {m_id = m.m_id; return *this;};
+ inline type &operator =( const id i) {m_id = i; return *this;};
+ inline ~type() {};
+ inline bool operator >(const type &a) {return m_id > a.m_id; };
+ inline bool operator >=(const type &a) {return m_id >= a.m_id; };
+ inline bool operator <=(const type &a) {return m_id <= a.m_id; };
+ inline bool operator <(const type &a) {return m_id < a.m_id; };
+ inline bool operator ==(const type &a) {return m_id == a.m_id; };
+
+ inline id operator()() const
+ {
+ return m_id;
+ }
+
+ const char *name() const ;
+ friend std::ostream & operator <<(std::ostream &os, const type &m)
+ {
+ os<<m.m_id;
+ return os;
+ }
+ protected:
+ id m_id;
+ };
+}
+#endif
--- /dev/null
+#ifndef ASN1_TYPE
+#define ASN1_TYPE(cls,parent,id)
+#endif
+
+ASN1_TYPE(reference,node,REFERENCE)
+ASN1_TYPE(exportvar,node,EXPORTVAR) /* Exported definition in Exports */
+//ASN1_TYPE(universal,node,UNIVERSAL) /* Constants in Enum, Int, BitString and OID */
+//ASN1_TYPE(bitvector,node,BITVECTOR)
+ASN1_TYPE(extensible,node,EXTENSIBLE)
+ASN1_TYPE(components_of,node,COMPONENTS_OF)
+ASN1_TYPE(valueset,typenode,VALUESET)
+ASN1_TYPE(objectset,typenode,OBJECTSET)
+ASN1_TYPE(classdef,node,CLASSDEF)
+// Not yet used
+//ASN1_TYPE(instance,node,INSTANCE)
+ASN1_TYPE(classfield,node,CLASSFIELD)
+/**
+ * CLASS FIELD TYPE
+ */
+#ifndef ASN1_CLASSFIELD_TYPE
+#define ASN1_CLASSFIELD_TYPE ASN1_TYPE
+#endif
+ASN1_CLASSFIELD_TYPE(classfield_tf,classfield,CLASSFIELD_TF) /* TYPE FIELD */
+ASN1_CLASSFIELD_TYPE(classfield_ftvf,classfield,CLASSFIELD_FTVF) /* FIXED TYPE VALUE FIELD */
+ASN1_CLASSFIELD_TYPE(classfield_vtvf,classfield,CLASSFIELD_VTVF) /* VARIABLE TYPE VALUE FIELD */
+ASN1_CLASSFIELD_TYPE(classfield_ftvsf,classfield,CLASSFIELD_FTVSF) /* FIXED TYPE VALUE SET FIELD */
+ASN1_CLASSFIELD_TYPE(classfield_vtvsf,classfield,CLASSFIELD_VTVSF) /* VARIABLE TYPE VALUE SET FIELD*/
+ASN1_CLASSFIELD_TYPE(classfield_of,classfield,CLASSFIELD_OF) /* OBJECT FIELD */
+ASN1_CLASSFIELD_TYPE(classfield_osf,classfield,CLASSFIELD_OSF) /* OBJECT SET FIELD */
+
+/*
+ * CONSTRUCTED TYPES
+ */
+#ifndef ASN1_CONSTRUCTED_TYPE
+#define ASN1_CONSTRUCTED_TYPE ASN1_TYPE
+#endif
+ASN1_CONSTRUCTED_TYPE(sequence,constructed,SEQUENCE) /* 17 */
+ASN1_CONSTRUCTED_TYPE(choice,constructed,CHOICE)
+ASN1_CONSTRUCTED_TYPE(set,constructed,SET)
+ASN1_CONSTRUCTED_TYPE(sequence_of,typenode,SEQUENCE_OF)
+ASN1_CONSTRUCTED_TYPE(set_of,typenode,SET_OF)
+ASN1_CONSTRUCTED_TYPE(selection,typeref,SELECTION)
+/*
+ * PRIMITIVE TYPES
+ */
+#ifndef ASN1_PRIMITIVE_TYPE
+#define ASN1_PRIMITIVE_TYPE ASN1_TYPE
+#endif
+ASN1_PRIMITIVE_TYPE(any,primitive,ANY)
+ASN1_PRIMITIVE_TYPE(boolean,primitive,BOOLEAN)
+ASN1_PRIMITIVE_TYPE(integer,constructed,INTEGER)
+ASN1_PRIMITIVE_TYPE(bit_string,constructed,BIT_STRING)
+ASN1_PRIMITIVE_TYPE(octet_string,primitive,OCTET_STRING)
+ASN1_PRIMITIVE_TYPE(null,primitive,NULL)
+ASN1_PRIMITIVE_TYPE(object_identifier,constructed,OBJECT_IDENTIFIER)
+ASN1_PRIMITIVE_TYPE(object_descriptor,primitive,OBJECT_DESCRIPTOR)
+ASN1_PRIMITIVE_TYPE(real,primitive,REAL)
+ASN1_PRIMITIVE_TYPE(enumerated,constructed,ENUMERATED)
+ASN1_PRIMITIVE_TYPE(relative_oid,primitive,RELATIVE_OID)
+ASN1_PRIMITIVE_TYPE(external,primitive,EXTERNAL)
+ASN1_PRIMITIVE_TYPE(embedded_pdv,primitive,EMBEDDED_PDV)
+ASN1_PRIMITIVE_TYPE(character_string,primitive,CHARACTER_STRING)
+ASN1_PRIMITIVE_TYPE(utctime,primitive,UTCTime)
+ASN1_PRIMITIVE_TYPE(generalizedtime,primitive,GeneralizedTime)
+/*
+ * STRING TYPES
+ */
+#ifndef ASN1_STRING_TYPE
+# define ASN1_STRING_TYPE ASN1_TYPE
+#endif
+#ifndef ASN1_ABSTRACT_STRING_TYPE
+# define ASN1_ABSTRACT_STRING_TYPE(cls,parent,id)
+#endif
+
+ASN1_ABSTRACT_STRING_TYPE(string,primitive,STRING)
+
+ASN1_STRING_TYPE(ia5string,primitive,IA5String)
+ASN1_STRING_TYPE(printablestring,primitive,PrintableString)
+ASN1_STRING_TYPE(visiblestring,primitive,VisibleString)
+ASN1_STRING_TYPE(iso646string,primitive,ISO646String) /* AKA VISIBLESTRING */
+ASN1_STRING_TYPE(numericstring,primitive,NumericString)
+ASN1_STRING_TYPE(universalstring,primitive,UniversalString)
+ASN1_STRING_TYPE(bmpstring,primitive,BMPString)
+ASN1_STRING_TYPE(utf8string,primitive,UTF8String)
+ASN1_STRING_TYPE(generalstring,primitive,GeneralString)
+ASN1_STRING_TYPE(graphicstring,primitive,GraphicString)
+ASN1_STRING_TYPE(teletexstring,primitive,TeletexString)
+ASN1_STRING_TYPE(t61string,primitive,T61String)
+ASN1_STRING_TYPE(videotexstring,primitive,VideotexString)
+ASN1_STRING_TYPE(objectdescriptor_string,primitive,ObjectDescriptor)
+
+#undef ASN1_STRING_TYPE
+#undef ASN1_ABSTRACT_STRING_TYPE
+#undef ASN1_PRIMITIVE_TYPE
+#undef ASN1_CONSTRUCTED_TYPE
+#undef ASN1_TYPE
+#undef ASN1_CLASSFIELD_TYPE
--- /dev/null
+#include <iostream>
+#include <sstream>
+#include <string>
+
+#include <list>
+#include "asn1_node.h"
+#include "asn1_reference.h"
+#include "asn1_value.h"
+#include "asn1_constraint.h"
+
+namespace asn1 {
+
+value::value(asn1::value::etype tp)
+ : type(tp) , m_ref(0) , m_constraint(NULL)
+{
+}
+
+value::value(const asn1::value &v)
+{
+}
+
+value::value( const std::string &_s)
+ : type(VT_STRING),m_string(_s),m_ref(0),m_constraint(NULL)
+{
+}
+value::value( const asn1::constraint *_c)
+ : m_ref(0),m_constraint(NULL)
+{
+ m_constraint = const_cast<asn1::constraint *>(_c);
+}
+value::value( double _d)
+ : type(VT_REAL),m_real(_d) , m_ref(0), m_constraint(NULL)
+{
+}
+value::value( long _l)
+ : type(VT_INTEGER),m_integer(_l),m_ref(0),m_constraint(NULL)
+{
+}
+value::value( long long _l)
+ : type(VT_INTEGER),m_integer(_l),m_ref(0),m_constraint(NULL)
+{
+}
+
+value::~value()
+{
+}
+
+std::string
+value::cpp_name() const
+{
+ switch (type)
+ {
+ case VT_TRUE:
+ return std::string("true");
+ case VT_FALSE:
+ return std::string("false");
+ case VT_MIN:
+ return std::string("MIN");
+ case VT_MAX:
+ return std::string("MAX");
+ case VT_STRING:
+ return m_string;
+ case VT_INTEGER:
+ {
+ std::ostringstream oss;
+ oss<<m_integer;
+ return oss.str();
+ }
+ case VT_REAL:
+ {
+ std::ostringstream oss;
+ oss<<m_real;
+ return oss.str();
+ }
+ case VT_COLON:
+ switch (m_node->type_id()())
+ {
+ case asn1::type::ASN1_OBJECT_IDENTIFIER:
+ {
+ std::ostringstream os;
+ asn1::object_identifier *oid = m_node->as_object_identifier();
+ os.str("");
+ os<<oid->hash();
+ return os.str();
+ }
+ case asn1::type::ASN1_INTEGER:
+ return m_node->cpp_name();
+ default:
+ {
+ std::ostringstream os;
+ os.str("");
+ os<<"<choice "<<m_node->cpp_name()<<" id="<<m_node->type_id()()<<">";
+ return os.str();
+ }
+ }
+ case VT_VALUESET: /* {1 | 2 | 3 } */
+ // this shall be a constraint ....
+ if (m_constraint)
+ {
+ return m_constraint->name();
+ } else
+ return std::string("todo");
+ case VT_REFERENCED: /* Reference a value elsewhere */
+ return m_reference->name();
+ default:
+ return std::string("unknown");
+ ;
+ };
+}
+
+};
--- /dev/null
+#ifndef ASN1_VALUE_H
+#define ASN1_VALUE_H
+#include "aeb/sys/log.h"
+#include "aeb/sys/log.h"
+#include "aeb/pointer/intrusive_ptr.h"
+
+namespace asn1 {
+// forward declaration
+ class constraint;
+ class reference;
+ class node;
+struct value
+{
+
+ public:
+ INTRUSIVE_DECLARATION(value)
+
+ enum etype {
+ VT_NOVALUE,
+ VT_TYPE,
+ VT_NULL,
+ VT_REAL,
+ VT_INTEGER, /* an Integer */
+ VT_MIN,
+ VT_MAX,
+ VT_TRUE,
+ VT_FALSE,
+ VT_STRING, /* "abcd" */
+ VT_BITVECTOR, /* binary - hex string */
+ VT_COLON, /* choice value ex local : value */
+ VT_VALUESET, /* {1 | 2 | 3 } */
+ VT_SETVALUE, /* { which list} needs to be parser with the right type for assignement. Is Opaque */
+ VT_REFERENCED /* Reference a value elsewhere */
+
+ } type;
+
+ value( asn1::value::etype tp = VT_NOVALUE);
+ value( const std::string &_s);
+ value( const asn1::constraint *_c);
+ value(const asn1::value &v);
+ value( double _d);
+ value( long _l);
+ value( long long _l);
+
+ ~value();
+
+ std::string cpp_name() const;
+ std::string m_string;
+ long long m_integer;
+ double m_real;
+ asn1::reference *m_reference;
+ asn1::constraint *m_constraint;
+ asn1::node *m_node;
+};
+
+};
+
+/*
+ vim:et:sw=2:ts=2
+ */
+#endif
--- /dev/null
+#ifndef ASN1_VISITOR_H__
+#define ASN1_VISITOR_H__
+
+class node;
+class constraint;
+
+#ifdef DISPATCH
+#undef DISPATCH
+#endif
+template <typename Impl,typename RetTyp>
+class node_visitor_base
+{
+ public:
+ node_visitor_base() {};
+ virtual ~node_visitor_base() {};
+#define PTR(x) asn1::x *
+
+#define DISPATCH(NAME,CLASS,DEF) \
+ return static_cast<Impl *>(this)->visit_ ## NAME(static_cast<asn1::CLASS *>(n));
+
+#define ASN1_TYPE(NAME,PARENT,DEF) \
+ case asn1::type::ASN1_##DEF : DISPATCH(NAME,NAME,DEF) ;
+
+#define ASN1_STRING_TYPE(NAME,PARENT,DEF) \
+ case asn1::type::ASN1_STRING_##DEF : DISPATCH(NAME,NAME,DEF) ;
+
+ RetTyp visit(asn1::node *n)
+ {
+ switch (n->type_id()())
+ {
+#include "adt/asn1_type.inc"
+ default:
+ ;
+ }
+ }
+ // Default behavior is : If user does not implement a certain class
+ // move to parent class
+#define ASN1_TYPE(NAME,PARENT,DEF) \
+ RetTyp visit_##NAME( PTR(NAME) n) \
+ {\
+ DISPATCH(PARENT,PARENT,DEF) ; \
+ }
+
+#include "adt/asn1_type.inc"
+ // Missing visitors
+ RetTyp visit_module(asn1::module *s)
+ {
+ return RetTyp();
+ }
+ RetTyp visit_typenode(asn1::typenode *s)
+ {
+ return RetTyp();
+ }
+ RetTyp visit_typeref(asn1::typeref *s)
+ {
+ return RetTyp();
+ }
+ //
+ RetTyp visit_primitive(asn1::primitive *s)
+ {
+ return RetTyp();
+ }
+ RetTyp visit_constructed(asn1::constructed *s)
+ {
+ return RetTyp();
+ }
+ RetTyp visit_node(asn1::node *s)
+ {
+ return RetTyp();
+ }
+};
+#undef DISPATCH
+template <typename Impl,typename RetTyp = void>
+class node_visitor : public node_visitor_base<Impl,RetTyp> {};
+
+/**
+ * Same for constraints
+ */
+template <typename Impl,typename RetTyp>
+class constraint_visitor_base
+{
+ public:
+ constraint_visitor_base() {};
+ virtual ~constraint_visitor_base() {};
+
+#define DISPATCH(DEF,NAME,CLASS) \
+ return static_cast<Impl *>(this)->visit_ ## NAME(static_cast<asn1::CLASS *>(n));
+
+#define ELEMENT_CONSTRAINT(DEF,NAME,PARENT) \
+ case asn1::constraint::DEF : DISPATCH(DEF,NAME,NAME) ;
+
+ RetTyp visit(asn1::constraint *n)
+ {
+ switch (n->type())
+ {
+#include "asn1_constraint.inc"
+ default:
+ ;
+ }
+ }
+ // Default behavior is : If user does not implement a certain class
+ // move to parent class
+#define ELEMENT_CONSTRAINT(DEF,NAME,PARENT) \
+ RetTyp visit_##NAME( PTR(NAME) n) \
+ {\
+ DISPATCH(DEF,PARENT,PARENT) ; \
+ }
+
+#include "asn1_constraint.inc"
+};
+
+template <typename Impl,typename RetTyp=void>
+class constraint_visitor : public constraint_visitor_base<Impl,RetTyp> {};
+
+
+/**
+ * And a Visitor for Assignments ...
+ */
+#undef DISPATCH
+template <typename Impl,typename RetTyp>
+class assignment_visitor_base
+{
+ public:
+ assignment_visitor_base() {};
+ virtual ~assignment_visitor_base() {};
+
+#define DISPATCH(DEF,NAME,CLASS) \
+ return static_cast<Impl *>(this)->visit_ ## NAME(static_cast<asn1::CLASS##_assignment *>(n));
+
+#define DISPATCH1(DEF,NAME,CLASS) \
+ return static_cast<Impl *>(this)->visit_ ## NAME(static_cast<asn1::CLASS *>(n));
+
+#define ASSIGNMENT(DEF,NAME,PARENT) \
+ case asn1::meta::DEF : DISPATCH(DEF,NAME,NAME) ;
+
+ RetTyp visit(asn1::assignment *n)
+ {
+ switch (n->meta_id()())
+ {
+#include "asn1_meta.inc"
+ default:
+ ;
+ }
+ }
+ RetTyp visit_assignment(asn1::assignment *a)
+ {}
+ // Default behavior is : If user does not implement a certain class
+ // move to parent class
+#define ASSIGNMENT(DEF,NAME,PARENT) \
+ RetTyp visit_##NAME( PTR(NAME##_assignment) n) \
+ {\
+ DISPATCH1(DEF,PARENT,PARENT) ; \
+ }
+
+#include "asn1_meta.inc"
+};
+
+template <typename Impl,typename RetTyp=void>
+class assignment_visitor : public assignment_visitor_base<Impl,RetTyp> {};
+#undef DISPATCH
+#undef DISPATCH1
+
+
+#endif
--- /dev/null
+#ifndef CMIPACTIONLISTENER_H
+#define CMIPACTIONLISTENER_H
+
+class CMIPActionListener
+{
+};
+#endif /*CMIPACTIONLISTENER_H*/
--- /dev/null
+#include <iostream>
+#include "Remote_Operations_Generic_ROS_PDUs.h"
+#include "CMIP_1.h"
+#include "CMIP_1.hpp"
+
+#include "rtasn1/asn1_codec.h"
+#include "rtasn1/asn1_codec_ber.h"
+
+#include "CMIPListener.h"
+#include "CMIPActionListener.h"
+#include "CMIPEventReportListener.h"
+#include "CMIPStack.h"
+#include "CMIPAgent.h"
+
+using namespace CMIP_1;
+using namespace Remote_Operations_Generic_ROS_PDUs;
+using namespace Remote_Operations_Information_Objects;
+namespace rose_ie = Remote_Operations_Information_Objects;
+
+
+
+
+
+/**
+ *
+ */
+CMIPAgent::CMIPAgent(CMIPStack &cmip_stack)
+ : m_CMIPStack(cmip_stack)
+{
+ std::cout<<"CMIPAgent::"<<__FUNCTION__<<std::endl;
+ m_CMIPStack.registerListener(this);
+}
+
+/**
+ *
+ */
+CMIPAgent::~CMIPAgent()
+{
+ std::cout<<"CMIPAgent::"<<__FUNCTION__<<std::endl;
+}
+
+/**
+ *
+ */
+void
+CMIPAgent::on_m_Create(CMIP_1::CreateArgument &o)
+{
+ std::cout<<"CMIPAgent::"<<__FUNCTION__<<std::endl;
+ o.printf(std::cout);
+}
+
+/**
+ *
+ */
+void
+CMIPAgent::on_m_Create(CMIP_1::CreateResult &o)
+{
+ std::cout<<"CMIPAgent::"<<__FUNCTION__<<std::endl;
+ o.printf(std::cout);
+}
+
+/**
+ *
+ */
+void
+CMIPAgent::on_m_Delete(CMIP_1::DeleteArgument &o)
+{
+ std::cout<<"CMIPAgent::"<<__FUNCTION__<<std::endl;
+ o.printf(std::cout);
+}
+
+/**
+ *
+ */
+void
+CMIPAgent::on_m_Delete(CMIP_1::DeleteResult &o)
+{
+ std::cout<<"CMIPAgent::"<<__FUNCTION__<<std::endl;
+ o.printf(std::cout);
+}
+
+
+/**
+ *
+ */
+void
+CMIPAgent::on_m_Get(CMIP_1::GetArgument &o)
+{
+ std::cout<<"CMIPAgent::"<<__FUNCTION__<<std::endl;
+ o.printf(std::cout);
+}
+
+/**
+ *
+ */
+void
+CMIPAgent::on_m_Get(CMIP_1::GetResult &o)
+{
+ std::cout<<"CMIPAgent::"<<__FUNCTION__<<std::endl;
+ o.printf(std::cout);
+}
+
+/**
+ *
+ */
+void
+CMIPAgent::on_m_CancelGet(CMIP_1::m_CancelGet &o)
+{
+ std::cout<<"CMIPAgent::"<<__FUNCTION__<<std::endl;
+}
+
+/**
+ *
+ */
+void
+CMIPAgent::on_m_Linked_Reply(CMIP_1::LinkedReplyArgument &o)
+{
+ std::cout<<"CMIPAgent::"<<__FUNCTION__<<std::endl;
+}
+
+/**
+ *
+ */
+void
+CMIPAgent::on_m_Set(CMIP_1::SetArgument &o)
+{
+ std::cout<<"CMIPAgent::"<<__FUNCTION__<<std::endl;
+ o.printf(std::cout);
+}
+
+/**
+ *
+ */
+void
+CMIPAgent::on_m_Set_Confirmed(CMIP_1::SetArgument &o)
+{
+ std::cout<<"CMIPAgent::"<<__FUNCTION__<<std::endl;
+ o.printf(std::cout);
+}
+
+/**
+ *
+ */
+void
+CMIPAgent::on_m_Set_Confirmed(CMIP_1::SetResult &o)
+{
+ std::cout<<"CMIPAgent::"<<__FUNCTION__<<std::endl;
+ o.printf(std::cout);
+}
+
+
--- /dev/null
+#ifndef CMIP_AGENT_H__
+#define CMIP_AGENT_H__
+
+class CMIPStack;
+
+class CMIPAgent : public CMIPListener
+{
+ public:
+ CMIPAgent(CMIPStack &cmip_stack);
+
+ ~CMIPAgent();
+
+ virtual void on_m_Create(CMIP_1::CreateArgument &o) ;
+ virtual void on_m_Create(CMIP_1::CreateResult &o) ;
+
+ virtual void on_m_Delete(CMIP_1::DeleteArgument &o) ;
+ virtual void on_m_Delete(CMIP_1::DeleteResult &o) ;
+
+ virtual void on_m_Get(CMIP_1::GetArgument &o) ;
+ virtual void on_m_Get(CMIP_1::GetResult &o) ;
+
+ virtual void on_m_CancelGet(CMIP_1::m_CancelGet &o) ;
+
+ virtual void on_m_Linked_Reply(CMIP_1::LinkedReplyArgument &o) ;
+
+ virtual void on_m_Set(CMIP_1::SetArgument &o) ;
+
+ virtual void on_m_Set_Confirmed(CMIP_1::SetArgument &o) ;
+ virtual void on_m_Set_Confirmed(CMIP_1::SetResult &o) ;
+
+ protected:
+ CMIPStack &m_CMIPStack;
+};
+
+#endif
--- /dev/null
+#ifndef CMIPEVENTREPORTLISTENER_H
+#define CMIPEVENTREPORTLISTENER_H
+
+/**
+ * @brief Interface that a class needs to implement in order
+ * to receive events from CMIP layer.
+ *
+ * Event Management might differ from current operation
+ *
+ */
+class CMIPEventReportListener
+{
+ public:
+ CMIPEventReportListener();
+
+ void on_m_EventReport(CMIP_1::m_EventReport &o);
+
+ void on_m_EventReport_Confirmed(CMIP_1::m_EventReport_Confirmed &o);
+
+
+ protected:
+};
+
+#endif /*CMIPEVENTREPORTLISTENER_H*/
--- /dev/null
+#ifndef CMIPLISTENER_H
+#define CMIPLISTENER_H
+
+/**
+ *
+ */
+class CMIPListener
+{
+ public:
+
+ CMIPListener() { } ;
+
+ ~CMIPListener() { } ;
+
+
+ virtual void on_m_Create(CMIP_1::CreateArgument &o) { } ;
+ virtual void on_m_Create(CMIP_1::CreateResult &o) { } ;
+
+ virtual void on_m_Delete(CMIP_1::DeleteArgument &o) { } ;
+ virtual void on_m_Delete(CMIP_1::DeleteResult &o) { } ;
+
+ virtual void on_m_Get(CMIP_1::GetArgument &o) { } ;
+ virtual void on_m_Get(CMIP_1::GetResult &o) { } ;
+
+ virtual void on_m_CancelGet(CMIP_1::m_CancelGet &o) { } ;
+
+ virtual void on_m_Linked_Reply(CMIP_1::LinkedReplyArgument &o) { } ;
+
+ virtual void on_m_Set(CMIP_1::SetArgument &o) { } ;
+
+ virtual void on_m_Set_Confirmed(CMIP_1::SetArgument &o) { } ;
+ virtual void on_m_Set_Confirmed(CMIP_1::SetResult &o) { } ;
+ protected:
+
+};
+#endif /*CMIPLISTENER_H*/
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <cassert>
+#include "Remote_Operations_Generic_ROS_PDUs.h"
+#include "CMIP_1.h"
+#include "CMIP_1.hpp"
+
+#include "rtasn1/asn1_codec.h"
+#include "rtasn1/asn1_codec_ber.h"
+
+#include "CMIPListener.h"
+#include "CMIPActionListener.h"
+#include "CMIPEventReportListener.h"
+#include "CMIPStack.h"
+
+using namespace CMIP_1;
+using namespace Remote_Operations_Generic_ROS_PDUs;
+using namespace Remote_Operations_Information_Objects;
+namespace rose_ie = Remote_Operations_Information_Objects;
+
+
+
+CMIPStack::CMIPStack()
+{
+}
+
+/**
+ *
+ */
+void
+CMIPStack::registerListener(CMIPActionListener *a)
+{
+}
+
+/**
+ *
+ */
+void
+CMIPStack::registerListener(CMIPEventReportListener *a)
+{
+}
+
+/**
+ *
+ */
+void
+CMIPStack::registerListener(CMIPListener *a)
+{
+ m_Listeners.push_back(a);
+}
+
+
+/**
+ * Down stream methods
+ * {m-Action | m-Action-Confirmed | m-CancelGet | m-Create | m-Delete |
+ * m-EventReport | m-EventReport-Confirmed | m-Get | m-Linked-Reply | m-Set |
+ * m-Set-Confirmed}
+ */
+void
+CMIPStack::send_m_Action(CMIP_1::m_Action &action)
+{
+ m_Ctx.reset();
+ ROS ros(ROS::typeof_invoke,asn1::tag(2,1));
+ //
+
+ Invoke &i = ros.get_invoke();
+ i.invokeId.get_present() = 8;
+ i.argument = &action;
+ i.opcode.set_tag(asn1::tag(0,2));
+ i.opcode.get_local() = action.get_operationCode().get_local();
+ std::cout<<std::setprecision(0);
+ i.printf(std::cout);
+ ros.encode(m_Ctx);
+ std::cout<<"\nSize "<<m_Ctx.nb_read_bits()<<" bits"<<std::endl;
+}
+
+
+void
+CMIPStack::send_m_Action_Confirmed(CMIP_1::m_Action_Confirmed &action)
+{
+}
+
+
+void
+CMIPStack::send_m_CancelGet(CMIP_1::m_CancelGet &o)
+{
+}
+
+
+void
+CMIPStack::send_m_Create(CMIP_1::m_Create &o)
+{
+}
+
+
+void
+CMIPStack::send_m_Delete(CMIP_1::m_Delete &o)
+{
+}
+
+
+void
+CMIPStack::send_m_EventReport(CMIP_1::m_EventReport &o)
+{
+}
+
+
+void
+CMIPStack::send_m_EventReport_Confirmed(CMIP_1::m_EventReport_Confirmed &o)
+{
+}
+
+
+void
+CMIPStack::send_m_Get(CMIP_1::m_Get &_get)
+{
+ m_Ctx.reset();
+ ROS ros(ROS::typeof_invoke,asn1::tag(2,1));
+ //
+
+ Invoke &i = ros.get_invoke();
+ i.invokeId.get_present() = 8;
+ i.argument = &_get;
+ i.opcode.set_local( _get.get_operationCode().get_local());
+ std::cout<<std::setprecision(0);
+ i.printf(std::cout);
+ ros.encode(m_Ctx);
+ std::cout<<"\n"<<__FUNCTION__;
+ std::cout<<" Size "<<m_Ctx.nb_read_bits()<<" bits"<<std::endl;
+ // Trye decode
+ m_Ctx.reset();
+ onReceive(m_Ctx);
+}
+
+
+void
+CMIPStack::send_m_Linked_Reply(CMIP_1::m_Linked_Reply &o)
+{
+}
+
+
+void
+CMIPStack::send_m_Set(CMIP_1::m_Set &_set)
+{
+ ROS ros(ROS::typeof_invoke,asn1::tag(2,1));
+ //
+ m_Ctx.reset();
+ Invoke &i = ros.get_invoke();
+ i.invokeId.get_present() = 8;
+ i.argument = &_set;
+ i.opcode.set_local( _set.get_operationCode().get_local());
+ std::cout<<std::setprecision(0);
+ i.printf(std::cout);
+ ros.encode(m_Ctx);
+ std::cout<<"\n"<<__FUNCTION__;
+ std::cout<<" Size "<<m_Ctx.nb_read_bits()<<" bits"<<std::endl;
+}
+
+
+void
+CMIPStack::send_m_Set_Confirmed(CMIP_1::m_Set_Confirmed &_set)
+{
+ m_Ctx.reset();
+ ROS ros(ROS::typeof_invoke,asn1::tag(2,1));
+ //
+
+ Invoke &i = ros.get_invoke();
+ i.invokeId.get_present() = 8;
+ i.argument = &_set;
+ i.opcode.set_local( _set.get_operationCode().get_local());
+ std::cout<<std::setprecision(0);
+ i.printf(std::cout);
+ ros.encode(m_Ctx);
+ std::cout<<"\n"<<__FUNCTION__;
+ std::cout<<" Size "<<m_Ctx.nb_read_bits()<<" bits"<<std::endl;
+}
+
+void
+CMIPStack::doInvoke(rose_pdu::Invoke &i)
+{
+ assert(i.opcode.get_kind() == Code::typeof_local);
+ std::cout<<"CMIPStack::"<<__FUNCTION__;
+ std::cout<<" got "<<i.opcode.get_local()<<"\n";
+ switch (i.opcode.get_local().get_sys_value())
+ {
+ case opEvent:
+ {
+ CMIP_1::m_EventReport *o
+ = static_cast<CMIP_1::m_EventReport *>(*(i.argument));
+ }
+ break;
+ case opEventConfirm :
+ break;
+ case opLinkedReply :
+ break;
+ case opGet :
+ {
+ struct doGet {
+ doGet(CMIP_1::GetArgument &a) : m_arg(a) {};
+ void operator ()(CMIPListener *l)
+ { l->on_m_Get(m_arg);}
+ CMIP_1::GetArgument &m_arg;
+ };
+ CMIP_1::m_Get *o
+ = static_cast<CMIP_1::m_Get *>(*(i.argument));
+ std::cout<<"CMIPStack::"<<__FUNCTION__;
+ std::cout<<" process GET"<<"\n";
+ std::for_each(m_Listeners.begin()
+ , m_Listeners.end()
+ , doGet(o->get_ArgumentType())
+ );
+ std::cout<<" END process GET"<<"\n";
+ }
+ break;
+ case opSet :
+ {
+ CMIP_1::m_Set *o
+ = static_cast<CMIP_1::m_Set *>(*(i.argument));
+ }
+ break;
+ case opSetConfirm :
+ {
+ CMIP_1::m_Set_Confirmed *o
+ = static_cast<CMIP_1::m_Set_Confirmed *>(*(i.argument));
+ }
+ break;
+ case opAction :
+ {
+ CMIP_1::m_Action *o
+ = static_cast<CMIP_1::m_Action *>(*(i.argument));
+ }
+ break;
+ case opActionConfirm :
+ break;
+ case opCreate :
+ {
+ CMIP_1::m_Create *o
+ = static_cast<CMIP_1::m_Create *>(*(i.argument));
+ }
+ break;
+ case opDelete :
+ {
+ CMIP_1::m_Delete *o
+ = static_cast<CMIP_1::m_Delete *>(*(i.argument));
+ }
+ break;
+ case opCancelGet :
+ break;
+ default:
+ ;
+ }
+}
+
+void
+CMIPStack::doReturnResult(rose_pdu::ReturnResult &r)
+{
+ if (r.bit_mask.test(rose_pdu::ReturnResult::result_present))
+ {
+ assert(r.result->opcode.get_kind() == Code::typeof_local);
+ std::cout<<"CMIPStack::"<<__FUNCTION__;
+ std::cout<<" got "<<r.result->opcode.get_local()<<"\n";
+ rose_pdu::ReturnResult_result *result = *r.result;
+ switch (result->opcode.get_local().get_sys_value())
+ {
+ case opEvent:
+ {
+ CMIP_1::m_EventReport *o
+ = static_cast<CMIP_1::m_EventReport *>(*(result->result));
+ }
+ break;
+ case opEventConfirm :
+ break;
+ case opLinkedReply :
+ break;
+ case opGet :
+ {
+ CMIP_1::m_Get *o
+ = static_cast<CMIP_1::m_Get *>(*(result->result));
+ std::cout<<"CMIPStack::"<<__FUNCTION__;
+ std::cout<<" process GET"<<"\n";
+ o->printf(std::cout);
+ std::cout<<" END process GET"<<"\n";
+
+ }
+ break;
+ case opSet :
+ {
+ CMIP_1::m_Set *o
+ = static_cast<CMIP_1::m_Set *>(*(result->result));
+ }
+ break;
+ case opSetConfirm :
+ {
+ CMIP_1::m_Set_Confirmed *o
+ = static_cast<CMIP_1::m_Set_Confirmed *>(*(result->result));
+ }
+ break;
+ case opAction :
+ {
+ CMIP_1::m_Action *o
+ = static_cast<CMIP_1::m_Action *>(*(result->result));
+ }
+ break;
+ case opActionConfirm :
+ break;
+ case opCreate :
+ {
+ CMIP_1::m_Create *o
+ = static_cast<CMIP_1::m_Create *>(*(result->result));
+ }
+ break;
+ case opDelete :
+ {
+ CMIP_1::m_Delete *o
+ = static_cast<CMIP_1::m_Delete *>(*result->result);
+ }
+ break;
+ case opCancelGet :
+ break;
+ default:
+ ;
+ }
+ } else
+ {
+ std::cout<<"CMIPStack::"<<__FUNCTION__;
+ std::cout<<" got "<<"no result"<<"\n";
+ }
+}
+
+void
+CMIPStack::doReturnError(rose_pdu::ReturnError &re)
+{
+ std::cout<<"CMIPStack::"<<__FUNCTION__;
+ std::cout<<" TODO "<<"no result"<<"\n";
+}
+
+void
+CMIPStack::doReject(rose_pdu::Reject &r)
+{
+ std::cout<<"CMIPStack::"<<__FUNCTION__;
+ std::cout<<" TODO "<<"no result"<<"\n";
+}
+
+namespace CMIP_1 {
+extern rose_ie::IOPERATION *CMIP_Operations[];
+}
+// Handle receive data from lower layer
+void
+CMIPStack::onReceive(asn1::streams::ber &ctx)
+{
+ //::asn1::types::debug_level = 8;
+ ROS ros;
+ ros.Invokable = CMIP_1::CMIP_Operations;
+ int result = ros.decode(ctx);
+ switch (ros.get_kind())
+ {
+ case ROS::typeof_invoke:
+ doInvoke(ros.get_invoke());
+ break;
+ case ROS::typeof_returnResult:
+ doReturnResult(ros.get_returnResult());
+ break;
+ case ROS::typeof_returnError:
+ doReturnError(ros.get_returnError());
+ break;
+ case ROS::typeof_reject:
+ doReject(ros.get_reject());
+ break;
+ default:
+ std::cerr<<"CMIPStack::"<<__FUNCTION__<<" Big Issue\n";
+ ;
+ }
+}
+
--- /dev/null
+#ifndef CMIPSTACK_H
+#define CMIPSTACK_H
+
+namespace rose_pdu = Remote_Operations_Generic_ROS_PDUs;
+/**
+ * @brief Public interface for the CMIP Stack
+ * Basicallly, the class allows sending data to lower
+ * and receive data from the lower layer.
+ * The layer below CMIP is ACSE / STASE The sub layer
+ * is responsible for association and authentication and so on
+ * Thus the stack should implement a Listener interface of
+ * the underneth Stack ACSE
+ */
+class CMIPStack
+{
+ public:
+ // Operations
+ enum {
+ opEvent = 0
+ , opEventConfirm = 1
+ , opLinkedReply = 2
+ , opGet = 3
+ , opSet = 4
+ , opSetConfirm = 5
+ , opAction = 6
+ , opActionConfirm = 7
+ , opCreate = 8
+ , opDelete = 9
+ , opCancelGet = 10
+ };
+
+ public:
+ typedef std::list<CMIPActionListener *> ActionListenerList;
+ typedef std::list<CMIPEventReportListener *> EventReportListenerList;
+ typedef std::list<CMIPListener *> ListenerList;
+ // Above Rose... And Stase
+ //
+ CMIPStack();
+ /**
+ *
+ */
+ void registerListener(CMIPActionListener *a);
+ /**
+ *
+ */
+ void registerListener(CMIPEventReportListener *a);
+ /**
+ *
+ */
+ void registerListener(CMIPListener *a);
+
+ /**
+ * Down stream methods
+ * {m-Action | m-Action-Confirmed | m-CancelGet | m-Create | m-Delete |
+ * m-EventReport | m-EventReport-Confirmed | m-Get | m-Linked-Reply | m-Set |
+ * m-Set-Confirmed}
+ */
+ void send_m_Action(CMIP_1::m_Action &o);
+
+ void send_m_Action_Confirmed(CMIP_1::m_Action_Confirmed &o);
+
+ void send_m_CancelGet(CMIP_1::m_CancelGet &o);
+
+ void send_m_Create(CMIP_1::m_Create &o);
+
+ void send_m_Delete(CMIP_1::m_Delete &o);
+
+ void send_m_EventReport(CMIP_1::m_EventReport &o);
+
+ void send_m_EventReport_Confirmed(CMIP_1::m_EventReport_Confirmed &o);
+
+ void send_m_Get(CMIP_1::m_Get &o);
+
+ void send_m_Linked_Reply(CMIP_1::m_Linked_Reply &o);
+
+ void send_m_Set(CMIP_1::m_Set &o);
+
+ void send_m_Set_Confirmed(CMIP_1::m_Set_Confirmed &o);
+ // Handle receive data from lower layer
+ void onReceive(asn1::streams::ber &ctx);
+ protected:
+ asn1::streams::ber m_Ctx;
+ ListenerList m_Listeners;
+
+ void doInvoke(rose_pdu::Invoke &i);
+ void doReturnResult(rose_pdu::ReturnResult &rr);
+ void doReturnError(rose_pdu::ReturnError &re);
+ void doReject(rose_pdu::Reject &r);
+};
+
+/*
+ * vi:et sw=2 ts=2:
+ */
+#endif
--- /dev/null
+PROJECT(cmip-lib)
+
+
+ADD_DEFINITIONS(-DASN1_ATTRIBUTE_OPTIONAL_AS_SHARED_POINTER)
+
+IF (WITH_CMIP)
+FILE(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/modules.txt CMIPMODULES)
+SET(CMIP_ASN1P ${CMAKE_CURRENT_BINARY_DIR}/../asn1p)
+SET(CMIP_ERULE "-e ber")
+FOREACH(ITEM ${CMIPMODULES})
+ STRING(REGEX REPLACE "-" "_" HITEM ${ITEM})
+ SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/${HITEM}.h GENERATED)
+ SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/${ITEM}.cpp GENERATED)
+ SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/${ITEM}.cpp COMPILE_FLAGS "-DASN1_ATTRIBUTE_OPTIONAL_AS_SHARED_POINTER")
+ SET(CMIPSRC ${CMIPSRC} ${ITEM}.cpp)
+ SET(CMIPHDR ${CMIPHDR} ${HITEM}.h)
+ENDFOREACH(ITEM)
+
+SET_DIRECTORY_PROPERTIES(PROPERTIES
+ ADDITIONAL_MAKE_CLEAN_FILES "${CMIPSRC} ${CMIPHDR}"
+ )
+
+SET(ROSE_PARSER_INC -n false -I ${asn1-data-models_SOURCE_DIR}/)
+SET(ROSE_PARSER_OPT ${ROSE_PARSER_INC} -fRemote-Operations-Generic-ROS-PDUs.asn1)
+SET(ROSE_PARSER_OPT ${ROSE_PARSER_OPT} -fRemote-Operations-Information-Objects.asn1)
+SET(ROSE_PARSER_OPT ${ROSE_PARSER_OPT}
+ -fRemote-Operations-Useful-Definitions.asn1)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+#
+#Remote-Operations-Generic-ROS-PDUs {joint-iso-itu-t remote-operations(4)
+#
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote_Operations_Generic_ROS_PDUs.h
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Generic-ROS-PDUs.cpp
+ COMMAND ${CMIP_ASN1P}
+ ARGS ${ROSE_PARSER_OPT} -o Remote-Operations-Generic-ROS-PDUs
+ DEPENDS ${CMIP_ASN1P}
+ COMMENT "Build Remote-Operations-Generic-ROS-PDUs .h and .cpp"
+ )
+
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Generic-ROS-PDUs.h
+ GENERATED)
+#
+#
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote_Operations_Useful_Definitions.h
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Useful-Definitions.cpp
+ COMMAND ${CMIP_ASN1P}
+ ARGS ${ROSE_PARSER_OPT} -o Remote-Operations-Useful-Definitions
+ DEPENDS ${CMIP_ASN1P}
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Generic-ROS-PDUs.cpp
+ COMMENT "Build Remote-Operations-Usful-Definitions .h and .cpp"
+ )
+
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Useful-Definitions.h
+ GENERATED)
+#
+#
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote_Operations_Information_Objects.h
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Information-Objects.cpp
+ COMMAND ${CMIP_ASN1P}
+ ARGS ${ROSE_PARSER_OPT} -o Remote-Operations-Information-Objects
+ DEPENDS ${CMIP_ASN1P}
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Useful-Definitions.cpp
+ COMMENT "Build Remote-Operations-Informations-Objects .h and .cpp"
+ )
+
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Information-Objects.h
+ GENERATED)
+
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/CMIP_1.h
+ ${CMAKE_CURRENT_BINARY_DIR}/CMIP-1.cpp
+ COMMAND ${CMIP_ASN1P}
+
+ ARGS ${ROSE_PARSER_OPT} -o CMIP-1
+ -f CMIP-1.asn1
+ DEPENDS ${CMIP_ASN1P}
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Information-Objects.cpp
+ COMMENT "Build CMIP-1 .h and .cpp"
+ )
+
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/ACSE_1.h
+ ${CMAKE_CURRENT_BINARY_DIR}/ACSE-1.cpp
+ COMMAND ${CMIP_ASN1P}
+
+ ARGS ${ROSE_PARSER_OPT} -o ACSE-1
+ -f cstav1/apdu_acse.asn1
+ DEPENDS ${CMIP_ASN1P}
+ COMMENT "Build ACSE-1 .h and .cpp"
+ )
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/ACSE-1.cpp
+ GENERATED)
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/ACSE-1.cpp
+ COMPILE_FLAGS "-DASN1_ATTRIBUTE_OPTIONAL_AS_SHARED_POINTER")
+# Attribute-ASN1Module
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/Attribute_ASN1Module.h
+ ${CMAKE_CURRENT_BINARY_DIR}/Attribute-ASN1Module.cpp
+ COMMAND ${CMIP_ASN1P}
+
+ ARGS ${ROSE_PARSER_OPT} -o Attribute-ASN1Module
+ -f cstav1/apdu_acse.asn1
+ -f cmip/Attribute-ASN1Module.asn1
+ -f CMIP-1.asn1
+ DEPENDS ${CMIP_ASN1P}
+ COMMENT "Build Attribute-ASN1Module .h and .cpp"
+ )
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/Attribute-ASN1Module.cpp
+ GENERATED)
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/Attribute-ASN1Module.cpp
+ COMPILE_FLAGS "-DASN1_ATTRIBUTE_OPTIONAL_AS_SHARED_POINTER")
+
+
+
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/X721.h
+ ${CMAKE_CURRENT_BINARY_DIR}/X721.hpp
+ ${CMAKE_CURRENT_BINARY_DIR}/X721.cpp
+ COMMAND ${CMIP_ASN1P}
+
+ ARGS ${ROSE_PARSER_OPT} -o X721
+ -f cmip/x721-gdmo.asn1
+ -f cmip/Attribute-ASN1Module.asn1
+ -f CMIP-1.asn1
+ -f x227/ACSE-1.asn1
+ DEPENDS ${CMIP_ASN1P}
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Information-Objects.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/Attribute-ASN1Module.cpp
+ COMMENT "Build X721 .h and .cpp from x721-gdmo.asn1"
+ )
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/X721.hpp
+ GENERATED)
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/X721.cpp
+ GENERATED)
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/X721.cpp
+ COMPILE_FLAGS "-DASN1_ATTRIBUTE_OPTIONAL_AS_SHARED_POINTER")
+
+ADD_LIBRARY(cmip
+ ${CMAKE_CURRENT_BINARY_DIR}/X721.hpp
+ ${CMIPSRC}
+ )
+
+ADD_EXECUTABLE( test_cmip
+ X721.cpp
+ Attribute-ASN1Module.cpp
+ ACSE-1.cpp
+ CMIPStack.cpp
+ CMIPAgent.cpp
+ main.cpp
+ )
+TARGET_LINK_LIBRARIES(test_cmip cmip asn1)
+ENDIF(WITH_CMIP)
--- /dev/null
+#include <iostream>
+
+#include "Remote_Operations_Generic_ROS_PDUs.h"
+#include "CMIP_1.h"
+#include "CMIP_1.hpp"
+
+#include "rtasn1/asn1_codec.h"
+#include "rtasn1/asn1_codec_ber.h"
+
+#include "CMIPListener.h"
+#include "CMIPActionListener.h"
+#include "CMIPEventReportListener.h"
+#include "CMIPStack.h"
+#include "CMIPAgent.h"
+
+#include "Attribute_ASN1Module.h"
+#include "X721.h"
+#include "X721.hpp"
+using namespace CMIP_1;
+using namespace Remote_Operations_Generic_ROS_PDUs;
+using namespace Remote_Operations_Information_Objects;
+
+void test1()
+{
+ std::cerr<<"\n*\n* test CODE\n*"<<std::endl;
+ Code c(Code::typeof_local);
+ c.get_local() = 1;
+ c.printf(std::cout);
+ std::cout<<"\n";
+}
+void test2()
+{
+ std::cerr<<"\n*\n* test Invoke\n*"<<std::endl;
+ Invoke i;
+ i.invokeId.set_tag(asn1::tag(0,2));
+ i.invokeId.get_present() = 4;
+ i.opcode.set_tag(asn1::tag(0,2));
+ i.opcode.get_local() = 1;
+ i.printf(std::cout);
+ std::cout<<std::endl;
+}
+
+void test3()
+{
+ asn1::streams::ber ctx;
+ std::cerr<<"\n*\n* test ROS\n*"<<std::endl;
+ ActionArgument aaa;
+ ROS ros(ROS::typeof_invoke,asn1::tag(2,1));
+ m_Action *a = new m_Action();
+ //
+ aaa.baseManagedObjectClass.set_tag(asn1::tag(2,0));
+ aaa.baseManagedObjectClass.get_globalForm() = OBJECT_IDENTIFIER(2,"\x2a\x32");
+
+ a->set_ArgumentType(aaa);
+ Invoke &i = ros.get_invoke();
+ i.invokeId.get_present() = 8;
+ i.argument = a;
+ i.opcode.set_tag(asn1::tag(0,2));
+ i.opcode.get_local() = 7;
+ std::cout<<std::setprecision(0);
+ i.printf(std::cout);
+ ros.encode(ctx);
+ std::cout<<"\nSize "<<ctx.nb_read_bits()<<" bits"<<std::endl;
+}
+
+
+void test4()
+{
+ std::cerr<<"\n*\n* test ComplexityLimitation\n*"<<std::endl;
+ ComplexityLimitation cl;
+ cl.scope = new Scope();
+ cl.filter = new CMISFilter();
+ // Set Filter to use
+ //cl.filter->set_tag(asn1::tag(2,CMISFilter::typeof_item));
+ cl.filter->set_tag(asn1::tag(2,8));
+ FilterItem &item = cl.filter->get_item();
+ item.set_tag(asn1::tag(2,FilterItem::typeof_equality));
+
+ Attribute &attr = item.get_equality();
+ X721::systemId *sid = new X721::systemId();
+ attr.id.set_globalForm( sid->get_id().get_globalForm());
+ sid->get_Value().set_number(asn1::INTEGER(3));
+ attr.value = sid;
+ cl.scope->get_namedNumbers() = 403;
+
+ std::cout<<std::setprecision(0)<<cl<<std::endl;
+}
+
+void test5()
+{
+ asn1::streams::ber ctx;
+ std::cout<<"\n*\n* test m-Get\n*"<<std::endl;
+ GetArgument getArgument;
+ getArgument.baseManagedObjectClass.set_globalForm( OBJECT_IDENTIFIER(2,"\x2a\x32"));
+ //getArgument.baseManagedObjectInstance.set_nonSpecificForm(OCTET_STRING("test_obj"));
+ getArgument.baseManagedObjectInstance.set_nonSpecificForm("test_obj");
+ getArgument.attributeIdList = new GetArgument_attributeIdList();
+ AttributeId ai;
+
+ ai.set_localForm(asn1::INTEGER(8));
+ getArgument.attributeIdList->push_back(ai);
+
+ ai.get_localForm() = 28;
+ getArgument.attributeIdList->push_back(ai);
+
+ ai.set_globalForm( OBJECT_IDENTIFIER(4,"\x2a\x14\x23\x41"));
+ getArgument.attributeIdList->push_back(ai);
+
+ m_Get *get = new m_Get();
+ //
+ getArgument.baseManagedObjectClass.set_globalForm(
+ OBJECT_IDENTIFIER(5,"\x2a\x32\x12\x35\x12"));
+
+ get->set_ArgumentType(getArgument);
+
+ CMIPStack stack;
+ CMIPAgent agent(stack);
+ stack.send_m_Get(*get);
+}
+
+void test6()
+{
+ std::cout<<"\n*\n* test CMIPStack "<<__FUNCTION__<<"\n*"<<std::endl;
+ ActionArgument aaa;
+ m_Action::ptr a = new m_Action();
+ // Both work
+ aaa.baseManagedObjectClass.set_globalForm( OBJECT_IDENTIFIER(2,"\x2a\x32"));
+ aaa.scope = new Scope();
+ //aaa.filter = new CMISFilter(asn1::tag(2,CMISFilter::typeof_item));
+ aaa.filter = new CMISFilter(asn1::tag(2,8));
+ aaa.filter->set_tag(asn1::tag(2,8)); // Way is this required ?
+ FilterItem &item = aaa.filter->get_item();
+ //item.set_tag(asn1::tag(2,FilterItem::typeof_equality));
+ item.set_tag(asn1::tag(2,0));
+ Attribute &attr = item.get_equality();
+ attr.id.set_tag(asn1::tag(2,2));
+ X721::pdusSentCounter *pdusS = new X721::pdusSentCounter();
+ pdusS->get_Value() = 23;
+ attr.id.set_globalForm( pdusS->get_id().get_globalForm());
+ attr.value = pdusS;
+
+ aaa.scope->get_namedNumbers() = 404;
+
+ a->set_ArgumentType(aaa);
+ CMIPStack stack;
+ stack.send_m_Action(**a);
+}
+
+void test7()
+{
+ std::cout<<"\n*\n* test CMIPStack "<<__FUNCTION__<<"\n*"<<std::endl;
+ SetArgument setA;
+ m_Set::ptr a = new m_Set();
+ setA.baseManagedObjectInstance.set_nonSpecificForm(OCTET_STRING("test_obj"));
+ setA.baseManagedObjectClass.set_globalForm( OBJECT_IDENTIFIER(2,"\x2a\x32"));
+ setA.scope = new Scope();
+#define UF 0
+#if UF
+ // Attention witout bit_mask value is not encoded
+ setA.bit_mask.set(SetArgument::filter_present);
+ setA.filter = new CMISFilter(asn1::tag(2,8));
+ setA.filter->set_tag(asn1::tag(2,8)); // Why is this required ?
+ FilterItem &item = setA.filter->get_item();
+ item.set_tag(asn1::tag(2,0));
+
+ Attribute &attr = item.get_equality();
+ attr.id.set_tag(asn1::tag(2,2));
+#endif
+ X721::pdusSentCounter *pdusS = new X721::pdusSentCounter();
+ pdusS->get_Value() = 25;
+#if UF
+ attr.id.set_globalForm( pdusS->get_id().get_globalForm());
+ attr.value = pdusS;
+#endif
+ setA.scope->get_namedNumbers() = 407;
+ //
+#if 1
+ SetArgument_modificationList_type sa_mlt;
+ sa_mlt.attributeId.set_globalForm( pdusS->get_id().get_globalForm());
+ sa_mlt.attributeValue = pdusS;
+ setA.modificationList.push_back(sa_mlt);
+ // Add another attribute
+ X721::systemId *sid = new X721::systemId();
+ sid->get_Value().set_number(asn1::INTEGER(9));
+ sa_mlt.attributeId.set_globalForm( sid->get_id().get_globalForm());
+ sa_mlt.attributeValue = sid;
+ setA.modificationList.push_back(sa_mlt);
+#endif
+ a->set_ArgumentType(setA);
+ CMIPStack stack;
+ stack.send_m_Set(**a);
+}
+
+
+
+int main(int argc,char **argv)
+{
+ asn1::INTEGER op(1);
+ ::asn1::types::debug_level = 1;
+ std::cout<<"main get_local"<<std::endl;
+ test1();
+ test2();
+ test3();
+ test4();
+ test5();
+ test6();
+ test7();
+ std::cout<<"END"<<std::endl;
+ std::cout<<std::endl;
+}
--- /dev/null
+CMIP-1
+Remote-Operations-Generic-ROS-PDUs
+Remote-Operations-Useful-Definitions
+Remote-Operations-Information-Objects
--- /dev/null
+PROJECT(csta-lib)
+
+FILE(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/modules.txt CSTAMODULES)
+
+FOREACH(ITEM ${CSTAMODULES})
+ STRING(REGEX REPLACE "-" "_" HITEM ${ITEM})
+ SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/${HITEM}.h GENERATED)
+ SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/${ITEM}.cpp GENERATED)
+ SET(CSTASRC ${CSTASRC} ${CMAKE_CURRENT_BINARY_DIR}/${ITEM}.cpp)
+ SET(CSTAHDR ${CSTAHDR} ${CMAKE_CURRENT_BINARY_DIR}/${HITEM}.h)
+
+ ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/${ITEM}.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/${HITEM}.h
+ ${CMAKE_CURRENT_BINARY_DIR}
+ COMMAND ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ ARGS
+ -I ${CMAKE_CURRENT_SOURCE_DIR}/../../data-models/
+ -f ecma-285.asn1
+ -f cstav2/ecma-218.asn1
+ -f cstav1/Remote-Operations-Information-Objects.asn1
+ -o ${ITEM}
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ COMMENT "Build ${ITEM} .h and .cpp"
+ )
+
+
+
+
+ENDFOREACH(ITEM)
+
+SET_DIRECTORY_PROPERTIES(PROPERTIES
+ ADDITIONAL_MAKE_CLEAN_FILES "${CSTASRC} ${CSTAHDR}"
+ )
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+IF (WITH_CSTA)
+# ${CMAKE_CURRENT_SOURCE_DIR}/../../../data-models/asn1/Remote-Operations-Information-Objects.asn1
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote_Operations_Generic_ROS_PDUs.h
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Generic-ROS-PDUs.cpp
+ COMMAND cat
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../data-models/asn1/Remote-Operations-Information-Objects.asn1
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../data-models/asn1/Remote-Operations-Generic-ROS-PDUs.asn1
+ ARGS | ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ COMMENT "Build ROI .h and .cpp"
+ )
+
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Generic-ROS-PDUs.h
+ GENERATED)
+#
+#
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote_Operations_Useful_Definitions.h
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Useful-Definitions.cpp
+ COMMAND cat
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../data-models/asn1/Remote-Operations-Useful-Definitions.asn1
+ ARGS | ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ COMMENT "Build ROI .h and .cpp"
+ )
+
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Useful-Definitions.h
+ GENERATED)
+#
+#
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote_Operations_Information_Objects.h
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Information-Objects.cpp
+ COMMAND ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ ARGS
+ -I ${asn1-data-models_SOURCE_DIR}/
+ -f cstav1/Remote-Operations-Information-Objects.asn1
+ -o Remote-Operations-Information-Objects
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ COMMENT "Build ROI .h and .cpp"
+ )
+
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Information-Objects.h
+ GENERATED)
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Information-Objects.cpp
+ GENERATED)
+
+ADD_LIBRARY(csta
+ ${CSTASRC}
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Information-Objects.cpp
+ )
+
+ADD_EXECUTABLE(test_csta
+ main.cpp
+ )
+
+TARGET_LINK_LIBRARIES(test_csta csta asn1)
+
+ENDIF(WITH_CSTA)
--- /dev/null
+
+#include <iostream>
+#include <string.h>
+
+#include "rtasn1/asn1.h"
+#include "rtasn1/asn1_codec.h"
+#include "rtasn1/asn1_codec_ber.h"
+
+#include "CSTA_event_report_definitions.h"
+#include "CSTA_event_report_definitions.hpp"
+
+/**
+
+CSTAEventReportArgument ::= SEQUENCE {
+ crossRefIdentifier MonitorCorssRefID
+ eventSpecificInfo EventSpecificInfo
+}
+ *
+EventSpecificInfo ::= CHOICE {
+ callControlEvent [0] CallcontrolEvents,
+
+}
+ *
+ConnectionID ::= [APPLICATION 11] CHOICE {
+ callID [0] IMPLICIT CallID,
+ deviceID [1] LocalDeviceID,
+ both SEQUENCE {
+ callID [0] IMPLICIT CallID,
+ deviceID [1] LocalDeviceID
+ }
+}
+
+CallID ::= OCTET STRING
+LocalDeviceID ::= CHOICE [
+ staticID DeviceID
+ dynamicID [3] IMPLICIT OCTET STRING
+}
+
+DeviceID ::= SEQUENCE {
+ deviceIdentifier CHOICE {
+ }
+}
+ */
+
+int test_decode()
+{
+ /* This sequence is for Alcatel CSTA which is not compatible with the ecma
+ * 285 description. Just forget it. Events are described diferently*/
+ const unsigned char d[] ={ 0x30,0x46,
+ 0x55,0x04,0x00,0x00,0x00,0x04,
+ 0x80,0x01,0x0d, // For alcated, this Event Type 13
+ //Context Specific - Primitive - Id=0 tag. Len 1 - value 0d 13 what is this ?
+ 0x30,0x1d, /* OriginatedEvent SEQUENCE len 0x1d 29*/
+ 0x6b,0x0a, /* ConnectionID tag APPL 11 len 10 CHOICE*/
+ 0x82,0x02,0x00,0x76, /* This should be both of ConnectionID*/
+ 0x83,0x04,0x00, 0x03,0x00,0x00, /* supposed to be dynamic ID*/
+ /**
+ SubjectDeviceID is (APPLICATION 3 Choice)
+ CalledDeviceID is (APPLICATION 2 Choice)
+
+ */
+ 0x4e,0x01,0x01, /* State initated */
+ 0x0a,0x01, 0x16, /* Event Cause newCall*/
+ /* I d'ont know what this is PRIVATE data */
+ 0x63,0x05,0x84,0x03,0x31,0x30,0x32, /* loocks like SubjectDeviceID */
+ 0x62,0x02,0x87,0x00}; /* looks like CalledDeviceID*/
+
+ CSTA_event_report_definitions::cSTAEventReport report;
+ asn1::context ctx;
+ memcpy(ctx.buffer(),d,41);
+ report.decode(ctx);
+
+}
+
+int main(int argc,char **argv)
+{
+
+ CSTA_event_report_definitions::cSTAEventReport report;
+ //asn1::context ctx;
+ test_decode();
+ //report.codec(ctx,asn1::CODEC_ENCODE);
+ std::cout<<"Hello world"<<std::endl;
+}
--- /dev/null
+CSTA-accept-call
+CSTA-activate
+CSTA-agent-busy-event
+CSTA-agent-logged-off-event
+CSTA-agent-logged-on-event
+CSTA-agent-not-ready-event
+CSTA-agent-ready-event
+CSTA-agent-working-after-call-event
+CSTA-alternate-call
+CSTA-answer-call
+CSTA-application-context-information-csta3
+CSTA-application-context-information
+CSTA-associate-data
+CSTA-attach-media-service
+CSTA-auto-answer-event
+CSTA-auto-work-mode-event
+CSTA-back-in-service-event
+CSTA-bookmark-reached-event
+CSTA-bridged-event
+CSTA-button-information-event
+CSTA-button-press-event
+CSTA-button-press
+CSTA-call-back-call-related
+CSTA-call-back-event
+CSTA-call-back-message-call-related
+CSTA-call-back-message-event
+CSTA-call-back-message-non-call-related
+CSTA-call-back-non-call-related
+CSTA-call-cleared-event
+CSTA-call-connection-identifiers
+CSTA-call-control
+CSTA-call-detail-record
+CSTA-call-detail-records-notification
+CSTA-call-detail-records-report
+CSTA-call-information-event
+CSTA-caller-id-status-event
+CSTA-camp-on-call
+CSTA-cancel-call-back-message
+CSTA-cancel-call-back
+CSTA-cancel-telephony-tones
+CSTA-capability-exchange
+CSTA-change-connection-information
+CSTA-change-monitor-filter
+CSTA-change-system-status-filter
+CSTA-charge-info
+CSTA-charging-event
+CSTA-clear-call
+CSTA-clear-connection
+CSTA-clear
+CSTA-completed-event
+CSTA-concatenate-message
+CSTA-conference-call
+CSTA-conferenced-event
+CSTA-connection-cleared-event
+CSTA-connection-states
+CSTA-consultation-call
+CSTA-data-call-types
+CSTA-data-collected
+CSTA-data-collection-resumed
+CSTA-data-collection-suspended
+CSTA-data-collection
+CSTA-data-path-resumed
+CSTA-data-path-suspended
+CSTA-deactivate
+CSTA-deflect-call
+CSTA-delete-message
+CSTA-delivered-event
+CSTA-detach-media-service
+CSTA-device-capabilities-changed-event
+CSTA-device-feature-types
+CSTA-device-identifiers
+CSTA-dial-digits
+CSTA-digits-dialed-event
+CSTA-digits-generated-event
+CSTA-directed-pickup-call
+CSTA-display-updated-event
+CSTA-diverted-event
+CSTA-do-not-disturb-event
+CSTA-dtmf-detected-event
+CSTA-emptied-event
+CSTA-error-definition
+CSTA-escape-register-abort
+CSTA-escape-register-cancel
+CSTA-escape-register
+CSTA-escape-service
+CSTA-escape-types
+CSTA-established-event
+CSTA-event-causes
+CSTA-event-report-definitions
+CSTA-extension-types
+CSTA-failed-event
+CSTA-fast-data
+CSTA-forwarding-event
+CSTA-generate-digits
+CSTA-generate-telephony-tones
+CSTA-get-agent-state
+CSTA-get-auditory-apparatus-information
+CSTA-get-auto-answer
+CSTA-get-auto-work-mode
+CSTA-get-button-information
+CSTA-get-call-back
+CSTA-get-caller-id-status
+CSTA-get-csta-features-service
+CSTA-get-display
+CSTA-get-do-not-disturb
+CSTA-get-forwarding
+CSTA-get-hookswitch-status
+CSTA-get-lamp-information
+CSTA-get-lamp-mode
+CSTA-get-last-number-dialed
+CSTA-get-location-information
+CSTA-get-location-tracking-capabilities
+CSTA-get-location-tracking-sessions
+CSTA-get-logical-device-information
+CSTA-get-message-waiting-indicator
+CSTA-get-microphone-gain
+CSTA-get-microphone-mute
+CSTA-get-monitor
+CSTA-get-physical-device-information
+CSTA-get-registrations
+CSTA-get-ringer-status
+CSTA-get-routeing-mode
+CSTA-get-speaker-mute
+CSTA-get-speaker-volume
+CSTA-get-switching-function-capabilities
+CSTA-get-switching-function-devices
+CSTA-group-pickup-call
+CSTA-held-event
+CSTA-hold-call
+CSTA-hookswitch-event
+CSTA-interruption-detected-event
+CSTA-intrude-call
+CSTA-io-register-abort
+CSTA-io-register-cancel
+CSTA-io-register
+CSTA-join-call
+CSTA-lamp-mode-event
+CSTA-location-information-report
+CSTA-location-session-info
+CSTA-location-tracking-session-resumed
+CSTA-location-tracking-session-suspended
+CSTA-make-call
+CSTA-make-connection
+CSTA-make-predictive-call
+CSTA-media-attached-event
+CSTA-media-detached-event
+CSTA-media-services
+CSTA-message-waiting-event
+CSTA-microphone-gain-event
+CSTA-microphone-mute-event
+CSTA-monitor-info
+CSTA-monitor-start
+CSTA-monitor-stop
+CSTA-network-capabilities-changed-event
+CSTA-network-reached-event
+CSTA-not-recognized-event
+CSTA-offered-event
+CSTA-originated-event
+CSTA-out-of-service-event
+CSTA-park-call
+CSTA-partially-in-service-event
+CSTA-physical-device-feature
+CSTA-play-event
+CSTA-play-message
+CSTA-private-data-version-selection
+CSTA-private-event
+CSTA-query-voice-attribute
+CSTA-queue
+CSTA-queued-event
+CSTA-re-route-request
+CSTA-recognized-event
+CSTA-reconnect-call
+CSTA-record-event
+CSTA-record-message
+CSTA-registration-info
+CSTA-reposition
+CSTA-request-system-status
+CSTA-resume-data-collection
+CSTA-resume-data-path
+CSTA-resume-location-tracking-session
+CSTA-resume
+CSTA-retrieve-call
+CSTA-retrieved-event
+CSTA-review-event
+CSTA-review
+CSTA-ringer-status-event
+CSTA-route-end-request
+CSTA-route-register-abort
+CSTA-route-register-cancel
+CSTA-route-register
+CSTA-route-reject
+CSTA-route-request
+CSTA-route-select-request
+CSTA-route-used-request
+CSTA-routeing-mode-event
+CSTA-security
+CSTA-send-broadcast-data
+CSTA-send-data
+CSTA-send-message
+CSTA-send-multicast-data
+CSTA-send-stored-call-detail-records
+CSTA-send-user-information
+CSTA-service-completion-failure-event
+CSTA-service-initiated-event
+CSTA-set-agent-state
+CSTA-set-auto-answer
+CSTA-set-auto-work-mode
+CSTA-set-button-information
+CSTA-set-caller-id-status
+CSTA-set-display
+CSTA-set-do-not-disturb
+CSTA-set-forwarding
+CSTA-set-hookswitch-status
+CSTA-set-lamp-mode
+CSTA-set-location-information
+CSTA-set-message-waiting-indicator
+CSTA-set-microphone-gain
+CSTA-set-microphone-mute
+CSTA-set-ringer-status
+CSTA-set-routeing-mode
+CSTA-set-speaker-mute
+CSTA-set-speaker-volume
+CSTA-set-voice-attribute
+CSTA-silence-timeout-expired-event
+CSTA-single-step-conference
+CSTA-single-step-transfer
+CSTA-snapshot-call-data
+CSTA-snapshot-call
+CSTA-snapshot-device-data
+CSTA-snapshot-device
+CSTA-speaker-mute-event
+CSTA-speaker-volume-event
+CSTA-speech-detected-event
+CSTA-start-call-detail-records-transmission
+CSTA-start-data-collection
+CSTA-start-data-path
+CSTA-start-location-tracking-session
+CSTA-start
+CSTA-started-event
+CSTA-status-reporting
+CSTA-stop-call-detail-records
+CSTA-stop-data-collection
+CSTA-stop-data-path
+CSTA-stop-event
+CSTA-stop-location-tracking-session
+CSTA-stop
+CSTA-suspend-data-collection
+CSTA-suspend-data-path
+CSTA-suspend-location-tracking-session
+CSTA-suspend-play-event
+CSTA-suspend-record-event
+CSTA-suspend
+CSTA-switching-function-capabilities-changed
+CSTA-switching-function-devices-changed
+CSTA-switching-function-devices
+CSTA-switching-function-objects
+CSTA-synthesize-message
+CSTA-system-register-abort
+CSTA-system-register-cancel
+CSTA-system-register
+CSTA-system-status
+CSTA-telephony-tones-generated-event
+CSTA-transfer-call
+CSTA-transferred-event
+CSTA-voice-attributes-change-event
+CSTA-voice-error-occured-event
--- /dev/null
+#include <iostream>
+// lib curl muli.
+#include "curl/curl.h"
+#include "AtraceReader.h"
+
+
+AtraceCurlReader::AtraceCurlReader()
+{
+}
+
+AtraceCurlReader::~AtraceCurlReader()
+{
+}
--- /dev/null
+#ifndef ATRACEDECODER_H
+#define ATRACEDECODER_H
+
+/**
+ * This class is responsible to decode binary traces and
+ * converte them into a readable form.
+ * -> Needs tbl files to be able to make the correspondance
+ * -> Need another listener. People might want trace from
+ * decoder and not Binary traces.
+ *
+ */
+class AtraceDecoder : public AtraceBinListener
+{
+ public:
+ AtraceDecoder();
+ ~AtraceDecoder();
+
+ //
+ virtual void onBinState() {};
+ virtual void onBinAel() {};
+ virtual void onBinSend() {};
+ virtual void onBinCmRecv() {};
+
+ //
+ virtual void onBinSoftAno() {};
+ virtual void onBinHardAno() {};
+ virtual void onBinHistoric() {};
+ virtual void onBinDba() {};
+ virtual void onBinString() {};
+
+ //
+ virtual void onIsbTrace() {};
+ virtual void onIsbDump() {};
+
+ //
+ virtual void onBinPrintf() {};
+ virtual void onCstaCore() {};
+ virtual void onCstaServer() {};
+ virtual void onManagedServices() {};
+
+ protected:
+};
+#endif /*ATRACEDECODER_H*/
--- /dev/null
+#ifndef ATRACELISTENER_H
+#define ATRACELISTENER_H
+
+/**
+ * Interface to be implemented by
+ * classes that intend to process
+ * Atrace Messages Implemented by Binary decoder
+ */
+class AtraceBinListener
+{
+ public:
+ AtraceBinListener() = 0 ;
+ ~AtraceBinListener() {} ;
+ //
+ virtual void onBinState() {};
+ virtual void onBinAel() {};
+ virtual void onBinSend() {};
+ virtual void onBinCmRecv() {};
+
+ //
+ virtual void onBinSoftAno() {};
+ virtual void onBinHardAno() {};
+ virtual void onBinHistoric() {};
+ virtual void onBinDba() {};
+ virtual void onBinString() {};
+
+ //
+ virtual void onIsbTrace() {};
+ virtual void onIsbDump() {};
+
+ //
+ virtual void onBinPrintf() {};
+ virtual void onCstaCore() {};
+ virtual void onCstaServer() {};
+ virtual void onManagedServices() {};
+};
+/**
+ * Interface to be implemented by
+ * classes that intend to process
+ * Atrace Messages
+ */
+class AtraceListener
+{
+ public:
+ AtraceListener() = 0 ;
+ ~AtraceListener() {} ;
+
+ virtual void onIsbMessage() {};
+};
+#endif /*ATRACELISTENER_H*/
--- /dev/null
+#ifndef ATRACEMSGS_H
+#define ATRACEMSGS_H
+
+typedef unsigned char byte;
+typedef byte g_isb_id;
+typedef byte g_isb_class;
+
+#define AT_DBG_BIN_STATE ((byte)0x0x01)
+#define AT_DBG_BIN_AEL ((byte)0x0x02)
+#define AT_DBG_BIN_CMSEND ((byte)0x0x03)
+#define AT_DBG_BIN_CMRECV ((byte)0x0x04)
+
+#define AT_DBG_BIN_SOFTANO ((byte)0x0x07)
+#define AT_DBG_BIN_HARDANO ((byte)0x0x08)
+#define AT_DBG_BIN_HISTORIC ((byte)0x0x09)
+#define AT_DBG_BIN_DBA ((byte)0x0x0A)
+#define AT_DBG_BIN_STRING ((byte)0x0x0B)
+
+#define AT_DBG_BIN_ISB_TRACE ((byte)0x0x0D)
+#define AT_DBG_BIN_ISB_DUMP ((byte)0x0x0E)
+#define AT_DBG_BIN_PRINTF ((byte)0x0x0F)
+
+#define AT_DBG_BIN_CSTA_CORE ((byte)0x0x19)
+#define AT_DBG_BIN_CSTA_SERVER ((byte)0x0x1A)
+#define AT_DBG_BIN_MANAGED_SERVICES ((byte)0x0x1B)
+
+
+/**
+ *
+ */
+typedef struct
+ char spyb_header;
+ byte high_length;
+ byte low_length;
+ g_isb_id transmitter_id;
+ g_isb_class clas;
+ byte msg_family;
+ byte msg_name;
+ byte eqt_id;
+ byte sub_eqt_id;
+ byte param[1];
+} g_header;
+
+/**
+ *
+ */
+typedef struct {
+ byte trace_pattern;
+ byte trace_format;
+ WORD trace_sequence;
+ // This is an endianess problem
+ unsigned trace_length_hi : 1;
+ unsigned trace_sender : 5;
+ unsigned trace_truncated : 1;
+ unsigned /* alignment */ : 1;
+ unsigned trace_length_lo : 8;
+} g_dbg_trace_header;
+
+
+#endif /*ATRACEMSGS_H*/
--- /dev/null
+#ifndef ATRACEREADER_H
+#define ATRACEREADER_H
+
+/**
+ * Generique class to read Debug messages.
+ * Decline this class into two other classes
+ * -> AtraceCURLReader
+ * -> AtraceFileReader
+ */
+class AtraceReader
+{
+ public:
+ typedef std::list<AtraceListener *> ListenerList;
+ typedef ListenerList::iterator iterator;
+
+ AtraceReader();
+ ~AtraceReader();
+
+ void registerListener(AtraceListener *l)
+ { m_Listener.push_back(l); };
+ protected:
+ ListenerList m_Listerners;
+
+};
+
+
+/**
+ * Atrace reader specialisation
+ * I need Host, Password Endianess
+ */
+class AtraceCurlReader : public AtraceReader
+{
+ public:
+ AtraceCurlReader();
+ ~AtraceCurlReader();
+ protected:
+};
+
+#endif /*ATRACEREADER_H*/
--- /dev/null
+#ifndef DSSI_EXPATIMPL_H
+ #define DSSI_EXPATIMPL_H
+#ifdef __GNUC__
+#define __cdecl __attribute__((__cdecl__))
+#endif
+ //-----------------------------------------------------------------------------
+ //
+ // @doc
+ //
+ // @module ExpatImpl.h - Expat class container |
+ //
+ // This module contains the definition of the expat class container.
+ //
+ // Copyright (c) 1994-2002 - Descartes Systems Sciences, Inc.
+ //
+ // @end
+ //
+ // $History: ExpatImpl.h $
+ //
+ // ***************** Version 1 *****************
+ // User: Tim Smith Date: 1/29/02 Time: 1:57p
+ // Created in $/Omni_V2/_ToolLib
+ // 1. String.h now replaced with StringCode.h.
+ // 2. StringRsrc.h modified to use new string class.
+ // 3. Added tons of new classes from the wedge work.
+ //
+ //-----------------------------------------------------------------------------
+
+ //-----------------------------------------------------------------------------
+ //
+ // Required include files
+ //
+ //-----------------------------------------------------------------------------
+
+ #include <assert.h>
+ #include "expat.h"
+
+ //-----------------------------------------------------------------------------
+ //
+ // Forward definitions
+ //
+ //-----------------------------------------------------------------------------
+
+ //-----------------------------------------------------------------------------
+ //
+ // Template class definition
+ //
+ //-----------------------------------------------------------------------------
+
+ template <class _T>
+ class CExpatImpl
+ {
+
+ // @access Constructors and destructors
+ public:
+
+ // @cmember General constructor
+
+ CExpatImpl ()
+ {
+ m_p = NULL;
+ }
+
+ // @cmember Destructor
+
+ ~CExpatImpl ()
+ {
+ Destroy ();
+ }
+
+ // @access Parser creation and deletion methods
+ public:
+
+ // @cmember Create a parser
+
+ bool Create (const XML_Char *pszEncoding = NULL,
+ const XML_Char *pszSep = NULL)
+ {
+
+ //
+ // Destroy the old parser
+ //
+
+ Destroy ();
+
+ //
+ // If the encoding or seperator are empty, then NULL
+ //
+
+ if (pszEncoding != NULL && pszEncoding [0] == 0)
+ pszEncoding = NULL;
+ if (pszSep != NULL && pszSep [0] == 0)
+ pszSep = NULL;
+
+ //
+ // Create the new one
+ //
+
+ m_p = XML_ParserCreate_MM (pszEncoding, NULL, pszSep);
+ if (m_p == NULL)
+ return false;
+
+ //
+ // Invoke the post create routine
+ //
+
+ _T *pThis = static_cast <_T *> (this);
+ pThis ->OnPostCreate ();
+
+ //
+ // Set the user data used in callbacks
+ //
+
+ XML_SetUserData (m_p, (void *) this);
+ return true;
+ }
+
+ // @cmember Destroy the parser
+
+ void Destroy ()
+ {
+ if (m_p != NULL)
+ XML_ParserFree (m_p);
+ m_p = NULL;
+ }
+
+ // @access Parser parse methods
+ public:
+
+ // @cmember Parse a block of data
+
+ bool Parse (const char *pszBuffer, int nLength = -1, bool fIsFinal = true)
+ {
+
+ //
+ // Validate
+ //
+
+ assert (m_p != NULL);
+
+ //
+ // Get the length if not specified
+ //
+
+ if (nLength < 0)
+ nLength = strlen (pszBuffer);
+
+ //
+ // Invoke the parser
+ //
+
+ return XML_Parse (m_p, pszBuffer, nLength, fIsFinal) != 0;
+ }
+
+ // @cmember Parse a block of data
+
+ #ifdef WCHAR
+ bool Parse (const WCHAR *pszBuffer, int nLength = -1, bool fIsFinal = true)
+ {
+
+ //
+ // Validate
+ //
+
+ assert (m_p != NULL);
+
+ //
+ // Get the length if not specified
+ //
+
+ if (nLength < 0)
+ nLength = wcslen (pszBuffer) * 2;
+
+ //
+ // Invoke the parser
+ //
+
+ return XML_Parse (m_p, pszBuffer, nLength, fIsFinal) != 0;
+ }
+ #endif
+
+ // @cmember Parse internal buffer
+
+ bool ParseBuffer (int nLength, bool fIsFinal = true)
+ {
+ assert (m_p != NULL);
+ return XML_ParseBuffer (m_p, nLength, fIsFinal) != 0;
+ }
+
+ // @cmember Get the internal buffer
+
+ void *GetBuffer (int nLength)
+ {
+ assert (m_p != NULL);
+ return XML_GetBuffer (m_p, nLength);
+ }
+
+ // @access Parser callback enable/disable methods
+ public:
+
+ // @cmember Enable/Disable the start element handler
+
+ void EnableStartElementHandler (bool fEnable = true)
+ {
+ assert (m_p != NULL);
+ XML_SetStartElementHandler (m_p, fEnable ? StartElementHandler : NULL);
+ }
+
+ // @cmember Enable/Disable the end element handler
+
+ void EnableEndElementHandler (bool fEnable = true)
+ {
+ assert (m_p != NULL);
+ XML_SetEndElementHandler (m_p, fEnable ? EndElementHandler : NULL);
+ }
+
+ // @cmember Enable/Disable the element handlers
+
+ void EnableElementHandler (bool fEnable = true)
+ {
+ assert (m_p != NULL);
+ EnableStartElementHandler (fEnable);
+ EnableEndElementHandler (fEnable);
+ }
+
+ // @cmember Enable/Disable the character data handler
+
+ void EnableCharacterDataHandler (bool fEnable = true)
+ {
+ assert (m_p != NULL);
+ XML_SetCharacterDataHandler (m_p,
+ fEnable ? CharacterDataHandler : NULL);
+ }
+
+ // @cmember Enable/Disable the processing instruction handler
+
+ void EnableProcessingInstructionHandler (bool fEnable = true)
+ {
+ assert (m_p != NULL);
+ XML_SetProcessingInstructionHandler (m_p,
+ fEnable ? ProcessingInstructionHandler : NULL);
+ }
+
+ // @cmember Enable/Disable the comment handler
+
+ void EnableCommentHandler (bool fEnable = true)
+ {
+ assert (m_p != NULL);
+ XML_SetCommentHandler (m_p, fEnable ? CommentHandler : NULL);
+ }
+
+ // @cmember Enable/Disable the start CDATA section handler
+
+ void EnableStartCdataSectionHandler (bool fEnable = true)
+ {
+ assert (m_p != NULL);
+ XML_SetStartCdataSectionHandler (m_p,
+ fEnable ? StartCdataSectionHandler : NULL);
+ }
+
+ // @cmember Enable/Disable the end CDATA section handler
+
+ void EnableEndCdataSectionHandler (bool fEnable = true)
+ {
+ assert (m_p != NULL);
+ XML_SetEndCdataSectionHandler (m_p,
+ fEnable ? EndCdataSectionHandler : NULL);
+ }
+
+ // @cmember Enable/Disable the CDATA section handlers
+
+ void EnableCdataSectionHandler (bool fEnable = true)
+ {
+ assert (m_p != NULL);
+ EnableStartCdataSectionHandler (fEnable);
+ EnableEndCdataSectionHandler (fEnable);
+ }
+
+ // @cmember Enable/Disable default handler
+
+ void EnableDefaultHandler (bool fEnable = true, bool fExpand = true)
+ {
+ assert (m_p != NULL);
+ if (fExpand)
+ {
+ XML_SetDefaultHandlerExpand (m_p,
+ fEnable ? DefaultHandler : NULL);
+ }
+ else
+ XML_SetDefaultHandler (m_p, fEnable ? DefaultHandler : NULL);
+ }
+
+ // @cmember Enable/Disable external entity ref handler
+
+ void EnableExternalEntityRefHandler (bool fEnable = true)
+ {
+ assert (m_p != NULL);
+ XML_SetExternalEntityRefHandler (m_p,
+ fEnable ? ExternalEntityRefHandler : NULL);
+ }
+
+ // @cmember Enable/Disable unknown encoding handler
+
+ void EnableUnknownEncodingHandler (bool fEnable = true)
+ {
+ assert (m_p != NULL);
+ XML_SetUnknownEncodingHandler (m_p,
+ fEnable ? UnknownEncodingHandler : NULL,NULL);
+ }
+
+ // @cmember Enable/Disable start namespace handler
+
+ void EnableStartNamespaceDeclHandler (bool fEnable = true)
+ {
+ assert (m_p != NULL);
+ XML_SetStartNamespaceDeclHandler (m_p,
+ fEnable ? StartNamespaceDeclHandler : NULL);
+ }
+
+ // @cmember Enable/Disable end namespace handler
+
+ void EnableEndNamespaceDeclHandler (bool fEnable = true)
+ {
+ assert (m_p != NULL);
+ XML_SetEndNamespaceDeclHandler (m_p,
+ fEnable ? EndNamespaceDeclHandler : NULL);
+ }
+
+ // @cmember Enable/Disable namespace handlers
+
+ void EnableNamespaceDeclHandler (bool fEnable = true)
+ {
+ EnableStartNamespaceDeclHandler (fEnable);
+ EnableEndNamespaceDeclHandler (fEnable);
+ }
+
+ // @cmember Enable/Disable the XML declaration handler
+
+ void EnableXmlDeclHandler (bool fEnable = true)
+ {
+ assert (m_p != NULL);
+ XML_SetXmlDeclHandler (m_p, fEnable ? XmlDeclHandler : NULL);
+ }
+
+ // @cmember Enable/Disable the start DOCTYPE declaration handler
+
+ void EnableStartDoctypeDeclHandler (bool fEnable = true)
+ {
+ assert (m_p != NULL);
+ XML_SetStartDoctypeDeclHandler (m_p,
+ fEnable ? StartDoctypeDeclHandler : NULL);
+ }
+
+ // @cmember Enable/Disable the end DOCTYPE declaration handler
+
+ void EnableEndDoctypeDeclHandler (bool fEnable = true)
+ {
+ assert (m_p != NULL);
+ XML_SetEndDoctypeDeclHandler (m_p,
+ fEnable ? EndDoctypeDeclHandler : NULL);
+ }
+
+ // @cmember Enable/Disable the DOCTYPE declaration handler
+
+ void EnableDoctypeDeclHandler (bool fEnable = true)
+ {
+ assert (m_p != NULL);
+ EnableStartDoctypeDeclHandler (fEnable);
+ EnableEndDoctypeDeclHandler (fEnable);
+ }
+
+ // @access Parser error reporting methods
+ public:
+
+ // @cmember Get last error
+
+ enum XML_Error GetErrorCode ()
+ {
+ assert (m_p != NULL);
+ return XML_GetErrorCode (m_p);
+ }
+
+ // @cmember Get the current byte index
+
+ long GetCurrentByteIndex ()
+ {
+ assert (m_p != NULL);
+ return XML_GetCurrentByteIndex (m_p);
+ }
+
+ // @cmember Get the current line number
+
+ int GetCurrentLineNumber ()
+ {
+ assert (m_p != NULL);
+ return XML_GetCurrentLineNumber (m_p);
+ }
+
+ // @cmember Get the current column number
+
+ int GetCurrentColumnNumber ()
+ {
+ assert (m_p != NULL);
+ return XML_GetCurrentColumnNumber (m_p);
+ }
+
+ // @cmember Get the current byte count
+
+ int GetCurrentByteCount ()
+ {
+ assert (m_p != NULL);
+ return XML_GetCurrentByteCount (m_p);
+ }
+
+ // @cmember Get the input context
+
+ const char *GetInputContext (int *pnOffset, int *pnSize)
+ {
+ assert (m_p != NULL);
+ return XML_GetInputContext (m_p, pnOffset, pnSize);
+ }
+
+ // @cmember Get last error string
+
+ const XML_LChar *GetErrorString ()
+ {
+ return XML_ErrorString (GetErrorCode ());
+ }
+
+ // @access Parser other methods
+ public:
+
+ // @cmember Return the version string
+
+ static const XML_LChar *GetExpatVersion ()
+ {
+ return XML_ExpatVersion ();
+ }
+
+ // @cmember Get the version information
+
+ static void GetExpatVersion (int *pnMajor, int *pnMinor, int *pnMicro)
+ {
+ XML_Expat_Version v = XML_ExpatVersionInfo ();
+ if (pnMajor)
+ *pnMajor = v .major;
+ if (pnMinor)
+ *pnMinor = v .minor;
+ if (pnMicro)
+ *pnMicro = v .micro;
+ }
+
+ // @cmember Get last error string
+
+ static const XML_LChar *GetErrorString (enum XML_Error nError)
+ {
+ return XML_ErrorString (nError);
+ }
+
+ // @access Public handler methods
+ public:
+
+ // @cmember Start element handler
+
+ void OnStartElement (const XML_Char *pszName, const XML_Char **papszAttrs)
+ {
+ return;
+ }
+
+ // @cmember End element handler
+
+ void OnEndElement (const XML_Char *pszName)
+ {
+ return;
+ }
+
+ // @cmember Character data handler
+
+ void OnCharacterData (const XML_Char *pszData, int nLength)
+ {
+ return;
+ }
+
+ // @cmember Processing instruction handler
+
+ void OnProcessingInstruction (const XML_Char *pszTarget,
+ const XML_Char *pszData)
+ {
+ return;
+ }
+
+ // @cmember Comment handler
+
+ void OnComment (const XML_Char *pszData)
+ {
+ return;
+ }
+
+ // @cmember Start CDATA section handler
+
+ void OnStartCdataSection ()
+ {
+ return;
+ }
+
+ // @cmember End CDATA section handler
+
+ void OnEndCdataSection ()
+ {
+ return;
+ }
+
+ // @cmember Default handler
+
+ void OnDefault (const XML_Char *pszData, int nLength)
+ {
+ return;
+ }
+
+ // @cmember External entity ref handler
+
+ bool OnExternalEntityRef (const XML_Char *pszContext,
+ const XML_Char *pszBase, const XML_Char *pszSystemID,
+ const XML_Char *pszPublicID)
+ {
+ return false;
+ }
+
+ // @cmember Unknown encoding handler
+
+ bool OnUnknownEncoding (const XML_Char *pszName, XML_Encoding *pInfo)
+ {
+ return false;
+ }
+
+ // @cmember Start namespace declaration handler
+
+ void OnStartNamespaceDecl (const XML_Char *pszPrefix,
+ const XML_Char *pszURI)
+ {
+ return;
+ }
+
+ // @cmember End namespace declaration handler
+
+ void OnEndNamespaceDecl (const XML_Char *pszPrefix)
+ {
+ return;
+ }
+
+ // @cmember XML declaration handler
+
+ void OnXmlDecl (const XML_Char *pszVersion, const XML_Char *pszEncoding,
+ bool fStandalone)
+ {
+ return;
+ }
+
+ // @cmember Start DOCTYPE declaration handler
+
+ void OnStartDoctypeDecl (const XML_Char *pszDoctypeName,
+ const XML_Char *pszSysID, const XML_Char *pszPubID,
+ bool fHasInternalSubset)
+ {
+ return;
+ }
+
+ // @cmember End DOCTYPE declaration handler
+
+ void OnEndDoctypeDecl ()
+ {
+ return;
+ }
+
+ // @access Protected methods
+ protected:
+
+ // @cmember Handle any post creation
+
+ void OnPostCreate ()
+ {
+ }
+
+ // @access Protected static methods
+ protected:
+
+ // @cmember Start element handler wrapper
+
+ static void __cdecl StartElementHandler (void *pUserData,
+ const XML_Char *pszName, const XML_Char **papszAttrs)
+ {
+ _T *pThis = static_cast <_T *> ((CExpatImpl <_T> *) pUserData);
+ pThis ->OnStartElement (pszName, papszAttrs);
+ }
+
+ // @cmember End element handler wrapper
+
+ static void __cdecl EndElementHandler (void *pUserData,
+ const XML_Char *pszName)
+ {
+ _T *pThis = static_cast <_T *> ((CExpatImpl <_T> *) pUserData);
+ pThis ->OnEndElement (pszName);
+ }
+
+ // @cmember Character data handler wrapper
+
+ static void __cdecl CharacterDataHandler (void *pUserData,
+ const XML_Char *pszData, int nLength)
+ {
+ _T *pThis = static_cast <_T *> ((CExpatImpl <_T> *) pUserData);
+ pThis ->OnCharacterData (pszData, nLength);
+ }
+
+ // @cmember Processing instruction handler wrapper
+
+ static void __cdecl ProcessingInstructionHandler (void *pUserData,
+ const XML_Char *pszTarget, const XML_Char *pszData)
+ {
+ _T *pThis = static_cast <_T *> ((CExpatImpl <_T> *) pUserData);
+ pThis ->OnProcessingInstruction (pszTarget, pszData);
+ }
+
+ // @cmember Comment handler wrapper
+
+ static void __cdecl CommentHandler (void *pUserData,
+ const XML_Char *pszData)
+ {
+ _T *pThis = static_cast <_T *> ((CExpatImpl <_T> *) pUserData);
+ pThis ->OnComment (pszData);
+ }
+
+ // @cmember Start CDATA section wrapper
+
+ static void __cdecl StartCdataSectionHandler (void *pUserData)
+ {
+ _T *pThis = static_cast <_T *> ((CExpatImpl <_T> *) pUserData);
+ pThis ->OnStartCdataSection ();
+ }
+
+ // @cmember End CDATA section wrapper
+
+ static void __cdecl EndCdataSectionHandler (void *pUserData)
+ {
+ _T *pThis = static_cast <_T *> ((CExpatImpl <_T> *) pUserData);
+ pThis ->OnEndCdataSection ();
+ }
+
+ // @cmember Default wrapper
+
+ static void __cdecl DefaultHandler (void *pUserData,
+ const XML_Char *pszData, int nLength)
+ {
+ _T *pThis = static_cast <_T *> ((CExpatImpl <_T> *) pUserData);
+ pThis ->OnDefault (pszData, nLength);
+ }
+
+ // @cmember External entity ref wrapper
+
+ static int __cdecl ExternalEntityRefHandler (void *pUserData,
+ const XML_Char *pszContext, const XML_Char *pszBase,
+ const XML_Char *pszSystemID, const XML_Char *pszPublicID)
+ {
+ _T *pThis = static_cast <_T *> ((CExpatImpl <_T> *) pUserData);
+ return pThis ->OnExternalEntityRef (pszContext,
+ pszBase, pszSystemID, pszPublicID) ? 1 : 0;
+ }
+
+ // @cmember Unknown encoding wrapper
+
+ static int __cdecl UnknownEncodingHandler (void *pUserData,
+ const XML_Char *pszName, XML_Encoding *pInfo)
+ {
+ _T *pThis = static_cast <_T *> ((CExpatImpl <_T> *) pUserData);
+ return pThis ->OnUnknownEncoding (pszName, pInfo) ? 1 : 0;
+ }
+
+ // @cmember Start namespace decl wrapper
+
+ static void __cdecl StartNamespaceDeclHandler (void *pUserData,
+ const XML_Char *pszPrefix, const XML_Char *pszURI)
+ {
+ _T *pThis = static_cast <_T *> ((CExpatImpl <_T> *) pUserData);
+ pThis ->OnStartNamespaceDecl (pszPrefix, pszURI);
+ }
+
+ // @cmember End namespace decl wrapper
+
+ static void __cdecl EndNamespaceDeclHandler (void *pUserData,
+ const XML_Char *pszPrefix)
+ {
+ _T *pThis = static_cast <_T *> ((CExpatImpl <_T> *) pUserData);
+ pThis ->OnEndNamespaceDecl (pszPrefix);
+ }
+
+ // @cmember XML declaration wrapper
+
+ static void __cdecl XmlDeclHandler (void *pUserData,
+ const XML_Char *pszVersion, const XML_Char *pszEncoding,
+ int nStandalone)
+ {
+ _T *pThis = static_cast <_T *> ((CExpatImpl <_T> *) pUserData);
+ pThis ->OnXmlDecl (pszVersion, pszEncoding, nStandalone != 0);
+ }
+
+ // @cmember Start Doctype declaration wrapper
+
+ static void __cdecl StartDoctypeDeclHandler (void *pUserData,
+ const XML_Char *pszDoctypeName, const XML_Char *pszSysID,
+ const XML_Char *pszPubID, int nHasInternalSubset)
+ {
+ _T *pThis = static_cast <_T *> ((CExpatImpl <_T> *) pUserData);
+ pThis ->OnStartDoctypeDecl (pszDoctypeName, pszSysID,
+ pszPubID, nHasInternalSubset != 0);
+ }
+
+ // @cmember End Doctype declaration wrapper
+
+ static void __cdecl EndDoctypeDeclHandler (void *pUserData)
+ {
+ _T *pThis = static_cast <_T *> ((CExpatImpl <_T> *) pUserData);
+ pThis ->OnEndDoctypeDecl ();
+ }
+
+ // @access Protected members
+ protected:
+
+ XML_Parser m_p;
+ };
+
+ //-----------------------------------------------------------------------------
+ //
+ // Virtual method class definition
+ //
+ //-----------------------------------------------------------------------------
+
+ class CExpat : public CExpatImpl <CExpat>
+ {
+ // @access Constructors and destructors
+ public:
+
+ CExpat ()
+ {
+ }
+
+ // @access Public handler methods
+ public:
+
+ // @cmember Start element handler
+
+ virtual void OnStartElement (const XML_Char *pszName,
+ const XML_Char **papszAttrs)
+ {
+ return;
+ }
+
+ // @cmember End element handler
+
+ virtual void OnEndElement (const XML_Char *pszName)
+ {
+ return;
+ }
+
+ // @cmember Character data handler
+
+ virtual void OnCharacterData (const XML_Char *pszData, int nLength)
+ {
+ return;
+ }
+
+ // @cmember Processing instruction handler
+
+ virtual void OnProcessingInstruction (const XML_Char *pszTarget,
+ const XML_Char *pszData)
+ {
+ return;
+ }
+
+ // @cmember Comment handler
+
+ virtual void OnComment (const XML_Char *pszData)
+ {
+ return;
+ }
+
+ // @cmember Start CDATA section handler
+
+ virtual void OnStartCdataSection ()
+ {
+ return;
+ }
+
+ // @cmember End CDATA section handler
+
+ virtual void OnEndCdataSection ()
+ {
+ return;
+ }
+
+ // @cmember Default handler
+
+ virtual void OnDefault (const XML_Char *pszData, int nLength)
+ {
+ return;
+ }
+
+ // @cmember External entity ref handler
+
+ virtual bool OnExternalEntityRef (const XML_Char *pszContext,
+ const XML_Char *pszBase, const XML_Char *pszSystemID,
+ const XML_Char *pszPublicID)
+ {
+ return false;
+ }
+
+ // @cmember Unknown encoding handler
+
+ virtual bool OnUnknownEncoding (const XML_Char *pszName, XML_Encoding *pInfo)
+ {
+ return false;
+ }
+
+ // @cmember Start namespace declaration handler
+
+ virtual void OnStartNamespaceDecl (const XML_Char *pszPrefix,
+ const XML_Char *pszURI)
+ {
+ return;
+ }
+
+ // @cmember End namespace declaration handler
+
+ virtual void OnEndNamespaceDecl (const XML_Char *pszPrefix)
+ {
+ return;
+ }
+
+ // @cmember XML declaration handler
+
+ virtual void OnXmlDecl (const XML_Char *pszVersion,
+ const XML_Char *pszEncoding, bool fStandalone)
+ {
+ return;
+ }
+
+ // @cmember Start DOCTYPE declaration handler
+
+ virtual void OnStartDoctypeDecl (const XML_Char *pszDoctypeName,
+ const XML_Char *pszSysID, const XML_Char *pszPubID,
+ bool fHasInternalSubset)
+ {
+ return;
+ }
+
+ // @cmember End DOCTYPE declaration handler
+
+ virtual void OnEndDoctypeDecl ()
+ {
+ return;
+ }
+ };
+
+#endif // DSSI_EXPATIMPL_H
--- /dev/null
+PROJECT(cstav1-lib)
+
+SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
+ "${rules_SOURCE_DIR}/")
+
+FIND_PACKAGE(PCAP REQUIRED)
+INCLUDE_DIRECTORIES(${PCAP_INCLUDE_DIRS})
+
+IF (WITH_CSTAV1)
+#for mingw32
+INCLUDE_DIRECTORIES(/include)
+INCLUDE_DIRECTORIES(${MAKE_CURRENT_BINARY_DIR})
+IF(NOT WIN32)
+FIND_PACKAGE(EXPAT REQUIRED )
+ENDIF(NOT WIN32)
+
+ADD_DEFINITIONS(-DASN1_ATTRIBUTE_OPTIONAL_AS_SHARED_POINTER)
+SET(CSTAV1_ERULE "-e ber")
+SET(CSTAV1_MODEL ${asn1-data-models_SOURCE_DIR}/cstav1/ CACHE STRING "CSTA V1 datamodel source directory")
+FILE(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/modules.txt CSTAV1MODULES)
+
+FOREACH(ITEM ${CSTAV1MODULES})
+ STRING(REGEX REPLACE "-" "_" HITEM ${ITEM})
+ SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/${HITEM}.h GENERATED)
+ SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/${ITEM}.cpp GENERATED)
+ SET(CSTAV1SRC ${CSTAV1SRC} ${CMAKE_CURRENT_BINARY_DIR}/${ITEM}.cpp)
+ SET(CSTAV1HDR ${CSTAV1HDR} ${CMAKE_CURRENT_BINARY_DIR}/${HITEM}.h)
+SET_DIRECTORY_PROPERTIES(PROPERTIES
+ ADDITIONAL_MAKE_CLEAN_FILES "${CMAKE_CURRENT_BINARY_DIR}/${ITEM}.cpp"
+ )
+
+SET_DIRECTORY_PROPERTIES(PROPERTIES
+ ADDITIONAL_MAKE_CLEAN_FILES "${CMAKE_CURRENT_BINARY_DIR}/${HITEM}.h"
+ )
+
+ENDFOREACH(ITEM)
+
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote_Operations_Generic_ROS_PDUs.h
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Generic-ROS-PDUs.cpp
+ COMMAND ${asn1p_EXE}
+ ARGS -I ${CSTAV1_MODEL} ${CSTAV1_ERULE}
+ -f Remote-Operations-Information-Objects.asn1
+ -f Remote-Operations-Generic-ROS-PDUs.asn1
+ -oRemote-Operations-Generic-ROS-PDUs
+ DEPENDS ${asn1p_EXE}
+ COMMENT "Build ROGR .h and .cpp"
+ )
+
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/Remote_Operations_Generic_ROS_PDUs.h
+ GENERATED)
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Generic-ROS-PDUs.cpp
+ GENERATED)
+#
+#
+#
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote_Operations_Information_Objects.h
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Information-Objects.cpp
+ COMMAND ${asn1p_EXE}
+ ARGS -I ${CSTAV1_MODEL} ${CSTAV1_ERULE}
+ -f Remote-Operations-Information-Objects.asn1
+ -oRemote-Operations-Information-Objects
+ DEPENDS ${asn1p_EXE}
+ COMMENT "Build ROIO .h and .cpp"
+ )
+
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/Remote_Operations_Information_Objects.h
+ GENERATED)
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Information-Objects.cpp
+ GENERATED)
+
+SET_DIRECTORY_PROPERTIES(PROPERTIES
+ ADDITIONAL_MAKE_CLEAN_FILES
+ "${CMAKE_CURRENT_BINARY_DIR}/Remote_Operations_Information_Objects.h ${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Information-Objects.cpp"
+ )
+
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA-event.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA_event.h
+ COMMAND ${asn1p_EXE}
+ ARGS -I ${CSTAV1_MODEL} ${CSTAV1_ERULE}
+ -f Remote-Operations-Information-Objects.asn1
+ -f apdu_rose_94.asn1
+ -f evt_definition_94.asn1
+ -f err_error.asn1
+ -f obj_extension_94.asn1
+ -f obj_private_94.asn1
+ -f obj_feature.asn1 -f obj_status.asn1
+ -f obj_device.asn1 -f obj_call.asn1
+ -f obj_connection.asn1 -f obj_switch.asn1 -oCSTA-event
+ DEPENDS ${asn1p_EXE}
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote_Operations_Information_Objects.h
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA_extend.h
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA_status.h
+ COMMENT "Build CSTA-event .h and .cpp"
+ )
+
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/Model.uml
+ COMMAND cat
+ ${asn1-data-models_SOURCE_DIR}/cstav1/apdu_rose_94.asn1
+ ${asn1-data-models_SOURCE_DIR}/cstav1/evt_definition_94.asn1
+ ${asn1-data-models_SOURCE_DIR}/cstav1/obj_connection.asn1
+ ${asn1-data-models_SOURCE_DIR}/cstav1/obj_call.asn1
+ ${asn1-data-models_SOURCE_DIR}/cstav1/obj_feature.asn1
+ ${asn1-data-models_SOURCE_DIR}/cstav1/obj_status.asn1
+ ${asn1-data-models_SOURCE_DIR}/cstav1/err_error.asn1
+ ARGS | ${asn1p_EXE} -u CstaV1Events.uml
+ COMMAND ${CMAKE_COMMAND} -E rename _model.uml Model.uml
+ DEPENDS ${asn1p_EXE}
+ COMMENT "Build UML cstav1 Events for UML"
+ )
+
+#ADD_CUSTOM_TARGET(Model.uml ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/_model.uml)
+#SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_CLEAN Model.uml)
+#SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_CLEAN _model.uml)
+
+
+
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA-connect.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA_connect.h
+ COMMAND ${asn1p_EXE}
+ ARGS -I ${CSTAV1_MODEL} ${CSTAV1_ERULE}
+ -f obj_device.asn1
+ -f obj_call.asn1
+ -f obj_connection.asn1
+ -f obj_switch.asn1
+ -oCSTA-connect
+ DEPENDS ${asn1p_EXE}
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote_Operations_Information_Objects.h
+ COMMENT "Build CSTA-connect.h and .cpp"
+ )
+
+
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA-status.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA_status.h
+ COMMAND ${asn1p_EXE}
+ ARGS -I ${CSTAV1_MODEL} ${CSTAV1_ERULE} -f obj_status.asn1 -f obj_device.asn1
+ -f obj_call.asn1 -f obj_connection.asn1 -f obj_switch.asn1
+ -oCSTA-status
+ DEPENDS ${asn1p_EXE}
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote_Operations_Information_Objects.h
+ COMMENT "Build CSTA-status.h and .cpp"
+ )
+
+
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA-feature.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA_feature.h
+ COMMAND ${asn1p_EXE}
+ ARGS -I ${CSTAV1_MODEL} ${CSTAV1_ERULE} -f obj_device.asn1 -f obj_feature.asn1
+ -f obj_call.asn1 -oCSTA-feature
+ DEPENDS ${asn1p_EXE}
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote_Operations_Information_Objects.h
+ COMMENT "Build CSTA-feature.h and .cpp"
+ )
+
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA-private.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA_private.h
+ COMMAND ${asn1p_EXE}
+ ARGS -I ${CSTAV1_MODEL} ${CSTAV1_ERULE} -f obj_device.asn1
+ -f obj_feature.asn1
+ -f obj_switch.asn1
+ -f obj_call.asn1
+ -f obj_extension_94.asn1
+ -f err_error.asn1
+ -f Remote-Operations-Information-Objects.asn1
+ -f obj_private_94.asn1 -oCSTA-private
+ DEPENDS ${asn1p_EXE}
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote_Operations_Information_Objects.h
+ COMMENT "Build CSTA-private.h and .cpp"
+ )
+
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA-call.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA_call.h
+ COMMAND ${asn1p_EXE}
+ ARGS -I ${CSTAV1_MODEL} ${CSTAV1_ERULE} -f obj_device.asn1 -f obj_status.asn1 -f obj_call.asn1 -oCSTA-call
+ DEPENDS ${asn1p_EXE}
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote_Operations_Information_Objects.h
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA-event.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA_status.h
+ COMMENT "Build CSTA-call .h and .cpp"
+ )
+
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA-device.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA_device.h
+ COMMAND ${asn1p_EXE}
+ ARGS -I ${CSTAV1_MODEL} -f obj_device.asn1 -f obj_status.asn1 -f obj_extension_94.asn1 -oCSTA-device
+ DEPENDS ${asn1p_EXE}
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote_Operations_Information_Objects.h
+ COMMENT "Build CSTA-device .h and .cpp"
+ )
+
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA-extend.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA_extend.h
+ COMMAND ${asn1p_EXE}
+ ARGS -I ${CSTAV1_MODEL}
+ -f obj_extension_94.asn1
+ -f obj_security.asn1 -f Remote-Operations-Information-Objects.asn1
+ -oCSTA-extend
+ DEPENDS ${asn1p_EXE}
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote_Operations_Information_Objects.h
+ ${CMAKE_CURRENT_BINARY_DIR}/ACSE_1.h
+ COMMENT "Build CSTA-extend .h and .cpp ${asn1-data-models_SOURCE_DIR}/cstav1"
+ )
+
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/Rose-Apdu.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/Rose_Apdu.h
+ COMMAND ${asn1p_EXE}
+ ARGS -I ${CSTAV1_MODEL} -fapdu_rose_94.asn1
+ -fobj_call.asn1
+ -fobj_status.asn1
+ -fobj_switch.asn1
+ -fobj_connection.asn1 -fobj_device.asn1 -fobj_feature.asn1
+ -ferr_error.asn1 -fevt_definition_94.asn1
+ -f obj_extension_94.asn1 -f obj_security.asn1
+ -f Remote-Operations-Information-Objects.asn1
+ -oRose-Apdu
+ DEPENDS ${asn1p_EXE}
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote_Operations_Information_Objects.h
+ ${CMAKE_CURRENT_BINARY_DIR}/ACSE_1.h
+ COMMENT "Build Rose-Apdu .h and .cpp"
+ )
+
+
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA-switch.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA_switch.h
+ COMMAND ${asn1p_EXE}
+ ARGS -I ${CSTAV1_MODEL}
+ -fobj_call.asn1
+ -fobj_device.asn1
+ -ferr_error.asn1
+ -f obj_switch.asn1
+ -f Remote-Operations-Information-Objects.asn1
+ -oCSTA-switch
+ DEPENDS ${asn1p_EXE}
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote_Operations_Information_Objects.h
+ COMMENT "Build cstav1 CSTA-switch.h and CSTA-switch.cpp"
+ )
+
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA-secure.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA_secure.h
+ COMMAND ${asn1p_EXE}
+ ARGS -I ${CSTAV1_MODEL}
+ -fobj_security.asn1
+ -oCSTA-secure
+ DEPENDS ${asn1p_EXE}
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote_Operations_Information_Objects.h
+ COMMENT "Build CSTA-secure .h and .cpp"
+ )
+
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA-error.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA_error.h
+ COMMAND ${asn1p_EXE}
+ ARGS -I ${CSTAV1_MODEL}
+ -f Remote-Operations-Information-Objects.asn1
+ -ferr_error.asn1
+ -oCSTA-error
+ DEPENDS ${asn1p_EXE}
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote_Operations_Information_Objects.h
+ COMMENT "Build CSTA-error .h and .cpp"
+ )
+
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/ACSE-1.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/ACSE_1.h
+ COMMAND ${asn1p_EXE}
+ ARGS -I ${CSTAV1_MODEL}
+ -fapdu_acse.asn1
+ -f Remote-Operations-Information-Objects.asn1
+ -oACSE-1
+ DEPENDS ${asn1p_EXE}
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote_Operations_Information_Objects.h
+ COMMENT "Build ACSE-1 .h and .cpp"
+ )
+
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA-MSG.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA_MSG.h
+
+ COMMAND ${asn1p_EXE}
+ ARGS -I ${CSTAV1_MODEL} -f apdu_csta.asn1 -f apdu_acse.asn1 -f
+ apdu_rose_94.asn1 -oCSTA-MSG
+ DEPENDS ${asn1p_EXE}
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote_Operations_Information_Objects.h
+ ${CMAKE_CURRENT_BINARY_DIR}/ACSE_1.h
+ COMMENT "Build CSTA-MSG .h and .cpp"
+ )
+
+
+ADD_LIBRARY(cstav1
+ ${CSTAV1SRC}
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Information-Objects.cpp
+ )
+
+ADD_EXECUTABLE(test_cstav1
+ main.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Information-Objects.cpp
+ )
+TARGET_LINK_LIBRARIES(test_cstav1 cstav1 asn1)
+
+IF (NOT CMAKE_CROSSCOMPILING)
+ IF(NOT WIN32)
+ FIND_PACKAGE(FLTK REQUIRED
+ NAME FLTK)
+ IF(FLTK_BUILT_WITH_CMAKE)
+ INCLUDE_DIRECTORIES(${FLTK_INCLUDE_DIR}/../include)
+ ELSE(FLTK_BUILT_WITH_CMAKE)
+ INCLUDE_DIRECTORIES(${FLTK_INCLUDE_DIR})
+ ENDIF(FLTK_BUILT_WITH_CMAKE)
+
+ FIND_PACKAGE(OpenGL REQUIRED)
+ ELSE(NOT WIN32)
+ INCLUDE_DIRECTORIES(${FLTK_INCLUDE_DIR})
+ ENDIF(NOT WIN32)
+FLTK_WRAP_UI(Ui cstaspyui.fl)
+
+ADD_LIBRARY(Ui
+ SequenceView.cpp
+ HeaderView.cpp
+ Model.cpp
+ Controler.cpp
+ ${Ui_FLTK_UI_SRCS}
+ Pcap.cpp
+ Packet.cpp
+ Timeline.cpp
+ TLMsg.cpp
+ IconFactory.cpp
+ CstaInsightLog.cpp
+ )
+ADD_DEPENDENCIES(Ui cstav1)
+
+ADD_EXECUTABLE(csta_insight
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Information-Objects.cpp
+ )
+
+ADD_DEPENDENCIES(csta_insight Ui)
+ADD_DEPENDENCIES(csta_insight cstav1)
+IF(APPLE)
+TARGET_LINK_LIBRARIES(csta_insight Ui)
+TARGET_LINK_LIBRARIES(csta_insight ${EXPAT_LIB})
+SET_TARGET_PROPERTIES(csta_insight PROPERTIES LINKER_FLAGS "-framework Cocoa")
+#Missing and don't know why
+MESSAGE(" FLTK_INCLUDE_DIR = ${FLTK_INCLUDE_DIR}")
+SET(FLTK_PNG_LIB /Users/aeb/Externals/MacOSX.10.11/fltk-1.3/lib/libfltk_png.a)
+#TARGET_LINK_LIBRARIES(csta_insight /usr/local/lib/libfltk_png.a)
+TARGET_LINK_LIBRARIES(csta_insight ${FLTK_PNG_LIB})
+ENDIF(APPLE)
+
+IF(UNIX AND NOT APPLE)
+# Find libdl for fltk on Ubuntu dlsym
+FIND_LIBRARY(DL_LIBRARY NAMES dl libdl)
+MESSAGE("Looking for DL library")
+TARGET_LINK_LIBRARIES(csta_insight ${DL_LIBRARY})
+MESSAGE("Have for DL library ${DL_LIBRARY}")
+TARGET_LINK_LIBRARIES(csta_insight Ui X11 Xft Xinerama fltk_images ${EXPAT_LIB})
+ENDIF()
+
+IF(WIN32)
+MESSAGE("WIN32 SETTINGS ")
+ TARGET_LINK_LIBRARIES(csta_insight Ui ws2_32)
+ TARGET_LINK_LIBRARIES(csta_insight ${EXPAT_LIBRARY})
+ TARGET_LINK_LIBRARIES(csta_insight ${FLTK_LIBRARIES})
+ELSEIF(MINGW)
+ MESSAGE("MINGW SETTINGS ")
+TARGET_LINK_LIBRARIES(Ui C:/MinGW/msys/1.0/opt/lib/libfltk_png.a)
+TARGET_LINK_LIBRARIES(Ui C:/MinGW/msys/1.0/opt/lib/libfltk_z.a)
+TARGET_LINK_LIBRARIES(csta_insight C:/MinGW/msys/1.0/opt/lib/libfltk_png.a)
+TARGET_LINK_LIBRARIES(csta_insight Ui ws2_32)
+TARGET_LINK_LIBRARIES(csta_insight ${EXPAT_LIBRARY})
+#Missing and don't know why
+ENDIF(WIN32)
+
+TARGET_LINK_LIBRARIES(csta_insight ${FLTK_LIBRARIES})
+TARGET_LINK_LIBRARIES(csta_insight cstav1)
+TARGET_LINK_LIBRARIES(csta_insight asn1)
+TARGET_LINK_LIBRARIES(csta_insight ${PCAP_LIBRARIES})
+
+ENDIF(NOT CMAKE_CROSSCOMPILING)
+
+#
+# Install stuff
+#
+
+IF (NOT CMAKE_CROSSCOMPILING)
+INSTALL(TARGETS csta_insight DESTINATION bin
+ COMPONENT Csta
+ )
+
+FILE(GLOB CSTA_IMAGES ${CMAKE_CURRENT_SOURCE_DIR}/images/*.png)
+INSTALL(FILES ${CSTA_IMAGES} DESTINATION share/csta_insight/images
+ COMPONENT Csta)
+ENDIF(NOT CMAKE_CROSSCOMPILING)
+
+INSTALL(FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA_feature.h
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA_private.h
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA_secure.h
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA_status.h
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA_switch.h
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA_device.h
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA_error.h
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA_event.h
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA_extend.h
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA_private.h
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA_connect.h
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA_call.h
+ ${CMAKE_CURRENT_BINARY_DIR}/CSTA_MSG.h
+ ${CMAKE_CURRENT_BINARY_DIR}/ACSE_1.h
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote_Operations_Information_Objects.h
+ ${CMAKE_CURRENT_BINARY_DIR}/Rose_Apdu.h
+ DESTINATION include/CSTA/
+ COMPONENT Csta-Header)
+
+FILE(GLOB CSTA_ACSE ${CMAKE_CURRENT_BINARY_DIR}/include/ACSE_1/*.h)
+INSTALL(FILES ${CSTA_ACSE} DESTINATION include/CSTA/ACSE_1
+ COMPONENT Csta-Headers)
+
+FILE(GLOB CSTA_MSG ${CMAKE_CURRENT_BINARY_DIR}/include/CSTA_MSG/*.h)
+INSTALL(FILES ${CSTA_MSG} DESTINATION include/CSTA/CSTA_MSG
+ COMPONENT Csta-Headers)
+
+FILE(GLOB CSTA_CONNECT ${CMAKE_CURRENT_BINARY_DIR}/include/CSTA_connect/*.h)
+INSTALL(FILES ${CSTA_CONNECT} DESTINATION include/CSTA/CSTA_connect
+ COMPONENT Csta-Headers)
+
+FILE(GLOB CSTA_EVENT ${CMAKE_CURRENT_BINARY_DIR}/include/CSTA_event/*.h)
+INSTALL(FILES ${CSTA_EVENT} DESTINATION include/CSTA/CSTA_event
+ COMPONENT Csta-Headers)
+
+FILE(GLOB CSTA_ERROR ${CMAKE_CURRENT_BINARY_DIR}/include/CSTA_error/*.h)
+INSTALL(FILES ${CSTA_ERROR} DESTINATION include/CSTA/CSTA_error
+ COMPONENT Csta-Headers)
+
+FILE(GLOB CSTA_EXTEND ${CMAKE_CURRENT_BINARY_DIR}/include/CSTA_extend/*.h)
+INSTALL(FILES ${CSTA_EXTEND} DESTINATION include/CSTA/CSTA_extend
+ COMPONENT Csta-Headers)
+
+FILE(GLOB CSTA_FEATURE ${CMAKE_CURRENT_BINARY_DIR}/include/CSTA_feature/*.h)
+INSTALL(FILES ${CSTA_FEATURE} DESTINATION include/CSTA/CSTA_feature
+ COMPONENT Csta-Headers)
+
+FILE(GLOB CSTA_PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/include/CSTA_private/*.h)
+INSTALL(FILES ${CSTA_PRIVATE} DESTINATION include/CSTA/CSTA_private
+ COMPONENT Csta-Headers)
+
+FILE(GLOB CSTA_SECURE ${CMAKE_CURRENT_BINARY_DIR}/include/CSTA_secure/*.h)
+INSTALL(FILES ${CSTA_SECURE} DESTINATION include/CSTA/CSTA_secure
+ COMPONENT Csta-Headers)
+
+FILE(GLOB CSTA_STATUS ${CMAKE_CURRENT_BINARY_DIR}/include/CSTA_status/*.h)
+INSTALL(FILES ${CSTA_STATUS} DESTINATION include/CSTA/CSTA_status
+ COMPONENT Csta-Headers)
+
+FILE(GLOB CSTA_SWITCH ${CMAKE_CURRENT_BINARY_DIR}/include/CSTA_switch/*.h)
+INSTALL(FILES ${CSTA_SWITCH} DESTINATION include/CSTA/CSTA_switch
+ COMPONENT Csta-Headers)
+
+FILE(GLOB CSTA_CALL ${CMAKE_CURRENT_BINARY_DIR}/include/CSTA_call/*.h)
+INSTALL(FILES ${CSTA_CALL} DESTINATION include/CSTA/CSTA_call
+ COMPONENT Csta-Headers)
+
+FILE(GLOB CSTA_DEVICE ${CMAKE_CURRENT_BINARY_DIR}/include/CSTA_device/*.h)
+INSTALL(FILES ${CSTA_DEVICE} DESTINATION include/CSTA/CSTA_device
+ COMPONENT Csta-Headers)
+
+INSTALL(TARGETS cstav1
+ DESTINATION lib
+ COMPONENT Csta-Lib
+ )
+
+#
+# Ok start working with Packaging stuff
+#
+INCLUDE(InstallRequiredSystemLibraries)
+#SET(CPACK_OUTPUT_CONFIG_FILE "${PROJECT_BINARY_DIR}/CPackConfig.cmake" )
+#SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Graphical user interface to visualize csta messages from pcap files")
+#SET(CPACK_PACKAGE_VENDOR "Aeb")
+#SET(CPACK_PACKAGE_DESCRIPTION_FILE "")
+#SET(CPACK_RESOURCE_FILE_LICENSE "")
+#SET(CPACK_PACKAGE_VERSION_MAJOR "1")
+#SET(CPACK_PACKAGE_VERSION_MINOR "0")
+#SET(CPACK_PACKAGE_VERSION_PATCH "0")
+
+#SET(CPACK_PACKAGE_FILE_NAME "CstaSpyInstaller")
+#SET(CPACK_PACKAGE_NAME "CstaSpy")
+
+IF(WIN32)
+ SET(CPACK_GENERATOR "NSIS")
+ENDIF()
+
+# IF(UNIX)
+IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux" )
+ SET(CPACK_INSTALL_CMAKE_PROJECTS "${PROJECT_BINARY_DIR};cstav1-lib;ALL;/")
+ SET(CPACK_RPM_COMPONENT_INSTALL ON)
+ SET(CPACK_PACKAGE_FILE_NAME "CstaSpyInstaller")
+ set(CPACK_COMPONENTS_ALL Csta-Headers Csta-Lib Csta)
+ SET(CPACK_COMPONENTS_IGNORE_GROUPS 1)
+ SET(CPACK_COMPONENTS_GROUPING "IGNORE")
+ SET(CPACK_GENERATOR "RPM")
+ENDIF()
+IF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin" )
+ SET(CPACK_GENERATOR "Bundel")
+ENDIF()
+#SET(CPACK_PACKAGE_EXECUTABLES "cstaspy")
+SET(CPACK_PACKAGE_EXECUTABLES "cstaInsight" "CSTA Insight")
+INCLUDE(CPack)
+
+ENDIF (WITH_CSTAV1)
--- /dev/null
+#ifndef __CALL_H__
+
+/**
+ *
+ */
+class Call {
+ public:
+ enum Type
+ {
+ UNKNOWN,
+ CSTA,
+ SIP
+ };
+
+ Call(std::string id, Type t = UNKNOWN) : m_Type(t), m_Id(id) {};
+ Call(const Call &c) : m_Type(c.Type), m_Id(c.m_Id) {};
+ virtual ~Call() {} ;
+
+ // set get
+ Type get_Type() const;
+ void set_Type(Type t) {m_Type = t;};
+
+ std::string get_CallId() const;
+ void set_CallId(std::string &s) {m_Id = s;};
+ protected:
+ Type m_Type;
+ std::string m_Id; // Call Identifier, can be string for tags, and an integer or OCTET STRING for CSTA
+};
+#endif
--- /dev/null
+#include <iostream>
+#include <cstdio>
+#include <iomanip>
+#include <sstream>
+#include <algorithm>
+#include <math.h>
+
+#include <pcap/pcap.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Widget.H>
+#include <FL/Fl_Tree.H>
+#include <FL/Fl_Text_Editor.H>
+#include <FL/Fl_Text_Buffer.H>
+
+#include "Pcap.h"
+#if defined(__WIN32__) || defined(_WINDOWS)
+#else
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#endif
+#include <CstaInsightLog.h>
+#include "TLMsg.h"
+
+#include "Model.h"
+#include <SequenceView.h>
+#include <HeaderView.h>
+#include <FL/fl_draw.H>
+
+//Asn1
+#include "rtasn1/asn1.h"
+#include "rtasn1/asn1_codec.h"
+#include "rtasn1/asn1_codec_ber.h"
+// CSTA Stubs
+#include "Rose_Apdu.h"
+#include "CSTA_event.h"
+#include "ACSE_1.h"
+#include "CSTA_MSG.h"
+
+#include "Controler.h"
+
+
+#include "Rose_Apdu.hpp"
+#include "CSTA_event.hpp"
+
+Controler::Controler(Model *m)
+ : m_Model(m),
+ m_SequenceUi(NULL),
+ m_HeaderUi(NULL)
+{
+ m_Events[2] = std::string("conferenced");
+ m_Events[3] = std::string("connectionCleared");
+ m_Events[4] = std::string("delivered");
+ m_Events[5] = std::string("diverted");
+ m_Events[6] = std::string("established");
+ m_Events[7] = std::string("failed");
+ m_Events[8] = std::string("held");
+ m_Events[9] = std::string("networkReached");
+ m_Events[10] = std::string("originated");
+ m_Events[11] = std::string("queued");
+ m_Events[12] = std::string("retrieved");
+ m_Events[13] = std::string("serviceInitiated");
+ m_Events[14] = std::string("transfered");
+ m_Events[101] = std::string("callInformation");
+ m_Events[102] = std::string("doNotDisturb");
+ m_Events[103] = std::string("forwarding");
+ m_Events[104] = std::string("messageWaiting");
+ m_Events[174] = std::string("maintenance");
+ m_Events[401] = std::string("privateEvent");
+ m_Events[301] = std::string("backInService");
+ m_Events[302] = std::string("outOfService");
+
+ m_Ops[10] = std::string("makeCall");
+ m_Ops[12] = std::string("queryDevice");
+ m_Ops[13] = std::string("reconnectCall");
+ m_Ops[14] = std::string("retrieveCall");
+ m_Ops[15] = std::string("setFeature");
+ m_Ops[16] = std::string("tranferCall");
+ m_Ops[2] = std::string("answerCall");
+ m_Ops[5] = std::string("clearConnection");
+ m_Ops[7] = std::string("consultationCall");
+ m_Ops[8] = std::string("divertCall");
+ m_Ops[9] = std::string("holdCall");
+ m_Ops[51] = std::string("escapeService");
+ m_Ops[71] = std::string("monitorStart");
+ m_Ops[52] = std::string("systemStatus");
+ m_Ops[74] = std::string("snapshotDevice");
+ m_Ops[101] = std::string("101");
+ m_Ops[107] = std::string("107xxx");
+ m_Ops[235] = std::string("changeConnectionInformation");
+
+}
+
+Controler::~Controler()
+{
+}
+
+void
+Controler::load(const char *filename,const char *expression)
+{
+ std::string fn(filename);
+ Pcap cap(fn);
+ Packet packet;
+
+ if (expression != NULL)
+ {
+ cap.set_filter(expression);
+ }
+ // In case the stack is not empty
+ m_SizeStack = std::deque<int>();
+
+
+ while (cap.next(packet) == true)
+ {
+ long plength= 0;
+ const struct sniff_tcp *tcp = packet.get_tcp();
+ const struct sniff_udp *udp = packet.get_udp();
+ unsigned short sport = 0,dport=0;
+
+ const unsigned char *data =packet.get_payload(plength);
+ if (tcp)
+ {
+ sport = htons(tcp->th_sport);
+ dport = htons(tcp->th_dport);
+ CI_LOG_DEBUG("%lu.%lu Controler::load TCP sport=%d dport=%d payload len=%ld",
+ packet.get_seconds()
+ ,packet.get_miliseconds()
+ ,sport
+ ,dport
+ ,plength
+ );
+ } else if (udp) {
+ sport = htons(udp->sport);
+ dport = htons(udp->dport);
+ CI_LOG_DEBUG("%lu.%lu Controler::load UDP sport=%d dport=%d payload len=%ld",
+ packet.get_seconds()
+ ,packet.get_miliseconds()
+ ,sport
+ ,dport
+ ,plength
+ );
+ }
+
+ if (plength > 0)
+ {
+ char *ld = (char *)data;
+ std::stringstream ss;
+ ss.rdbuf()->sputn(ld,plength);
+
+ if ((sport == 2555) ||( dport == 2555 )) {
+ parse_csta(packet,ss,plength);
+ } else if ((sport ==5059) || (dport == 5059) || (dport == 5060) || (sport == 5060)) {
+ //SIP Packet
+ parse_sip(packet,ss);
+ } else if ( (sport == 8894) || (dport == 8894) || (dport == 56000) || (sport == 56000) )
+ {
+ // OTS message I think mainly soap
+ if (plength > 6)
+ parse_ots(packet,ss);
+ }
+#if 0
+ if (m_DumpHex->value() )
+ for (int i = 0 ; i < plength ; i++)
+ {
+ printf("%02x ",data[i]);
+ }
+#endif
+ //std::cout<<"\n";
+ }
+
+ }
+ if (m_Model)
+ {
+ std::cout<<"Controler::load tl_count="<<m_Model->tl_count()<<std::endl;
+ }
+}
+
+void
+Controler::close()
+{
+ m_Model->clean();
+ ;
+}
+
+
+void
+Controler::onSelectTree()
+{;
+}
+void Controler::onSelectSequence()
+{
+ ;
+}
+
+
+void
+Controler::parse_sip(const Packet &packet,std::stringstream &is)
+{;
+ const struct sniff_udp *udp = packet.get_udp();
+ const struct sniff_tcp *tcp = packet.get_tcp();
+ const struct sniff_ip *ip = packet.get_ip();
+ unsigned short sport,dport;
+ bool is_notify = false;
+ bool is_xml = false;
+ int length = 0;
+ size_t found = 0;
+ char buf[64];
+ memset(buf,0x00,64);
+ CI_LOG_DEBUG("Controler::parse_sip PROCESS size=%ld",
+ is.str().size());
+ std::stringstream ss;
+ std::string fline,line;
+ ss.str("");
+ // get first line
+ std::getline(is,fline,'\r');
+ is.seekg(0);
+ std::replace(fline.begin(),fline.end(),'/','.');
+
+ if (fline.find("NOTIFY") != std::string::npos)
+ is_notify = true;
+
+ if (udp) {
+ sport = htons(udp->sport);
+ dport = htons(udp->dport);
+ } else if (tcp)
+ {
+ sport = htons(tcp->th_sport);
+ dport = htons(tcp->th_dport);
+
+ } else {
+ CI_LOG_WARN("Controler::parse_sip HOHO SIP nor UDP neither TCP");
+ }
+
+ ss<<" "<<fline;
+
+ Timeline tld(ip->ip_dst,"");
+ Timeline tls(ip->ip_src,"");
+ CI_LOG_DEBUG("Controler::parse_sip PROCESS create TLMsg=%s size=%ld"
+ , fline.c_str()
+ , fline.size());
+ if (fline.size() < 7)
+ {
+ fline.assign("sip wierd ");
+ }
+ TLMsg *msg = new TLMsg(packet,fline);
+ msg->msg_type(TLMsg::SIP);
+ ss.str("");
+ ss<<is.str()<<std::endl;
+ msg->m_content = ss.str();
+ if (m_Model)
+ {
+
+ m_Model->add_TLMsg(msg,tls,tld);
+ }
+#if 0
+
+ // Add packet in sequence
+
+ // Ok parser data and check if it's a XML message
+ while (! std::getline(is,line,'\n').eof() )
+ {
+ std::replace(line.begin(),line.end(),'\r','\n');
+
+ if ( (found =line.find("Content-Length:")) != std::string::npos)
+ {
+ std::cout<<"Found Length : "<<line<<std::endl;
+ found = line.find(":");
+ // Found length extract
+ length =atoi(line.substr(found+1).c_str());
+ }
+ if ( (found =line.find("Content-Type:")) != std::string::npos)
+ {
+ if (line.find("application/xml") != std::string::npos)
+ is_xml = true;
+ }
+ if ( line.size()==1) {
+ //time to break;
+ break;
+ }
+
+ }
+ if (length && is_notify && is_xml)
+ {
+ std::cout<<"OTS: OK Got length="<<length<<std::endl;
+ XMLMessage msg(tree,item);
+ msg.Create();
+
+ void *p = msg.GetBuffer(length);
+ is.read((char *)p,length);
+ std::cout<<"OTS: Read buffer to be parsed len="<<length<<std::endl;
+ msg.ParseBuffer(length);
+
+ } else if (length == 0) {
+ // Length is 0 don't do any thing.
+ std::cout<<"Length is 0 don't print any thing."<<std::endl;
+ } else {
+ ss.str("");
+ std::cout<<" BAD len=0"<<std::endl;
+ ss<<is.str()<<std::endl;
+ m_Editor->insert(ss.str().c_str());
+ }
+#endif
+}
+void
+Controler::parse_ots(const Packet &packet,std::stringstream &is)
+{
+ const struct sniff_tcp *tcp = packet.get_tcp();
+ const struct sniff_ip *ip = packet.get_ip();
+ unsigned short sport,dport;
+
+ char buf[64];
+ memset(buf,0x00,64);
+
+ std::stringstream ss;
+
+ sport = htons(tcp->th_sport);
+ dport = htons(tcp->th_dport);
+
+ ss.str("");
+ strcpy(buf,inet_ntoa(ip->ip_src));
+
+
+ //Fl_Tree_Item *item = tree->add("/XML");
+
+
+ Timeline tld(ip->ip_dst,"");
+ Timeline tls(ip->ip_src,"");
+ TLMsg *msg = new TLMsg(packet,"XML ");
+ ss.str("");
+ CI_LOG_DEBUG("Controler::parse_ots");
+ ss<<is.str()<<std::endl;
+ msg->msg_type(TLMsg::SOAP_RESPONSE);
+ msg->m_content = ss.str();
+ //XMLMessage msg(tree,item);
+ //msg.Create();
+ std::string line;
+ size_t found;
+ int length = 0;
+ while (! std::getline(is,line,'\n').eof() )
+ {
+ std::replace(line.begin(),line.end(),'\r','\n');
+
+ if ( (found =line.find("Content-Length:")) != std::string::npos)
+ {
+ CI_LOG_DEBUG("Controler::parse_ots Found Length : %s",line.c_str());
+ found = line.find(":");
+ // Found length extract
+ length =atoi(line.substr(found+1).c_str());
+ }
+ if ( (found =line.find("SOAPAction:")) != std::string::npos)
+ {
+ CI_LOG_DEBUG("Controler::parse_ots Found Action : %s",line.c_str());
+ found = line.find(":");
+ // Found length extract
+ std::string soapaction(line.substr(found+1));
+ std::replace(soapaction.begin(),soapaction.end(),'\r',' ');
+ std::replace(soapaction.begin(),soapaction.end(),'\n',' ');
+ std::replace(soapaction.begin(),soapaction.end(),'\"',' ');
+ msg->msg_type(TLMsg::SOAP_REQUEST);
+ msg->name.append(soapaction.c_str());
+ }
+ if ( line.size()==1) {
+ //time to break;
+ break;
+ }
+ // Chunk XML
+ if (line.find("<?xml version=\"1.0\"") != std::string::npos)
+ {
+ int pos = is.tellg();
+ //void *p = msg.GetBuffer(is.str().size());
+ msg->msg_type(TLMsg::ICS_EVENT);
+
+ long toparse = is.str().size() -pos;
+ //is.read((char *)p,is.str().size()-pos);
+ CI_LOG_DEBUG("Controler::parse_ots Read Buffer to be parsed chunk len=%ld"
+ , is.str().size());
+ //msg.ParseBuffer(is.str().size()-pos);
+#if 0
+ long index = msg.GetCurrentByteIndex();
+ if (index < toparse)
+ {
+ std::string notparsed((const char *)p+index,toparse-index);
+
+ m_Editor->insert("\nUNPARSED DATA\n");
+ m_Editor->insert(notparsed.c_str());
+ }
+#endif
+ }
+
+ }
+ //m_Editor->insert("\n");
+ if (length)
+ {
+ CI_LOG_DEBUG("Controler::parser_ots : OK got length=%ld",length);
+ CI_LOG_DEBUG("Controler::parser_ots : Read buffer to be parsed len=%ld"
+ , length);
+
+ } else
+ {
+ CI_LOG_WARN("Controler::parse_ots: BAD len=0 true for chunk");
+ }
+ if (m_Model)
+ {
+ m_Model->add_TLMsg(msg,tls,tld);
+ }
+ ;
+}
+
+
+void
+Controler::parse_csta(const Packet &packet,std::stringstream &is,long read_len)
+{
+ int len = 0;
+ const struct sniff_tcp *tcp = packet.get_tcp();
+ const struct sniff_ip *ip = packet.get_ip();
+ unsigned short sport,dport;
+ char buf[64];
+ memset(buf,0x00,64);
+
+ sport = htons(tcp->th_sport);
+ dport = htons(tcp->th_dport);
+ strcpy(buf,inet_ntoa(ip->ip_src));
+
+
+ unsigned char bl[3];
+
+
+ while ( !is.eof() /*is.good()*/)
+ {
+ unsigned int low = 0,high = 0;
+ int at = is.tellg();
+ memset(bl,0x00,3);
+ is.read((char *)bl,2);
+ low = bl[0];
+ high = bl[1];
+ len = (unsigned short )bl[1] | ((unsigned short)bl[0] << 8);
+ CI_LOG_DEBUG("\n\n * HEADER b[0]=%u %u LEN=%ld at=%x",
+ low
+ ,high
+ ,len
+ ,at);
+ if ( (( (bl[0] & 0xf8) == 0xa0) || ((bl[0] & 0xf8 ) == 0x60 )) && !m_SizeStack.empty() )
+ { // Probably a packet
+ CI_LOG_DEBUG(" * HEADER pop length current=%ld new of m_SizeStack.front=%d or m_SizeStack.back=%d"
+ , len
+ , m_SizeStack.front()
+ , m_SizeStack.back());
+ len = m_SizeStack.back();
+ m_SizeStack.pop_back();
+ is.seekg(at); // Go back to initial position
+ } else {
+ // Prob next value if its a packet or another length
+ unsigned char c;
+ if (is.eof() || (at == -1))
+ {
+ CI_LOG_DEBUG(" * Probabl nothing todo at == -1 or eof");
+ // On windows when at == -1 is.eof is not set
+ if (at == -1)
+ break;
+ } else {
+ c = is.get();
+ is.putback(c);
+ if ( ! ( ( (c & 0xf8) == 0xa0) || ((c & 0xf8) == 0x60 )))
+ { // Next Is not a packet stack the length and restart reading
+ CI_LOG_DEBUG("\n * Push and read next c=%0x LEN=%ld at=%0x"
+ , c
+ , len
+ , at);
+ CI_LOG_DEBUG(" stack empty = %d Size=%ld"
+ , m_SizeStack.empty()
+ , m_SizeStack.size());
+ m_SizeStack.push_back(len);
+ continue;
+ } else if (! m_SizeStack.empty())
+ { // Why should I pop the length ?
+ CI_LOG_DEBUG(" * HEADER use length current=%d queue len=%d"
+ ,len
+ ,m_SizeStack.front()
+ );
+ }
+ }
+ }
+
+ memset(bl,0x00,3);
+ if ( (len > 0) && (len < 4096))
+ {
+ int before,after;
+ // Top level that must be used
+ CSTA_MSG::CSTA_msg message;
+
+ //asn1::context ctx(len+1);
+ asn1::streams::ber ctx(len+1);
+ before = is.tellg();
+ is.read((char *)ctx.buffer(),len);
+ after = is.tellg();
+ if ((after - before ) != len)
+ {
+ CI_LOG_ERROR(" ERROR did not read right length %d expected: %ld only: %ld "
+ ,(after-before)
+ ,len
+ ,is.gcount());
+ } else
+ {
+ CI_LOG_DEBUG(" * READ LENGTH %d",(after-before));
+ }
+ //int result = pdu.codec(ctx,pdu,asn1::CODEC_DECODE);
+ //int result = message.codec(ctx,message,asn1::CODEC_DECODE);
+ int result = message.decode(ctx);
+
+
+ if (( (ctx.nb_read_bits()>>3) == len) || (ctx.nb_read_bits() >>3) == read_len)
+ {
+ if (( (ctx.nb_read_bits()>>3) != len) || (ctx.nb_read_bits() >>3) == read_len)
+ {
+ CI_LOG_DEBUG(" * WIERD CASE may be I should push back len : %d expected: %d payload: %d analysed: "
+ ,( after-before)
+ , len
+ , read_len
+ , (ctx.nb_read_bits()>>3));
+ }
+ if (message.tag().byte() == asn1::tag(1,0,true).byte()
+ || message.tag().byte() == asn1::tag(1,1,true).byte()
+ || message.tag().byte() == asn1::tag(1,2,true).byte()
+ )
+ {
+ std::stringstream ss,stitle;
+ //int invokeID = .retError.invokeID;
+ stitle<<"acse ()";
+
+ ss<<message.get_aPDU_acse()<<std::endl;
+ Timeline tld(0,dport,"");
+ Timeline tls(0,sport,"");
+ TLMsg *msg = new TLMsg(packet,stitle.str().c_str());
+ msg->m_content = ss.str();
+ switch(message.get_aPDU_acse().get_kind())
+ {
+ case ACSE_1::ACSE_apdu::typeof_aarq :
+ msg->msg_type(TLMsg::CSTA_REQUEST);
+ break;
+ case ACSE_1::ACSE_apdu::typeof_aare :
+ msg->msg_type(TLMsg::CSTA_RESPONSE);
+ break;
+ case ACSE_1::ACSE_apdu::typeof_rlrq :
+ msg->msg_type(TLMsg::CSTA_REQUEST);
+ break;
+ case ACSE_1::ACSE_apdu::typeof_rlre :
+ msg->msg_type(TLMsg::CSTA_RESPONSE);
+ break;
+ default:
+ msg->msg_type(TLMsg::CSTA_REJECT);
+ }
+ if (m_Model)
+ {
+ m_Model->add_TLMsg(msg,tls,tld);
+ }
+
+ } else
+ {
+ Rose_Apdu::RoseAPDU &pdu= message.get_aPDU_rose();
+ switch (pdu.get_kind())
+ {
+ case Rose_Apdu::RoseAPDU::typeof_invoke:
+ CI_LOG_DEBUG("\tGot invoke ID=%ld",pdu.get_invoke().invokeID.get_sys_value());
+ if (pdu.get_invoke().operationValue.get_kind() == Remote_Operations_Information_Objects::OpCode::typeof_local)
+ {
+ Remote_Operations_Information_Objects::IOPERATION::ptr op = pdu.get_invoke().argument;
+ // asn1::Object * _o = pdu.get_invoke().argument;
+ // Remote_Operations_Information_Objects::IOPERATION *op =
+ // dynamic_cast<Remote_Operations_Information_Objects::IOPERATION *>(_o);
+
+ doInvoke( packet
+ , pdu.get_invoke().operationValue.get_local().get_sys_value()
+ , pdu.get_invoke().invokeID.get_sys_value(),op);
+
+ } else {
+
+ }
+ // std::cout<<std::endl;
+ break;
+ case Rose_Apdu::RoseAPDU::typeof_retResult:
+ CI_LOG_DEBUG("\tGot resultID=%ld",pdu.get_retResult().invokeID.get_sys_value());
+ if ( (! pdu.get_retResult().anonymousSEQUENCE.is_nul()) &&
+ (pdu.get_retResult().anonymousSEQUENCE->operationValue.get_kind() == Remote_Operations_Information_Objects::OpCode::typeof_local))
+ {
+ std::stringstream ss,ss1;
+
+ if (m_Ops[pdu.get_retResult().anonymousSEQUENCE->operationValue.get_local().get_sys_value()].size() >0)
+ {
+ ss1<<"/SR "<<m_Ops[pdu.get_retResult().anonymousSEQUENCE->operationValue.get_local().get_sys_value()]<<" (id="<<pdu.get_retResult().invokeID.get_sys_value()<<")";
+ } else {
+ ss1<<"/SR ("<<pdu.get_retResult().anonymousSEQUENCE->operationValue.get_local().get_sys_value()<<")";
+ }
+ // complete other text fields
+
+ ss<<pdu.get_retResult()<<std::endl;
+
+
+ Timeline tld(0,dport,"");
+ Timeline tls(0,sport,"");
+ TLMsg *msg = new TLMsg(packet,ss1.str().c_str());
+ msg->msg_type(TLMsg::CSTA_RESPONSE);
+ msg->m_content = ss.str();
+ if (m_Model)
+ {
+ m_Model->add_TLMsg(msg,tls,tld);
+ }
+
+ } else
+ {
+ std::cout<<"Got Result anonymous is_nul ? "<<pdu.get_retResult().anonymousSEQUENCE.is_nul()<<std::endl;
+ }
+ break;
+ case Rose_Apdu::RoseAPDU::typeof_retError:
+ {
+ std::stringstream ss,stitle;
+ int invokeID = pdu.get_retError().invokeID.get_sys_value();
+ stitle<<"retError ("<<invokeID<<")";
+
+ ss<<pdu.get_retError()<<std::endl;
+ Timeline tld(0,dport,"");
+ Timeline tls(0,sport,"");
+ TLMsg *msg = new TLMsg(packet,stitle.str().c_str());
+ msg->m_content = ss.str();
+ msg->msg_type(TLMsg::CSTA_RESPONSE_ERROR);
+ if (m_Model)
+ {
+ m_Model->add_TLMsg(msg,tls,tld);
+ }
+
+
+ }
+ break;
+ case Rose_Apdu::RoseAPDU::typeof_reject:
+ {
+ std::stringstream ss,stitle;
+
+ stitle<<"Reject "<<pdu.get_reject().invokeID;
+ ss<<pdu.get_reject()<<std::endl;
+
+ Timeline tld(0,dport,"");
+ Timeline tls(0,sport,"");
+ TLMsg *msg = new TLMsg(packet,stitle.str().c_str());
+
+ msg->msg_type(TLMsg::CSTA_REJECT);
+ msg->m_content = ss.str();
+
+ if (m_Model)
+ {
+ m_Model->add_TLMsg(msg,tls,tld);
+ }
+
+ }
+ break;
+ default:
+ ;
+
+ } /* end switch */
+ }
+ } else
+ {
+ std::stringstream msg;
+ msg<<"Err Pdu len="<<len<<" read:"<<(ctx.nb_read_bits()>>3)<<"";
+ // not properly decoded see why.
+ // tree->add(msg.str().c_str());
+ CI_LOG_DEBUG("\n * %s",msg.str().c_str());
+ Timeline tld(0,dport,"");
+ Timeline tls(0,sport,"");
+ TLMsg *tmsg = new TLMsg(packet,msg.str().c_str());
+ if (m_Model)
+ {
+ tmsg->m_content.resize(len *3+2);
+ char * buf = const_cast<char *>(tmsg->m_content.c_str());
+ for (int i = 0 ; i < len ; i++)
+ {
+ char b[4];
+ sprintf(b,"%02x ",ctx.buffer()[i]);
+ strcat(buf,b);
+ }
+ strcat(buf,"\n");
+ m_Model->add_TLMsg(tmsg,tls,tld);
+ }
+ }
+ } else {
+ int at = is.tellg();
+ if (at != -1 )
+ {
+ CI_LOG_ERROR(" * BAD LENGTH %d at=%0x",len,at);
+ }
+ }
+ }
+
+}
+
+
+
+void
+Controler::doInvoke(const Packet &packet,int opId,int InvokeId,Remote_Operations_Information_Objects::IOPERATION *op)
+{
+
+ const struct sniff_tcp *tcp = packet.get_tcp();
+ const struct sniff_ip *ip = packet.get_ip();
+ unsigned short sport,dport;
+
+ char buf[64];
+ memset(buf,0x00,64);
+
+ sport = htons(tcp->th_sport);
+ dport = htons(tcp->th_dport);
+ strcpy(buf,inet_ntoa(ip->ip_src));
+
+ CI_LOG_DEBUG("Controler::doInvoke Process invoke request opId=%d invokeId=%d",opId,InvokeId);
+
+ if (opId == 21)
+ {
+ std::stringstream ss,ss1;
+ // Get OPERATION
+ CSTA_event::cSTAEventEvent *event;
+ event = dynamic_cast<CSTA_event::cSTAEventEvent *>(op);
+ // Get OBJECT-TYPE
+ CSTA_event::CSTAEventReportArgument report;
+ event->get_ArgumentType(report);
+ CI_LOG_DEBUG("Got type info=%ld",report.eventType.get_local().get_sys_value());
+ Remote_Operations_Information_Objects::IOBJECT_TYPE *event_obj;
+ asn1::Object * _o = report.eventInfo;
+ event_obj = dynamic_cast<Remote_Operations_Information_Objects::IOBJECT_TYPE *>(_o);
+ ss.str(""); ss1.str("");
+ std::string s = report.crossRefIdentifier.get_sys_value();
+ unsigned char a0,a1,a2,a3;
+ a0 = (unsigned short)s[0];
+ a1 = (unsigned short)s[1];
+ a2 = (unsigned short)s[2];
+ a3 = (unsigned short)s[3];
+ int crid = (a2<<8) | a3;
+
+ std::string addons;
+ Timeline tld(crid,dport,"");
+ Timeline tls(0,sport,"");
+
+ if (m_Events[report.eventType.get_local().get_sys_value()].size()>0 )
+ {
+ ss1<<"/"<<m_Events[report.eventType.get_local().get_sys_value()]<<"("<<crid<<")";
+ } else
+ ss1<<"/Event_("<<crid<<")"<<report.eventType.get_local();
+ addons = ss1.str();
+ TLMsg *msg = NULL;
+ if (m_Model)
+ m_Model->new_TLMsg(packet,&msg);
+ doInvokeEvent(report.eventType.get_local().get_sys_value()
+ ,event_obj,tld,addons,msg);
+ //TLMsg *msg = new TLMsg(packet,ss1.str().c_str());
+ //TLMsg *msg = new TLMsg(packet,addons);
+ msg->name = addons;
+ msg->msg_type(TLMsg::CSTA_EVENT);
+
+ ss<<report<<std::endl;
+ msg->m_content = ss.str();
+ if (m_Model)
+ m_Model->add_TLMsg(msg,tls,tld);
+#if 0
+
+ Fl_Tree_Item *item = tree->add(ss1.str().c_str());
+ // Here we can decide to add sub stree information and build a string for the sequence diagram
+ std::string addons;
+ addons = m_Events[report.eventType.local];
+ ProcessEvent(report.eventType.local,event_obj,item,addons);
+
+ int lines = m_Editor->count_lines(0,m_Editor->buffer()->length(),1);
+
+ item->user_data((void *)lines);
+ Fl_Text_Buffer *buffer = m_Editor->buffer();
+ m_Sequence->add_event(crid,packet,addons.c_str(),item);
+ assign_icons(item,1);
+
+ ss<<" == From : "<<buf<<":"<<sport<<" To "<<inet_ntoa(ip->ip_dst)<<":"<<dport<<" ========================================="<<std::endl;
+ ss<<ss1.str()<<std::endl;
+ ss<<report<<std::endl;
+ // char *dst = (char *)malloc(ss.str().size()*2);
+ // fl_utf8froma(dst,ss.str().size()*2,ss.str().c_str(),ss.str().size());
+ //m_Buffer->append(ss.str().c_str());
+ m_Editor->insert(ss.str().c_str());
+#endif
+ } else {
+ std::stringstream ss,ss1;
+ asn1::Object *obj= dynamic_cast<asn1::Object *>(op);
+ Timeline tld(0,dport,"");
+ Timeline tls(0,sport,"");
+ if (m_Ops[opId].size() > 0)
+ {
+ ss1<<"/SReq "<<m_Ops[opId]<<" (id="<<(long)InvokeId<<")";
+ } else {
+ ss1<<"/Ope_("<<opId<<")";
+ }
+ TLMsg *msg = new TLMsg(packet,ss1.str().c_str());
+ msg->msg_type(TLMsg::CSTA_REQUEST);
+ if (obj != NULL)
+ obj->printf(ss);
+ msg->m_content =ss.str();
+ if (m_Model)
+ m_Model->add_TLMsg(msg,tls,tld);
+#if 0
+ Fl_Tree_Item *item = tree->add(ss1.str().c_str());
+
+ int lines = m_Editor->count_lines(0,m_Editor->buffer()->length(),1);
+
+ item->user_data((void *)lines);
+ Fl_Text_Buffer *buffer = m_Editor->buffer();
+ m_Sequence->add_invoke(packet,ss1.str().c_str(),item);
+
+ assign_icons(item,0);
+ ss<<" == From : "<<buf<<":"<<sport<<" To "<<inet_ntoa(ip->ip_dst)<<":"<<dport<<" ========================================="<<std::endl;
+ ss<<ss1.str()<<std::endl;
+ //ss<<" ==========================================="<<std::endl;
+ if (obj != NULL)
+ obj->printf(ss);
+#endif
+ }
+ ;
+}
+
+
+void
+Controler::doInvokeEvent(int id,Remote_Operations_Information_Objects::IOBJECT_TYPE *_evt,Timeline &tld,std::string &str,TLMsg *_msg)
+{
+ switch (id)
+ {
+ case 3: //connectionCleared
+ {
+ CSTA_event::connectionClearedEvent *p = dynamic_cast<CSTA_event::connectionClearedEvent *>(_evt);
+ CSTA_event::ConnectionClearedEventInfo report;
+ p->get_ArgumentType(report);
+ std::string octs = report.droppedConnection.call->get_sys_value();
+ std::string local(" Call=");
+ callToString(octs,local);
+ str+=local;
+ callToString(octs,_msg->m_callid);
+ //tree->add(item,local.c_str());
+ //tree->close(item);
+ std::ostringstream oss; oss << report.localConnectionInfo;
+ str+= std::string(" lCI=")+oss.str();
+ }
+ break;
+
+ case 4: //deliveredEvent
+ {
+ CSTA_event::deliveredEvent *p = dynamic_cast<CSTA_event::deliveredEvent *>(_evt);
+ CSTA_event::DeliEstaEventInfo report;
+ p->get_ArgumentType(report);
+ CI_LOG_DEBUG("Event Delivered for call %s",report.connection.call->get_sys_value().c_str());
+ std::string octs = report.connection.call->get_sys_value();
+ str+= " Call=";
+ callToString(octs,str);
+ callToString(octs,_msg->m_callid);
+
+ std::ostringstream oss ; oss<< report.localConnectionInfo;
+ str+= std::string(" lCI=") + oss.str();
+ if (**report.localConnectionInfo == CSTA_connect::LocalConnectionState::alerting)
+ {
+ std::string local;
+ if (report.alertingDevice.get_kind() == CSTA_device::SubjectDeviceID::typeof_deviceIdentifier)
+ {
+ switch(report.alertingDevice.get_deviceIdentifier().get_kind())
+ {
+ case CSTA_device::ExtendedDeviceID::typeof_deviceIdentifier:
+ break;
+ case CSTA_device::ExtendedDeviceID::typeof_implicitPublic:
+ break;
+ case CSTA_device::ExtendedDeviceID::typeof_explicitPublic:
+ break;
+ case CSTA_device::ExtendedDeviceID::typeof_implicitPrivate:
+ {
+ std::string result = report.alertingDevice.get_deviceIdentifier().get_implicitPrivate().get_sys_value();
+ local = std::string(" initiating=") + result;
+ std::replace(result.begin(),result.end(),'\n',' ');
+ tld.set_device(result);
+ //tree->add(item,local.c_str());
+ str+= local;
+ }
+ break;
+ case CSTA_device::ExtendedDeviceID::typeof_explicitPrivate:
+ break;
+ default:
+ ;
+ }
+ }
+ }
+
+ }
+ break;
+
+ case 5: //divertedEvent
+ {
+ CSTA_event::divertedEvent *p = dynamic_cast<CSTA_event::divertedEvent *>(_evt);
+ CSTA_event::DivertedEventInfo report;
+ p->get_ArgumentType(report);
+ CI_LOG_DEBUG("Event Diverted %s",report.connection->call->get_sys_value().c_str());
+ std::string octs = report.connection->call->get_sys_value();
+ callToString(octs,_msg->m_callid);
+
+ }
+ break;
+ case 6: //establishedEvent
+ {
+ CSTA_event::establishedEvent *p = dynamic_cast<CSTA_event::establishedEvent *>(_evt);
+ CSTA_event::DeliEstaEventInfo report;
+ p->get_ArgumentType(report);
+ CI_LOG_DEBUG("Event Established for call %s",report.connection.call->get_sys_value().c_str());
+ std::string octs = report.connection.call->get_sys_value();
+ str+= " Call=";
+ callToString(octs,str);
+ callToString(octs,_msg->m_callid);
+ std::ostringstream oss ; oss<< report.localConnectionInfo;
+ str+= std::string(" lCI=") + oss.str();
+
+
+ }
+ break;
+ case 7: //failedEvent
+ {
+ CSTA_event::failedEvent *p = dynamic_cast<CSTA_event::failedEvent *>(_evt);
+ CSTA_event::FailNetwOrigEventInfo report;
+ p->get_ArgumentType(report);
+ CI_LOG_DEBUG("Event Failed for call %s",report.connection.call->get_sys_value().c_str());
+ std::string octs = report.connection.call->get_sys_value();
+ callToString(octs,_msg->m_callid);
+
+ }
+ break;
+ case 8: //heldEvent
+ {
+ CSTA_event::heldEvent *p = dynamic_cast<CSTA_event::heldEvent *>(_evt);
+ CSTA_event::HeldEventInfo report;
+ p->get_ArgumentType(report);
+ CI_LOG_DEBUG("Event held for call %s",report.heldConnection.call->get_sys_value().c_str());
+ std::string octs = report.heldConnection.call->get_sys_value();
+ str+= " Call=";
+ callToString(octs,str);
+ callToString(octs,_msg->m_callid);
+ std::ostringstream oss ; oss<< report.localConnectionInfo;
+ str+= std::string(" lCI=") + oss.str();
+
+ }
+ break;
+ case 9: //networkReachedEvent
+ {
+ CSTA_event::networkReachedEvent *p = dynamic_cast<CSTA_event::networkReachedEvent *>(_evt);
+ CSTA_event::FailNetwOrigEventInfo report;
+ p->get_ArgumentType(report);
+ CI_LOG_DEBUG("Event Network reached for call %s",report.connection.call->get_sys_value().c_str());
+ std::string octs = report.connection.call->get_sys_value();
+ str+= " Call=";
+ callToString(octs,str);
+ callToString(octs,_msg->m_callid);
+ std::ostringstream oss; oss <<report.localConnectionInfo;
+ str+= std::string(" lCI=")+oss.str();
+
+ }
+ break;
+ case 10: //originatedEvent
+ {
+ CSTA_event::originatedEvent *p = dynamic_cast<CSTA_event::originatedEvent *>(_evt);
+ CSTA_event::FailNetwOrigEventInfo report;
+ p->get_ArgumentType(report);
+ CI_LOG_DEBUG("Event Originated for call %s",report.connection.call->get_sys_value().c_str());
+ std::string octs = report.connection.call->get_sys_value();
+ str+= " Call=";
+ callToString(octs,str);
+ callToString(octs,_msg->m_callid);
+ std::ostringstream oss ; oss<< report.localConnectionInfo;
+ str+= std::string(" lCI=") + oss.str();
+
+
+ }
+ break;
+ case 11: //queuedEvent
+ {
+ CSTA_event::queuedEvent *p = dynamic_cast<CSTA_event::queuedEvent *>(_evt);
+ CSTA_event::QueuedEventInfo report;
+ p->get_ArgumentType(report);
+ CI_LOG_DEBUG("Event Queued for call %s",report.connection.call->get_sys_value().c_str());
+ std::string octs = report.connection.call->get_sys_value();
+ str+= " Call=";
+ callToString(octs,str);
+ callToString(octs,_msg->m_callid);
+ std::ostringstream oss ; oss<< report.localConnectionInfo;
+ str+= std::string(" lCI=") + oss.str();
+
+ }
+ break;
+ case 12: //retrievedEvent
+ {
+ CSTA_event::retrievedEvent *p = dynamic_cast<CSTA_event::retrievedEvent *>(_evt);
+ CSTA_event::ConnectionEventInfo report;
+ p->get_ArgumentType(report);
+ CI_LOG_DEBUG("Event Retrieved for call %s",report.connection.call->get_sys_value().c_str());
+ std::string octs = report.connection.call->get_sys_value();
+ str+= " Call=";
+ callToString(octs,str);
+ callToString(octs,_msg->m_callid);
+
+ }
+ break;
+ case CSTA_event::serviceInitiatedEvent::uuid : //serviceInitiatedEvent
+ {
+ CSTA_event::serviceInitiatedEvent *p = dynamic_cast<CSTA_event::serviceInitiatedEvent *>(_evt);
+ CSTA_event::ServiceInitiatedEventInfo report;
+ p->get_ArgumentType(report);
+ CI_LOG_DEBUG("Event Initiated for call %s",report.initiatedConnection.call->get_sys_value().c_str());
+ std::string local;
+ std::string octs = report.initiatedConnection.call->get_sys_value();
+ //std::string octs1 = report.call;
+ str+= " Call=";
+ callToString(octs,str);
+ callToString(octs,_msg->m_callid);
+ // convert call string to integer
+ switch (report.initiatingDevice.get_kind())
+ {
+ case CSTA_device::ExtendedDeviceID::typeof_deviceIdentifier:
+ break;
+ case CSTA_device::ExtendedDeviceID::typeof_implicitPublic:
+ break;
+ case CSTA_device::ExtendedDeviceID::typeof_explicitPublic:
+ break;
+ case CSTA_device::ExtendedDeviceID::typeof_implicitPrivate:
+ {
+ std::string result = report.initiatingDevice.get_implicitPrivate().get_sys_value();
+ local = std::string(" initiating=") + result;
+ std::replace(result.begin(),result.end(),'\n',' ');
+ tld.set_device(result);
+ //tree->add(item,local.c_str());
+ str+= local;
+ }
+ break;
+ case CSTA_device::ExtendedDeviceID::typeof_explicitPrivate:
+ break;
+ default:
+ ;
+ }
+ std::ostringstream oss ;
+ if (!report.localConnectionInfo.is_nul()) {
+ oss<< (report.localConnectionInfo);
+ str+= std::string(" lCI=") + oss.str();
+ }
+ //tree->close(item);
+
+ }
+ break;
+ case 14: //transferredEvent
+ {
+ CSTA_event::transferredEvent *p = dynamic_cast<CSTA_event::transferredEvent *>(_evt);
+ CSTA_event::TransferredEventInfo report;
+ p->get_ArgumentType(report);
+ CI_LOG_DEBUG("Event CallInformation for call %s",report.primaryOldCall.call->get_sys_value().c_str());
+ std::ostringstream oss ; oss<< report.localConnectionInfo;
+ std::string octs;
+ //if (! report.primaryOldCall.is_nul())
+ octs = report.primaryOldCall.call->get_sys_value();
+ str+= " PrimOldCall=";
+ callToString(octs,str);
+ if (! report.secondaryOldCall.is_nul())
+ if ( ! report.secondaryOldCall->call.is_nul())
+ octs = report.secondaryOldCall->call->get_sys_value();
+ str+= " SecondOldCall=";
+ callToString(octs,str);
+ str+= std::string(" lCI=") + oss.str();
+
+ //octs = report.call;
+ if (report.transferredConnections->get_kind() == CSTA_connect::ConnectionList::typeof_callinformation) {
+ CSTA_call::ConnectionID conn = report.transferredConnections->get_callinformation()[0].endpoint;
+ if (!conn.call.is_nul())
+ octs = conn.call->get_sys_value();
+ callToString(octs,_msg->m_callid);
+ }
+
+
+ }
+ break;
+ case 101: //callInformationEvent
+ {
+ CSTA_event::callInformationEvent *p = dynamic_cast<CSTA_event::callInformationEvent *>(_evt);
+ CSTA_event::CallInformationEventInfo report;
+ p->get_ArgumentType(report);
+ CI_LOG_DEBUG("Event CallInformation for call %s",report.connection.call->get_sys_value().c_str());
+ std::string octs = report.connection.call->get_sys_value();
+ str+= " Call=";
+ callToString(octs,str);
+ callToString(octs,_msg->m_callid);
+
+ }
+ break;
+
+ case 145: //otherPrivateEvent
+ {
+ CSTA_event::otherPrivateEvent *p = dynamic_cast<CSTA_event::otherPrivateEvent *>(_evt);
+ }
+ break;
+ default:
+ _msg->m_callid = "default";
+ ;
+ }
+
+
+}
+
+
+void
+Controler::callToString(const std::string &ins,std::string &out)
+{
+ int res = 0;
+ for (std::string::const_iterator it = ins.begin() ;
+ it != ins.end(); ++it)
+ res = res << 8 | (unsigned char)(*it);
+
+ std::stringstream ints; ints<<res;
+ out += ints.str();
+
+}
+
+void
+Controler::select(TLMsg *m)
+{
+ Model::EventType_const_iterator it = std::find_if(m_Model->evt_begin(),m_Model->evt_end(),Model::tlmsg_finder(m));
+ if (it != m_Model->evt_end() )
+ {
+ m_Model->select(m);
+ }
+}
+
--- /dev/null
+#ifndef CONTROLER_H__
+#define CONTROLER_H__
+
+#include <stack>
+#include <queue>
+#include <deque>
+#include <map>
+#include "sigslot.h"
+
+class Controler
+{
+ public:
+ Controler(Model *m);
+ ~Controler();
+
+
+ void load(const char *fn,const char *expr = NULL);
+ void close();
+ void onSelectTree();
+ void onSelectSequence();
+ //Not sur if it's the right place.
+ void parse_sip(const Packet &packet,std::stringstream &is);
+ void parse_ots(const Packet &packet,std::stringstream &is);
+ void parse_csta(const Packet &packet,std::stringstream &is,long read_length);
+ void doInvoke(const Packet &packet,int opId,int InvokeId,Remote_Operations_Information_Objects::IOPERATION *op);
+ void doInvokeEvent(int id,Remote_Operations_Information_Objects::IOBJECT_TYPE *_evt,Timeline &tld,std::string &str,TLMsg *_m);
+
+ void callToString(const std::string &ins,std::string &out);
+ // Invoked when an item in the tree is selected
+ void select(TLMsg *m);
+ protected:
+ // Owns a pointer to view and one to Model
+ Model *m_Model;
+ SequenceView *m_SequenceUi;
+ HeaderView *m_HeaderUi;
+
+ std::deque<int> m_SizeStack;
+ std::map<int,std::string> m_Events;
+ std::map<int,std::string> m_Ops;
+
+};
+
+#endif
--- /dev/null
+
+int cid_level = 1;
--- /dev/null
+#ifndef CSTAINSIGHT_LOG_H__
+#define CSTAINSIGHT_LOG_H__
+
+#ifndef GCC_VERSION
+#define GCC_VERSION (__GNUC__ *10000 \
+ + __GNUC_MINOR__ * 100 \
+ + __GNUC_PATCHLEVEL__ )
+#endif
+
+#if defined(__APPLE__) || (GCC_VERSION > 40800)
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#endif
+#if defined(_WIN32)
+# include <io.h>
+#else
+#include <string.h>
+#endif
+
+
+extern int cid_level;
+
+#if defined(__GNUC__) && defined(DEBUG)
+
+#define __MYFILE__ (strrchr(__FILE__,'/')?strrchr(__FILE__,'/')+1 : __FILE__)
+
+# define CI_LOG_DEBUG(fmt,args...) do {\
+ if (cid_level >= 7) \
+ { fprintf(stderr,fmt,##args);\
+ fprintf(stderr," (%s : %d)\n",__MYFILE__,__LINE__); \
+ } \
+} while (0);
+
+# define CI_LOG_INFO(fmt,args...) do {\
+ if (cid_level >= 3) \
+ { fprintf(stderr,fmt,##args);\
+ fprintf(stderr," (%s : %d)\n",__FILE__,__LINE__);\
+ } \
+} while (0);
+
+# define CI_LOG_WARN(fmt,args...) do {\
+ fprintf(stderr,fmt,##args);\
+ fprintf(stderr," (%s : %d)\n",__MYFILE__,__LINE__);\
+} while (0);
+
+# define CI_LOG_ERROR(fmt,args...) do {\
+ fprintf(stderr,fmt,##args);\
+ fprintf(stderr," (%s : %d)\n",__MYFILE__,__LINE__);\
+} while (0);
+
+#elif defined(_WIN32) || defined(_WINDOWS)
+
+#define __MYFILE__ (strrchr(__FILE__,'/')?strrchr(__FILE__,'/')+1 : __FILE__)
+
+# define CI_LOG_DEBUG(fmt,...) do {\
+ if (cid_level >= 7) \
+ { fprintf(stderr,fmt,__VA_ARGS__);\
+ fprintf(stderr," (%s : %d)\n",__MYFILE__,__LINE__); \
+ } \
+ } while (0);
+
+# define CI_LOG_INFO(fmt,...) do {\
+ } while (0);
+
+# define CI_LOG_WARN(fmt,...) do {\
+ fprintf(stderr,fmt,__VA_ARGS__);\
+ fprintf(stderr," (%s : %d)\n",__FILE__,__LINE__);\
+ } while (0);
+
+# define CI_LOG_ERROR(fmt,...) do {\
+ fprintf(stderr,fmt,__VA_ARGS__);\
+ fprintf(stderr," (%s : %d)\n",__FILE__,__LINE__);\
+ } while (0);
+#else
+// Not debug but Release Target
+# if not(defined(CI_LOG_DEBUG))
+# define CI_LOG_DEBUG(fmt,args...) do {} while (0);
+ //static inline void CI_LOG_DEBUG(const char *fmt,...) {(void)fmt;};
+# else
+ static inline void CI_LOG_DEBUG(const char *fmt,...) {(void)fmt;};
+# endif
+
+#define CI_LOG_INFO(fmt,args...) do {\
+ fprintf(stderr,fmt,##args);\
+ fprintf(stderr," (%s : %d)\n",__FILE__,__LINE__);\
+} while (0);
+
+# define CI_LOG_WARN(fmt,args...) do {\
+ fprintf(stderr,fmt,##args);\
+ fprintf(stderr," (%s : %d)\n",__FILE__,__LINE__);\
+} while (0);
+
+# define CI_LOG_ERROR(fmt,args...) do {\
+ fprintf(stderr,fmt,##args);\
+ fprintf(stderr," (%s : %d)\n",__FILE__,__LINE__);\
+} while (0);
+
+#endif
+
+#endif
--- /dev/null
+#include <iostream>
+#include <cstdio>
+#include <iomanip>
+#include <sstream>
+#include <math.h>
+// For windows
+#include <pcap/pcap.h>
+
+#include <FL/Fl.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Widget.H>
+#include <FL/Fl_Tree.H>
+#include <FL/Fl_PNG_Image.H>
+#include <FL/Fl_Preferences.H>
+
+#include "Pcap.h"
+#if defined( __WIN32__) || defined(_WINDOWS)
+#include <winsock2.h>
+#else
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#endif
+
+#include "TLMsg.h"
+
+#include <HeaderView.h>
+#include <FL/fl_draw.H>
+
+#include "Model.h"
+
+
+
+HeaderView::HeaderView(int x,int y , int h, int w, const char *l)
+ : Fl_Widget(x,y,h,w,l) , m_Model(NULL)
+{
+
+ ;
+}
+
+HeaderView::~HeaderView()
+{
+ ;
+}
+
+void HeaderView::resize(int X,int Y,int W,int H)
+{
+#if 0
+ printf("HeaderView::resize : x=%d y=%d w=%d h=%d\n",X,Y,W,H);
+#endif
+ Fl_Widget::resize(X,Y,W,H);
+ damage(FL_DAMAGE_ALL);
+}
+void
+HeaderView::draw()
+{
+ int m_separator = 120;
+ int y_base = 40;
+ char iPath[79];
+ Fl_Preferences app(Fl_Preferences::USER,"CSTASpy","main");
+ Fl_Preferences iconPath(app,"iconPath");
+ iconPath.get("path",iPath,"",79);
+#if 0
+ printf("HeaderView:Draw x=%d y=%d\n",x(),y());
+#endif
+ std::string imgServer(iPath); imgServer.append(std::string("Server_24.png"));
+ std::string imgVT(iPath); imgVT.append("VT_24.png");
+ Fl_PNG_Image s(imgServer.c_str());
+ Fl_PNG_Image sip(imgVT.c_str());
+ if (m_Model)
+ {
+ int i = 0;
+ Timeline tl_csta = Timeline(0,m_Model->portCsta(),"");
+ //
+ fl_color(FL_BLACK);
+ fl_font(0,8);
+ for (Model::TimelineType_const_iterator it = m_Model->tl_begin();
+ it != m_Model->tl_end();
+ ++it)
+ {
+ if ((*it) == tl_csta) {
+ s.draw(x()+140+i*120,y()+5);
+ fl_draw((*it).name(),x()+130 + i*m_separator,y()-2+y_base);
+ } else
+ {
+ std::string dev;
+ (*it).get_device(dev);
+ sip.draw(x()+140+i*120 ,y()+5);
+ if (dev.size() > 1) {
+ fl_draw(dev.c_str(),x()+170 + i*m_separator,y()-2+20);
+ }
+ fl_draw((*it).name(),x()+130 + i*m_separator,y()-2+y_base);
+ }
+ i++;
+ }
+ size(150 + i*m_separator + 50,h());
+ } else
+ {
+ s.draw(x()+140,y()+5);
+
+ for (int i = 1 ; i < 5; i++)
+ sip.draw(x()+140+i*120 ,y()+5);
+ }
+}
+
+void
+HeaderView::model(Model *m)
+{
+ m_Model = m;
+ m->subscribe(this);
+};
+
+void
+HeaderView::onClean()
+{
+ std::cout<<"HeaderView::onClean"<<std::endl;
+ damage(FL_DAMAGE_ALL);
+ //redraw();
+ parent()->redraw();
+}
+
+void
+HeaderView::onAdd(TLMsg * ,Timeline &tls,Timeline &tld)
+{
+ ;
+ this->damage(FL_DAMAGE_ALL);
+ this->parent()->redraw();
+}
--- /dev/null
+#ifndef HEADERVIEW_H__
+#define HEADERVIEW_H__
+
+#include <iostream>
+#include <string>
+#include <vector>
+#include <stdlib.h>
+#include <time.h>
+
+#if defined(__WIN32__) || defined(_WINDOWS)
+#include <pcap/pcap.h>
+#endif
+#include <FL/Fl.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Widget.H>
+#include <FL/Fl_Tree.H>
+#include <FL/Fl_Scroll.H>
+#include "Timeline.h"
+// Packet information ...
+#include "Pcap.h"
+#if defined(__WIN32__) || defined (_WINDOWS)
+#include <winsock2.h>
+#else
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#endif
+
+#include "TLMsg.h"
+#include "sigslot.h"
+#include "Observer.h"
+
+class Model;
+
+class HeaderView : public Fl_Widget, public Observer
+{
+ public:
+
+ HeaderView(int x,int y , int h, int w, const char *l=NULL);
+ ~HeaderView();
+
+ void draw();
+
+ void resize(int X,int Y,int W,int H);
+
+ void model(Model *m) ;
+ void onClean();
+ void onNew(TLMsg *msg) {};
+ void onAdd(TLMsg * ,Timeline &tls,Timeline &tld);
+ void onSelected(TLMsg *msg) {};
+ inline void onScroll(int _x) {
+ Fl_Scroll *s = dynamic_cast<Fl_Scroll *>(this->parent());
+ Fl_Scrollbar *sb = &dynamic_cast<Fl_Scroll *>(this->parent())->hscrollbar;
+ s->scroll_to(_x,s->yposition());
+ s->redraw();
+ };
+
+ protected:
+ Model *m_Model;
+};
+
+#endif
--- /dev/null
+#include <map>
+#include <string>
+
+
+#include <FL/Fl_Image.H>
+#include <FL/Fl_PNG_Image.H>
+#include <FL/Fl_Preferences.H>
+
+#include "IconFactory.h"
+
+IconFactory *IconFactory::m_IconFactory = NULL;
+
+IconFactory::IconFactory()
+{
+}
+
+Fl_Image *IconFactory::get_Icon(const char *n)
+{
+ if (m_IconFactory == NULL)
+ {
+ m_IconFactory = new IconFactory();
+ }
+
+ return m_IconFactory->image(n);
+
+}
+
+Fl_Image *IconFactory::image(const char *name)
+{
+ if (m_Images[name] == NULL)
+ {
+ char iPath[79];
+ // Build the picture
+ Fl_Preferences app(Fl_Preferences::USER,"CSTASpy","main");
+ Fl_Preferences iconPath(app,"iconPath");
+ iconPath.get("path",iPath,"",79);
+ std::string img(iPath);
+
+ img.append(name);
+ m_Images[std::string(name)] = new Fl_PNG_Image(img.c_str());
+ }
+ return m_Images[name];
+}
+
+
--- /dev/null
+#ifndef ICON_FACTORY_H__
+#define ICON_FACTORY_H__
+
+
+
+class IconFactory
+{
+ public:
+ IconFactory();
+
+ Fl_Image *image(const char *name);
+ static Fl_Image *get_Icon(const char *);
+ protected:
+
+ std::map<std::string,Fl_Image *> m_Images;
+ private:
+ static IconFactory *m_IconFactory;
+
+};
+
+#endif
--- /dev/null
+#include <algorithm>
+#include <functional>
+
+#include <fstream>
+
+#include "Model.h"
+
+
+Model::Model()
+ : m_portCsta(2555),m_portSip(5059),m_portXml(8894)
+{
+ Timeline csta(0,m_portCsta,"CSTA srv");
+ m_Timelines.push_back(csta);
+}
+
+Model::~Model()
+{
+}
+
+void
+Model::parse_sip(const Packet &packet,std::stringstream &is)
+{
+ ;
+}
+
+void
+Model::parse_ots(const Packet &packet,std::stringstream &is)
+{
+ ;
+}
+
+void
+Model::parse_csta(const Packet &packet,std::stringstream &is)
+{
+ ;
+}
+
+void
+Model::clean()
+{
+ m_Timelines.erase(m_Timelines.begin(),m_Timelines.end());
+
+ //
+ for_each(m_Events.begin(),m_Events.end(),tlmsg_deleter());
+ m_Events.erase(m_Events.begin(),m_Events.end());
+
+ int crid = 0;
+ unsigned short port= m_portCsta;
+ Timeline csta(crid,port,"CSTA srv");
+ m_Timelines.push_back(csta);
+
+ m_Calls.clear();
+ m_OnClean();
+}
+
+void
+Model::new_TLMsg(const Packet &p,TLMsg **m)
+{
+ std::string nm("NEWMSG");
+ *m = new TLMsg(p,nm);
+}
+
+void
+Model::add_TLMsg(TLMsg *m,Timeline &tls,Timeline &tld)
+{
+ int dist = 0;
+ bool found = false;
+ // Find destination Timeline If not found add it in the list.
+ found = find_timeline(tld,dist);
+ if (!found)
+ m_Timelines.push_back(tld);
+ m->distance = dist;
+
+ // Find Source Timeline
+ if ( ! find_timeline(tls,dist))
+ m_Timelines.push_back(tls);
+
+ if (m != NULL)
+ m->sdistance = dist;
+
+ if (m != NULL)
+ m_Events.push_back(m);
+
+ // Ok, process Calls msg->msg_type(TLMsg::CSTA_EVENT);
+ if (m->msg_type() == TLMsg::CSTA_EVENT) {
+ int nbcalls = m_Calls.size();
+ Calls_const_iterator it = m_Calls.find(m->m_callid);
+ if ( it == m_Calls.end()) {
+ m_Calls[m->m_callid] = nbcalls;
+ }
+ }
+
+ m_OnAdd(m,tls,tld);
+}
+
+
+bool
+Model::have_Call(std::string &c,int &i) const
+{
+ Calls_const_iterator it = m_Calls.find(c);
+ if (it != m_Calls.end()) {
+ i = (it)->second;
+ return true;
+ }
+ return false;
+}
+
+bool
+Model::find_timeline(const Timeline &tl,int &distance )
+{
+ bool found = false;
+ int dist = 0;
+
+
+ for (TimelineType_const_iterator it= m_Timelines.begin() ;
+ it != m_Timelines.end(); ++it)
+ {
+ if ((*it) == tl){
+ found = true;
+ break;
+ }
+ dist++;
+ }
+ distance = dist;
+ return found;
+
+}
+
+
+void
+Model::subscribe(Observer *o)
+{
+ m_OnClean.connect(o,&Observer::onClean);
+ m_OnAdd.connect(o,&Observer::onAdd);
+ m_OnSelected.connect(o,&Observer::onSelected);
+ m_OnScroll.connect(o,&Observer::onScroll);
+}
+
+void
+Model::select(TLMsg *m)
+{
+ m_OnSelected(m);
+}
+
+
+
+void
+Model::export_msc(const char *fn)
+{
+ int i = 0;
+ std::ofstream msc(fn);
+
+
+
+ for (TimelineType_const_iterator it= m_Timelines.begin() ;
+ it != m_Timelines.end(); ++it , i++)
+ {
+ std::string dev;
+ (*it).get_device(dev);
+
+ if ((it) != m_Timelines.begin()){
+ msc<<",";
+ }
+ msc<<"L"<<i<<" [label=\""<<(*it).name();
+ if (dev.size() > 0)
+ {
+ msc<<" "<<dev;
+ }
+ msc<<"\"]"<<std::endl;
+ }
+ msc<<";"<<std::endl<<std::endl;
+ // Now the events
+ for (EventType_const_iterator it= m_Events.begin() ;
+ it != m_Events.end(); ++it)
+ {
+
+ msc<<"L"<<(*it)->sdistance<<"-> L"<<(*it)->distance<<": [label=\""<<(*it)->name<<"\"];"<<std::endl;
+ }
+
+
+ msc.close();
+}
--- /dev/null
+#ifndef MODEL_H__
+#define MODEL_H__
+
+#include <iostream>
+#include <string>
+#include <vector>
+#include <map>
+#include <stdlib.h>
+#include <time.h>
+
+#if defined(__WIN32__) || defined(_WINDOWS)
+#include <pcap/pcap.h>
+#endif
+#include <FL/Fl.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Widget.H>
+#include <FL/Fl_Tree.H>
+#include "Timeline.h"
+// Packet information ...
+#include "Pcap.h"
+#if defined(__WIN32__) || defined(_WINDOWS)
+#else
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#endif
+
+#include "TLMsg.h"
+#include "sigslot.h"
+#include "Observer.h"
+class Model {
+ public:
+
+ typedef std::vector<Timeline> TimelineType;
+ typedef std::vector<Timeline>::const_iterator TimelineType_const_iterator;
+ typedef std::vector<TLMsg *> EventType;
+ typedef std::vector<TLMsg *>::const_iterator EventType_const_iterator;
+
+ typedef std::map<std::string,int> Calls;
+ typedef std::map<std::string,int>::const_iterator Calls_const_iterator;
+
+ typedef sigslot::signal0<> cleanEvent;
+ typedef sigslot::signal3<TLMsg *,Timeline &,Timeline &> addEvent;
+ typedef sigslot::signal1<TLMsg *> selectEvent;
+ typedef sigslot::signal1<int> scrollEvent;
+
+ struct tlmsg_deleter {
+ inline void operator ()(TLMsg *& e) { delete e; e= NULL;}
+ };
+
+ struct tlmsg_finder {
+ tlmsg_finder(TLMsg * e) : m_e(e) {};
+ inline bool operator ()(TLMsg * e) { return e == m_e;};
+ TLMsg *m_e;
+ };
+
+ Model();
+ ~Model();
+
+ inline int tl_count() {return m_Timelines.size();};
+ inline TimelineType_const_iterator tl_begin() {return m_Timelines.begin();};
+ inline TimelineType_const_iterator tl_end() {return m_Timelines.end();};
+
+ inline EventType_const_iterator evt_begin() {return m_Events.begin();};
+ inline EventType_const_iterator evt_end() {return m_Events.end();};
+
+ inline short portCsta() { return m_portCsta;};
+ inline short portSip() { return m_portSip; };
+ inline short portXml() { return m_portXml; };
+
+ inline void scroll_to(int x) {m_OnScroll(x);};
+ void parse_sip(const Packet &packet,std::stringstream &is);
+ void parse_ots(const Packet &packet,std::stringstream &is);
+ void parse_csta(const Packet &packet,std::stringstream &is);
+
+ // We should find setter and getters here.
+
+ /**
+ * \brief build a new TimeLine Message. Also inform all views that a new entry has just been created.
+ */
+ void new_TLMsg(const Packet &p,TLMsg **_msg);
+
+ void add_TLMsg(TLMsg *_msg,Timeline &tsl,Timeline &tld);
+
+ bool have_Call(std::string &,int &) const;
+ void clean();
+
+ void select(TLMsg *m);
+
+ void export_msc(const char *fn);
+
+ bool find_timeline(const Timeline &tl,int &distance );
+ // Mvc subscription
+ void subscribe(Observer *o);
+ protected:
+ TimelineType m_Timelines;
+ EventType m_Events;
+ short m_portCsta;
+ short m_portSip;
+ short m_portXml;
+
+ // Calls
+ Calls m_Calls;
+ // Events
+ cleanEvent m_OnClean;
+ addEvent m_OnAdd;
+ selectEvent m_OnSelected;
+ selectEvent m_OnNew;
+ scrollEvent m_OnScroll;
+};
+
+#endif
--- /dev/null
+#ifndef OBSERVER_H__
+#define OBSERVER_H__
+#include "sigslot.h"
+
+class Observer : public sigslot::has_slots<>
+{
+ public:
+ Observer() {};
+ virtual ~Observer() {};
+ virtual void onClean() = 0;
+ virtual void onNew(TLMsg *msg) = 0;
+ virtual void onAdd(TLMsg *msg,Timeline &tls,Timeline &tld) = 0;
+ virtual void onSelected(TLMsg *msg) = 0;
+ virtual void onScroll(int x) = 0;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <pcap/pcap.h>
+
+#include "Packet.h"
+#define __FAVOR_BSD
+#if ! defined(__WIN32__) && ! defined(_WINDOWS)
+#include "netinet/in.h"
+#include "netinet/tcp.h"
+#endif
+#include "SniffHeader.h"
+#define SIZE_ETHERNET 14
+
+#include <string.h>
+#include <stdlib.h>
+
+//#define PAYLOAD_DEBUG
+
+Packet::Packet()
+ : m_managed(false)
+{
+}
+
+Packet::~Packet()
+{
+ if (m_managed)
+ {
+ std::cout<<"Packet::~Packet Release allocated\n";
+ free(mp_data);
+ }
+}
+
+
+Packet::Packet(const unsigned char *d,size_t length)
+ : m_managed(false)
+{
+}
+
+
+Packet::Packet(const Header &header,const unsigned char *data)
+ : m_header(header),
+ mp_data(const_cast<unsigned char *>(data))
+ ,m_managed(false)
+{
+}
+
+Packet::Packet(const Packet &p) : m_header(p.m_header), mp_data(p.mp_data)
+ ,m_managed(false)
+{
+
+}
+
+Packet & Packet::operator =(const Packet &p)
+{
+ if (this != &p)
+ {
+ m_header = p.m_header;
+ mp_data = p.mp_data;
+ }
+ return *this;
+}
+
+const unsigned char *
+Packet::get_payload(long &length)
+{
+ const struct sniff_ethernet *ethernet; /* The ethernet header */
+ const struct sniff_ip *ip; /* The IP header */
+ const struct sniff_tcp *tcp; /* The TCP header */
+ const char unsigned *payload; /* Packet payload */
+ long cooked_header = 0;
+ u_int size_ip;
+ u_int size_tcp;
+
+ // OK cast at the proper position
+
+ if ( ((mp_data[2] == 0x03) && (mp_data[3] == 0x04))
+ ||
+ ((mp_data[14] == 0x08) && (mp_data[15] == 0x00))) {
+ cooked_header = 2;
+#ifdef PAYLOAD_DEBUG
+ std::cout<<"Packet::get_payload Cooked header\n";
+#endif
+ }
+ ethernet = (struct sniff_ethernet*)(mp_data+cooked_header);
+ ip = (struct sniff_ip*)(mp_data + SIZE_ETHERNET+cooked_header);
+ size_ip = IP_HL(ip)*4;
+ if (size_ip < 20) {
+ printf(" * Invalid IP header length: %u bytes\n", size_ip);
+ return NULL;
+ }
+ tcp = (struct sniff_tcp*)(mp_data + SIZE_ETHERNET + size_ip+cooked_header);
+ if (ip->ip_p == 0x06) {
+ size_tcp = TH_OFF(tcp)*4;
+ if (size_tcp < 20) {
+ printf(" * Invalid TCP header length: %u bytes\n", size_tcp);
+ return NULL;
+ }
+ } else if (ip->ip_p == 0x11) { // UDP
+ size_tcp = sizeof(sniff_udp);
+ } else {
+ size_tcp = 0;
+ printf(" * Invalid unkwnow protocol: %u bytes %02x\n", size_tcp,ip->ip_p);
+
+ }
+ payload = (u_char *)(mp_data + SIZE_ETHERNET + size_ip + size_tcp+cooked_header);
+
+ int len = payload -mp_data;
+ length = m_header.len-len;
+ return payload;
+}
+
+const struct sniff_ip *
+Packet::get_ip() const /* The IP header */
+{
+ const struct sniff_ethernet *ethernet; /* The ethernet header */
+ const struct sniff_ip *ip; /* The IP header */
+ const struct sniff_tcp *tcp; /* The TCP header */
+ const char unsigned *payload; /* Packet payload */
+ long cooked_header = 0;
+ u_int size_ip;
+ u_int size_tcp;
+
+ // OK cast at the proper position
+
+ if ( ((mp_data[2] == 0x03) && (mp_data[3] == 0x04))
+ ||
+ ((mp_data[14] == 0x08) && (mp_data[15] == 0x00))) {
+ cooked_header = 2;
+#ifdef PAYLOAD_DEBUG
+ std::cout<<" Cooked header\n";
+#endif
+ }
+ ethernet = (struct sniff_ethernet*)(mp_data+cooked_header);
+ ip = (struct sniff_ip*)(mp_data + SIZE_ETHERNET+cooked_header);
+ size_ip = IP_HL(ip)*4;
+ if (size_ip < 20) {
+ printf(" * Invalid IP header length: %u bytes\n", size_ip);
+ return NULL;
+ }
+ return ip;
+
+}
+
+const struct sniff_tcp *
+Packet::get_tcp() const /* The TCP header */
+{
+ const struct sniff_ethernet *ethernet; /* The ethernet header */
+ const struct sniff_ip *ip; /* The IP header */
+ const struct sniff_tcp *tcp = NULL; /* The TCP header */
+ const char unsigned *payload; /* Packet payload */
+ long cooked_header = 0;
+ u_int size_ip;
+ u_int size_tcp;
+
+ // OK cast at the proper position
+
+ if ( ((mp_data[2] == 0x03) && (mp_data[3] == 0x04))
+ ||
+ ((mp_data[14] == 0x08) && (mp_data[15] == 0x00))) {
+ cooked_header = 2;
+#ifdef PAYLOAD_DEBUG
+ std::cout<<"Packet::get_tcp Cooked header\n";
+#endif
+ }
+ ethernet = (struct sniff_ethernet*)(mp_data+cooked_header);
+ ip = (struct sniff_ip*)(mp_data + SIZE_ETHERNET+cooked_header);
+ size_ip = IP_HL(ip)*4;
+ if (size_ip < 20) {
+ printf(" * Invalid IP header length: %u bytes\n", size_ip);
+ return NULL;
+ }
+ if (ip->ip_p == 0x06) {
+ tcp = (struct sniff_tcp*)(mp_data + SIZE_ETHERNET + size_ip+cooked_header);
+ size_tcp = TH_OFF(tcp)*4;
+ if (size_tcp < 20) {
+ printf(" * Invalid TCP header length: %u bytes\n", size_tcp);
+ return NULL;
+ }
+ }
+
+ return tcp;
+}
+
+
+const struct sniff_udp *
+Packet::get_udp() const /* The TCP header */
+{
+ const struct sniff_ethernet *ethernet; /* The ethernet header */
+ const struct sniff_ip *ip; /* The IP header */
+ const struct sniff_udp *udp = NULL; /* The TCP header */
+ const char unsigned *payload; /* Packet payload */
+ long cooked_header = 0;
+ u_int size_ip;
+ u_int size_udp;
+
+ // OK cast at the proper position
+
+ if ( ((mp_data[2] == 0x03) && (mp_data[3] == 0x04))
+ ||
+ ((mp_data[14] == 0x08) && (mp_data[15] == 0x00))) {
+ cooked_header = 2;
+#ifdef PAYLOAD_DEBUG
+ std::cout<<"Packet::get_udp Cooked header\n";
+#endif
+ }
+ ethernet = (struct sniff_ethernet*)(mp_data+cooked_header);
+ ip = (struct sniff_ip*)(mp_data + SIZE_ETHERNET+cooked_header);
+ size_ip = IP_HL(ip)*4;
+ if (size_ip < 20) {
+ printf(" * Invalid IP header length: %u bytes\n", size_ip);
+ return NULL;
+ }
+ if (ip->ip_p == 0x11) {
+ udp = (struct sniff_udp*)(mp_data + SIZE_ETHERNET + size_ip+cooked_header);
+#if 0
+ size_udp = TH_OFF(tcp)*4;
+ if (size_udp < sizeof(struct_udp)) {
+ printf(" * Invalid UDP header length: %u bytes\n", size_tcp);
+ return NULL;
+ }
+#endif
+ }
+
+ return udp;
+}
+
+void
+Packet::manage()
+{
+ if (m_managed || mp_data == NULL)
+ return;
+ unsigned char * dest = (unsigned char *)malloc(m_header.caplen);
+ memcpy(dest, mp_data,m_header.caplen);
+ mp_data = dest;
+ m_managed = true;
+}
+
+std::string
+Packet::string_srcdst(void)
+{
+ const struct sniff_udp *udp = get_udp();
+ const struct sniff_tcp *tcp = get_tcp();
+ const struct sniff_ip *ip = get_ip();
+ unsigned short sport,dport;
+
+ char buf[128];
+
+ if (udp) {
+ sport = htons(udp->sport);
+ dport = htons(udp->dport);
+ } else if (tcp)
+ {
+ sport = htons(tcp->th_sport);
+ dport = htons(tcp->th_dport);
+ }
+ strcpy(buf,inet_ntoa(ip->ip_src));
+ strcat(buf,":");
+ int len = strlen(buf);
+ sprintf(buf+len,"%d To %s:%d",sport,inet_ntoa(ip->ip_dst),dport);
+
+ std::string result(buf);
+ return result;
+
+
+}
--- /dev/null
+#ifndef __MPACKET_H__
+#define __MPACKET_H__
+#if defined(WIN32) || defined(_WINDOWS)
+#else
+// Only for Unix
+#define __FAVOR_BSD
+#include <netinet/in.h>
+#include "netinet/tcp.h"
+#include <arpa/inet.h>
+#endif
+#include "SniffHeader.h"
+
+#include <pcap/pcap.h>
+
+class Packet {
+ public:
+
+ typedef struct pcap_pkthdr Header;
+
+ Packet();
+ ~Packet();
+ Packet(const Packet &p) ;
+ Packet(const unsigned char *,size_t length);
+ Packet(const Header &header,const unsigned char *data);
+
+ Packet & operator =(const Packet &p);
+
+ inline struct timeval get_timeval() const
+ { return m_header.ts; };
+
+ inline long get_seconds() const
+ { return m_header.ts.tv_sec; };
+
+ inline long get_miliseconds() const
+ { return m_header.ts.tv_usec; };
+
+ inline long get_length() const
+ { return m_header.len; };
+
+ const struct sniff_ip *get_ip() const; /* The IP header */
+ const struct sniff_tcp *get_tcp() const; /* The TCP header */
+ const struct sniff_udp *get_udp() const; /* The TCP header */
+
+ std::string string_srcdst(void);
+ /**
+ * Return data only if available
+ */
+ const unsigned char *get_payload(long &len);
+
+ ///
+ /// @brief keep a local copy of the buffer.
+ ///
+ /// By default, the data are those from the pcap librarie.
+ void manage();
+ protected:
+ Header m_header;
+ unsigned char *mp_data;
+ bool m_managed;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <pcap/pcap.h>
+#include "Pcap.h"
+#include "CstaInsightLog.h"
+
+char Pcap::s_ebuf[PCAP_ERRBUF_SIZE + 1] = "";
+
+Pcap::Pcap(const std::string &file_name)
+ : m_ok(true)
+ ,m_mp_pcap_t(NULL)
+{
+ CI_LOG_DEBUG("Pcap::Pcap with file %s",file_name.c_str());
+ if (! (m_mp_pcap_t = pcap_open_offline(file_name.c_str(),s_ebuf)) )
+ {
+ // error
+ std::cerr<<"Failed open cap file\n";
+ m_ok = false;
+ }
+}
+
+Pcap::~Pcap()
+{
+ CI_LOG_DEBUG("Pcap::~Pcap");
+ if (m_mp_pcap_t)
+ pcap_close(m_mp_pcap_t);
+}
+
+void
+Pcap::set_filter(const std::string &expression)
+{
+ struct bpf_program bpf;
+
+ int ret = pcap_compile(m_mp_pcap_t,&bpf,
+ expression.c_str(),false,0);
+
+ if (ret < 0)
+ {
+ CI_LOG_ERROR("Pcap::set_filter Failed compile expression : %s",expression.c_str());
+ }
+ if (! (ret < 0 ) && pcap_setfilter(m_mp_pcap_t,&bpf) < 0 )
+ {
+ CI_LOG_ERROR("Pcap::set_filter Failed set filter");
+ }
+ pcap_freecode(&bpf);
+
+ m_filter = expression;
+}
+
+//friend
+//
+Pcap &operator>>(Pcap &cap , Packet &packet)
+{
+ static struct pcap_pkthdr *header;
+ static const u_char *data;
+
+ switch( pcap_next_ex(cap.m_mp_pcap_t, const_cast<pcap_pkthdr **>(&header),
+ &data ) )
+ {
+ case 1: // ok
+ packet = Packet(*header,data);
+ break;
+ case -1: //error
+ cap.m_ok = false;
+ break;
+ default: // EOF or expires
+ cap.m_ok = false;
+ ;
+ }
+ return cap;
+
+
+}
+
--- /dev/null
+#ifndef PCAPPP_H__
+#define PCAPPP_H__
+
+#include "Packet.h"
+#include <pcap.h>
+#include <string>
+
+
+class Pcap {
+ public:
+ Pcap(const std::string &f);
+ ~Pcap();
+
+ bool next(Packet &p)
+ { return (*this>>p);};
+
+ friend Pcap &operator>>(Pcap &p,Packet &packet);
+
+
+ void set_filter(const std::string &expression);
+ operator bool() const
+ {
+ return m_ok;
+ };
+ protected:
+ static char s_ebuf[];
+ pcap_t *m_mp_pcap_t;
+ bool m_ok;
+ std::string m_filter;
+ std::string m_filename;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+
+#include "PrivateEla.h"
+
+PrivateEla::PrivateEla(const char *)
+{
+}
+
+PrivateEla::~PrivateEla()
+{
+}
+
--- /dev/null
+#ifndef PRIVATE_ELA_H__
+#define PRIVATE_ELA_H__
+
+
+class PrivateEla {
+ public:
+ PrivateEla(const char *=NULL);
+ ~PrivateEla();
+
+ struct _Cs {
+ unsigned short connCall;
+ unsigned short connNeqt;
+ unsigned short connType;
+ };
+
+ struct Event {
+ unsigned char pType; // Private type
+ unsigned short pId; // Private identifier
+ unsigned long tbd;
+ unsigned long crid; // Crid
+ struct _Cs arr[5]; //
+ char arrS1[25]; // Array of chars
+ char arrS2[25]; // Array of chars
+ unsigned char as1Type;
+ unsigned char as2Type;
+ char arrL1[25]; // Array of chars
+ char arrL2[25]; // Array of chars
+ unsigned char al1Type;
+ unsigned char al2Type;
+ unsigned short line; // Private identifier
+ unsigned short cause; // Private identifier
+ };
+
+ protected:
+
+};
+
+
+
+#endif
--- /dev/null
+#include <iostream>
+#include <cstdio>
+#include <iomanip>
+#include <sstream>
+#include <math.h>
+#include <map>
+// Seems to be included before every thing else.
+#include <pcap/pcap.h>
+
+#include <FL/Fl.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Widget.H>
+#include <FL/Fl_Tree.H>
+#include <FL/Fl_Image.H>
+#include <FL/Fl_Scroll.H>
+#include <FL/Fl_Scrollbar.H>
+
+#if defined(WIN32) || defined(_WIN32) || defined(_WINDOWS)
+#else
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#endif
+#include "Pcap.h"
+
+#include "XMLMessage.h"
+
+#include "TLMsg.h"
+#include <FL/Fl_Text_Editor.H>
+#include <FL/Fl_Text_Buffer.H>
+#include <SequenceView.h>
+#include <FL/fl_draw.H>
+
+#include "Model.h"
+#include "IconFactory.h"
+
+SequenceView::
+SequenceView(int x,int y , int h, int w, const char *l)
+ : Fl_Widget(x,y,h,w,l)
+ ,m_separator(120),
+ m_Model(NULL),
+ m_Editor(NULL),
+ m_Buffer(NULL),
+ m_Selected(NULL),
+ m_Tree(NULL)
+{
+ int crid = 0;
+ unsigned short csta_port = 2555;
+ color(FL_WHITE);
+ Timeline csta(crid,csta_port,"CSTA srv");
+ m_Crids.push_back(csta);
+}
+
+void
+SequenceView::add_event(int crid,Packet &p,const char *name,Fl_Tree_Item *_item)
+{
+ const struct sniff_ip *ip = p.get_ip();
+ const struct sniff_tcp *tcp = p.get_tcp();
+ int dist = 0;
+ TLMsg e(p,"");
+ e.crid = crid;
+ e.name = name;
+ e.item = _item;
+ e.sdistance = 0;
+ short csta_src = 2555;
+ bool found = false;
+ unsigned short dest_port = htons(tcp->th_dport);
+ unsigned short src_port = htons(tcp->th_sport);
+ Timeline tl(crid,dest_port,"");
+ for (CridType_const_iterator it= m_Crids.begin() ;
+ it != m_Crids.end(); ++it)
+ {
+
+ if ((*it) == tl){
+ found = true;
+// std::cout<<"Crid in list\n";
+ break;
+ }
+ dist++;
+ }
+ if (!found)
+ {
+ m_Crids.push_back(tl);
+ }
+ e.distance = dist;
+ m_Events.push_back(e);
+}
+
+void
+SequenceView::add_invoke(Packet &packet,const char *name, Fl_Tree_Item *_item )
+{
+ const struct sniff_ip *ip = packet.get_ip();
+ const struct sniff_tcp *tcp = packet.get_tcp();
+ bool found = false;
+ int dist = 0;
+ int crid = 0;
+ unsigned short dest_port = htons(tcp->th_dport);
+ unsigned short src_port = htons(tcp->th_sport);
+ Timeline tl(crid,dest_port,"");
+ found = find_timeline(tl,dist);
+
+ if (!found)
+ m_Crids.push_back(tl);
+
+ // Add a message in the list
+ TLMsg e(packet,name);
+ e.crid = ip->ip_src.s_addr;
+ e.name = name;
+ e.item = _item;
+ //e.packet = packet;
+ //e.packet.manage();
+ e.distance = dist;
+
+ Timeline tls(crid,src_port,"");
+ if ( ! find_timeline(tls,dist))
+ m_Crids.push_back(tls);
+ e.sdistance = dist;
+
+ m_Events.push_back(e);
+ (m_Events.back()).packet.manage();
+
+}
+
+void
+SequenceView::add_result(Packet &packet,const char *name, Fl_Tree_Item *_item )
+{
+ const struct sniff_ip *ip = packet.get_ip();
+ const struct sniff_tcp *tcp = packet.get_tcp();
+ bool found = false;
+ int dist = 0;
+ int crid = 0;
+ unsigned short dest_port = htons(tcp->th_dport);
+ unsigned short src_port = htons(tcp->th_sport);
+ Timeline tl(crid,dest_port,"");
+ found = find_timeline(tl,dist);
+
+ if (!found)
+ m_Crids.push_back(tl);
+#if 1
+ // Add a message in the list
+ TLMsg e(packet,name);
+ e.crid = ip->ip_src.s_addr;
+ e.name = name;
+ e.item = _item;
+ e.distance = dist;
+
+ Timeline tls(crid,src_port,"");
+ if ( ! find_timeline(tls,dist))
+ m_Crids.push_back(tls);
+ e.sdistance = dist;
+
+ m_Events.push_back(e);
+ (m_Events.back()).packet.manage();
+#endif
+
+}
+
+bool
+SequenceView::find_timeline(const Timeline &tl,int &distance )
+{
+ bool found = false;
+ int dist = 0;
+
+
+ for (CridType_const_iterator it= m_Crids.begin() ;
+ it != m_Crids.end(); ++it)
+ {
+ if ((*it) == tl){
+ found = true;
+ break;
+ }
+ dist++;
+ }
+ distance = dist;
+ return found;
+
+}
+
+void
+SequenceView::add_sip(const char *name,Packet &packet, Fl_Tree_Item *_item )
+{
+ int dist = 0;
+ bool found = false;
+// std::cout<<"SequenceView::add_sip\n";
+ const struct sniff_ip *ip = packet.get_ip();
+
+ Timeline tl(ip->ip_dst,"");
+ found = find_timeline(tl,dist);
+
+ if (!found)
+ m_Crids.push_back(tl);
+#if 1
+ // Add a message in the list
+ TLMsg e;
+ e.tv = packet.get_timeval();
+ e.crid = ip->ip_src.s_addr;
+ e.name = name;
+ e.item = _item;
+ e.packet = packet;
+ //e.packet.manage();
+ e.distance = dist;
+
+ Timeline tls(ip->ip_src,"");
+ if ( ! find_timeline(tls,dist))
+ m_Crids.push_back(tls);
+ e.sdistance = dist;
+
+ m_Events.push_back(e);
+ (m_Events.back()).packet.manage();
+#endif
+}
+
+
+void
+SequenceView::clear()
+{
+ color(FL_WHITE);
+ m_Crids.erase(m_Crids.begin(),m_Crids.end());
+ m_Events.erase(m_Events.begin(),m_Events.end());
+ damage(FL_DAMAGE_ALL);
+ int crid = 0;
+ unsigned short port= 2555;
+ Timeline csta(crid,port,"CSTA srv");
+ m_Crids.push_back(csta);
+}
+
+void SequenceView::resize(int _x, int _y, int w, int h )
+{
+ Fl_Widget::resize(_x,_y,w,h);
+}
+
+void
+SequenceView::draw()
+{
+#if 0
+ if (m_Model) {
+ Fl_Scrollbar *sb = &dynamic_cast<Fl_Scroll *>(this->parent())->hscrollbar;
+ m_Model->scroll_to(sb->value());
+ }
+#endif
+ uchar s = damage();
+ if (s & FL_DAMAGE_ALL) {
+ draw2();
+ } else {
+ //draw2();
+ }
+}
+
+void
+SequenceView::draw1()
+{
+ int new_x = 0;
+ int new_y = 0;
+ int y_base =20;
+ int space = 19;
+ int line = 0,column = 0;
+
+ color(FL_WHITE);
+
+ fl_push_clip(x(),y(),w(),h());
+ fl_push_matrix();
+ fl_translate(x(),y());
+
+ fl_font(0,10);
+ fl_color(FL_BLACK);
+ // Draw crid length
+ for (CridType_const_iterator it = m_Crids.begin();
+ it!= m_Crids.end();
+ ++it)
+ {
+ std::stringstream scrid;
+ // draw text ...
+ fl_draw((*it).name(),x()+130 + column*m_separator,y()-2+y_base);
+ // beginning of line ....
+ fl_begin_line();
+ fl_vertex(150+column*m_separator,y_base);
+ fl_vertex(150+column*m_separator,y_base+h());
+ fl_end_line();
+ column++;
+ }
+ new_y = 19+22;
+ new_x = 150 + column*m_separator + 50;
+ line = 1;
+ for (EventType_const_iterator it = m_Events.begin();
+ it != m_Events.end();
+ ++it)
+ {
+ if ((*it).item && (*it).item->is_selected())
+ {
+ fl_color(FL_RED);
+ } else
+ fl_color(FL_BLUE);
+ // Begin arrow line
+ fl_begin_line();
+ fl_vertex(150+(*it).sdistance*m_separator,y_base+space*line);
+ fl_vertex(150+(*it).distance*m_separator,y_base+space*line);
+ fl_end_line();
+ // Should draw an arrow
+ int delta;
+ if ((*it).sdistance > (*it).distance)
+ {
+ delta = 5;
+ } else
+ delta = -5;
+ fl_begin_line();
+ fl_vertex(150 +delta +(*it).distance*m_separator ,y_base-3+space*line);
+ fl_vertex(150+(*it).distance*m_separator,y_base+space*line);
+ fl_vertex(150 + delta +(*it).distance*m_separator,y_base+3+space*line);
+ fl_end_line();
+ new_y+= space;
+ if ((*it).item && (*it).item->is_selected())
+ {
+ fl_color(FL_RED);
+ } else
+ fl_color(FL_BLACK);
+ // Draw the text
+ std::string ts;
+ tvtostring((*it).get_timeval(),ts);
+ ts = ts ;//+ (*it).name;
+ fl_draw(ts.c_str(),15+x(),y()-2+space*line+y_base);
+ ts = (*it).name;
+ if ((*it).distance > ((*it).sdistance))
+ {
+ fl_draw(ts.c_str(),150+x()+(*it).sdistance*m_separator,y()-2+space*line+y_base);
+ } else
+ {
+ fl_draw(ts.c_str(),150+x()+(*it).distance*m_separator,y()-2+space*line+y_base);
+ }
+ line++;
+ }
+
+ fl_pop_matrix();
+ fl_pop_clip();
+ if (new_x < w())
+ new_x = w();
+ if (new_y < h())
+ new_y = h();
+ size(new_x,new_y);
+}
+
+
+void
+SequenceView::draw2()
+{
+ int new_x = 0;
+ int new_y = 0;
+ int y_base =20;
+ int space = 19;
+ int line = 0,column = 0;
+
+ color(FL_WHITE);
+
+ fl_push_clip(x(),y(),w(),h());
+ fl_push_matrix();
+ fl_translate(x(),y());
+
+ fl_font(0,10);
+ fl_color(FL_BLACK);
+ // Draw crid length
+ for (Model::TimelineType_const_iterator it = m_Model->tl_begin();
+ it!= m_Model->tl_end();
+ ++it)
+ {
+ std::stringstream scrid;
+ // draw text ...
+ fl_draw((*it).name(),x()+130 + column*m_separator,y()-2+y_base);
+ // beginning of line ....
+ fl_begin_line();
+ fl_vertex(150+column*m_separator,y_base);
+ fl_vertex(150+column*m_separator,y_base+h());
+ fl_end_line();
+ column++;
+ }
+ new_y = 19+22;
+ new_x = 150 + column*m_separator + 50;
+ line = 1;
+ for (Model::EventType_const_iterator it = m_Model->evt_begin();
+ it != m_Model->evt_end();
+ ++it)
+ {
+ int id;
+ // Draw Background box
+ if (m_Model->have_Call((*it)->m_callid,id)) {
+ struct col {
+ unsigned char r;
+ unsigned char g;
+ unsigned char b;
+ } col[] = {
+ {0xAA,0xAA,0xAA},
+ {0xAA,0xFF,0xFF},
+ {0xAA,0xFF,0x00},
+ {0xFF,0x00,0x88},
+ {0x55,0xAA,0x55}
+ } ;
+ fl_rectf(x(),y()+space*(line)+5,150+new_x,space,col[id].r,col[id].g,col[id].b) ;
+ } else {
+ fl_rectf(x(),y()+space*(line)+5,150+new_x,space,0xFF,0xFF,0xFF) ;
+ }
+ if ((*it) == m_Selected)
+ {
+ fl_color(FL_RED);
+ } else
+ fl_color(FL_BLUE);
+ // Begin arrow line
+ fl_begin_line();
+ fl_vertex(150+(*it)->sdistance*m_separator,y_base+space*line);
+ fl_vertex(150+(*it)->distance*m_separator,y_base+space*line);
+ fl_end_line();
+ // Should draw an arrow
+ int delta;
+ if ((*it)->sdistance > (*it)->distance)
+ {
+ delta = 5;
+ } else
+ delta = -5;
+ fl_begin_line();
+ fl_vertex(150 +delta +(*it)->distance*m_separator ,y_base-3+space*line);
+ fl_vertex(150+(*it)->distance*m_separator,y_base+space*line);
+ fl_vertex(150 + delta +(*it)->distance*m_separator,y_base+3+space*line);
+ fl_end_line();
+ new_y+= space;
+ if ((*it)->item && (*it)->item->is_selected())
+ {
+ fl_color(FL_RED);
+ } else
+ fl_color(FL_BLACK);
+ // Draw the text
+ std::string ts;
+ tvtostring((*it)->get_timeval(),ts);
+ ts = ts ;//+ (*it).name;
+ fl_draw(ts.c_str(),15+x(),y()-2+space*line+y_base);
+ ts = (*it)->name;
+ if ((*it)->distance > ((*it)->sdistance))
+ {
+ fl_draw(ts.c_str(),150+x()+(*it)->sdistance*m_separator,y()-2+space*line+y_base);
+ } else
+ {
+ fl_draw(ts.c_str(),150+x()+(*it)->distance*m_separator,y()-2+space*line+y_base);
+ }
+ line++;
+ }
+ // Redraw lines
+ column = 0;
+ fl_color(FL_BLACK);
+ fl_line_style(FL_DASH);
+ // Draw crid length
+ for (Model::TimelineType_const_iterator it = m_Model->tl_begin();
+ it!= m_Model->tl_end();
+ ++it)
+ {
+ // beginning of line ....
+ fl_begin_line();
+ fl_vertex(150+column*m_separator,y_base);
+ fl_vertex(150+column*m_separator,y_base+h());
+ fl_end_line();
+ column++;
+ }
+ fl_line_style(0);
+
+ fl_pop_matrix();
+ fl_pop_clip();
+ if (new_x < w())
+ new_x = w();
+ if (new_y < h())
+ new_y = h();
+ size(new_x,new_y);
+}
+
+void SequenceView::tvtostring(struct timeval v,std::string &s)
+{
+ time_t t = v.tv_sec;
+ char buf[22];
+ std::stringstream ss;
+ struct tm *tm = localtime(&t);
+ memset(buf,0x00,22);
+#ifdef WIN32
+ strftime(buf,21,"%y-%m-%d %H:%M:%S",tm);
+#else
+ strftime(buf,21,"%F %H:%M:%S",tm);
+#endif
+ long milliseconds = v.tv_usec /1000;
+ ss<<buf<<"."<<std::setw(3)<<std::setfill('0')<<std::right<<milliseconds<<" ";
+ s.assign(ss.str());
+}
+
+/**
+ *
+ */
+void SequenceView::model(Model *m)
+{
+ m_Model = m;
+ m->subscribe(this);
+};
+
+int SequenceView::handle(int e)
+{
+ int X = x(); int Y = y(); int W = w(); int H = h();
+ int dx = Fl::event_x() - X;
+ int dy = Fl::event_y() - Y;
+ switch(e)
+ {
+ case FL_NO_EVENT:
+ break;
+ case FL_DRAG:
+ {
+ //printf("SequenceView::handle drag %d dx=%d\n",e,dx);
+ return 1;
+ }
+ break;
+ case FL_PUSH:
+ {
+ Fl_Scrollbar *sb = &dynamic_cast<Fl_Scroll *>(this->parent())->scrollbar;
+ if (sb) {
+ int y_base = 19;
+ int lines = 1;
+ for (Model::EventType_const_iterator it = m_Model->evt_begin();
+ it != m_Model->evt_end();
+ ++it)
+ {
+ if ( (dy > y_base * lines ) && dy < (y_base *(lines + 1)) ) {
+ //printf("Found : %s\n",(*it)->name.c_str());
+ m_Model->select((*it));
+ this->parent()->redraw();
+ break;
+ }
+ if (dy > y_base) {
+ lines++;
+ } else
+ break;
+ }
+ }
+ }
+ if (callback() && (when() & FL_WHEN_CHANGED))
+ do_callback();
+ return 1;
+ break;
+ case FL_RELEASE:
+ // printf("SequenceView::handle release %d\n",e);
+ this->parent()->redraw();
+ if (callback() && (when() & FL_WHEN_CHANGED))
+ do_callback();
+ return 1;
+ break;
+ case FL_MOVE:
+ //printf("SequenceView::handle move %d\n",e);
+ break;
+ case FL_ENTER:
+ case FL_LEAVE:
+ if (m_Model) {
+ Fl_Scrollbar *sb = &dynamic_cast<Fl_Scroll *>(this->parent())->hscrollbar;
+ m_Model->scroll_to(sb->value());
+ }
+ return 1;
+ break;
+ case FL_SHOW:
+ break;
+ default:
+ //printf("SequenceView::handle %d\n",e);
+ ;
+ }
+ return Fl_Widget::handle(e);
+}
+
+void SequenceView::onSelected(TLMsg *s)
+{
+ m_Selected = s;
+ m_Editor->scroll(s->line()+1,0);
+ // Find item in Tree
+ Fl_Tree_Item *item = m_Tree->first();
+ do {
+ if (item->user_data() == s) {
+ m_Tree->select_only(item,0); // Don't call callback. infinit loop
+ break;
+ }
+ } while ((item = m_Tree->next(item)) != NULL);
+
+ redraw();
+}
+
+/**
+ * The name of tree items must be unique.
+ */
+static int counter = 0;
+
+void SequenceView::onClean()
+{
+ counter = 0;
+ damage(FL_DAMAGE_ALL);
+}
+
+void SequenceView::onNew(TLMsg *s)
+{
+
+}
+
+void SequenceView::onAdd(TLMsg *msg,Timeline &tsl,Timeline &tld)
+{
+ std::stringstream ss; //Used for output
+ Fl_Tree_Item * item = NULL;
+ if (msg)
+ {
+// std::cout<<"SequenceView::onAdd "<<msg->name<<std::endl;
+ if (msg->name.size() > 1)
+ {
+ if ( msg->name.size() < 4)
+ {
+ m_CurrentTreeItem = item = m_Tree->add("undefined");
+ } else
+ {
+ ss<<msg->name<<" "<<counter;
+ counter++;
+ m_CurrentTreeItem = item = m_Tree->add(ss.str().c_str());
+ }
+ int lines = m_Editor->count_lines(0,m_Editor->buffer()->length(),1);
+ /*
+ * As said, the string used by add must be unique.
+ */
+ if (item)
+ {
+ item->user_data((void *)msg);
+ } else
+ {
+ std::cerr<<"SequenceView::onAdd item is NULL msg.name.size : "<<msg->name.size()<<std::endl;
+ }
+ msg->line(lines);
+ ss<<"== "<<msg->packet.string_srcdst()<<" =="<<std::endl;
+ // Here, I should add the decoded content
+ if (msg->msg_type() != TLMsg::SIP)
+ ss<<msg->name<<std::endl;
+ ss<<msg->m_content;
+ m_Editor->insert(ss.str().c_str());
+ }
+ switch (msg->msg_type())
+ {
+ case TLMsg::CSTA_REQUEST:
+ if (item)
+ item->usericon(IconFactory::get_Icon("Request_16.png"));
+ break;
+ case TLMsg::CSTA_RESPONSE:
+ if (item)
+ item->usericon(IconFactory::get_Icon("Response_16.png"));
+ break;
+ case TLMsg::CSTA_RESPONSE_ERROR:
+ if (item)
+ item->usericon(IconFactory::get_Icon("ResponseError_16.png"));
+ break;
+ case TLMsg::CSTA_REJECT:
+ if (item)
+ item->usericon(IconFactory::get_Icon("ResponseReject_16.png"));
+ break;
+ case TLMsg::CSTA_EVENT:
+ if (item)
+ item->usericon(IconFactory::get_Icon("Lighting_16.png"));
+ break;
+ case TLMsg::SOAP_REQUEST:
+ {
+ if (item)
+ {
+ size_t found = 0;
+ item->usericon(IconFactory::get_Icon("RequestSoap_16.png"));
+ XMLMessage xmlmsg(m_Tree,item);
+ xmlmsg.Create();
+
+ void *p = xmlmsg.GetBuffer(msg->m_content.size());
+ if ( (found =msg->m_content.find("<?xml version=")) != std::string::npos)
+ {
+ strncpy((char *)p,msg->m_content.substr(found).c_str(),msg->m_content.size()-found);
+ xmlmsg.ParseBuffer(msg->m_content.size()-found);
+ }
+
+ }
+ break;
+ }
+ case TLMsg::SOAP_RESPONSE:
+ if (item)
+ {
+ size_t found = 0;
+ item->usericon(IconFactory::get_Icon("ResponseSoap_16.png"));
+ XMLMessage xmlmsg(m_Tree,item);
+ xmlmsg.Create();
+
+ void *p = xmlmsg.GetBuffer(msg->m_content.size());
+ if ( (found =msg->m_content.find("<?xml version=")) != std::string::npos)
+ {
+ strncpy((char *)p,msg->m_content.substr(found).c_str(),msg->m_content.size()-found);
+ xmlmsg.ParseBuffer(msg->m_content.size()-found);
+ }
+ }
+ break;
+ case TLMsg::SIP:
+ if (item)
+ {
+ size_t found = 0;
+ item->usericon(IconFactory::get_Icon("Sip_16.png"));
+ if ( (found =msg->m_content.find("<?xml version=")) != std::string::npos)
+ {
+ XMLMessage xmlmsg(m_Tree,item);
+ xmlmsg.Create();
+ void *p = xmlmsg.GetBuffer(msg->m_content.size());
+ strncpy((char *)p,msg->m_content.substr(found).c_str(),msg->m_content.size()-found);
+ xmlmsg.ParseBuffer(msg->m_content.size()-found);
+ }
+ }
+ break;
+ case TLMsg::ICS_EVENT:
+ if (item)
+ {
+ size_t found = 0;
+ item->usericon(IconFactory::get_Icon("Lighting_16.png"));
+ XMLMessage xmlmsg(m_Tree,item);
+ xmlmsg.Create();
+
+ void *p = xmlmsg.GetBuffer(msg->m_content.size());
+ if ( (found =msg->m_content.find("<?xml version=")) != std::string::npos)
+ {
+ strncpy((char *)p,msg->m_content.substr(found).c_str(),msg->m_content.size()-found);
+ xmlmsg.ParseBuffer(msg->m_content.size()-found);
+ }
+ }
+ break;
+ default:
+ ;
+ };
+ } else
+ {
+// std::cout<<"SequenceView::onAdd"<<std::endl;
+ ;
+ }
+ damage(FL_DAMAGE_ALL);
+ this->parent()->redraw();
+ m_Tree->parent()->redraw();
+}
--- /dev/null
+#ifndef __SEQ_VIEW_H__
+#define __SEQ_VIEW_H__
+#include <iostream>
+#include <string>
+#include <vector>
+#include <stdlib.h>
+#include <time.h>
+
+#if defined(__WIN32__) || defined(_WINDOWS)
+#include <pcap/pcap.h>
+#endif
+#include <FL/Fl.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Widget.H>
+#include <FL/Fl_Tree.H>
+#include "Timeline.h"
+// Packet information ...
+#if defined(__WIN32__) ||defined(_WINDOWS)
+#else
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#endif
+#include "Pcap.h"
+
+#include "sigslot.h"
+#include "TLMsg.h"
+#include "Observer.h"
+/**
+ */
+
+class Model;
+
+class SequenceView : public Fl_Widget ,public Observer
+ //,public sigslot::multi_threaded_local
+{
+ public:
+
+ typedef std::vector<Timeline> CridType;
+ typedef std::vector<Timeline>::const_iterator CridType_const_iterator;
+ typedef std::vector<TLMsg> EventType;
+ typedef std::vector<TLMsg>::const_iterator EventType_const_iterator;
+
+ SequenceView(int x,int y , int h, int w, const char *l=NULL);
+
+ void draw();
+ void draw1(); // Old way
+
+ void draw2(); // New way
+
+ int handle(int event);
+ void clear();
+
+ void resize(int x, int y, int w, int h );
+
+ void add_event(int crid,Packet &p,const char *name, Fl_Tree_Item *_item = NULL);
+ void add_invoke(Packet &packet,const char *name, Fl_Tree_Item *_item = NULL);
+ void add_result(Packet &packet,const char *name, Fl_Tree_Item *_item = NULL);
+ void add_sip(const char *name,Packet &packet, Fl_Tree_Item *_item = NULL);
+
+ inline void tree(Fl_Tree *t) {m_Tree = t;};
+ inline void editor(Fl_Text_Editor *t) {m_Editor = t;};
+
+ bool find_timeline(const Timeline &tl,int &distance );
+
+ void model(Model *m);
+
+ void onClean();
+ void onNew(TLMsg *);
+ void onAdd(TLMsg *,Timeline &tsl,Timeline &tld);
+ void onSelected(TLMsg *);
+ void onScroll(int x) { };
+ protected:
+ void tvtostring(struct timeval t,std::string &s);
+
+ protected:
+ CridType m_Crids;
+ EventType m_Events;
+
+ TLMsg *m_Selected;
+ long m_separator;
+ int m_new_x;
+ int m_new_y;
+ Fl_Tree *m_Tree;
+ Fl_Tree_Item *m_CurrentTreeItem;
+ Fl_Text_Editor *m_Editor;
+ Fl_Text_Buffer *m_Buffer;
+ Model *m_Model;
+};
+
+#endif
+//
+//
+//
--- /dev/null
+#ifndef __SNIFF_HEADER_H__
+#define __SNIFF_HEADER_H__
+
+/* Ethernet addresses are 6 bytes */
+#define ETHER_ADDR_LEN 6
+
+ /* Ethernet header */
+ struct sniff_ethernet {
+ u_char ether_dhost[ETHER_ADDR_LEN]; /* Destination host address */
+ u_char ether_shost[ETHER_ADDR_LEN]; /* Source host address */
+ u_short ether_type; /* IP? ARP? RARP? etc */
+ };
+
+ /* IP header */
+ struct sniff_ip {
+ u_char ip_vhl; /* version << 4 | header length >> 2 */
+ u_char ip_tos; /* type of service */
+ u_short ip_len; /* total length */
+ u_short ip_id; /* identification */
+ u_short ip_off; /* fragment offset field */
+ #define IP_RF 0x8000 /* reserved fragment flag */
+ #define IP_DF 0x4000 /* dont fragment flag */
+ #define IP_MF 0x2000 /* more fragments flag */
+ #define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
+ u_char ip_ttl; /* time to live */
+ u_char ip_p; /* protocol */
+ u_short ip_sum; /* checksum */
+ struct in_addr ip_src,ip_dst; /* source and dest address */
+ };
+ #define IP_HL(ip) (((ip)->ip_vhl) & 0x0f)
+ #define IP_V(ip) (((ip)->ip_vhl) >> 4)
+
+ /* TCP header */
+ struct sniff_tcp {
+ u_short th_sport; /* source port */
+ u_short th_dport; /* destination port */
+#ifdef WIN32
+ unsigned long th_seq; /* sequence number */
+ unsigned long th_ack; /* acknowledgement number */
+#else
+ tcp_seq th_seq; /* sequence number */
+ tcp_seq th_ack; /* acknowledgement number */
+#endif
+ u_char th_offx2; /* data offset, rsvd */
+ #define TH_OFF(th) (((th)->th_offx2 & 0xf0) >> 4)
+ u_char th_flags;
+ #define TH_FIN 0x01
+ #define TH_SYN 0x02
+ #define TH_RST 0x04
+ #define TH_PUSH 0x08
+ #define TH_ACK 0x10
+ #define TH_URG 0x20
+ #define TH_ECE 0x40
+ #define TH_CWR 0x80
+ #define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
+ u_short th_win; /* window */
+ u_short th_sum; /* checksum */
+ u_short th_urp; /* urgent pointer */
+};
+
+struct sniff_udp {
+ u_short sport;
+ u_short dport;
+ u_short length;
+ u_short checksum;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <string>
+#include <vector>
+#include <stdlib.h>
+#include <time.h>
+
+#if defined(_WINDOWS)
+#include <pcap/pcap.h>
+#endif
+#include <FL/Fl.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Widget.H>
+#include <FL/Fl_Tree.H>
+
+#include <CstaInsightLog.h>
+
+#if ! defined(__WIN32__) && ! defined(_WINDOWS)
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#endif
+
+#include "Pcap.h"
+#include "TLMsg.h"
+
+TLMsg::TLMsg(const Packet &p,const std::string &_name)
+ : packet(p), name(_name),item(NULL),m_callid(""),m_Type(TLMsg::UNKNOWN)
+{
+}
+
+TLMsg::TLMsg(const TLMsg &t)
+{
+ name = t.name;
+ distance = t.distance;
+ sdistance = t.sdistance;
+ packet = t.packet;
+ crid = t.crid;
+ item = t.item;
+ m_callid = t.m_callid;
+ m_Type = t.m_Type;
+}
+
+TLMsg::~TLMsg()
+{
+ CI_LOG_DEBUG("TLMsg::~TLMsg %s",name.c_str());
+}
+
+void
+TLMsg::set_distance(int source,int dest)
+{
+ sdistance = source;
+ distance = dest;
+}
--- /dev/null
+#ifndef TIMELINE_MSG_H__
+#define TIMELINE_MSG_H__
+
+/**
+ * TimelineMsg class represents one line in the sequence diagram.
+ *
+ * For now, all attributes are public but they need to be made protected.
+ * The value tv can directly be extracated from the Packet Class.
+ *
+ *
+ */
+class TLMsg {
+ public:
+
+ enum eMsgType {
+ SIP,
+ CSTA_REQUEST,
+ CSTA_RESPONSE,
+ CSTA_EVENT,
+ CSTA_RESPONSE_ERROR,
+ CSTA_REJECT,
+ SOAP_REQUEST,
+ SOAP_RESPONSE,
+ ICS_EVENT,
+ UNKNOWN
+ };
+ inline eMsgType msg_type() { return m_Type;};
+ inline void msg_type(eMsgType t) {m_Type = t; };
+
+ // The Distance in stored in a pair where first is source and second dest.
+ typedef std::pair<int,int> Distance;
+
+ TLMsg() : item(NULL) {};
+
+ TLMsg(const Packet &p,const std::string &_name);
+
+ TLMsg(const TLMsg &t);
+ ~TLMsg();
+
+ inline struct timeval get_timeval() const {return packet.get_timeval();};
+
+ Distance get_distance() const {return Distance(sdistance,distance);};
+
+ void set_distance(int source,int dest);
+ // Title settings
+ inline void title(const std::string &s) {m_title = s;};
+ inline const char * title(void) {return m_title.c_str();};
+
+ inline void line(int l ) {m_line = l;};
+ inline int line(void) {return m_line;};
+
+ inline void call_id(const std::string &s) {m_callid = s;};
+ inline std::string call_id() {return m_callid;};
+ eMsgType m_Type;
+ std::string name;
+ int crid; // Destination of the message. Crid was used because at the begining, only CSTA was concerned
+ int distance; // Distance from 0 to Crid is not enough for sip messages.
+ int sdistance; // By default, sdistance is 0
+ struct timeval tv;
+ // What to when sip with source and destination ?
+ Packet packet;
+ std::string m_title; // Title of the message will be different from core message
+ std::string m_callid; // Callid used to color line depending on call
+ Fl_Tree_Item *item; // This must disapear
+ int m_line; // Save the position of the text for this line.
+ std::string m_content; // Content to be displayed
+} ;
+
+
+#endif
--- /dev/null
+#ifndef TLMSGCSTA_H__
+#define TLMSGCSTA_H__
+
+class TLMsgCsta : public TLMsg
+{
+ public:
+ TLMsgCsta();
+ TLMsgCsta(
+ long crid,
+ long eventType,
+ Remote_Operations_Information_Objects::IOBJECT_TYPE *event_obj);
+ ~TLMsgCsta();
+
+
+};
+
+#endif
--- /dev/null
+#ifndef TLMSGSIP_H__
+#define TLMSGSIP_H__
+
+class TLMsgSip : public TLMsg
+{
+ public:
+ TLMsgSip();
+ TLMsgSip(const TLMsgSip &_m);
+ ~TLMsgSip();
+ protected:
+};
+
+#endif
--- /dev/null
+#ifndef TLMSGXML_H__
+#define TLMSGXML_H__
+
+
+class TLMsgXml : public TLMsg
+{
+ public:
+ TLMsgXml();
+ ~TLMsgXml();
+
+ protected:
+};
+#endif
--- /dev/null
+#include <iostream>
+#include <sstream>
+
+#ifdef WIN32
+#include <winsock2.h>
+#else
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#endif
+#include "Timeline.h"
+
+Timeline::Timeline(int crid, const char *name)
+ : m_crid(crid), m_port(0),m_name(name),m_type(TL_CRID)
+{
+ if (m_name.size() < 2)
+ {
+ std::stringstream ss;
+ ss<<"Crid<"<<crid<<">";
+ m_name = ss.str();
+ }
+}
+
+Timeline::Timeline(int crid, unsigned short port,const char *name)
+ : m_crid(crid), m_port(port),m_name(name),m_type(TL_CRID_PORT)
+{
+ if (m_name.size() < 2)
+ {
+ std::stringstream ss;
+ ss<<"Crid<"<<crid<<">{"<<port<<"}";
+ m_name = ss.str();
+ }
+}
+
+
+Timeline::Timeline(unsigned short port, const char *name)
+ : m_crid(0),m_port(port), m_name(name),m_type(TL_PORT)
+{
+ if (m_name.size() < 2)
+ {
+ std::stringstream ss;
+ ss<<"Crid<"<<m_crid<<">("<<port<<")";
+ m_name = ss.str();
+ }
+}
+
+
+Timeline::Timeline(struct in_addr crid, const char *name)
+ : m_crid((int)crid.s_addr), m_port(0),m_name(name),m_type(TL_IP)
+{
+ if (m_name.size() < 2)
+ {
+ std::stringstream ss;
+ ss<<"@<"<<inet_ntoa(crid)<<">";
+ m_name = ss.str();
+ }
+}
+
+
+Timeline::Timeline(const Timeline &t)
+{
+ m_crid = t.m_crid;
+ m_name = t.m_name;
+ m_type = t.m_type;
+ m_port = t.m_port;
+ m_device = t.m_device;
+}
+
+Timeline::~Timeline()
+{
+}
+
+bool
+Timeline::operator ==(const Timeline &_t) const
+{
+ if (m_type == TL_CRID)
+ {
+ return (m_crid == _t.m_crid);
+ } else if (m_type == TL_CRID_PORT && _t.m_type == TL_CRID)
+ {
+ return (m_crid == _t.m_crid);
+ } else if (m_type == TL_CRID_PORT && _t.m_type == TL_CRID_PORT)
+ {
+ return ((m_port == _t.m_port) &&
+ (m_crid == _t.m_crid)
+ );
+ } else if (m_type == TL_CRID_PORT && _t.m_type == TL_PORT)
+ {
+ return ((m_port == _t.m_port)
+ );
+ } else if (m_type == TL_PORT && _t.m_type == TL_CRID_PORT)
+ {
+ return ((m_port == _t.m_port)
+ );
+ } else if (m_type == TL_IP && _t.m_type == TL_IP)
+ {
+ return ((m_crid == _t.m_crid)
+ );
+ } else if (m_type == TL_PORT && _t.m_type == TL_PORT)
+ {
+ return ((m_port == _t.m_port)
+ );
+ }else
+ return false;
+}
+
+
+bool
+Timeline::operator ==(const struct in_addr &_t) const
+{
+ return (m_crid == _t.s_addr) && (m_type == TL_IP);
+}
+
+bool
+Timeline::operator ==(short _t) const
+{
+ return (m_port == _t) && (
+ (m_type == TL_PORT)
+ ||(m_type == TL_CRID_PORT));
+}
--- /dev/null
+#ifndef __TIMELINE_H__
+#define __TIMELINE_H__
+
+class Timeline {
+ public:
+ enum {
+ TL_CRID,
+ TL_CRID_PORT,
+ TL_PORT, // from one IP port to another
+ TL_IP
+ };
+ Timeline (int crid,const char *name=NULL);
+ Timeline (int crid,unsigned short port,const char *name=NULL);
+ Timeline (unsigned short port,const char *name=NULL);
+ Timeline (struct in_addr crid,const char *name=NULL);
+ Timeline (const Timeline &t);
+ virtual ~Timeline();
+
+ inline const char *name() const {return m_name.c_str();};
+
+ inline void set_device(std::string &_d) { m_device = _d;};
+ inline void get_device(std::string &_d) const { _d = m_device;};
+
+ bool operator ==(const Timeline &_t) const;
+ bool operator ==(short _t) const;
+ bool operator ==(const struct in_addr &_t) const;
+
+ protected:
+ std::string m_name;
+ int m_crid; // In case the time lines belongs to csta events
+ int m_type;
+ unsigned short m_port;
+ std::string m_device; // Device number. If available not null.
+};
+
+#endif
--- /dev/null
+#ifndef XMLMESSAGES_H__
+#define XMLMESSAGES_H__
+
+#include <iostream>
+#include <string>
+#include <vector>
+#include <stack>
+#include <stdlib.h>
+#include <time.h>
+
+#include <FL/Fl.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Widget.H>
+#include <FL/Fl_Tree.H>
+
+#include "CExpatImpl.h"
+/**
+ * \brief This class is used to parse ics events and soap requests.
+ * The parse request will be put in a tree
+ */
+class XMLMessage : public CExpatImpl<XMLMessage>
+{
+ public:
+ XMLMessage(Fl_Tree *tree,Fl_Tree_Item *item) :m_tree(tree),m_item(item){
+ m_stack.push(item);
+ item->close();
+ };
+ ~XMLMessage() {};
+
+ void OnPostCreate()
+ {
+ // Enable all the event routines we want
+ EnableStartElementHandler ();
+ EnableEndElementHandler ();
+ // Note: EnableElementHandler will do both start and end
+ EnableCharacterDataHandler ();
+ }
+
+ virtual void OnStartElement (const XML_Char *pszName,
+ const XML_Char **papszAttrs)
+ {
+ m_stack.push(m_tree->add(m_stack.top(),pszName));
+ return;
+ }
+
+ // @cmember End element handler
+
+ virtual void OnEndElement (const XML_Char *pszName)
+ {
+ m_stack.pop();
+ return;
+ }
+
+ // @cmember Character data handler
+
+ virtual void OnCharacterData (const XML_Char *pszData, int nLength)
+ {
+ std::string old(m_stack.top()->label());
+ std::string toadd(pszData,nLength);
+ old+= " ";
+ old+=toadd;
+ m_stack.top()->label(old.c_str());
+ return;
+ }
+
+
+ protected:
+ Fl_Tree *m_tree; // The tree were to inserr sub elements
+ Fl_Tree_Item *m_item; // Base Itesm
+ std::stack<Fl_Tree_Item *> m_stack;
+};
+#endif
--- /dev/null
+# data file for the Fltk User Interface Designer (fluid)
+version 1.0300
+header_name {.h}
+code_name {.cxx}
+decl {\#include <iostream>} {public global
+}
+
+decl {\#include <fstream>} {public global
+}
+
+decl {\#include <string.h>} {public global
+}
+
+decl {\#include <sstream>} {private global
+}
+
+decl {\#include <map>} {public global
+}
+
+decl {\#include <algorithm>} {private global
+}
+
+decl {\#include <stack>} {public global
+}
+
+declblock {\#if defined(__WIN32__) ||defined (_WINDOWS)} {public after {\#endif}
+} {
+ decl {\#include <pcap/pcap.h>} {public global
+ }
+}
+
+decl {\#include "XMLMessage.h"} {public global
+}
+
+decl {\#include "Pcap.h"} {public global
+}
+
+decl {\#include <FL/Fl_File_Chooser.H>} {private global
+}
+
+decl {\#include <FL/Fl_PNG_Image.H>} {public local
+}
+
+decl {\#include <FL/Fl_Text_Editor.H>} {public local
+}
+
+decl {\#include <FL/Fl_Text_Buffer.H>} {public local
+}
+
+decl {\#include "CstaInsightLog.h"} {public global
+}
+
+declblock {\#if defined(__WIN32__) ||defined (_WINDOWS)} {public after {\#endif}
+} {
+ decl {\#include <pcap/pcap.h>} {public global
+ }
+ decl {\#else} {public global
+ }
+ decl {\#include <netinet/in.h>} {public global
+ }
+ decl {\#include <arpa/inet.h>} {public global
+ }
+}
+
+decl {\#include "rtasn1/asn1.h"} {
+ comment {// Asn1 stuff} private local
+}
+
+decl {\#include "rtasn1/asn1_codec.h"} {private global
+}
+
+decl {\#include "rtasn1/asn1_codec_ber.h"} {private local
+}
+
+decl {\#include "Rose_Apdu.h"} {
+ comment {// CSTA stubs} public global
+}
+
+decl {\#include "CSTA_event.h"} {public global
+}
+
+decl {\#include "SequenceView.h"} {public global
+}
+
+decl {\#include "HeaderView.h"} {public global
+}
+
+decl {\#include "Model.h"} {
+ comment {// Model View Controler files} public global
+}
+
+decl {\#include "Controler.h"} {public global
+}
+
+decl {Fl_File_Chooser *fc;} {
+ comment {// File Chooser} private local
+}
+
+class MainUI {open
+} {
+ Function {MainUI()} {} {
+ code {m_Buffer = new Fl_Text_Buffer(1024*16);\r
+m_Model = new Model();\r
+m_Controler = new Controler(m_Model);} {}
+ }
+ Function {make_window()} {open
+ } {
+ Fl_Window m_Window {
+ label {CSTA Insight} open
+ xywh {815 139 1035 855} type Double resizable
+ code0 {fc = new Fl_File_Chooser(".","*",Fl_File_Chooser::SINGLE,"Select OmniPCX Office CSTA stream");} visible
+ } {
+ Fl_Menu_Bar {} {open
+ xywh {0 0 1035 22}
+ } {
+ Submenu {} {
+ label {&File}
+ xywh {0 0 100 20} labelsize 12
+ } {
+ MenuItem {} {
+ label {&Open}
+ callback {int i;\r
+int count = 0;\r
+char relative[FL_PATH_MAX];\r
+\r
+fc->show();\r
+\r
+while(fc->visible() )\r
+{\r
+ Fl::wait();\r
+}\r
+\r
+count = fc->count();\r
+std::cout<<"Got count = "<<count<<"\\n";\r
+\r
+if (count > 0)\r
+{\r
+ for (i = 0 ; i < count; i++)\r
+ {\r
+ if (!fc->value(i))\r
+ break;\r
+ fl_filename_relative(relative,sizeof(relative),fc->value(i));\r
+ std::cout<<" Selected : "<<relative<<std::endl;\r
+ if (strstr(fc->value(i),".pcap"))\r
+ {\r
+ char *pos = (char *)strstr(fc->value(i),".pcap");\r
+ m_current_filename = relative;\r
+\#ifndef __WIN32__\r
+ while (*pos != '/')\r
+ pos--;\r
+\#endif\r
+ pos++;\r
+ std::cout<<"Process PCAP file :"<<fc->value(i)<<std::endl;\r
+ if (!tree->root())\r
+ {\r
+ tree->add("ROOT");\r
+ }\r
+ tree->root_label(pos);\r
+ m_Controler->load(relative);\r
+// do_pcap(relative);\r
+ } else {\r
+ std::cout<<"Unsuported format\\n";\r
+ }\r
+ \r
+ }\r
+}\r
+\r
+char iPath[100];\r
+\r
+Fl_Preferences app(Fl_Preferences::USER,"CSTASpy","main");\r
+Fl_Preferences Cfg(app,m_current_filename.c_str());\r
+Cfg.get("filter",iPath,m_InputChoice->value(),99);\r
+m_InputChoice->value(iPath);\r
+//Cfg.set("filter",m_InputChoice->value());}
+ xywh {0 0 100 20} labelsize 12
+ }
+ MenuItem {} {
+ label {&Close}
+ callback {tree->clear_children(tree->root());\r
+m_Controler->close();\r
+tree->root_label("ROOT");\r
+m_Sequence->clear();\r
+tree->redraw();\r
+m_Sequence->redraw();\r
+m_Scroll->redraw();\r
+m_Editor->buffer()->remove(0,m_Editor->buffer()->length());}
+ xywh {0 0 100 20} labelsize 12 divider
+ }
+ MenuItem {} {
+ label {&Export XMI}
+ xywh {0 0 100 20} labelsize 12
+ }
+ MenuItem {} {
+ label {Export Msc}
+ callback {int i;\r
+int count = 0;\r
+char relative[FL_PATH_MAX];\r
+\r
+fc->show();\r
+\r
+while(fc->visible() )\r
+{\r
+ Fl::wait();\r
+}\r
+\r
+count = fc->count();\r
+\r
+\r
+if (count > 0)\r
+{\r
+ for (i = 0 ; i < count; i++)\r
+ {\r
+ if (!fc->value(i))\r
+ break;\r
+ fl_filename_relative(relative,sizeof(relative),fc->value(i));\r
+ std::cout<<" Selected : "<<relative<<std::endl;\r
+ if (strstr(fc->value(i),".pcap"))\r
+ {\r
+ \r
+ char *pos = strstr(relative,".pcap");\r
+ //m_current_filename = relative;\r
+\#ifndef __WIN32__\r
+ //while (*pos != '/')\r
+ // pos--;\r
+\#else\r
+ std::cout<<"HOHOHOHOHO"<<std::endl;\r
+\#endif\r
+ if (pos != NULL)\r
+ {\r
+ strcpy(pos,".signaling");\r
+ }\r
+ \r
+ std::cout<<"Export to file :"<<relative<<std::endl;\r
+ m_Model->export_msc(relative);\r
+ //m_Controler->load(relative);\r
+// do_pcap(relative);\r
+ } else {\r
+ std::cout<<"Unsuported format\\n";\r
+ }\r
+ \r
+ }\r
+}\r
+\r
+//Fl_Preferences app(Fl_Preferences::USER,"CSTASpy","main");\r
+//Fl_Preferences Cfg(app,m_current_filename.c_str());\r
+//Cfg.get("filter",iPath,m_InputChoice->value(),99);\r
+//m_InputChoice->value(iPath);}
+ xywh {0 0 100 20} labelsize 12 divider
+ }
+ MenuItem {} {
+ label {&Preferences}
+ callback {m_Preferences->show();}
+ xywh {0 0 100 20} labelsize 12
+ }
+ MenuItem {} {
+ label {&Print}
+ xywh {0 0 100 20} labelsize 12 divider
+ }
+ MenuItem {} {
+ label {&Quit}
+ callback {exit(1);}
+ xywh {0 0 100 20} labelsize 12
+ }
+ }
+ Submenu {} {
+ label {&View} open
+ xywh {0 0 100 20} labelsize 12
+ } {
+ MenuItem {} {
+ label {Expand Tree}
+ xywh {0 0 36 21} labelsize 12
+ }
+ MenuItem {} {
+ label {Collapse Tree}
+ xywh {0 0 36 21} labelsize 12
+ }
+ }
+ Submenu {} {
+ label {&Help} open
+ xywh {0 0 100 20} labelsize 12
+ } {
+ MenuItem {} {
+ label {&About}
+ xywh {0 0 100 20} labelsize 12
+ }
+ }
+ }
+ Fl_Group {} {open
+ xywh {0 22 1035 22}
+ } {
+ Fl_Button {} {
+ label Apply
+ callback {if (m_current_filename.size() > 3) {\r
+ std::string rl(tree->root()->label());\r
+ // First clean inputs.\r
+ do_close();\r
+ // call do_pcap with filter.\r
+ std::string filter(m_InputChoice->value());\r
+ //do_pcap(m_current_filename.c_str(),m_Filter->value());\r
+// do_pcap(m_current_filename.c_str(),filter.c_str());\r
+\r
+ m_Controler->load(m_current_filename.c_str(),filter.c_str());\r
+ m_ScrollHeader->redraw();\r
+ tree->root()->label(rl.c_str());\r
+}}
+ xywh {401 22 70 22} labelsize 12
+ }
+ Fl_Button {} {
+ label Clear
+ callback {if (m_current_filename.size() > 4) \r
+{\r
+ do_close();\r
+ m_ScrollHeader->redraw();\r
+}}
+ xywh {469 22 70 22} labelsize 12
+ }
+ Fl_Input_Choice m_InputChoice {
+ label Filter
+ callback {char iPath[100];\r
+\r
+Fl_Preferences app(Fl_Preferences::USER,"CSTASpy","main");\r
+Fl_Preferences Cfg(app,m_current_filename.c_str());\r
+//Cfg.get("filter",iPath,m_InputChoice->value(),99);\r
+Cfg.set("filter",m_InputChoice->value());} open
+ xywh {36 22 365 22} down_box DOWN_FRAME labelsize 12 textsize 12
+ } {}
+ Fl_Box {} {
+ xywh {543 23 489 21} resizable
+ }
+ }
+ Fl_Tile {} {
+ callback {CI_LOG_DEBUG("Tile Event");
+//tree->redraw();\r
+//m_Editor->redraw();\r
+//m_Sequence->redraw();\r
+\r
+//m_Tabs->damage(FL_DAMAGE_ALL);\r
+//m_Tabs->value()->redraw()} open selected
+ xywh {0 45 1035 810} box BORDER_BOX when 1 resizable
+ } {
+ Fl_Tree tree {
+ callback {Fl_Tree_Item *item = tree->callback_item();\r
+\r
+if (item)\r
+{\r
+ if (tree->callback_reason() == FL_TREE_REASON_SELECTED)\r
+ {\r
+ m_Controler->select((TLMsg *)item->user_data());\r
+ //m_Editor->scroll((long )item->user_data(),0);
+ m_Scroll->redraw();
+ } else if (tree->callback_reason() == FL_TREE_REASON_DESELECTED)\r
+ {\r
+ }\r
+} else {\r
+ // No Item forget the event\r
+}\r
+\r
+tree->clear_changed();}
+ xywh {0 45 300 610} selection_color 23 labelsize 10 align 65
+ }
+ Fl_Scroll m_ScrollHeader {
+ xywh {300 45 735 70} box DOWN_BOX color 7 labelsize 12
+ } {
+ Fl_Box m_Header {
+ xywh {300 45 735 70} color 7 selection_color 40
+ code0 {\#include "HeaderView.h"}
+ class HeaderView
+ }
+ }
+ Fl_Scroll m_Scroll {
+ callback {printf("Event : Scroll\\n");
+m_Scroll->clear_changed();} open
+ xywh {300 115 735 540} box DOWN_BOX color 7 align 65 when 1
+ } {
+ Fl_Box m_Sequence {
+ label {Sequence view}
+ callback {printf("Possile if handle method is properly coded\\n");}
+ xywh {300 115 735 540} color 7 selection_color 55 labelsize 12 when 1
+ code0 {\#include "SequenceView.h"}
+ class SequenceView
+ }
+ }
+ Fl_Group {} {open
+ xywh {0 655 1035 200} box FLAT_BOX
+ } {
+ Fl_Tabs m_Tabs {open
+ xywh {0 655 1035 200} labelsize 12 align 65 when 1
+ } {
+ Fl_Group {} {
+ label Traces
+ xywh {7 680 1030 175} selection_color 41 labelsize 12 resizable
+ } {
+ Fl_Text_Editor m_Editor {
+ callback {//m_Editor->buffer(m_Buffer);\r
+printf("m_Editor what here ?\\n");}
+ xywh {10 686 1023 165} box BORDER_BOX labelsize 10 textsize 12 resizable
+ }
+ }
+ Fl_Group {} {
+ label Preferences open
+ xywh {7 680 1030 175} selection_color 41 labelsize 12 hide
+ } {
+ Fl_Scroll {} {open
+ xywh {0 680 1034 171}
+ } {
+ Fl_Group {} {
+ label Ports open
+ xywh {20 705 300 140} box ENGRAVED_FRAME color 48 labelsize 12 align 133
+ } {
+ Fl_Input {} {
+ label {CSTA port :}
+ xywh {100 725 96 22} labelsize 12 textsize 12
+ code0 {o->value("2555");}
+ }
+ Fl_Input {} {
+ label {SIP port :}
+ xywh {100 751 96 22} labelsize 12 textsize 12
+ code0 {o->value("5059");}
+ }
+ Fl_Input {} {
+ label {OTS port :}
+ xywh {100 777 95 22} labelsize 12 textsize 12
+ code0 {o->value("8894");}
+ }
+ Fl_Box {} {
+ xywh {22 818 293 25} resizable
+ }
+ }
+ Fl_Box {} {
+ label License
+ xywh {349 705 267 140} box ENGRAVED_FRAME labelsize 12 align 5
+ }
+ Fl_Box {} {
+ xywh {630 708 29 126} resizable
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ Function {make_prefs()} {open
+ } {
+ Fl_Window m_Preferences {
+ label Preferences
+ xywh {1360 53 370 350} type Double modal visible
+ } {
+ Fl_Tabs {} {open
+ xywh {0 1 370 325}
+ } {
+ Fl_Group {} {
+ label {Gérénal}
+ xywh {0 25 370 300} labelsize 12 hide
+ } {
+ Fl_Group {} {
+ label Application open
+ xywh {5 45 357 270} box EMBOSSED_FRAME labelsize 12 align 517
+ } {
+ Fl_File_Input m_IconPath {
+ label Icon
+ xywh {42 54 293 32} labelsize 12 textsize 12
+ }
+ }
+ }
+ Fl_Group {} {
+ label {Séquence View}
+ xywh {0 25 370 300} labelsize 12 hide
+ } {
+ Fl_Check_Button {} {
+ label {Display port number }
+ xywh {145 33 20 25} down_box DOWN_BOX labelsize 12 align 4
+ }
+ Fl_Spinner {} {
+ label {Timeline space }
+ xywh {145 53 50 25} labelsize 12 value 150
+ }
+ }
+ Fl_Group {} {
+ label Ports
+ xywh {0 25 370 300} labelsize 12 hide
+ } {
+ Fl_Group {} {
+ label {Port numbers} open
+ xywh {11 47 345 275} box ENGRAVED_FRAME labelsize 12 align 5
+ } {
+ Fl_Input {} {
+ label {CSTA port }
+ xywh {100 60 70 25} labelsize 12 textsize 12
+ code0 {o->value("2555");}
+ }
+ Fl_Input {} {
+ label {OTS port }
+ xywh {100 88 70 25} labelsize 12 textsize 12
+ code0 {o->value("8894");}
+ }
+ Fl_Input {} {
+ label {SIP port }
+ xywh {100 116 70 25} labelsize 12 textsize 12
+ code0 {o->value("5059");}
+ }
+ }
+ }
+ Fl_Group {} {
+ label Debug open
+ xywh {0 25 370 300} labelsize 12
+ } {
+ Fl_Check_Button m_DumpHex {
+ label {Dump hex in console }
+ xywh {150 29 67 25} down_box DOWN_BOX labelsize 12 align 4
+ }
+ Fl_Input_Choice m_Asn1DebugLevel {
+ label {Asn1 Debug Level } open
+ xywh {150 51 67 25} labelsize 12 textsize 12
+ } {
+ MenuItem {} {
+ label Critical
+ callback {asn1::types::debug_level = 4;\r
+m_Asn1DebugLevel->value("Critical");}
+ xywh {15 15 100 20}
+ }
+ MenuItem {} {
+ label Error
+ callback {asn1::types::debug_level = 5;\r
+m_Asn1DebugLevel->value("Error");}
+ xywh {15 15 100 20}
+ }
+ MenuItem {} {
+ label Info
+ callback {asn1::types::debug_level = 6;\r
+m_Asn1DebugLevel->value("Info");}
+ xywh {15 15 100 20}
+ }
+ MenuItem {} {
+ label Debug
+ callback {asn1::types::debug_level = 7;\r
+m_Asn1DebugLevel->value("Debug");}
+ xywh {15 15 100 20}
+ }
+ }
+ Fl_Input_Choice m_AppDebugLevel {
+ label {App Debug Level } open
+ xywh {150 80 67 25} labelsize 12 align 132 textsize 12
+ } {
+ MenuItem {} {
+ label Critical
+ callback {cid_level = 4;
+m_AppDebugLevel->value("Critical");}
+ xywh {0 0 100 20}
+ }
+ MenuItem {} {
+ label Error
+ callback {cid_level = 3;
+m_AppDebugLevel->value("Error");}
+ xywh {0 0 100 20}
+ }
+ MenuItem {} {
+ label Warning
+ callback {cid_level = 4;
+m_AppDebugLevel->value("Warning");}
+ xywh {0 0 100 20}
+ }
+ MenuItem {} {
+ label Info
+ callback {cid_level = 5;
+m_AppDebugLevel->value("Info");}
+ xywh {0 0 100 20}
+ }
+ MenuItem {} {
+ label Debug
+ callback {cid_level = 8;
+m_AppDebugLevel->value("Debug");}
+ xywh {0 0 100 20}
+ }
+ }
+ }
+ }
+ Fl_Group {} {open
+ xywh {2 324 369 26}
+ } {
+ Fl_Return_Button {} {
+ label Ok
+ callback {writePrefs();\r
+m_Preferences->hide();}
+ xywh {239 327 54 22}
+ }
+ Fl_Button {} {
+ label Cancel
+ callback {m_Preferences->hide();}
+ xywh {290 327 81 22}
+ }
+ }
+ }
+ }
+ Function {readPrefs()} {} {
+ code {Fl_Preferences app(Fl_Preferences::USER,"CSTASpy","main");\r
+\r
+Fl_Preferences iconPath(app,"iconPath");\r
+char ipath[79];\r
+iconPath.get("path",ipath,"/home/aebersol/Devs/home/home/parser/asn1/cstav1/images/",79);\r
+m_IconPath->value(ipath);} {}
+ }
+ Function {writePrefs()} {} {
+ code {Fl_Preferences app(Fl_Preferences::USER,"CSTASpy","main");\r
+\r
+Fl_Preferences iconPath(app,"iconPath");\r
+iconPath.set("path",m_IconPath->value());} {}
+ }
+ Function {show(int argc,char **argv)} {open
+ } {
+ code {m_Editor->buffer(m_Buffer);\r
+// Only here\r
+m_InputChoice->add("");\r
+m_InputChoice->add("not(src and dst port 5059 or port 5080)");\r
+m_InputChoice->add("not(port 5080)");\r
+m_InputChoice->add("not(src and dst port 5059 or port 5080 or 8894)");\r
+\r
+asn1::types::debug_level = 6;\r
+m_Asn1DebugLevel->value("Info");\r
+m_Header->model(m_Model);\r
+m_Sequence->model(m_Model);\r
+m_Sequence->tree(tree);\r
+m_Sequence->editor(m_Editor);\r
+m_Window->show(argc,argv);} {}
+ }
+ Function {do_close()} {} {
+ code {tree->clear_children(tree->root());\r
+tree->root_label("ROOT");\r
+m_Sequence->clear();\r
+tree->redraw();\r
+m_Sequence->redraw();\r
+m_Scroll->redraw();\r
+m_Editor->buffer()->remove(0,m_Editor->buffer()->length());\r
+m_Controler->close();\r
+m_Header->damage(FL_DAMAGE_ALL);\r
+m_Header->redraw();} {}
+ }
+ decl {Fl_Text_Buffer *m_Buffer;} {protected local
+ }
+ decl {std::string m_current_filename} {protected local
+ }
+ decl {Model *m_Model;} {protected local
+ }
+ decl {Controler *m_Controler;} {protected local
+ }
+ Function {callToString(const std::string &ins,std::string &out)} {open
+ } {
+ code {int res = 0;\r
+for (std::string::const_iterator it = ins.begin() ; \r
+ it != ins.end(); ++it)\r
+ res = res << 8 | (unsigned char)(*it);\r
+\r
+std::stringstream ints; ints<<res;\r
+out += ints.str();} {}
+ }
+ Function {make_slash_screen()} {
+ comment {//Build the splash screen} open
+ } {
+ code {Fl_Window *o = new Fl_Window(550,400,"Splash Screen");
+o->type(241);
+o->begin();
+ Fl_Group *g = new Fl_Group(0,0,550,400);
+ g->resizable(o);
+o->end();
+o->set_non_modal();
+o->clear_border();
+o->resizable(o);
+
+o->border(false);
+
+o->show();
+// o->flush();
+do {
+ Fl::check();
+} while(! o->visible());} {}
+ }
+}
+
+Function {} {
+ comment {// Main entry point}
+} {
+ code {MainUI m;\r
+m.make_window();\r
+m.make_prefs();\r
+m.readPrefs();\r
+m.show(argc,argv);\r
+Fl::run();} {}
+}
--- /dev/null
+
+#include <iostream>
+#include <fstream>
+#include <string.h>
+#include <typeinfo>
+#include <stdlib.h>
+#include "rtasn1/asn1.h"
+#include "rtasn1/asn1_codec.h"
+#include "rtasn1/asn1_codec_ber.h"
+
+#include "Rose_Apdu.h"
+#include "CSTA_event.h"
+
+#include "Rose_Apdu.hpp"
+#include "CSTA_event.hpp"
+/**
+
+CSTAEventReportArgument ::= SEQUENCE {
+ crossRefIdentifier MonitorCorssRefID
+ eventSpecificInfo EventSpecificInfo
+}
+ *
+ServiceInitiatedEventInfo ::= SEQUENCE {
+ initatedConnection ConnectionID,
+ localConnectionInfo LocalConnectionState OPTIONAL
+ cause EventCause OPTIONAL
+ }
+ *
+ConnectionID ::= [APPLICATION 11] CHOICE {
+ call [2] IMPLICIT OCTET STRING OPTIONAL,
+ device CHOICE {
+ staticID DeviceID,
+ dynamicID [3] IMPLICIT OCTET STRING
+ }
+}
+
+CallID ::= OCTET STRING
+LocalDeviceID ::= CHOICE [
+ staticID DeviceID
+ dynamicID [3] IMPLICIT OCTET STRING
+}
+
+DeviceID ::= SEQUENCE {
+ deviceIdentifier CHOICE {
+ }
+}
+ */
+
+int test_decode()
+{
+ /* This sequence is for Alcatel CSTA which is not compatible with the ecma
+ * 285 description. Just forget it. Events are described diferently*/
+ const unsigned char d[] ={ 0x30,0x46,
+ 0x55,0x04,0x00,0x00,0x00,0x04,
+ 0x80,0x01,0x0d, // For alcated, this Event Type 13
+ //Context Specific - Primitive - Id=0 tag. Len 1 - value 0d 13 what is this ?
+ 0x30,0x1d, /* ServiceInitiatedEvent SEQUENCE len 0x1d 29*/
+ 0x6b,0x0a, /* ConnectionID tag APPL 11 len 10 CHOICE*/
+ 0x82,0x02,0x00,0x76, /* This should be both of ConnectionID*/
+ 0x83,0x04,0x00, 0x03,0x00,0x00, /* supposed to be dynamic ID*/
+ /** */
+ /* I d'ont know what this is */
+ 0x4e,0x01,0x01, /* State initated */
+ 0x0a,0x01, 0x16, /* Event Cause newCall*/
+ 0x63,0x05,0x84,0x03,0x31,0x30,0x32,
+ 0x62,0x02,0x87,0X00,
+ 0x7d,0x1c, /* private date [APPLICATION 24 ] implicit */
+ 0x06,0x06,0x2b,0x0c,0x89,0x36,0x83, 0x74,/* manufacturer OBJECT ID 1.3.12.1206.500 */
+ 0x04,0x12,0x03,0x01,0x00,0x00,0x0c,0x49,0x43,0x54,0x4f,0x55,0x43,0x48,0x5f,
+ 0x4e , 0x4f,0x4e,0x45,0x00
+ };
+
+ CSTA_event::CSTAEventReportArgument report;
+ asn1::streams::ber ctx;
+ memcpy(ctx.buffer(),d,74);
+ //report.codec(ctx,report,asn1::CODEC_DECODE);
+ report.decode(ctx);
+ std::cout<<"Go type info="<<report.eventType.get_local().get_value()<<std::endl;
+ return 0;
+}
+
+int main(int argc,char **argv)
+{
+
+ //CSTA_event_report_definitions::cSTAEventReport report;
+ //asn1::context ctx;
+
+ if (argc > 1) {
+ // Try to decode a stream ....
+ std::ifstream is;
+ is.open(argv[1],std::ios::binary);
+ int len = 0;
+ char bl[2];
+
+ memset(bl,0x00,3);
+ while (is.read(bl,2) && is.good())
+ {
+ len = bl[1] | bl[0]<<8;
+ std::cout<<" Read header "<<(unsigned short)bl[0]<<"-"<<(unsigned short)bl[1]<<" should decode len="<<len<<std::endl;
+ if (len < 4096)
+ {
+ Rose_Apdu::RoseAPDU pdu;
+ //asn1::context ctx(len);
+ asn1::streams::ber ctx(len);
+ is.read((char *)ctx.buffer(),len);
+ //pdu.codec(ctx,pdu,asn1::CODEC_DECODE);
+ pdu.decode(ctx);
+ if ( (ctx.nb_read_bits()>>3) == len )
+ {
+ std::cout<<"\n\n\tYES COMPLETELY DECODED\n";
+ switch (pdu.get_kind())
+ {
+ case Rose_Apdu::RoseAPDU::typeof_invoke:
+ std::cout<<"\tGot invoke ID="<<pdu.get_invoke().invokeID<<" ";
+ if (pdu.get_invoke().operationValue.get_kind() == Remote_Operations_Information_Objects::OpCode::typeof_local)
+ {
+ std::cout<<" op code="<<pdu.get_invoke().operationValue.get_local()<<" "<<typeid(&pdu.get_invoke().argument).name()<<"\n";
+ if (pdu.get_invoke().operationValue.get_local().get_value() == 21)
+ {
+ // Get OPERATION
+ CSTA_event::cSTAEventEvent *event;
+ asn1::Object *_o = pdu.get_invoke().argument;
+ event = dynamic_cast<CSTA_event::cSTAEventEvent *>(_o);
+ // Get OBJECT-TYPE
+ CSTA_event::CSTAEventReportArgument report;
+ event->get_ArgumentType(report);
+ std::cout<<"Go type info="<<report.eventType.get_local()<<std::endl;
+ Remote_Operations_Information_Objects::IOBJECT_TYPE *event_obj;
+ asn1::Object *_o1 = report.eventInfo;
+ event_obj = dynamic_cast<Remote_Operations_Information_Objects::IOBJECT_TYPE *>(_o1);
+
+ }
+ } else {
+ std::cout<<std::endl;
+ }
+ break;
+ case Rose_Apdu::RoseAPDU::typeof_retResult:
+ break;
+ case Rose_Apdu::RoseAPDU::typeof_retError:
+ break;
+ case Rose_Apdu::RoseAPDU::typeof_reject:
+ break;
+ default:
+ ;
+ }
+ } else {
+ std::cout<<"\n\n\tINCOMPLET DECODE len="<<len<<" Decoded= "<<(ctx.nb_read_bits()>>3)<<"\n";
+ }
+ }
+ std::cout<<"\n\n";
+ }
+
+ }
+ else
+ test_decode();
+ //report.codec(ctx,asn1::CODEC_ENCODE);
+ std::cout<<"Hello world"<<std::endl;
+}
--- /dev/null
+CSTA-connect
+CSTA-call
+CSTA-event
+CSTA-device
+CSTA-error
+CSTA-extend
+CSTA-feature
+CSTA-private
+CSTA-status
+CSTA-secure
+CSTA-switch
+Rose-Apdu
+CSTA-MSG
+ACSE-1
--- /dev/null
+// sigslot.h: Signal/Slot classes\r
+//\r
+// \r
+// Written by Sarah Thompson (sarah@telergy.com) 2002.\r
+//\r
+// License: Public domain. You are free to use this code however you like, with the proviso that\r
+// the author takes on no responsibility or liability for any use.\r
+//\r
+// QUICK DOCUMENTATION \r
+// \r
+// (see also the full documentation at http://sigslot.sourceforge.net/)\r
+//\r
+// #define switches\r
+// SIGSLOT_PURE_ISO - Define this to force ISO C++ compliance. This also disables\r
+// all of the thread safety support on platforms where it is \r
+// available.\r
+//\r
+// SIGSLOT_USE_POSIX_THREADS - Force use of Posix threads when using a C++ compiler other than\r
+// gcc on a platform that supports Posix threads. (When using gcc,\r
+// this is the default - use SIGSLOT_PURE_ISO to disable this if \r
+// necessary)\r
+//\r
+// SIGSLOT_DEFAULT_MT_POLICY - Where thread support is enabled, this defaults to multi_threaded_global.\r
+// Otherwise, the default is single_threaded. #define this yourself to\r
+// override the default. In pure ISO mode, anything other than\r
+// single_threaded will cause a compiler error.\r
+//\r
+// PLATFORM NOTES\r
+//\r
+// Win32 - On Win32, the WIN32 symbol must be #defined. Most mainstream\r
+// compilers do this by default, but you may need to define it\r
+// yourself if your build environment is less standard. This causes\r
+// the Win32 thread support to be compiled in and used automatically.\r
+//\r
+// Unix/Linux/BSD, etc. - If you're using gcc, it is assumed that you have Posix threads\r
+// available, so they are used automatically. You can override this\r
+// (as under Windows) with the SIGSLOT_PURE_ISO switch. If you're using\r
+// something other than gcc but still want to use Posix threads, you\r
+// need to #define SIGSLOT_USE_POSIX_THREADS.\r
+//\r
+// ISO C++ - If none of the supported platforms are detected, or if\r
+// SIGSLOT_PURE_ISO is defined, all multithreading support is turned off,\r
+// along with any code that might cause a pure ISO C++ environment to\r
+// complain. Before you ask, gcc -ansi -pedantic won't compile this \r
+// library, but gcc -ansi is fine. Pedantic mode seems to throw a lot of\r
+// errors that aren't really there. If you feel like investigating this,\r
+// please contact the author.\r
+//\r
+// \r
+// THREADING MODES\r
+//\r
+// single_threaded - Your program is assumed to be single threaded from the point of view\r
+// of signal/slot usage (i.e. all objects using signals and slots are\r
+// created and destroyed from a single thread). Behaviour if objects are\r
+// destroyed concurrently is undefined (i.e. you'll get the occasional\r
+// segmentation fault/memory exception).\r
+//\r
+// multi_threaded_global - Your program is assumed to be multi threaded. Objects using signals and\r
+// slots can be safely created and destroyed from any thread, even when\r
+// connections exist. In multi_threaded_global mode, this is achieved by a\r
+// single global mutex (actually a critical section on Windows because they\r
+// are faster). This option uses less OS resources, but results in more\r
+// opportunities for contention, possibly resulting in more context switches\r
+// than are strictly necessary.\r
+//\r
+// multi_threaded_local - Behaviour in this mode is essentially the same as multi_threaded_global,\r
+// except that each signal, and each object that inherits has_slots, all \r
+// have their own mutex/critical section. In practice, this means that\r
+// mutex collisions (and hence context switches) only happen if they are\r
+// absolutely essential. However, on some platforms, creating a lot of \r
+// mutexes can slow down the whole OS, so use this option with care.\r
+//\r
+// USING THE LIBRARY\r
+//\r
+// See the full documentation at http://sigslot.sourceforge.net/\r
+//\r
+//\r
+\r
+#ifndef SIGSLOT_H__\r
+#define SIGSLOT_H__\r
+\r
+#include <set>\r
+#include <list>\r
+\r
+#define SIGSLOT_USE_POSIX_THREADS\r
+#define SIGSLOT_DEFAULT_MT_POLICY multi_threaded_local\r
+\r
+#if defined(SIGSLOT_PURE_ISO) || (!defined(WIN32) && !defined(__GNUG__) && !defined(SIGSLOT_USE_POSIX_THREADS))\r
+# define _SIGSLOT_SINGLE_THREADED\r
+#elif defined(WIN32)\r
+# define _SIGSLOT_HAS_WIN32_THREADS\r
+# include <windows.h>\r
+#elif defined(__GNUG__) || defined(SIGSLOT_USE_POSIX_THREADS)\r
+# define _SIGSLOT_HAS_POSIX_THREADS\r
+# include <pthread.h>\r
+#else\r
+# define _SIGSLOT_SINGLE_THREADED\r
+#endif\r
+\r
+#ifndef SIGSLOT_DEFAULT_MT_POLICY\r
+# ifdef _SIGSLOT_SINGLE_THREADED\r
+# define SIGSLOT_DEFAULT_MT_POLICY single_threaded\r
+# else\r
+# define SIGSLOT_DEFAULT_MT_POLICY multi_threaded_local\r
+# endif\r
+#endif\r
+\r
+\r
+namespace sigslot {\r
+\r
+ class single_threaded\r
+ {\r
+ public:\r
+ single_threaded()\r
+ {\r
+ ;\r
+ }\r
+\r
+ virtual ~single_threaded()\r
+ {\r
+ ;\r
+ }\r
+\r
+ virtual void lock()\r
+ {\r
+ ;\r
+ }\r
+\r
+ virtual void unlock()\r
+ {\r
+ ;\r
+ }\r
+ };\r
+\r
+#ifdef _SIGSLOT_HAS_WIN32_THREADS\r
+ // The multi threading policies only get compiled in if they are enabled.\r
+ class multi_threaded_global\r
+ {\r
+ public:\r
+ multi_threaded_global()\r
+ {\r
+ static bool isinitialised = false;\r
+\r
+ if(!isinitialised)\r
+ {\r
+ InitializeCriticalSection(get_critsec());\r
+ isinitialised = true;\r
+ }\r
+ }\r
+\r
+ multi_threaded_global(const multi_threaded_global&)\r
+ {\r
+ ;\r
+ }\r
+\r
+ virtual ~multi_threaded_global()\r
+ {\r
+ ;\r
+ }\r
+\r
+ virtual void lock()\r
+ {\r
+ EnterCriticalSection(get_critsec());\r
+ }\r
+\r
+ virtual void unlock()\r
+ {\r
+ LeaveCriticalSection(get_critsec());\r
+ }\r
+\r
+ private:\r
+ CRITICAL_SECTION* get_critsec()\r
+ {\r
+ static CRITICAL_SECTION g_critsec;\r
+ return &g_critsec;\r
+ }\r
+ };\r
+\r
+ class multi_threaded_local\r
+ {\r
+ public:\r
+ multi_threaded_local()\r
+ {\r
+ InitializeCriticalSection(&m_critsec);\r
+ }\r
+\r
+ multi_threaded_local(const multi_threaded_local&)\r
+ {\r
+ InitializeCriticalSection(&m_critsec);\r
+ }\r
+\r
+ virtual ~multi_threaded_local()\r
+ {\r
+ DeleteCriticalSection(&m_critsec);\r
+ }\r
+\r
+ virtual void lock()\r
+ {\r
+ EnterCriticalSection(&m_critsec);\r
+ }\r
+\r
+ virtual void unlock()\r
+ {\r
+ LeaveCriticalSection(&m_critsec);\r
+ }\r
+\r
+ private:\r
+ CRITICAL_SECTION m_critsec;\r
+ };\r
+#endif // _SIGSLOT_HAS_WIN32_THREADS\r
+\r
+#ifdef _SIGSLOT_HAS_POSIX_THREADS\r
+ // The multi threading policies only get compiled in if they are enabled.\r
+ class multi_threaded_global\r
+ {\r
+ public:\r
+ multi_threaded_global()\r
+ {\r
+ pthread_mutex_init(get_mutex(), NULL);\r
+ }\r
+\r
+ multi_threaded_global(const multi_threaded_global&)\r
+ {\r
+ ;\r
+ }\r
+\r
+ virtual ~multi_threaded_global()\r
+ {\r
+ ;\r
+ }\r
+\r
+ virtual void lock()\r
+ {\r
+ pthread_mutex_lock(get_mutex());\r
+ }\r
+\r
+ virtual void unlock()\r
+ {\r
+ pthread_mutex_unlock(get_mutex());\r
+ }\r
+\r
+ private:\r
+ pthread_mutex_t* get_mutex()\r
+ {\r
+ static pthread_mutex_t g_mutex;\r
+ return &g_mutex;\r
+ }\r
+ };\r
+\r
+ class multi_threaded_local\r
+ {\r
+ public:\r
+ multi_threaded_local()\r
+ {\r
+ pthread_mutex_init(&m_mutex, NULL);\r
+ }\r
+\r
+ multi_threaded_local(const multi_threaded_local&)\r
+ {\r
+ pthread_mutex_init(&m_mutex, NULL);\r
+ }\r
+\r
+ virtual ~multi_threaded_local()\r
+ {\r
+ pthread_mutex_destroy(&m_mutex);\r
+ }\r
+\r
+ virtual void lock()\r
+ {\r
+ pthread_mutex_lock(&m_mutex);\r
+ }\r
+\r
+ virtual void unlock()\r
+ {\r
+ pthread_mutex_unlock(&m_mutex);\r
+ }\r
+\r
+ private:\r
+ pthread_mutex_t m_mutex;\r
+ };\r
+#endif // _SIGSLOT_HAS_POSIX_THREADS\r
+\r
+ template<typename mt_policy>\r
+ class lock_block\r
+ {\r
+ public:\r
+ mt_policy *m_mutex;\r
+\r
+ lock_block(mt_policy *mtx)\r
+ : m_mutex(mtx)\r
+ {\r
+ m_mutex->lock();\r
+ }\r
+\r
+ ~lock_block()\r
+ {\r
+ m_mutex->unlock();\r
+ }\r
+ };\r
+\r
+ template<typename mt_policy>\r
+ class has_slots;\r
+\r
+ template<typename mt_policy>\r
+ class _connection_base0\r
+ {\r
+ public:\r
+ virtual has_slots<mt_policy>* getdest() const = 0;\r
+ virtual void emit() = 0;\r
+ virtual _connection_base0* clone() = 0;\r
+ virtual _connection_base0* duplicate(has_slots<mt_policy>* pnewdest) = 0;\r
+ };\r
+\r
+ template<typename arg1_type, typename mt_policy>\r
+ class _connection_base1\r
+ {\r
+ public:\r
+ virtual has_slots<mt_policy>* getdest() const = 0;\r
+ virtual void emit(arg1_type) = 0;\r
+ virtual _connection_base1<arg1_type, mt_policy>* clone() = 0;\r
+ virtual _connection_base1<arg1_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;\r
+ };\r
+\r
+ template<class arg1_type, class arg2_type, class mt_policy>\r
+ class _connection_base2\r
+ {\r
+ public:\r
+ virtual has_slots<mt_policy>* getdest() const = 0;\r
+ virtual void emit(arg1_type, arg2_type) = 0;\r
+ virtual _connection_base2<arg1_type, arg2_type, mt_policy>* clone() = 0;\r
+ virtual _connection_base2<arg1_type, arg2_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;\r
+ };\r
+\r
+ template<class arg1_type, class arg2_type, class arg3_type, class mt_policy>\r
+ class _connection_base3\r
+ {\r
+ public:\r
+ virtual has_slots<mt_policy>* getdest() const = 0;\r
+ virtual void emit(arg1_type, arg2_type, arg3_type) = 0;\r
+ virtual _connection_base3<arg1_type, arg2_type, arg3_type, mt_policy>* clone() = 0;\r
+ virtual _connection_base3<arg1_type, arg2_type, arg3_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;\r
+ };\r
+\r
+ template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, class mt_policy>\r
+ class _connection_base4\r
+ {\r
+ public:\r
+ virtual has_slots<mt_policy>* getdest() const = 0;\r
+ virtual void emit(arg1_type, arg2_type, arg3_type, arg4_type) = 0;\r
+ virtual _connection_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>* clone() = 0;\r
+ virtual _connection_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;\r
+ };\r
+\r
+ template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,\r
+ class arg5_type, class mt_policy>\r
+ class _connection_base5\r
+ {\r
+ public:\r
+ virtual has_slots<mt_policy>* getdest() const = 0;\r
+ virtual void emit(arg1_type, arg2_type, arg3_type, arg4_type, \r
+ arg5_type) = 0;\r
+ virtual _connection_base5<arg1_type, arg2_type, arg3_type, arg4_type,\r
+ arg5_type, mt_policy>* clone() = 0;\r
+ virtual _connection_base5<arg1_type, arg2_type, arg3_type, arg4_type,\r
+ arg5_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;\r
+ };\r
+\r
+ template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,\r
+ class arg5_type, class arg6_type, class mt_policy>\r
+ class _connection_base6\r
+ {\r
+ public:\r
+ virtual has_slots<mt_policy>* getdest() const = 0;\r
+ virtual void emit(arg1_type, arg2_type, arg3_type, arg4_type, arg5_type,\r
+ arg6_type) = 0;\r
+ virtual _connection_base6<arg1_type, arg2_type, arg3_type, arg4_type,\r
+ arg5_type, arg6_type, mt_policy>* clone() = 0;\r
+ virtual _connection_base6<arg1_type, arg2_type, arg3_type, arg4_type,\r
+ arg5_type, arg6_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;\r
+ };\r
+\r
+ template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,\r
+ class arg5_type, class arg6_type, class arg7_type, class mt_policy>\r
+ class _connection_base7\r
+ {\r
+ public:\r
+ virtual has_slots<mt_policy>* getdest() const = 0;\r
+ virtual void emit(arg1_type, arg2_type, arg3_type, arg4_type, arg5_type,\r
+ arg6_type, arg7_type) = 0;\r
+ virtual _connection_base7<arg1_type, arg2_type, arg3_type, arg4_type,\r
+ arg5_type, arg6_type, arg7_type, mt_policy>* clone() = 0;\r
+ virtual _connection_base7<arg1_type, arg2_type, arg3_type, arg4_type,\r
+ arg5_type, arg6_type, arg7_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;\r
+ };\r
+\r
+ template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,\r
+ class arg5_type, class arg6_type, class arg7_type, class arg8_type, class mt_policy>\r
+ class _connection_base8\r
+ {\r
+ public:\r
+ virtual has_slots<mt_policy>* getdest() const = 0;\r
+ virtual void emit(arg1_type, arg2_type, arg3_type, arg4_type, arg5_type,\r
+ arg6_type, arg7_type, arg8_type) = 0;\r
+ virtual _connection_base8<arg1_type, arg2_type, arg3_type, arg4_type,\r
+ arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>* clone() = 0;\r
+ virtual _connection_base8<arg1_type, arg2_type, arg3_type, arg4_type,\r
+ arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;\r
+ };\r
+\r
+ template<typename mt_policy>\r
+ class _signal_base : public mt_policy\r
+ {\r
+ public:\r
+ virtual void slot_disconnect(has_slots<mt_policy>* pslot) = 0;\r
+ virtual void slot_duplicate(const has_slots<mt_policy>* poldslot, has_slots<mt_policy>* pnewslot) = 0;\r
+ };\r
+\r
+ template<typename mt_policy = SIGSLOT_DEFAULT_MT_POLICY>\r
+ class has_slots : public mt_policy \r
+ {\r
+ private:\r
+ typedef typename std::set<_signal_base<mt_policy> *> sender_set;\r
+ typedef typename sender_set::const_iterator const_iterator;\r
+\r
+ public:\r
+ has_slots()\r
+ {\r
+ ;\r
+ }\r
+\r
+ has_slots(const has_slots& hs)\r
+ : mt_policy(hs)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ const_iterator it = hs.m_senders.begin();\r
+ const_iterator itEnd = hs.m_senders.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ (*it)->slot_duplicate(&hs, this);\r
+ m_senders.insert(*it);\r
+ ++it;\r
+ }\r
+ } \r
+\r
+ void signal_connect(_signal_base<mt_policy>* sender)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ m_senders.insert(sender);\r
+ }\r
+\r
+ void signal_disconnect(_signal_base<mt_policy>* sender)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ m_senders.erase(sender);\r
+ }\r
+\r
+ virtual ~has_slots()\r
+ {\r
+ disconnect_all();\r
+ }\r
+\r
+ void disconnect_all()\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ const_iterator it = m_senders.begin();\r
+ const_iterator itEnd = m_senders.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ (*it)->slot_disconnect(this);\r
+ ++it;\r
+ }\r
+\r
+ m_senders.erase(m_senders.begin(), m_senders.end());\r
+ }\r
+\r
+ private:\r
+ sender_set m_senders;\r
+ };\r
+\r
+ template<typename mt_policy>\r
+ class _signal_base0 : public _signal_base<mt_policy>\r
+ {\r
+ public:\r
+ typedef typename std::list<_connection_base0<mt_policy> *> connections_list;\r
+ typedef typename connections_list::const_iterator const_iterator;\r
+ typedef typename connections_list::iterator iterator;\r
+ _signal_base0()\r
+ {\r
+ ;\r
+ }\r
+\r
+ _signal_base0(const _signal_base0& s)\r
+ : _signal_base<mt_policy>(s)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ const_iterator it = s.m_connected_slots.begin();\r
+ const_iterator itEnd = s.m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ (*it)->getdest()->signal_connect(this);\r
+ m_connected_slots.push_back((*it)->clone());\r
+\r
+ ++it;\r
+ }\r
+ }\r
+\r
+ ~_signal_base0()\r
+ {\r
+ disconnect_all();\r
+ }\r
+\r
+ void disconnect_all()\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ const_iterator it = m_connected_slots.begin();\r
+ const_iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ (*it)->getdest()->signal_disconnect(this);\r
+ delete *it;\r
+\r
+ ++it;\r
+ }\r
+\r
+ m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());\r
+ }\r
+\r
+ void disconnect(has_slots<mt_policy>* pclass)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ iterator it = m_connected_slots.begin();\r
+ iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ if((*it)->getdest() == pclass)\r
+ {\r
+ delete *it;\r
+ m_connected_slots.erase(it);\r
+ pclass->signal_disconnect(this);\r
+ return;\r
+ }\r
+\r
+ ++it;\r
+ }\r
+ }\r
+\r
+ void slot_disconnect(has_slots<mt_policy>* pslot)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ iterator it = m_connected_slots.begin();\r
+ iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ iterator itNext = it;\r
+ ++itNext;\r
+\r
+ if((*it)->getdest() == pslot)\r
+ {\r
+ m_connected_slots.erase(it);\r
+ // delete *it;\r
+ }\r
+\r
+ it = itNext;\r
+ }\r
+ }\r
+\r
+ void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ iterator it = m_connected_slots.begin();\r
+ iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ if((*it)->getdest() == oldtarget)\r
+ {\r
+ m_connected_slots.push_back((*it)->duplicate(newtarget));\r
+ }\r
+\r
+ ++it;\r
+ }\r
+ }\r
+\r
+ protected:\r
+ connections_list m_connected_slots; \r
+ };\r
+\r
+ template<class arg1_type, class mt_policy>\r
+ class _signal_base1 : public _signal_base<mt_policy>\r
+ {\r
+ public:\r
+ typedef typename std::list<_connection_base1<arg1_type, mt_policy> *> connections_list;\r
+ typedef typename connections_list::const_iterator const_iterator;\r
+ typedef typename connections_list::iterator iterator;\r
+\r
+ _signal_base1()\r
+ {\r
+ ;\r
+ }\r
+\r
+ _signal_base1(const _signal_base1<arg1_type, mt_policy>& s)\r
+ : _signal_base<mt_policy>(s)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ const_iterator it = s.m_connected_slots.begin();\r
+ const_iterator itEnd = s.m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ (*it)->getdest()->signal_connect(this);\r
+ m_connected_slots.push_back((*it)->clone());\r
+\r
+ ++it;\r
+ }\r
+ }\r
+\r
+ void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ iterator it = m_connected_slots.begin();\r
+ iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ if((*it)->getdest() == oldtarget)\r
+ {\r
+ m_connected_slots.push_back((*it)->duplicate(newtarget));\r
+ }\r
+\r
+ ++it;\r
+ }\r
+ }\r
+\r
+ ~_signal_base1()\r
+ {\r
+ disconnect_all();\r
+ }\r
+\r
+ void disconnect_all()\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ const_iterator it = m_connected_slots.begin();\r
+ const_iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ (*it)->getdest()->signal_disconnect(this);\r
+ delete *it;\r
+\r
+ ++it;\r
+ }\r
+\r
+ m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());\r
+ }\r
+\r
+ void disconnect(has_slots<mt_policy>* pclass)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ iterator it = m_connected_slots.begin();\r
+ iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ if((*it)->getdest() == pclass)\r
+ {\r
+ delete *it;\r
+ m_connected_slots.erase(it);\r
+ pclass->signal_disconnect(this);\r
+ return;\r
+ }\r
+\r
+ ++it;\r
+ }\r
+ }\r
+\r
+ void slot_disconnect(has_slots<mt_policy>* pslot)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ iterator it = m_connected_slots.begin();\r
+ iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ iterator itNext = it;\r
+ ++itNext;\r
+\r
+ if((*it)->getdest() == pslot)\r
+ {\r
+ m_connected_slots.erase(it);\r
+ // delete *it;\r
+ }\r
+\r
+ it = itNext;\r
+ }\r
+ }\r
+\r
+\r
+ protected:\r
+ connections_list m_connected_slots; \r
+ };\r
+\r
+ template<class arg1_type, class arg2_type, class mt_policy>\r
+ class _signal_base2 : public _signal_base<mt_policy>\r
+ {\r
+ public:\r
+ typedef typename std::list<_connection_base2<arg1_type, arg2_type, mt_policy> *>\r
+ connections_list;\r
+ typedef typename connections_list::const_iterator const_iterator;\r
+ typedef typename connections_list::iterator iterator;\r
+\r
+ _signal_base2()\r
+ {\r
+ ;\r
+ }\r
+\r
+ _signal_base2(const _signal_base2<arg1_type, arg2_type, mt_policy>& s)\r
+ : _signal_base<mt_policy>(s)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ const_iterator it = s.m_connected_slots.begin();\r
+ const_iterator itEnd = s.m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ (*it)->getdest()->signal_connect(this);\r
+ m_connected_slots.push_back((*it)->clone());\r
+\r
+ ++it;\r
+ }\r
+ }\r
+\r
+ void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ iterator it = m_connected_slots.begin();\r
+ iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ if((*it)->getdest() == oldtarget)\r
+ {\r
+ m_connected_slots.push_back((*it)->duplicate(newtarget));\r
+ }\r
+\r
+ ++it;\r
+ }\r
+ }\r
+\r
+ ~_signal_base2()\r
+ {\r
+ disconnect_all();\r
+ }\r
+\r
+ void disconnect_all()\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ const_iterator it = m_connected_slots.begin();\r
+ const_iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ (*it)->getdest()->signal_disconnect(this);\r
+ delete *it;\r
+\r
+ ++it;\r
+ }\r
+\r
+ m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());\r
+ }\r
+\r
+ void disconnect(has_slots<mt_policy>* pclass)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ iterator it = m_connected_slots.begin();\r
+ iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ if((*it)->getdest() == pclass)\r
+ {\r
+ delete *it;\r
+ m_connected_slots.erase(it);\r
+ pclass->signal_disconnect(this);\r
+ return;\r
+ }\r
+\r
+ ++it;\r
+ }\r
+ }\r
+\r
+ void slot_disconnect(has_slots<mt_policy>* pslot)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ iterator it = m_connected_slots.begin();\r
+ iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ iterator itNext = it;\r
+ ++itNext;\r
+\r
+ if((*it)->getdest() == pslot)\r
+ {\r
+ m_connected_slots.erase(it);\r
+ // delete *it;\r
+ }\r
+\r
+ it = itNext;\r
+ }\r
+ }\r
+\r
+ protected:\r
+ connections_list m_connected_slots; \r
+ };\r
+ template<class arg1_type, class arg2_type, class arg3_type, class mt_policy>\r
+ class _signal_base3 : public _signal_base<mt_policy>\r
+ {\r
+ public:\r
+ typedef typename std::list<_connection_base3<arg1_type, arg2_type, arg3_type, mt_policy> *>\r
+ connections_list;\r
+ typedef typename connections_list::const_iterator const_iterator;\r
+ typedef typename connections_list::iterator iterator;\r
+ \r
+ _signal_base3()\r
+ {\r
+ ;\r
+ }\r
+\r
+ _signal_base3(const _signal_base3<arg1_type, arg2_type, arg3_type, mt_policy>& s)\r
+ : _signal_base<mt_policy>(s)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ const_iterator it = s.m_connected_slots.begin();\r
+ const_iterator itEnd = s.m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ (*it)->getdest()->signal_connect(this);\r
+ m_connected_slots.push_back((*it)->clone());\r
+\r
+ ++it;\r
+ }\r
+ }\r
+\r
+ void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ iterator it = m_connected_slots.begin();\r
+ iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ if((*it)->getdest() == oldtarget)\r
+ {\r
+ m_connected_slots.push_back((*it)->duplicate(newtarget));\r
+ }\r
+\r
+ ++it;\r
+ }\r
+ }\r
+\r
+ ~_signal_base3()\r
+ {\r
+ disconnect_all();\r
+ }\r
+\r
+ void disconnect_all()\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ const_iterator it = m_connected_slots.begin();\r
+ const_iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ (*it)->getdest()->signal_disconnect(this);\r
+ delete *it;\r
+\r
+ ++it;\r
+ }\r
+\r
+ m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());\r
+ }\r
+\r
+ void disconnect(has_slots<mt_policy>* pclass)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ iterator it = m_connected_slots.begin();\r
+ iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ if((*it)->getdest() == pclass)\r
+ {\r
+ delete *it;\r
+ m_connected_slots.erase(it);\r
+ pclass->signal_disconnect(this);\r
+ return;\r
+ }\r
+\r
+ ++it;\r
+ }\r
+ }\r
+\r
+ void slot_disconnect(has_slots<mt_policy>* pslot)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ iterator it = m_connected_slots.begin();\r
+ iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ iterator itNext = it;\r
+ ++itNext;\r
+\r
+ if((*it)->getdest() == pslot)\r
+ {\r
+ m_connected_slots.erase(it);\r
+ // delete *it;\r
+ }\r
+\r
+ it = itNext;\r
+ }\r
+ }\r
+\r
+ protected:\r
+ connections_list m_connected_slots; \r
+ };\r
+\r
+ template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, class mt_policy>\r
+ class _signal_base4 : public _signal_base<mt_policy>\r
+ {\r
+ public:\r
+ typedef typename std::list<_connection_base4<arg1_type, arg2_type, arg3_type,\r
+ arg4_type, mt_policy> *> connections_list;\r
+ typedef typename connections_list::const_iterator const_iterator;\r
+ typedef typename connections_list::iterator iterator;\r
+\r
+ _signal_base4()\r
+ {\r
+ ;\r
+ }\r
+\r
+ _signal_base4(const _signal_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>& s)\r
+ : _signal_base<mt_policy>(s)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ const_iterator it = s.m_connected_slots.begin();\r
+ const_iterator itEnd = s.m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ (*it)->getdest()->signal_connect(this);\r
+ m_connected_slots.push_back((*it)->clone());\r
+\r
+ ++it;\r
+ }\r
+ }\r
+\r
+ void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ iterator it = m_connected_slots.begin();\r
+ iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ if((*it)->getdest() == oldtarget)\r
+ {\r
+ m_connected_slots.push_back((*it)->duplicate(newtarget));\r
+ }\r
+\r
+ ++it;\r
+ }\r
+ }\r
+\r
+ ~_signal_base4()\r
+ {\r
+ disconnect_all();\r
+ }\r
+\r
+ void disconnect_all()\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ const_iterator it = m_connected_slots.begin();\r
+ const_iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ (*it)->getdest()->signal_disconnect(this);\r
+ delete *it;\r
+\r
+ ++it;\r
+ }\r
+\r
+ m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());\r
+ }\r
+\r
+ void disconnect(has_slots<mt_policy>* pclass)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ iterator it = m_connected_slots.begin();\r
+ iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ if((*it)->getdest() == pclass)\r
+ {\r
+ delete *it;\r
+ m_connected_slots.erase(it);\r
+ pclass->signal_disconnect(this);\r
+ return;\r
+ }\r
+\r
+ ++it;\r
+ }\r
+ }\r
+\r
+ void slot_disconnect(has_slots<mt_policy>* pslot)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ iterator it = m_connected_slots.begin();\r
+ iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ iterator itNext = it;\r
+ ++itNext;\r
+\r
+ if((*it)->getdest() == pslot)\r
+ {\r
+ m_connected_slots.erase(it);\r
+ // delete *it;\r
+ }\r
+\r
+ it = itNext;\r
+ }\r
+ }\r
+\r
+ protected:\r
+ connections_list m_connected_slots; \r
+ };\r
+\r
+#if 0\r
+ template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,\r
+ class arg5_type, class mt_policy>\r
+ class _signal_base5 : public _signal_base<mt_policy>\r
+ {\r
+ public:\r
+ typedef typename std::list<_connection_base5<arg1_type, arg2_type, arg3_type,\r
+ arg4_type, arg5_type, mt_policy> *> connections_list;\r
+ typedef typename connections_list::const_iterator const_iterator;\r
+ typedef typename connections_list::iterator iterator;\r
+\r
+ _signal_base5()\r
+ {\r
+ ;\r
+ }\r
+\r
+ _signal_base5(const _signal_base5<arg1_type, arg2_type, arg3_type, arg4_type,\r
+ arg5_type, mt_policy>& s)\r
+ : _signal_base<mt_policy>(s)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ connections_list::const_iterator it = s.m_connected_slots.begin();\r
+ connections_list::const_iterator itEnd = s.m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ (*it)->getdest()->signal_connect(this);\r
+ m_connected_slots.push_back((*it)->clone());\r
+\r
+ ++it;\r
+ }\r
+ }\r
+\r
+ void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ connections_list::iterator it = m_connected_slots.begin();\r
+ connections_list::iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ if((*it)->getdest() == oldtarget)\r
+ {\r
+ m_connected_slots.push_back((*it)->duplicate(newtarget));\r
+ }\r
+\r
+ ++it;\r
+ }\r
+ }\r
+\r
+ ~_signal_base5()\r
+ {\r
+ disconnect_all();\r
+ }\r
+\r
+ void disconnect_all()\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ connections_list::const_iterator it = m_connected_slots.begin();\r
+ connections_list::const_iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ (*it)->getdest()->signal_disconnect(this);\r
+ delete *it;\r
+\r
+ ++it;\r
+ }\r
+\r
+ m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());\r
+ }\r
+\r
+ void disconnect(has_slots<mt_policy>* pclass)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ connections_list::iterator it = m_connected_slots.begin();\r
+ connections_list::iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ if((*it)->getdest() == pclass)\r
+ {\r
+ delete *it;\r
+ m_connected_slots.erase(it);\r
+ pclass->signal_disconnect(this);\r
+ return;\r
+ }\r
+\r
+ ++it;\r
+ }\r
+ }\r
+\r
+ void slot_disconnect(has_slots<mt_policy>* pslot)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ connections_list::iterator it = m_connected_slots.begin();\r
+ connections_list::iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ connections_list::iterator itNext = it;\r
+ ++itNext;\r
+\r
+ if((*it)->getdest() == pslot)\r
+ {\r
+ m_connected_slots.erase(it);\r
+ // delete *it;\r
+ }\r
+\r
+ it = itNext;\r
+ }\r
+ }\r
+\r
+ protected:\r
+ connections_list m_connected_slots; \r
+ };\r
+\r
+ template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,\r
+ class arg5_type, class arg6_type, class mt_policy>\r
+ class _signal_base6 : public _signal_base<mt_policy>\r
+ {\r
+ public:\r
+ typedef typename std::list<_connection_base6<arg1_type, arg2_type, arg3_type, \r
+ arg4_type, arg5_type, arg6_type, mt_policy> *> connections_list;\r
+ typedef typename connections_list::const_iterator const_iterator;\r
+ typedef typename connections_list::iterator iterator;\r
+\r
+ _signal_base6()\r
+ {\r
+ ;\r
+ }\r
+\r
+ _signal_base6(const _signal_base6<arg1_type, arg2_type, arg3_type, arg4_type,\r
+ arg5_type, arg6_type, mt_policy>& s)\r
+ : _signal_base<mt_policy>(s)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ connections_list::const_iterator it = s.m_connected_slots.begin();\r
+ connections_list::const_iterator itEnd = s.m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ (*it)->getdest()->signal_connect(this);\r
+ m_connected_slots.push_back((*it)->clone());\r
+\r
+ ++it;\r
+ }\r
+ }\r
+\r
+ void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ connections_list::iterator it = m_connected_slots.begin();\r
+ connections_list::iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ if((*it)->getdest() == oldtarget)\r
+ {\r
+ m_connected_slots.push_back((*it)->duplicate(newtarget));\r
+ }\r
+\r
+ ++it;\r
+ }\r
+ }\r
+\r
+ ~_signal_base6()\r
+ {\r
+ disconnect_all();\r
+ }\r
+\r
+ void disconnect_all()\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ connections_list::const_iterator it = m_connected_slots.begin();\r
+ connections_list::const_iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ (*it)->getdest()->signal_disconnect(this);\r
+ delete *it;\r
+\r
+ ++it;\r
+ }\r
+\r
+ m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());\r
+ }\r
+\r
+ void disconnect(has_slots<mt_policy>* pclass)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ connections_list::iterator it = m_connected_slots.begin();\r
+ connections_list::iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ if((*it)->getdest() == pclass)\r
+ {\r
+ delete *it;\r
+ m_connected_slots.erase(it);\r
+ pclass->signal_disconnect(this);\r
+ return;\r
+ }\r
+\r
+ ++it;\r
+ }\r
+ }\r
+\r
+ void slot_disconnect(has_slots<mt_policy>* pslot)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ connections_list::iterator it = m_connected_slots.begin();\r
+ connections_list::iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ connections_list::iterator itNext = it;\r
+ ++itNext;\r
+\r
+ if((*it)->getdest() == pslot)\r
+ {\r
+ m_connected_slots.erase(it);\r
+ // delete *it;\r
+ }\r
+\r
+ it = itNext;\r
+ }\r
+ }\r
+\r
+ protected:\r
+ connections_list m_connected_slots; \r
+ };\r
+\r
+ template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,\r
+ class arg5_type, class arg6_type, class arg7_type, class mt_policy>\r
+ class _signal_base7 : public _signal_base<mt_policy>\r
+ {\r
+ public:\r
+ typedef typename std::list<_connection_base7<arg1_type, arg2_type, arg3_type, \r
+ arg4_type, arg5_type, arg6_type, arg7_type, mt_policy> *> connections_list;\r
+ typedef typename connections_list::const_iterator const_iterator;\r
+ typedef typename connections_list::iterator iterator;\r
+\r
+ _signal_base7()\r
+ {\r
+ ;\r
+ }\r
+\r
+ _signal_base7(const _signal_base7<arg1_type, arg2_type, arg3_type, arg4_type,\r
+ arg5_type, arg6_type, arg7_type, mt_policy>& s)\r
+ : _signal_base<mt_policy>(s)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ connections_list::const_iterator it = s.m_connected_slots.begin();\r
+ connections_list::const_iterator itEnd = s.m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ (*it)->getdest()->signal_connect(this);\r
+ m_connected_slots.push_back((*it)->clone());\r
+\r
+ ++it;\r
+ }\r
+ }\r
+\r
+ void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ connections_list::iterator it = m_connected_slots.begin();\r
+ connections_list::iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ if((*it)->getdest() == oldtarget)\r
+ {\r
+ m_connected_slots.push_back((*it)->duplicate(newtarget));\r
+ }\r
+\r
+ ++it;\r
+ }\r
+ }\r
+\r
+ ~_signal_base7()\r
+ {\r
+ disconnect_all();\r
+ }\r
+\r
+ void disconnect_all()\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ connections_list::const_iterator it = m_connected_slots.begin();\r
+ connections_list::const_iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ (*it)->getdest()->signal_disconnect(this);\r
+ delete *it;\r
+\r
+ ++it;\r
+ }\r
+\r
+ m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());\r
+ }\r
+\r
+ void disconnect(has_slots<mt_policy>* pclass)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ connections_list::iterator it = m_connected_slots.begin();\r
+ connections_list::iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ if((*it)->getdest() == pclass)\r
+ {\r
+ delete *it;\r
+ m_connected_slots.erase(it);\r
+ pclass->signal_disconnect(this);\r
+ return;\r
+ }\r
+\r
+ ++it;\r
+ }\r
+ }\r
+\r
+ void slot_disconnect(has_slots<mt_policy>* pslot)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ connections_list::iterator it = m_connected_slots.begin();\r
+ connections_list::iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ connections_list::iterator itNext = it;\r
+ ++itNext;\r
+\r
+ if((*it)->getdest() == pslot)\r
+ {\r
+ m_connected_slots.erase(it);\r
+ // delete *it;\r
+ }\r
+\r
+ it = itNext;\r
+ }\r
+ }\r
+\r
+ protected:\r
+ connections_list m_connected_slots; \r
+ };\r
+\r
+ template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,\r
+ class arg5_type, class arg6_type, class arg7_type, class arg8_type, class mt_policy>\r
+ class _signal_base8 : public _signal_base<mt_policy>\r
+ {\r
+ public:\r
+ typedef typename std::list<_connection_base8<arg1_type, arg2_type, arg3_type, \r
+ arg4_type, arg5_type, arg6_type, arg7_type, arg8_type, mt_policy> *>\r
+ connections_list;\r
+ typedef typename connections_list::const_iterator const_iterator;\r
+ typedef typename connections_list::iterator iterator;\r
+\r
+ _signal_base8()\r
+ {\r
+ ;\r
+ }\r
+\r
+ _signal_base8(const _signal_base8<arg1_type, arg2_type, arg3_type, arg4_type,\r
+ arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>& s)\r
+ : _signal_base<mt_policy>(s)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ connections_list::const_iterator it = s.m_connected_slots.begin();\r
+ connections_list::const_iterator itEnd = s.m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ (*it)->getdest()->signal_connect(this);\r
+ m_connected_slots.push_back((*it)->clone());\r
+\r
+ ++it;\r
+ }\r
+ }\r
+\r
+ void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ connections_list::iterator it = m_connected_slots.begin();\r
+ connections_list::iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ if((*it)->getdest() == oldtarget)\r
+ {\r
+ m_connected_slots.push_back((*it)->duplicate(newtarget));\r
+ }\r
+\r
+ ++it;\r
+ }\r
+ }\r
+\r
+ ~_signal_base8()\r
+ {\r
+ disconnect_all();\r
+ }\r
+\r
+ void disconnect_all()\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ connections_list::const_iterator it = m_connected_slots.begin();\r
+ connections_list::const_iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ (*it)->getdest()->signal_disconnect(this);\r
+ delete *it;\r
+\r
+ ++it;\r
+ }\r
+\r
+ m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());\r
+ }\r
+\r
+ void disconnect(has_slots<mt_policy>* pclass)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ connections_list::iterator it = m_connected_slots.begin();\r
+ connections_list::iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ if((*it)->getdest() == pclass)\r
+ {\r
+ delete *it;\r
+ m_connected_slots.erase(it);\r
+ pclass->signal_disconnect(this);\r
+ return;\r
+ }\r
+\r
+ ++it;\r
+ }\r
+ }\r
+\r
+ void slot_disconnect(has_slots<mt_policy>* pslot)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ connections_list::iterator it = m_connected_slots.begin();\r
+ connections_list::iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ connections_list::iterator itNext = it;\r
+ ++itNext;\r
+\r
+ if((*it)->getdest() == pslot)\r
+ {\r
+ m_connected_slots.erase(it);\r
+ // delete *it;\r
+ }\r
+\r
+ it = itNext;\r
+ }\r
+ }\r
+\r
+ protected:\r
+ connections_list m_connected_slots; \r
+ };\r
+\r
+#endif\r
+\r
+ template<typename dest_type, typename mt_policy>\r
+ class _connection0 : public _connection_base0<mt_policy>\r
+ {\r
+ public:\r
+ _connection0()\r
+ {\r
+ m_pobject = NULL;\r
+ m_pmemfun = NULL;\r
+ }\r
+\r
+ _connection0(dest_type* pobject, void (dest_type::*pmemfun)())\r
+ {\r
+ m_pobject = pobject;\r
+ m_pmemfun = pmemfun;\r
+ }\r
+\r
+ virtual _connection_base0<mt_policy>* clone()\r
+ {\r
+ return new _connection0<dest_type, mt_policy>(*this);\r
+ }\r
+\r
+ virtual _connection_base0<mt_policy>* duplicate(has_slots<mt_policy>* pnewdest)\r
+ {\r
+ return new _connection0<dest_type, mt_policy>((dest_type *)pnewdest, m_pmemfun);\r
+ }\r
+\r
+ virtual void emit()\r
+ {\r
+ (m_pobject->*m_pmemfun)();\r
+ }\r
+\r
+ virtual has_slots<mt_policy>* getdest() const\r
+ {\r
+ return m_pobject;\r
+ }\r
+\r
+ private:\r
+ dest_type* m_pobject;\r
+ void (dest_type::* m_pmemfun)();\r
+ };\r
+\r
+ template<class dest_type, class arg1_type, class mt_policy>\r
+ class _connection1 : public _connection_base1<arg1_type, mt_policy>\r
+ {\r
+ public:\r
+ _connection1()\r
+ {\r
+ m_pobject = NULL;\r
+ m_pmemfun = NULL;\r
+ }\r
+\r
+ _connection1(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type))\r
+ {\r
+ m_pobject = pobject;\r
+ m_pmemfun = pmemfun;\r
+ }\r
+\r
+ virtual _connection_base1<arg1_type, mt_policy>* clone()\r
+ {\r
+ return new _connection1<dest_type, arg1_type, mt_policy>(*this);\r
+ }\r
+\r
+ virtual _connection_base1<arg1_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest)\r
+ {\r
+ return new _connection1<dest_type, arg1_type, mt_policy>((dest_type *)pnewdest, m_pmemfun);\r
+ }\r
+\r
+ virtual void emit(arg1_type a1)\r
+ {\r
+ (m_pobject->*m_pmemfun)(a1);\r
+ }\r
+\r
+ virtual has_slots<mt_policy>* getdest() const\r
+ {\r
+ return m_pobject;\r
+ }\r
+\r
+ private:\r
+ dest_type* m_pobject;\r
+ void (dest_type::* m_pmemfun)(arg1_type);\r
+ };\r
+\r
+ template<class dest_type, class arg1_type, class arg2_type, class mt_policy>\r
+ class _connection2 : public _connection_base2<arg1_type, arg2_type, mt_policy>\r
+ {\r
+ public:\r
+ _connection2()\r
+ {\r
+ m_pobject = NULL;\r
+ m_pmemfun = NULL;\r
+ }\r
+\r
+ _connection2(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type,\r
+ arg2_type))\r
+ {\r
+ m_pobject = pobject;\r
+ m_pmemfun = pmemfun;\r
+ }\r
+\r
+ virtual _connection_base2<arg1_type, arg2_type, mt_policy>* clone()\r
+ {\r
+ return new _connection2<dest_type, arg1_type, arg2_type, mt_policy>(*this);\r
+ }\r
+\r
+ virtual _connection_base2<arg1_type, arg2_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest)\r
+ {\r
+ return new _connection2<dest_type, arg1_type, arg2_type, mt_policy>((dest_type *)pnewdest, m_pmemfun);\r
+ }\r
+\r
+ virtual void emit(arg1_type a1, arg2_type a2)\r
+ {\r
+ (m_pobject->*m_pmemfun)(a1, a2);\r
+ }\r
+\r
+ virtual has_slots<mt_policy>* getdest() const\r
+ {\r
+ return m_pobject;\r
+ }\r
+\r
+ private:\r
+ dest_type* m_pobject;\r
+ void (dest_type::* m_pmemfun)(arg1_type, arg2_type);\r
+ };\r
+\r
+ template<class dest_type, class arg1_type, class arg2_type, class arg3_type, class mt_policy>\r
+ class _connection3 : public _connection_base3<arg1_type, arg2_type, arg3_type, mt_policy>\r
+ {\r
+ public:\r
+ _connection3()\r
+ {\r
+ m_pobject = NULL;\r
+ m_pmemfun = NULL;\r
+ }\r
+\r
+ _connection3(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type,\r
+ arg2_type, arg3_type))\r
+ {\r
+ m_pobject = pobject;\r
+ m_pmemfun = pmemfun;\r
+ }\r
+\r
+ virtual _connection_base3<arg1_type, arg2_type, arg3_type, mt_policy>* clone()\r
+ {\r
+ return new _connection3<dest_type, arg1_type, arg2_type, arg3_type, mt_policy>(*this);\r
+ }\r
+\r
+ virtual _connection_base3<arg1_type, arg2_type, arg3_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest)\r
+ {\r
+ return new _connection3<dest_type, arg1_type, arg2_type, arg3_type, mt_policy>((dest_type *)pnewdest, m_pmemfun);\r
+ }\r
+\r
+ virtual void emit(arg1_type a1, arg2_type a2, arg3_type a3)\r
+ {\r
+ (m_pobject->*m_pmemfun)(a1, a2, a3);\r
+ }\r
+\r
+ virtual has_slots<mt_policy>* getdest() const\r
+ {\r
+ return m_pobject;\r
+ }\r
+\r
+ private:\r
+ dest_type* m_pobject;\r
+ void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type);\r
+ };\r
+\r
+ template<class dest_type, class arg1_type, class arg2_type, class arg3_type,\r
+ class arg4_type, class mt_policy>\r
+ class _connection4 : public _connection_base4<arg1_type, arg2_type,\r
+ arg3_type, arg4_type, mt_policy>\r
+ {\r
+ public:\r
+ _connection4()\r
+ {\r
+ m_pobject = NULL;\r
+ m_pmemfun = NULL;\r
+ }\r
+\r
+ _connection4(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type,\r
+ arg2_type, arg3_type, arg4_type))\r
+ {\r
+ m_pobject = pobject;\r
+ m_pmemfun = pmemfun;\r
+ }\r
+\r
+ virtual _connection_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>* clone()\r
+ {\r
+ return new _connection4<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>(*this);\r
+ }\r
+\r
+ virtual _connection_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest)\r
+ {\r
+ return new _connection4<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>((dest_type *)pnewdest, m_pmemfun);\r
+ }\r
+\r
+ virtual void emit(arg1_type a1, arg2_type a2, arg3_type a3, \r
+ arg4_type a4)\r
+ {\r
+ (m_pobject->*m_pmemfun)(a1, a2, a3, a4);\r
+ }\r
+\r
+ virtual has_slots<mt_policy>* getdest() const\r
+ {\r
+ return m_pobject;\r
+ }\r
+\r
+ private:\r
+ dest_type* m_pobject;\r
+ void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type,\r
+ arg4_type);\r
+ };\r
+\r
+ template<class dest_type, class arg1_type, class arg2_type, class arg3_type,\r
+ class arg4_type, class arg5_type, class mt_policy>\r
+ class _connection5 : public _connection_base5<arg1_type, arg2_type,\r
+ arg3_type, arg4_type, arg5_type, mt_policy>\r
+ {\r
+ public:\r
+ _connection5()\r
+ {\r
+ m_pobject = NULL;\r
+ m_pmemfun = NULL;\r
+ }\r
+\r
+ _connection5(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type,\r
+ arg2_type, arg3_type, arg4_type, arg5_type))\r
+ {\r
+ m_pobject = pobject;\r
+ m_pmemfun = pmemfun;\r
+ }\r
+\r
+ virtual _connection_base5<arg1_type, arg2_type, arg3_type, arg4_type, \r
+ arg5_type, mt_policy>* clone()\r
+ {\r
+ return new _connection5<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, \r
+ arg5_type, mt_policy>(*this);\r
+ }\r
+\r
+ virtual _connection_base5<arg1_type, arg2_type, arg3_type, arg4_type, \r
+ arg5_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest)\r
+ {\r
+ return new _connection5<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, \r
+ arg5_type, mt_policy>((dest_type *)pnewdest, m_pmemfun);\r
+ }\r
+\r
+ virtual void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4,\r
+ arg5_type a5)\r
+ {\r
+ (m_pobject->*m_pmemfun)(a1, a2, a3, a4, a5);\r
+ }\r
+\r
+ virtual has_slots<mt_policy>* getdest() const\r
+ {\r
+ return m_pobject;\r
+ }\r
+\r
+ private:\r
+ dest_type* m_pobject;\r
+ void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type, arg4_type,\r
+ arg5_type);\r
+ };\r
+\r
+ template<class dest_type, class arg1_type, class arg2_type, class arg3_type,\r
+ class arg4_type, class arg5_type, class arg6_type, class mt_policy>\r
+ class _connection6 : public _connection_base6<arg1_type, arg2_type,\r
+ arg3_type, arg4_type, arg5_type, arg6_type, mt_policy>\r
+ {\r
+ public:\r
+ _connection6()\r
+ {\r
+ m_pobject = NULL;\r
+ m_pmemfun = NULL;\r
+ }\r
+\r
+ _connection6(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type,\r
+ arg2_type, arg3_type, arg4_type, arg5_type, arg6_type))\r
+ {\r
+ m_pobject = pobject;\r
+ m_pmemfun = pmemfun;\r
+ }\r
+\r
+ virtual _connection_base6<arg1_type, arg2_type, arg3_type, arg4_type, \r
+ arg5_type, arg6_type, mt_policy>* clone()\r
+ {\r
+ return new _connection6<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, \r
+ arg5_type, arg6_type, mt_policy>(*this);\r
+ }\r
+\r
+ virtual _connection_base6<arg1_type, arg2_type, arg3_type, arg4_type, \r
+ arg5_type, arg6_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest)\r
+ {\r
+ return new _connection6<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, \r
+ arg5_type, arg6_type, mt_policy>((dest_type *)pnewdest, m_pmemfun);\r
+ }\r
+\r
+ virtual void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4,\r
+ arg5_type a5, arg6_type a6)\r
+ {\r
+ (m_pobject->*m_pmemfun)(a1, a2, a3, a4, a5, a6);\r
+ }\r
+\r
+ virtual has_slots<mt_policy>* getdest() const\r
+ {\r
+ return m_pobject;\r
+ }\r
+\r
+ private:\r
+ dest_type* m_pobject;\r
+ void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type, arg4_type,\r
+ arg5_type, arg6_type);\r
+ };\r
+\r
+ template<class dest_type, class arg1_type, class arg2_type, class arg3_type,\r
+ class arg4_type, class arg5_type, class arg6_type, class arg7_type, class mt_policy>\r
+ class _connection7 : public _connection_base7<arg1_type, arg2_type,\r
+ arg3_type, arg4_type, arg5_type, arg6_type, arg7_type, mt_policy>\r
+ {\r
+ public:\r
+ _connection7()\r
+ {\r
+ m_pobject = NULL;\r
+ m_pmemfun = NULL;\r
+ }\r
+\r
+ _connection7(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type,\r
+ arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, arg7_type))\r
+ {\r
+ m_pobject = pobject;\r
+ m_pmemfun = pmemfun;\r
+ }\r
+\r
+ virtual _connection_base7<arg1_type, arg2_type, arg3_type, arg4_type, \r
+ arg5_type, arg6_type, arg7_type, mt_policy>* clone()\r
+ {\r
+ return new _connection7<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, \r
+ arg5_type, arg6_type, arg7_type, mt_policy>(*this);\r
+ }\r
+\r
+ virtual _connection_base7<arg1_type, arg2_type, arg3_type, arg4_type, \r
+ arg5_type, arg6_type, arg7_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest)\r
+ {\r
+ return new _connection7<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, \r
+ arg5_type, arg6_type, arg7_type, mt_policy>((dest_type *)pnewdest, m_pmemfun);\r
+ }\r
+\r
+ virtual void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4,\r
+ arg5_type a5, arg6_type a6, arg7_type a7)\r
+ {\r
+ (m_pobject->*m_pmemfun)(a1, a2, a3, a4, a5, a6, a7);\r
+ }\r
+\r
+ virtual has_slots<mt_policy>* getdest() const\r
+ {\r
+ return m_pobject;\r
+ }\r
+\r
+ private:\r
+ dest_type* m_pobject;\r
+ void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type, arg4_type,\r
+ arg5_type, arg6_type, arg7_type);\r
+ };\r
+\r
+ template<class dest_type, class arg1_type, class arg2_type, class arg3_type,\r
+ class arg4_type, class arg5_type, class arg6_type, class arg7_type, \r
+ class arg8_type, class mt_policy>\r
+ class _connection8 : public _connection_base8<arg1_type, arg2_type,\r
+ arg3_type, arg4_type, arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>\r
+ {\r
+ public:\r
+ _connection8()\r
+ {\r
+ m_pobject = NULL;\r
+ m_pmemfun = NULL;\r
+ }\r
+\r
+ _connection8(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type,\r
+ arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, \r
+ arg7_type, arg8_type))\r
+ {\r
+ m_pobject = pobject;\r
+ m_pmemfun = pmemfun;\r
+ }\r
+\r
+ virtual _connection_base8<arg1_type, arg2_type, arg3_type, arg4_type, \r
+ arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>* clone()\r
+ {\r
+ return new _connection8<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, \r
+ arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>(*this);\r
+ }\r
+\r
+ virtual _connection_base8<arg1_type, arg2_type, arg3_type, arg4_type, \r
+ arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest)\r
+ {\r
+ return new _connection8<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, \r
+ arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>((dest_type *)pnewdest, m_pmemfun);\r
+ }\r
+\r
+ virtual void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4,\r
+ arg5_type a5, arg6_type a6, arg7_type a7, arg8_type a8)\r
+ {\r
+ (m_pobject->*m_pmemfun)(a1, a2, a3, a4, a5, a6, a7, a8);\r
+ }\r
+\r
+ virtual has_slots<mt_policy>* getdest() const\r
+ {\r
+ return m_pobject;\r
+ }\r
+\r
+ private:\r
+ dest_type* m_pobject;\r
+ void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type, arg4_type,\r
+ arg5_type, arg6_type, arg7_type, arg8_type);\r
+ };\r
+\r
+ template<typename mt_policy = SIGSLOT_DEFAULT_MT_POLICY>\r
+ class signal0 : public _signal_base0<mt_policy>\r
+ {\r
+ public:\r
+ signal0()\r
+ {\r
+ ;\r
+ }\r
+\r
+ signal0(const signal0<mt_policy>& s)\r
+ : _signal_base0<mt_policy>(s)\r
+ {\r
+ ;\r
+ }\r
+\r
+ template<typename desttype>\r
+ void connect(desttype* pclass, void (desttype::*pmemfun)())\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ _connection0<desttype, mt_policy>* conn = \r
+ new _connection0<desttype, mt_policy>(pclass, pmemfun);\r
+ _signal_base0<mt_policy>::m_connected_slots.push_back(conn);\r
+ pclass->signal_connect(this);\r
+ }\r
+\r
+ void emit()\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ typename _signal_base0<mt_policy>::const_iterator itNext, it = this->m_connected_slots.begin();\r
+ //::sigslot::_signal_base0<mt_policy>::const_iterator itNext, it = m_connected_slots.begin();\r
+ typename _signal_base0<mt_policy>::const_iterator itEnd = this->m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ itNext = it;\r
+ ++itNext;\r
+\r
+ (*it)->emit();\r
+\r
+ it = itNext;\r
+ }\r
+ }\r
+\r
+ void operator()()\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ typename _signal_base0<mt_policy>::const_iterator itNext, it = this->m_connected_slots.begin();\r
+ typename _signal_base0<mt_policy>::const_iterator itEnd = this->m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ itNext = it;\r
+ ++itNext;\r
+\r
+ (*it)->emit();\r
+\r
+ it = itNext;\r
+ }\r
+ }\r
+ };\r
+\r
+ template<class arg1_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>\r
+ class signal1 : public _signal_base1<arg1_type, mt_policy>\r
+ {\r
+ public:\r
+ signal1()\r
+ {\r
+ ;\r
+ }\r
+\r
+ signal1(const signal1<arg1_type, mt_policy>& s)\r
+ : _signal_base1<arg1_type, mt_policy>(s)\r
+ {\r
+ ;\r
+ }\r
+\r
+ template<class desttype>\r
+ void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type))\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ _connection1<desttype, arg1_type, mt_policy>* conn = \r
+ new _connection1<desttype, arg1_type, mt_policy>(pclass, pmemfun);\r
+ this->m_connected_slots.push_back(conn);\r
+ pclass->signal_connect(this);\r
+ }\r
+\r
+ void emit(arg1_type a1)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ typename _signal_base1<arg1_type,mt_policy>::const_iterator itNext, it = this->m_connected_slots.begin();\r
+ typename _signal_base1<arg1_type,mt_policy>::const_iterator itEnd = this->m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ itNext = it;\r
+ ++itNext;\r
+\r
+ (*it)->emit(a1);\r
+\r
+ it = itNext;\r
+ }\r
+ }\r
+\r
+ void operator()(arg1_type a1)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ typename _signal_base1<arg1_type,mt_policy>::const_iterator itNext, it = this->m_connected_slots.begin();\r
+ typename _signal_base1<arg1_type,mt_policy>::const_iterator itEnd = this->m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ itNext = it;\r
+ ++itNext;\r
+\r
+ (*it)->emit(a1);\r
+\r
+ it = itNext;\r
+ }\r
+ }\r
+ };\r
+ \r
+ template<typename arg1_type, typename arg2_type, typename mt_policy = SIGSLOT_DEFAULT_MT_POLICY>\r
+ class signal2 : public _signal_base2<arg1_type, arg2_type, mt_policy>\r
+ {\r
+ public:\r
+ signal2()\r
+ {\r
+ ;\r
+ }\r
+\r
+ signal2(const signal2<arg1_type, arg2_type, mt_policy>& s)\r
+ : _signal_base2<arg1_type, arg2_type, mt_policy>(s)\r
+ {\r
+ ;\r
+ }\r
+\r
+ template<typename desttype>\r
+ void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type,\r
+ arg2_type))\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ _connection2<desttype, arg1_type, arg2_type, mt_policy>* conn = new\r
+ _connection2<desttype, arg1_type, arg2_type, mt_policy>(pclass, pmemfun);\r
+ this->m_connected_slots.push_back(conn);\r
+ pclass->signal_connect(this);\r
+ }\r
+\r
+ void emit(arg1_type a1, arg2_type a2)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ typename _signal_base2<arg1_type,arg2_type,mt_policy>::const_iterator itNext, it = this->m_connected_slots.begin();\r
+ typename _signal_base2<arg1_type,arg2_type,mt_policy>::const_iterator itEnd = this->m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ itNext = it;\r
+ ++itNext;\r
+\r
+ (*it)->emit(a1, a2);\r
+\r
+ it = itNext;\r
+ }\r
+ }\r
+\r
+ void operator()(arg1_type a1, arg2_type a2)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ typename _signal_base2<arg1_type,arg2_type,mt_policy>::const_iterator itNext, it = this->m_connected_slots.begin();\r
+ typename _signal_base2<arg1_type,arg2_type,mt_policy>::const_iterator itEnd = this->m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ itNext = it;\r
+ ++itNext;\r
+\r
+ (*it)->emit(a1, a2);\r
+\r
+ it = itNext;\r
+ }\r
+ }\r
+ };\r
+\r
+ template<class arg1_type, class arg2_type, class arg3_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>\r
+ class signal3 : public _signal_base3<arg1_type, arg2_type, arg3_type, mt_policy>\r
+ {\r
+ public:\r
+ signal3()\r
+ {\r
+ ;\r
+ }\r
+\r
+ signal3(const signal3<arg1_type, arg2_type, arg3_type, mt_policy>& s)\r
+ : _signal_base3<arg1_type, arg2_type, arg3_type, mt_policy>(s)\r
+ {\r
+ ;\r
+ }\r
+\r
+ template<class desttype>\r
+ void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type,\r
+ arg2_type, arg3_type))\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ _connection3<desttype, arg1_type, arg2_type, arg3_type, mt_policy>* conn = \r
+ new _connection3<desttype, arg1_type, arg2_type, arg3_type, mt_policy>(pclass,\r
+ pmemfun);\r
+ this->m_connected_slots.push_back(conn);\r
+ pclass->signal_connect(this);\r
+ }\r
+\r
+ void emit(arg1_type a1, arg2_type a2, arg3_type a3)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ typename _signal_base3<arg1_type,arg2_type,arg3_type,mt_policy>::const_iterator itNext, it = this->m_connected_slots.begin();\r
+ typename _signal_base3<arg1_type,arg2_type,arg3_type,mt_policy>::const_iterator itEnd = this->m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ itNext = it;\r
+ ++itNext;\r
+\r
+ (*it)->emit(a1, a2, a3);\r
+\r
+ it = itNext;\r
+ }\r
+ }\r
+\r
+ void operator()(arg1_type a1, arg2_type a2, arg3_type a3)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ typename _signal_base3<arg1_type,arg2_type,arg3_type,mt_policy>::const_iterator itNext, it = this->m_connected_slots.begin();\r
+ typename _signal_base3<arg1_type,arg2_type,arg3_type,mt_policy>::const_iterator itEnd = this->m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ itNext = it;\r
+ ++itNext;\r
+\r
+ (*it)->emit(a1, a2, a3);\r
+\r
+ it = itNext;\r
+ }\r
+ }\r
+ };\r
+\r
+ template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>\r
+ class signal4 : public _signal_base4<arg1_type, arg2_type, arg3_type,\r
+ arg4_type, mt_policy>\r
+ {\r
+ public:\r
+ signal4()\r
+ {\r
+ ;\r
+ }\r
+\r
+ signal4(const signal4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>& s)\r
+ : _signal_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>(s)\r
+ {\r
+ ;\r
+ }\r
+\r
+ template<class desttype>\r
+ void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type,\r
+ arg2_type, arg3_type, arg4_type))\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ _connection4<desttype, arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>*\r
+ conn = new _connection4<desttype, arg1_type, arg2_type, arg3_type,\r
+ arg4_type, mt_policy>(pclass, pmemfun);\r
+ this->m_connected_slots.push_back(conn);\r
+ pclass->signal_connect(this);\r
+ }\r
+\r
+ void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ typename _signal_base4<arg1_type,arg2_type,arg3_type,arg4_type,mt_policy>::const_iterator itNext, it = this->m_connected_slots.begin();\r
+ typename _signal_base4<arg1_type,arg2_type,arg3_type,arg4_type,mt_policy>::const_iterator itEnd = this->m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ itNext = it;\r
+ ++itNext;\r
+\r
+ (*it)->emit(a1, a2, a3, a4);\r
+\r
+ it = itNext;\r
+ }\r
+ }\r
+\r
+ void operator()(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ typename _signal_base4<arg1_type,arg2_type,arg3_type,arg4_type,mt_policy>::const_iterator itNext, it = this->m_connected_slots.begin();\r
+ typename _signal_base4<arg1_type,arg2_type,arg3_type,arg4_type,mt_policy>::const_iterator itEnd = this->m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ itNext = it;\r
+ ++itNext;\r
+\r
+ (*it)->emit(a1, a2, a3, a4);\r
+\r
+ it = itNext;\r
+ }\r
+ }\r
+ };\r
+\r
+#if 0\r
+ template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,\r
+ class arg5_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>\r
+ class signal5 : public _signal_base5<arg1_type, arg2_type, arg3_type,\r
+ arg4_type, arg5_type, mt_policy>\r
+ {\r
+ public:\r
+ signal5()\r
+ {\r
+ ;\r
+ }\r
+\r
+ signal5(const signal5<arg1_type, arg2_type, arg3_type, arg4_type,\r
+ arg5_type, mt_policy>& s)\r
+ : _signal_base5<arg1_type, arg2_type, arg3_type, arg4_type,\r
+ arg5_type, mt_policy>(s)\r
+ {\r
+ ;\r
+ }\r
+\r
+ template<class desttype>\r
+ void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type,\r
+ arg2_type, arg3_type, arg4_type, arg5_type))\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ _connection5<desttype, arg1_type, arg2_type, arg3_type, arg4_type,\r
+ arg5_type, mt_policy>* conn = new _connection5<desttype, arg1_type, arg2_type,\r
+ arg3_type, arg4_type, arg5_type, mt_policy>(pclass, pmemfun);\r
+ m_connected_slots.push_back(conn);\r
+ pclass->signal_connect(this);\r
+ }\r
+\r
+ void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4,\r
+ arg5_type a5)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ typename _signal_base0<mt_policy>::const_iterator itNext, it = this->m_connected_slots.begin();\r
+ typename _signal_base0<mt_policy>::const_iterator itEnd = this->m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ itNext = it;\r
+ ++itNext;\r
+\r
+ (*it)->emit(a1, a2, a3, a4, a5);\r
+\r
+ it = itNext;\r
+ }\r
+ }\r
+\r
+ void operator()(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4,\r
+ arg5_type a5)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ connections_list::const_iterator itNext, it = m_connected_slots.begin();\r
+ connections_list::const_iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ itNext = it;\r
+ ++itNext;\r
+\r
+ (*it)->emit(a1, a2, a3, a4, a5);\r
+\r
+ it = itNext;\r
+ }\r
+ }\r
+ };\r
+\r
+\r
+ template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,\r
+ class arg5_type, class arg6_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>\r
+ class signal6 : public _signal_base6<arg1_type, arg2_type, arg3_type,\r
+ arg4_type, arg5_type, arg6_type, mt_policy>\r
+ {\r
+ public:\r
+ signal6()\r
+ {\r
+ ;\r
+ }\r
+\r
+ signal6(const signal6<arg1_type, arg2_type, arg3_type, arg4_type,\r
+ arg5_type, arg6_type, mt_policy>& s)\r
+ : _signal_base6<arg1_type, arg2_type, arg3_type, arg4_type,\r
+ arg5_type, arg6_type, mt_policy>(s)\r
+ {\r
+ ;\r
+ }\r
+\r
+ template<class desttype>\r
+ void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type,\r
+ arg2_type, arg3_type, arg4_type, arg5_type, arg6_type))\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ _connection6<desttype, arg1_type, arg2_type, arg3_type, arg4_type,\r
+ arg5_type, arg6_type, mt_policy>* conn = \r
+ new _connection6<desttype, arg1_type, arg2_type, arg3_type,\r
+ arg4_type, arg5_type, arg6_type, mt_policy>(pclass, pmemfun);\r
+ m_connected_slots.push_back(conn);\r
+ pclass->signal_connect(this);\r
+ }\r
+\r
+ void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4,\r
+ arg5_type a5, arg6_type a6)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ connections_list::const_iterator itNext, it = m_connected_slots.begin();\r
+ connections_list::const_iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ itNext = it;\r
+ ++itNext;\r
+\r
+ (*it)->emit(a1, a2, a3, a4, a5, a6);\r
+\r
+ it = itNext;\r
+ }\r
+ }\r
+\r
+ void operator()(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4,\r
+ arg5_type a5, arg6_type a6)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ connections_list::const_iterator itNext, it = m_connected_slots.begin();\r
+ connections_list::const_iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ itNext = it;\r
+ ++itNext;\r
+\r
+ (*it)->emit(a1, a2, a3, a4, a5, a6);\r
+\r
+ it = itNext;\r
+ }\r
+ }\r
+ };\r
+\r
+ template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,\r
+ class arg5_type, class arg6_type, class arg7_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>\r
+ class signal7 : public _signal_base7<arg1_type, arg2_type, arg3_type,\r
+ arg4_type, arg5_type, arg6_type, arg7_type, mt_policy>\r
+ {\r
+ public:\r
+ signal7()\r
+ {\r
+ ;\r
+ }\r
+\r
+ signal7(const signal7<arg1_type, arg2_type, arg3_type, arg4_type,\r
+ arg5_type, arg6_type, arg7_type, mt_policy>& s)\r
+ : _signal_base7<arg1_type, arg2_type, arg3_type, arg4_type,\r
+ arg5_type, arg6_type, arg7_type, mt_policy>(s)\r
+ {\r
+ ;\r
+ }\r
+\r
+ template<class desttype>\r
+ void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type,\r
+ arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, \r
+ arg7_type))\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ _connection7<desttype, arg1_type, arg2_type, arg3_type, arg4_type,\r
+ arg5_type, arg6_type, arg7_type, mt_policy>* conn = \r
+ new _connection7<desttype, arg1_type, arg2_type, arg3_type,\r
+ arg4_type, arg5_type, arg6_type, arg7_type, mt_policy>(pclass, pmemfun);\r
+ m_connected_slots.push_back(conn);\r
+ pclass->signal_connect(this);\r
+ }\r
+\r
+ void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4,\r
+ arg5_type a5, arg6_type a6, arg7_type a7)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ connections_list::const_iterator itNext, it = m_connected_slots.begin();\r
+ connections_list::const_iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ itNext = it;\r
+ ++itNext;\r
+\r
+ (*it)->emit(a1, a2, a3, a4, a5, a6, a7);\r
+\r
+ it = itNext;\r
+ }\r
+ }\r
+\r
+ void operator()(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4,\r
+ arg5_type a5, arg6_type a6, arg7_type a7)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ connections_list::const_iterator itNext, it = m_connected_slots.begin();\r
+ connections_list::const_iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ itNext = it;\r
+ ++itNext;\r
+\r
+ (*it)->emit(a1, a2, a3, a4, a5, a6, a7);\r
+\r
+ it = itNext;\r
+ }\r
+ }\r
+ };\r
+\r
+ template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,\r
+ class arg5_type, class arg6_type, class arg7_type, class arg8_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>\r
+ class signal8 : public _signal_base8<arg1_type, arg2_type, arg3_type,\r
+ arg4_type, arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>\r
+ {\r
+ public:\r
+ signal8()\r
+ {\r
+ ;\r
+ }\r
+\r
+ signal8(const signal8<arg1_type, arg2_type, arg3_type, arg4_type,\r
+ arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>& s)\r
+ : _signal_base8<arg1_type, arg2_type, arg3_type, arg4_type,\r
+ arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>(s)\r
+ {\r
+ ;\r
+ }\r
+\r
+ template<class desttype>\r
+ void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type,\r
+ arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, \r
+ arg7_type, arg8_type))\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ _connection8<desttype, arg1_type, arg2_type, arg3_type, arg4_type,\r
+ arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>* conn = \r
+ new _connection8<desttype, arg1_type, arg2_type, arg3_type,\r
+ arg4_type, arg5_type, arg6_type, arg7_type, \r
+ arg8_type, mt_policy>(pclass, pmemfun);\r
+ m_connected_slots.push_back(conn);\r
+ pclass->signal_connect(this);\r
+ }\r
+\r
+ void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4,\r
+ arg5_type a5, arg6_type a6, arg7_type a7, arg8_type a8)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ connections_list::const_iterator itNext, it = m_connected_slots.begin();\r
+ connections_list::const_iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ itNext = it;\r
+ ++itNext;\r
+\r
+ (*it)->emit(a1, a2, a3, a4, a5, a6, a7, a8);\r
+\r
+ it = itNext;\r
+ }\r
+ }\r
+\r
+ void operator()(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4,\r
+ arg5_type a5, arg6_type a6, arg7_type a7, arg8_type a8)\r
+ {\r
+ lock_block<mt_policy> lock(this);\r
+ connections_list::const_iterator itNext, it = m_connected_slots.begin();\r
+ connections_list::const_iterator itEnd = m_connected_slots.end();\r
+\r
+ while(it != itEnd)\r
+ {\r
+ itNext = it;\r
+ ++itNext;\r
+\r
+ (*it)->emit(a1, a2, a3, a4, a5, a6, a7, a8);\r
+\r
+ it = itNext;\r
+ }\r
+ }\r
+ };\r
+#endif\r
+}; // namespace sigslot\r
+\r
+#endif // SIGSLOT_H__\r
+\r
--- /dev/null
+PROJECT(gsm-rrc)
+
+#EXEC_PROGRAM(cat ARGS ${CMAKE_CURRENT_SOURCE_DIR}/modules.txt OUTPUT_VARIABLE
+# CSTAMODULES)
+
+FILE(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/modules.txt GSMMODULES)
+
+FOREACH(ITEM ${GSMMODULES})
+ STRING(REGEX REPLACE "-" "_" HITEM ${ITEM})
+ SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/${HITEM}.h GENERATED)
+ SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/${ITEM}.cpp GENERATED)
+ SET(GSMRRCSRC ${GSMRRCSRC} ${CMAKE_CURRENT_BINARY_DIR}/${ITEM}.cpp)
+ SET(GSMRRCHDR ${CSTAV1HDR} ${CMAKE_CURRENT_BINARY_DIR}/${HITEM}.h)
+
+SET_DIRECTORY_PROPERTIES(PROPERTIES
+ ADDITIONAL_MAKE_CLEAN_FILES "${CMAKE_CURRENT_BINARY_DIR}/${ITEM}.cpp"
+ )
+
+SET_DIRECTORY_PROPERTIES(PROPERTIES
+ ADDITIONAL_MAKE_CLEAN_FILES "${CMAKE_CURRENT_BINARY_DIR}/${HITEM}.h"
+ )
+
+ENDFOREACH(ITEM)
+
+SET(GSM_PARSER_INC -I ${asn1-data-models_SOURCE_DIR}/gsm/)
+#SET(GSM_PARSER_OPT ${GSM_PARSER_INC} -fConstant-definitions.asn1)
+SET(GSM_PARSER_OPT ${GSM_PARSER_INC} -fpdu_cd.asn1)
+#SET(GSM_PARSER_OPT1 ${GSM_PARSER_OPT} -fInformationElements.asn1)
+SET(GSM_PARSER_OPT1 ${GSM_PARSER_OPT} -fpdu_ie.asn1)
+SET(GSM_PARSER_OPT2 ${GSM_PARSER_OPT1} -fpdu.asn1)
+SET(GSM_PARSER_OPT4 ${GSM_PARSER_OPT2} -frrc.asn1)
+#SET(GSM_PARSER_OPT3 ${GSM_PARSER_OPT2} -fInternode-definitions.asn1)
+SET(GSM_PARSER_OPT3 ${GSM_PARSER_OPT2} -fpdu_ind.asn1)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+IF(WITH_GSM)
+
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/Constant-definitions.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/Constant_definitions.h
+ COMMAND ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ ARGS ${GSM_PARSER_OPT} -o Constant-definitions
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ COMMENT "Build ConstantDefinitions.h and .cpp"
+)
+
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/InformationElements.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/InformationElements.h
+ COMMAND ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ ARGS ${GSM_PARSER_OPT1} -o InformationElements
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ COMMENT "Build InformationElements.h and .cpp"
+ )
+
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/PDU_definitions.h
+ ${CMAKE_CURRENT_BINARY_DIR}/PDU-definitions.cpp
+ COMMAND ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ ARGS ${GSM_PARSER_OPT2} -o PDU-definitions
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ COMMENT "Build PDU-definitions.h and .cpp"
+ )
+
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/Internode-definitions.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/Internode_definitions.h
+ COMMAND ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ ARGS ${GSM_PARSER_OPT3} -o Internode-definitions
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ COMMENT "Build Internode-definitions.h and .cpp"
+ )
+
+
+
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/Class_definitions.h
+ ${CMAKE_CURRENT_BINARY_DIR}/Class-definitions.cpp
+ COMMAND ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ ARGS ${GSM_PARSER_OPT4} -o Class-definitions
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ COMMENT "Build Class-definitions.h and .cpp"
+ )
+
+ADD_LIBRARY(gsmrrc
+ ${GSMRRCSRC}
+ )
+
+#ADD_EXECUTABLE(test_cstav1
+# main.cpp
+# )
+
+#TARGET_LINK_LIBRARIES(test_cstav1 cstav1 asn1)
+ENDIF(WITH_GSM)
--- /dev/null
+Constant-definitions
+InformationElements
+Class-definitions
+Internode-definitions
+PDU-definitions
--- /dev/null
+PROJECT(gsmmap)
+
+
+#EXEC_PROGRAM(cat ARGS ${CMAKE_CURRENT_SOURCE_DIR}/modules.txt OUTPUT_VARIABLE
+# CSTAMODULES)
+SET(GSMMAPDIR ${CMAKE_SOURCE_DIR}/../../../data-models/asn1/gsmmpa CACHE
+ STRING "GSMMAP ASN1 Source DIR")
+FILE(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/modules.txt GSMMAPMODULES)
+
+FOREACH(ITEM ${GSMMAPMODULES})
+ SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/${ITEM}.h GENERATED)
+ SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/${ITEM}.cpp GENERATED)
+ SET(GSMMAPSRC ${GSMRRCSRC} ${CMAKE_CURRENT_BINARY_DIR}/${ITEM}.cpp)
+ SET(GSMMAPHDR ${CSTAV1HDR} ${CMAKE_CURRENT_BINARY_DIR}/${ITEM}.h)
+
+SET_DIRECTORY_PROPERTIES(PROPERTIES
+ ADDITIONAL_MAKE_CLEAN_FILES "${CMAKE_CURRENT_BINARY_DIR}/${ITEM}.cpp"
+ )
+
+SET_DIRECTORY_PROPERTIES(PROPERTIES
+ ADDITIONAL_MAKE_CLEAN_FILES "${CMAKE_CURRENT_BINARY_DIR}/${ITEM}.h"
+ )
+
+ENDFOREACH(ITEM)
+
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+
+
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/DummyMap.cpp
+ COMMAND cat
+ ${GSMMAPDIR}/GSMMAP.asn1
+ ARGS | ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ COMMENT "Build InformationElements.h and .cpp"
+ )
+
+
+
+ADD_LIBRARY(gsmmmap
+ ${GSMMAPSRC}
+ )
+
+#ADD_EXECUTABLE(test_cstav1
+# main.cpp
+# )
+
+#TARGET_LINK_LIBRARIES(test_cstav1 cstav1 asn1)
--- /dev/null
+DummyMAP
+MAP-CommonDataTypes
+MAP-ExtensionDataTypes
+MAP-CH-DataTypes
--- /dev/null
+PROJECT(h248)
+
+SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
+ "${rules_SOURCE_DIR}/")
+
+OPTION(H248_ASN1_NESTED "Generated H248 nested code or not" ON)
+OPTION(H248_ASN1_COMMENT "Generate H248 with comment in source" OFF)
+
+FIND_PACKAGE(PCAP REQUIRED)
+INCLUDE_DIRECTORIES(${PCAP_INCLUDE_DIRS})
+
+FIND_PACKAGE(Sqlite3)
+FIND_PACKAGE(Fcgi)
+#EXEC_PROGRAM(cat ARGS ${CMAKE_CURRENT_SOURCE_DIR}/modules.txt OUTPUT_VARIABLE
+# CSTAMODULES)
+
+FILE(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/modules.txt H248MODULES)
+
+FOREACH(ITEM ${H248MODULES})
+ STRING(REGEX REPLACE "-" "_" HITEM ${ITEM})
+ SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/${HITEM}.h GENERATED)
+ SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/${ITEM}.cpp GENERATED)
+ SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/${ITEM}.lds GENERATED)
+ SET(H248SRC ${H248SRC} ${CMAKE_CURRENT_BINARY_DIR}/${ITEM}.cpp)
+ SET(H248HDR ${H248HDR} ${CMAKE_CURRENT_BINARY_DIR}/${HITEM}.h)
+ SET(H248LDS ${H248LDS} ${CMAKE_CURRENT_BINARY_DIR}/${ITEM}.lds)
+
+SET_DIRECTORY_PROPERTIES(PROPERTIES
+ ADDITIONAL_MAKE_CLEAN_FILES "${CMAKE_CURRENT_BINARY_DIR}/${ITEM}.cpp"
+ )
+
+SET_DIRECTORY_PROPERTIES(PROPERTIES
+ ADDITIONAL_MAKE_CLEAN_FILES "${CMAKE_CURRENT_BINARY_DIR}/${HITEM}.h"
+ )
+SET_DIRECTORY_PROPERTIES(PROPERTIES
+ ADDITIONAL_MAKE_CLEAN_FILES "${CMAKE_CURRENT_BINARY_DIR}/${ITEM}.lds"
+ )
+
+ENDFOREACH(ITEM)
+
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/MEDIA-GATEWAY-CONTROL.cpp COMPILE_FLAGS "-DASN1_ATTRIBUTE_OPTIONAL_AS_SHARED_POINTER")
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_SOURCE_DIR}/main.cpp COMPILE_FLAGS "-DASN1_ATTRIBUTE_OPTIONAL_AS_SHARED_POINTER")
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+
+#
+#
+#
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote_Operations_Information_Objects.h
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Information-Objects.cpp
+ COMMAND cat
+ ${asn1-data-models_SOURCE_DIR}/cstav1/Remote-Operations-Information-Objects.asn1
+ ARGS | ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ COMMENT "Build ROIO .h and .cpp"
+ )
+
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/Remote_Operations_Information_Objects.h
+ GENERATED)
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Information-Objects.cpp
+ GENERATED)
+
+SET_DIRECTORY_PROPERTIES(PROPERTIES
+ ADDITIONAL_MAKE_CLEAN_FILES
+ "${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Information-Objects.h ${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Information-Objects.cpp"
+ )
+
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${H248SRC}
+ ${H248HDR}
+ COMMAND ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ ARGS -n ${H248_ASN1_NESTED} -c ${H248_ASN1_COMMENT}
+ -I ${asn1-data-models_SOURCE_DIR}/h323/ -f h248v3.asn1 -o MEDIA-GATEWAY-CONTROL
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ COMMENT "Build H248 V3 library .h and .cpp"
+ )
+
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${H248LDS}
+ COMMAND ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ ARGS -n ${H248_ASN1_NESTED} -c ${H248_ASN1_COMMENT}
+ -I ${asn1-data-models_SOURCE_DIR}/h323/ -l lds -f h248v3.asn1 -o MEDIA-GATEWAY-CONTROL
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ COMMENT "Build H248 V3 library lds"
+ )
+
+
+
+ADD_LIBRARY(h248
+ ${H248SRC}
+ ${H248LDS}
+ )
+
+ADD_EXECUTABLE(test_h248
+ main.cpp
+ )
+
+TARGET_LINK_LIBRARIES(test_h248 h248 asn1)
+
+
+IF(APPLE)
+ #SET_TARGET_PROPERTIES(cstaspy PROPERTIES LINKER_FLAGS "-framework Cocoa")
+#Missing and don't know why
+#TARGET_LINK_LIBRARIES(cstaspy /usr/local/lib/libfltk_png.a)
+ENDIF(APPLE)
+
+IF(UNIX AND NOT APPLE)
+ #TARGET_LINK_LIBRARIES(cstaspy Ui X11 Xft Xinerama fltk_images)
+ENDIF()
+
+IF(WIN32)
+ #TARGET_LINK_LIBRARIES(cstaspy Ui ws2_32)
+ENDIF()
+
+#TARGET_LINK_LIBRARIES(cstaspy ${FLTK_LIBRARIES})
+#TARGET_LINK_LIBRARIES(cstaspy cstav1)
+#TARGET_LINK_LIBRARIES(cstaspy asn1)
+#TARGET_LINK_LIBRARIES(cstaspy ${PCAP_LIBRARIES})
+
+#
+# Install stuff
+#
+#INSTALL(TARGETS cstaspy DESTINATION bin)
+
+#
+# Ok start working with Packaging stuff
+#
+INCLUDE(InstallRequiredSystemLibraries)
+
+SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Graphical user interface to visualize
+csta phase 2 and sip messages from pcap files")
+SET(CPACK_PACKAGE_VENDOR "Aeb")
+#SET(CPACK_PACKAGE_DESCRIPTION_FILE "")
+#SET(CPACK_RESOURCE_FILE_LICENSE "")
+SET(CPACK_PACKAGE_VERSION_MAJOR "1")
+SET(CPACK_PACKAGE_VERSION_MINOR "0")
+SET(CPACK_PACKAGE_VERSION_PATCH "0")
+
+SET(CPACK_PACKAGE_FILE_NAME "CstaSpyInstaller")
+SET(CPACK_PACKAGE_NAME "CstaSpy")
+
+IF(WIN32)
+ SET(CPACK_GENERATOR "NSIS")
+ENDIF()
+
+IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux" )
+ SET(CPACK_GENERATOR "RPM")
+ENDIF()
+#SET(CPACK_PACKAGE_EXECUTABLES "cstaspy")
+#SET(CPACK_PACKAGE_EXECUTABLES "cstaspy" "CSTA Spy")
+INCLUDE(CPack)
--- /dev/null
+#include <iostream>
+#include <fstream>
+#include <string.h>
+#include <typeinfo>
+#include <stdlib.h>
+#include "rtasn1/asn1.h"
+#include "rtasn1/asn1_codec.h"
+#include "rtasn1/asn1_codec_ber.h"
+
+#include "MEDIA_GATEWAY_CONTROL.h"
+
+using namespace MEDIA_GATEWAY_CONTROL;
+
+void test_message() {
+ asn1::streams::ber ctx;
+ asn1::streams::ber ctx1;
+ ::asn1::types::debug_level = 8;
+ IP4Address ip4;
+ Message m;
+ m.version = 2;
+ ip4.address = std::string("0345");
+ ip4.portNumber = asn1::intrusive_ptr<INTEGER>(new INTEGER(asn1::prim::types::Integer(1045)));
+ //m.mId.ip4Address = ip4;
+ //m.mId.kind_ = Mid::typeof_ip4Address;
+ //m.mId.set_tag(asn1::tag(asn1::types::CONTEXT_SPECIFIC,Mid::typeof_ip4Address));
+ m.mId.set_tag(asn1::tag(asn1::types::CONTEXT_SPECIFIC,0));
+ //m.mId.set_ip4Address ( ip4 );
+ m.mId.get_ip4Address() = ip4 ;
+ std::cout<<m<<std::endl;
+ std::cout<<"IP4=\n"<<m.mId.get_ip4Address()<<std::endl;
+ m.encode(ctx1);
+
+ m.encode(ctx);
+}
+
+
+int main(int argc,char **argv)
+{
+ test_message();
+}
+
--- /dev/null
+MEDIA-GATEWAY-CONTROL
--- /dev/null
+PROJECT(h323-lib)
+
+
+#SET(WITH_H323 TRUE CACHE TYPE BOOLEAN)
+#EXEC_PROGRAM(cat ARGS ${CMAKE_CURRENT_SOURCE_DIR}/modules.txt OUTPUT_VARIABLE
+# CSTAMODULES)
+IF (WITH_H323)
+FILE(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/modules.txt H323MODULES)
+
+FOREACH(ITEM ${H323MODULES})
+ STRING(REGEX REPLACE "-" "_" HITEM ${ITEM})
+ SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/${HITEM}.h GENERATED)
+ SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/${ITEM}.cpp GENERATED)
+ SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/${ITEM}.cpp COMPILE_FLAGS "-DASN1_ATTRIBUTE_OPTIONAL_AS_SHARED_POINTER")
+ SET(H323SRC ${H323SRC} ${ITEM}.cpp)
+ SET(H323HDR ${H323HDR} ${HITEM}.h)
+ ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/${HITEM}.h
+ ${CMAKE_CURRENT_BINARY_DIR}/${ITEM}.cpp
+ COMMAND ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ ARGS -I ${asn1-data-models_SOURCE_DIR}/h323/
+ -f h2250v7.asn
+ -f H245v15.asn
+ -f h235-security-messages.asn1
+ -o ${ITEM}
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+# ${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Information-Objects.cpp
+ COMMENT "Build ${ITEM} .h and .cpp"
+ )
+
+ENDFOREACH(ITEM)
+
+SET_DIRECTORY_PROPERTIES(PROPERTIES
+ ADDITIONAL_MAKE_CLEAN_FILES "${H323SRC} ${H323HDR}"
+ )
+
+SET(ROSE_PARSER_INC -I ${asn1-data-models_SOURCE_DIR}/)
+SET(ROSE_PARSER_OPT ${ROSE_PARSER_INC} -fRemote-Operations-Generic-ROS-PDUs.asn1)
+SET(ROSE_PARSER_OPT ${ROSE_PARSER_OPT} -fRemote-Operations-Information-Objects.asn1)
+SET(ROSE_PARSER_OPT ${ROSE_PARSER_OPT}
+ -fRemote-Operations-Useful-Definitions.asn1)
+#
+#Remote-Operations-Generic-ROS-PDUs {joint-iso-itu-t remote-operations(4)
+#
+IF (FALSE)
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote_Operations_Generic_ROS_PDUs.h
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Generic-ROS-PDUs.cpp
+ COMMAND ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ ARGS ${ROSE_PARSER_OPT} -o Remote-Operations-Generic-ROS-PDUs
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ COMMENT "Build Remote-Operations-Generic-ROS-PDUs .h and .cpp"
+ )
+
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Generic-ROS-PDUs.h
+ GENERATED)
+#
+#
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote_Operations_Useful_Definitions.h
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Useful-Definitions.cpp
+ COMMAND ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ ARGS ${ROSE_PARSER_OPT} -o Remote-Operations-Useful-Definitions
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Generic-ROS-PDUs.cpp
+ COMMENT "Build Remote-Operations-Usful-Definitions .h and .cpp"
+ )
+
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Useful-Definitions.h
+ GENERATED)
+#
+#
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote_Operations_Information_Objects.h
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Information-Objects.cpp
+ COMMAND ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ ARGS ${ROSE_PARSER_OPT} -o Remote-Operations-Information-Objects
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Useful-Definitions.cpp
+ COMMENT "Build Remote-Operations-Informations-Objects .h and .cpp"
+ )
+
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Information-Objects.h
+ GENERATED)
+ENDIF(FALSE)
+
+ADD_LIBRARY(h323
+ ${H323SRC}
+ )
+
+ENDIF(WITH_H323)
--- /dev/null
+H323-MESSAGES
+MULTIMEDIA-SYSTEM-CONTROL
+H235-SECURITY-MESSAGES
--- /dev/null
+PROJECT(ledger-lib)
+
+SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
+ "${rules_SOURCE_DIR}/")
+
+FIND_PACKAGE(PCAP REQUIRED)
+INCLUDE_DIRECTORIES(${PCAP_INCLUDE_DIRS})
+
+FIND_PACKAGE(Sqlite3)
+FIND_PACKAGE(Fcgi)
+#EXEC_PROGRAM(cat ARGS ${CMAKE_CURRENT_SOURCE_DIR}/modules.txt OUTPUT_VARIABLE
+# CSTAMODULES)
+
+FILE(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/modules.txt LEDGERMODULES)
+SET(LEDGER_MODEL ${asn1-data-models_SOURCE_DIR}/ledger/ CACHE STRING "Ledger datamodel source directory")
+
+FOREACH(ITEM ${LEDGERMODULES})
+ STRING(REGEX REPLACE "-" "_" HITEM ${ITEM})
+ SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/${HITEM}.h GENERATED)
+ SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/${ITEM}.cpp GENERATED)
+ SET(LEDGERSRC ${LEDGERSRC} ${CMAKE_CURRENT_BINARY_DIR}/${ITEM}.cpp)
+ SET(LEDGERHDR ${LEDGERHDR} ${CMAKE_CURRENT_BINARY_DIR}/${HITEM}.h)
+
+ SET_DIRECTORY_PROPERTIES(PROPERTIES
+ ADDITIONAL_MAKE_CLEAN_FILES "${CMAKE_CURRENT_BINARY_DIR}/${ITEM}.cpp"
+ )
+
+ SET_DIRECTORY_PROPERTIES(PROPERTIES
+ ADDITIONAL_MAKE_CLEAN_FILES "${CMAKE_CURRENT_BINARY_DIR}/${HITEM}.h"
+ )
+ ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/${ITEM}.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/${HITEM}.h
+ COMMAND ${asn1p_EXE}
+ ARGS -e ber
+ -I ${asn1-data-models_SOURCE_DIR}/
+ -f cstav1/Remote-Operations-Information-Objects.asn1
+ -f /ledger/Ledger-definitions.asn1
+ -f /ledger/Ledger-bookkeeping.asn1
+ -f /ledger/Ledger-lifecycle.asn1
+ -f /ledger/Ledger-retrieve.asn1
+ -f /ledger/Ledger-error.asn1
+ -f /ledger/Ledger.asn1
+ -o ${ITEM}
+ DEPENDS ${asn1p_EXE}
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote_Operations_Information_Objects.h
+ COMMENT "Build Ledger .h and .cpp"
+ )
+
+ SET_DIRECTORY_PROPERTIES(PROPERTIES
+ ADDITIONAL_MAKE_CLEAN_FILES
+ "${CMAKE_CURRENT_BINARY_DIR}/${HITEM}.h
+ ${CMAKE_CURRENT_BINARY_DIR}/${ITEM}.cpp"
+ )
+ENDFOREACH(ITEM)
+
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+
+#
+#
+#
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote_Operations_Information_Objects.h
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Information-Objects.cpp
+ COMMAND ${asn1p_EXE}
+ ARGS -e ber
+ -I ${asn1-data-models_SOURCE_DIR}/cstav1/
+ -f Remote-Operations-Information-Objects.asn1
+ -o Remote-Operations-Information-Objects
+ DEPENDS ${asn1p_EXE}
+ COMMENT "Build ROIO .h and .cpp"
+ )
+
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/Remote_Operations_Information_Objects.h
+ GENERATED)
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Information-Objects.cpp
+ GENERATED)
+
+SET_DIRECTORY_PROPERTIES(PROPERTIES
+ ADDITIONAL_MAKE_CLEAN_FILES
+ "${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Information-Objects.h ${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Information-Objects.cpp"
+ )
+
+ADD_LIBRARY(ledger
+ ${LEDGERSRC}
+ )
+
+ADD_EXECUTABLE(test_ledger
+ main.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Information-Objects.cpp
+ )
+
+TARGET_LINK_LIBRARIES(test_ledger ledger asn1)
+
+
+IF(APPLE)
+ #SET_TARGET_PROPERTIES(cstaspy PROPERTIES LINKER_FLAGS "-framework Cocoa")
+#Missing and don't know why
+#TARGET_LINK_LIBRARIES(cstaspy /usr/local/lib/libfltk_png.a)
+ENDIF(APPLE)
+
+IF(UNIX AND NOT APPLE)
+ #TARGET_LINK_LIBRARIES(cstaspy Ui X11 Xft Xinerama fltk_images)
+ENDIF()
+
+IF(WIN32)
+ #TARGET_LINK_LIBRARIES(cstaspy Ui ws2_32)
+ENDIF()
+
+#TARGET_LINK_LIBRARIES(cstaspy ${FLTK_LIBRARIES})
+#TARGET_LINK_LIBRARIES(cstaspy cstav1)
+#TARGET_LINK_LIBRARIES(cstaspy asn1)
+#TARGET_LINK_LIBRARIES(cstaspy ${PCAP_LIBRARIES})
+
+#
+# Install stuff
+#
+#INSTALL(TARGETS cstaspy DESTINATION bin)
+
+#
+# Ok start working with Packaging stuff
+#
+INCLUDE(InstallRequiredSystemLibraries)
+
+SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Graphical user interface to visualize
+csta phase 2 and sip messages from pcap files")
+SET(CPACK_PACKAGE_VENDOR "Aeb")
+#SET(CPACK_PACKAGE_DESCRIPTION_FILE "")
+#SET(CPACK_RESOURCE_FILE_LICENSE "")
+SET(CPACK_PACKAGE_VERSION_MAJOR "1")
+SET(CPACK_PACKAGE_VERSION_MINOR "0")
+SET(CPACK_PACKAGE_VERSION_PATCH "0")
+
+SET(CPACK_PACKAGE_FILE_NAME "CstaSpyInstaller")
+SET(CPACK_PACKAGE_NAME "CstaSpy")
+
+IF(WIN32)
+ SET(CPACK_GENERATOR "NSIS")
+ENDIF()
+
+IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux" )
+ SET(CPACK_GENERATOR "RPM")
+ENDIF()
+#SET(CPACK_PACKAGE_EXECUTABLES "cstaspy")
+#SET(CPACK_PACKAGE_EXECUTABLES "cstaspy" "CSTA Spy")
+INCLUDE(CPack)
--- /dev/null
+
+#include <iostream>
+#include <fstream>
+#include <string.h>
+#include <typeinfo>
+#include <stdlib.h>
+#include "rtasn1/asn1.h"
+#include "rtasn1/asn1_codec.h"
+#include "rtasn1/asn1_codec_ber.h"
+
+#include "Ledger_Apdu.h"
+#include "Ledger_retrieve.hpp"
+#include "Ledger_lifecycle.hpp"
+#include "Ledger_Book_Keeping.hpp"
+
+/**
+
+ */
+
+void test()
+{
+ Ledger_Book_Keeping::postTransaction p;
+ Ledger_Book_Keeping::PostTransactionArgument arg;
+ Ledger_definitions::Date d;
+ Ledger_definitions::Entry e1,e2;
+ Ledger_definitions::AccountId a;
+ std::string s("Test entry");
+ asn1::prim::types::String s1("Jones");
+ asn1::prim::types::UTCTime tx("1307120000Z");
+ d.is_set = true;
+ d.time = asn1::prim::types::UTCTime(std::string("1212050000Z"));
+ p.get_ArgumentType(arg);
+
+ a = s1;
+ e1.acc_id = a;
+ e1.entry_date = d;
+ e1.description= s1;
+ e1.op = Ledger_definitions::DebitOrCredit::credit;
+ std::cout<<"Date:"<<d<<std::endl;
+ std::cout<<"Entry:"<<e1<<std::endl;
+ std::cout<<"postTransaction:";
+ p.printf(std::cout);
+}
+
+int main(int argc,char **argv)
+{
+
+ //CSTA_event_report_definitions::cSTAEventReport report;
+ //asn1::context ctx;
+
+ if (argc > 1) {
+ // Try to decode a stream ....
+ std::ifstream is;
+ is.open(argv[1],std::ios::binary);
+ int len = 0;
+ char bl[2];
+ }
+ std::cout<<"Hello world"<<std::endl;
+ test();
+}
--- /dev/null
+Ledger-lifecycle
+Ledger-definitions
+Ledger-Book-Keeping
+Ledger-retrieve
+Ledger-error
+Ledger-Apdu
--- /dev/null
+PROJECT(libgen)
+
+SET(OPT_GEN_SRC "")
+
+CONFIGURE_FILE(asn1_gen_config.h.in asn1_gen_config.h)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+IF (WITH_ASN1_GEN_UML)
+ SET(OPT_GEN_SRC ${OPT_GEN_SRC} uml/asn1_gen_uml.cpp)
+ENDIF(WITH_ASN1_GEN_UML)
+
+IF (WITH_ASN1_GEN_JS)
+ SET(OPT_GEN_SRC ${OPT_GEN_SRC} ${CMAKE_CURRENT_SOURCE_DIR}/js/asn1_gen_js.cpp)
+ENDIF(WITH_ASN1_GEN_JS)
+
+ SET(OPT_GEN_SRC ${OPT_GEN_SRC} lds/asn1_gen_lds.cpp)
+
+ADD_LIBRARY(libgen
+ asn1_gen_constraints.cpp
+ asn1_generator.cpp
+ asn1_gen_hpp.cpp
+ ${OPT_GEN_SRC}
+ asn1_gen_cpp.cpp
+ asn1_gen_codec_cpp.cpp
+ asn1_gen_auto_tag.cpp
+ asn1_gen_optimizer.cpp
+ cpp/cgcpp_helper.cpp
+ cpp/cgcpph_bitstring.cpp
+ cpp/cgcpph_enumerated.cpp
+ cpp/cgcpph_integer.cpp
+ cpp/cgcpph_octetstring.cpp
+ cpp/cgcpph_sequence.cpp
+ cpp/cgcpph_set.cpp
+ cpp/cgcpph_choice.cpp
+ cpp/cgcpph_typeref.cpp
+ cpp/cgcpph_object.cpp
+ cpp/cgcpph_import.cpp
+ cpp/cgcpph_boolean.cpp
+ cpp/cgcpph_oid.cpp
+ cpp/cgcpph_string.cpp
+ cpp/cgcpph_primitive.cpp
+ cpp/cgcpph_sequenceof.cpp
+ cpp/cgcpph_setof.cpp
+ cpp/cgcpph_real.cpp
+
+ cpp/cgh_object.cpp
+ cpp/cgh_construct.cpp
+
+ cpp/cghpp_helper.cpp
+ cpp/cgh_hconstruct.cpp
+ cpp/cghpph_bitstring.cpp
+ cpp/cghpph_classdef.cpp
+ cpp/cghpph_enumerated.cpp
+ cpp/cghpph_integer.cpp
+ cpp/cghpph_octetstring.cpp
+ cpp/cghpph_sequence.cpp
+ cpp/cghpph_choice.cpp
+ cpp/cghpph_set.cpp
+ cpp/cghpph_typeref.cpp
+ cpp/cghpph_object.cpp
+ cpp/cghpph_import.cpp
+ cpp/cghpph_oid.cpp
+ cpp/cghpph_boolean.cpp
+ cpp/cghpph_string.cpp
+ cpp/cghpph_primitive.cpp
+ cpp/cghpph_real.cpp
+ cpp/cghpph_sequenceof.cpp
+ cpp/cghpph_setof.cpp
+ )
--- /dev/null
+
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include "asn1_generator.h"
+
+#include "asn1_gen_auto_tag.h"
+
+namespace asn1
+{
+/**
+ * Default Cosntructor
+ */
+gen_auto_tag::gen_auto_tag(asn1::module *n) : asn1::generator(n)
+{}
+
+gen_auto_tag::gen_auto_tag(asn1::module *n,asn1::module::modules_type &m)
+ : asn1::generator(n,m)
+{
+}
+
+
+void
+gen_auto_tag::gen_typeref(std::ostream &os,typeref *type)
+{
+ GEN_LOG_DEBUG("type %s\n",type->name().c_str());
+}
+
+void
+gen_auto_tag::gen_seq(std::ostream &os,std::string &scope,asn1::sequence *type,bool priv)
+{
+ asn1::node *n= type->identifier();
+ asn1::node::iterator lit;
+ asn1::constructed *params = n->parameters();
+ int i = 0;
+
+ os<<scope<<"struct /*SEQUENCE */ "<<n->cpp_name()<<" {\n";
+ // default constructor
+ // I should probaly push optionnal attributes and OBEJECTS in a stack and add a initializer here.
+ for (asn1::node::iterator it = type->begin(); it != type->end() ; it++,i++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*it);
+ asn1::node *attr_type = f->get_type();
+ //TODO: is this correct ?
+ if (f->type_id()() == asn1::type::ASN1_EXTENSIBLE)
+ {
+ os<<scope<<"\t// Extensible marker strange this is the ..."<<std::endl;
+ i--;
+ }
+ if (attr_type != NULL)
+ {
+ asn1::node::tag_type tag;
+ tag.m_mode = asn1::node::tag_type::TM_IMPLICIT;
+ tag.m_class = asn1::node::tag_type::TC_CONTEXT_SPECIFIC;
+ tag.m_value = i;
+ switch (attr_type->type_id()())
+ {
+ case asn1::type::ASN1_SEQUENCE:
+ {
+ std::string s = scope+"\t";
+ attr_type->tag(tag);
+ gen_seq(os,s,attr_type->as_sequence());
+ }
+ break;
+ case asn1::type::ASN1_SET:
+ {
+ std::string s = scope+"\t";
+ attr_type->tag(tag);
+ gen_set(os,s,attr_type->as_set());
+ }
+ break;
+ case asn1::type::ASN1_CHOICE:
+ {
+ std::string s = scope+"\t";
+ tag.m_mode = asn1::node::tag_type::TM_EXPLICIT;
+ attr_type->tag(tag);
+ gen_choice(os,s,attr_type->as_choice());
+ }
+ break;
+ default:
+ attr_type->tag(tag);
+ ;
+ }
+ }
+
+ } // end for
+ os<<scope<<"};\n";
+}
+
+void
+gen_auto_tag::gen_set(std::ostream &os,std::string &scope,asn1::set *type,bool priv)
+{
+ asn1::node *n = type->identifier();
+ asn1::node::iterator lit;
+ asn1::node *params = n->parameters();
+ int i = 0;
+ /*
+ * Try to handler sequence of sequence
+ */
+#if 0
+ if ( type == NULL)
+ {
+ os<<scope<<"SET TYPE is NULL"<<std::endl;
+ type = n->as_set();
+ }
+#endif
+
+ os<<scope<<"struct /*SET */ "<<(n)->cpp_name()<<" {\n";
+ // default constructor
+ // I should probaly push optionnal attributes and OBEJECTS in a stack and add a initializer here.
+ for ( asn1::node::iterator it = type->begin()
+ ; it != type->end() ; it++,i++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*it);
+ asn1::node *attr_type = f->get_type();
+ if ((*it)->type_id()() == asn1::type::ASN1_EXTENSIBLE)
+ {
+ os<<scope<<"\t// Extensible marker strange this is the ..."<<std::endl;
+ i--;
+ }
+ if (attr_type != NULL)
+ {
+ asn1::node::tag_type tag;
+ tag.m_mode = asn1::node::tag_type::TM_IMPLICIT;
+ tag.m_class = asn1::node::tag_type::TC_CONTEXT_SPECIFIC;
+ tag.m_value = i;
+ switch (attr_type->type_id()())
+ {
+ case asn1::type::ASN1_SEQUENCE:
+ {
+ std::string s = scope+"\t";
+ attr_type->tag(tag);
+ gen_seq(os,s,attr_type->as_sequence());
+ }
+ break;
+ case asn1::type::ASN1_SET:
+ {
+ std::string s = scope+"\t";
+ attr_type->tag(tag);
+ gen_set(os,s,attr_type->as_set());
+ }
+ break;
+ case asn1::type::ASN1_CHOICE:
+ {
+ std::string s = scope+"\t";
+ tag.m_mode = asn1::node::tag_type::TM_EXPLICIT;
+ attr_type->tag(tag);
+ gen_choice(os,s,attr_type->as_choice());
+ }
+ break;
+ default:
+ attr_type->tag(tag);
+ ;
+ }
+ }
+
+ } // end for
+ os<<scope<<"};\n";
+}
+
+void
+gen_auto_tag::gen_choice(std::ostream &os,std::string &scope,asn1::choice *type,bool priv )
+{
+ asn1::node *n = type->identifier();
+ asn1::node::iterator it;
+ int i = 0;
+
+ it = type->begin();
+ asn1::node::iterator lit = type->begin();
+ os<<scope<<"struct /*CHOICE */ "<<(n)->cpp_name()<<" {\n";
+ // Parameter stuff here
+ // switch case
+ for (; lit != type->end() ; ++lit,i++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*lit);
+ asn1::node *attr_type = f->get_type();
+ if ((*lit)->type_id()() == asn1::type::ASN1_EXTENSIBLE)
+ {
+ os<<scope<<"\t// Extensible marker strange this is the ..."<<std::endl;
+ i--;
+ }
+ if (attr_type != NULL)
+ {
+ asn1::node::tag_type tag;
+ tag.m_mode = asn1::node::tag_type::TM_IMPLICIT;
+ tag.m_class = asn1::node::tag_type::TC_CONTEXT_SPECIFIC;
+ tag.m_value = i;
+ os<<scope<<"\t"<<(*lit)->cpp_name()<<" ["<<i<<"] "<<attr_type->name();
+ os<<std::endl;
+ switch (attr_type->type_id()())
+ {
+ case asn1::type::ASN1_SEQUENCE:
+ {
+ std::string s = scope+"\t";
+ attr_type->tag(tag);
+ gen_seq(os,s,attr_type->as_sequence());
+ }
+ break;
+ case asn1::type::ASN1_SET:
+ {
+ std::string s = scope+"\t";
+ attr_type->tag(tag);
+ gen_set(os,s,attr_type->as_set());
+ }
+ break;
+ case asn1::type::ASN1_CHOICE:
+ {
+ std::string s = scope+"\t";
+ tag.m_mode = asn1::node::tag_type::TM_EXPLICIT;
+ attr_type->tag(tag);
+ gen_choice(os,s,attr_type->as_choice());
+ }
+ break;
+ default:
+ attr_type->tag(tag);
+ ;
+ } // End switch
+ }
+ } //end for
+}
+
+
+void gen_auto_tag::gen_typedef(std::ostream &os,asn1::typenode *type)
+{
+
+ if (type != NULL)
+ switch (type->type_id()())
+ {
+ case asn1::type::ASN1_REFERENCE:
+ {
+ std::cout<<"__FUNCTION__"<<" ERROR "<<type->cpp_name()<<std::endl;
+ exit(0);
+ asn1::node *ns = NULL;
+ if (type->tag().m_value != -1)
+ {
+ if (type->tag().m_mode == asn1::node::tag_type::TM_IMPLICIT)
+ {
+ }
+ }
+
+ }
+ break;
+ case asn1::type::ASN1_INTEGER:
+ {
+ }
+ break;
+ case asn1::type::ASN1_SEQUENCE:
+ {
+ std::string scope("");
+ gen_seq(os,scope,type->as_sequence());
+ return ;
+ }
+ break;
+ case asn1::type::ASN1_SEQUENCE_OF:
+ {
+ asn1::node *ns = NULL;
+ asn1::typenode *seqof_type = type->get_eltype();
+ if (type_in_imports(seqof_type,&ns) ) {
+ } else {
+ switch (seqof_type->type_id()())
+ {
+ case asn1::type::ASN1_SEQUENCE:
+ {
+ std::string scope("\t");
+ seqof_type->name(type->identifier_cpp_name()+"_type");
+ gen_seq(os,scope,seqof_type->as_sequence());
+ }
+ break;
+ case asn1::type::ASN1_CHOICE:
+ case asn1::type::ASN1_SET:
+ default:
+ ;
+ }
+ }
+ }
+ break;
+ case asn1::type::ASN1_SET:
+ {
+ std::string scope("\t");
+ gen_set(os,scope,type->as_set());
+ return ;
+ }
+ break;
+ case asn1::type::ASN1_SET_OF:
+ {
+ }
+ break;
+ case asn1::type::ASN1_CHOICE:
+ {
+ std::string scope("\t");
+ gen_choice(os,scope,type->as_choice());
+ return;
+ }
+ break;
+ default:
+ ;
+ };
+
+
+}
+
+
+
+
+/**
+ *
+ */
+void gen_auto_tag::gen_module(std::ostream &os,asn1::module *n)
+{
+ asn1::import_list *imports = n->imports();
+ // Add include for external dependencies
+ asn1::node::tag_type t = n->tag();
+
+ if (imports != NULL)
+ {
+ for (asn1::node::iterator it = imports->begin(); it!= imports->end(); it++)
+ {
+ /**/
+ // Loop over items and check if OPERATION is imported
+ }
+
+ }
+
+
+ n->sort_childs();
+ asn1::node::iterator it = (n)->begin();
+
+ if (t.m_mode == asn1::node::tag_type::TM_AUTOMATIC)
+ {
+ for (; it != (n)->end() ; it++)
+ {
+ asn1::assignment *a = (*it)->as_assignment();
+ std::cout<<"gen_auto_tag::"<<__FUNCTION__<<" process "<<(*it)->name();
+ std::cout.flush();
+ if (a->get_type() != NULL)
+ {
+ if ( (*it)->is_generated())
+ {
+ std::cout<<" ALREADY PROCESSED "<<std::endl;
+ continue;
+ }
+ switch ( (*it)->meta_id()() )
+ {
+ case asn1::meta::VALUE:
+ {
+ }
+ break;
+ case asn1::meta::VALUESET:
+ {
+ }
+ break;
+ case asn1::meta::TYPE:
+ {
+ gen_typedef(os,a->get_type());
+ }
+ break;
+ case asn1::meta::TYPEREF:
+ {
+ gen_typeref(os,a->get_type()->as_typeref());
+ }
+ break;
+ case asn1::meta::OBJECT:
+ {
+ // gen_object(os,*it);
+ }
+ break;
+ case asn1::meta::OBJECTCLASS:
+ {
+ std::cout<<"gen_uto_tag::"<<__FUNCTION__<<"gen object_class OBJECT CLASS "<<(*it)->cpp_name()<<std::endl;
+ // gen_object_class(os,*it);
+ }
+ break;
+ default:
+ std::cerr<<"gen_auto_tag::"<<__FUNCTION__<<"undefinded meta for node: "<<(*it)->name()<<std::endl;
+ ;
+ }
+ os<<std::endl;
+ //(*it)->set_generated(true);
+ // No coloration for this
+ //(*it)->set_color(asn1::node::CL_RED);
+ } else
+ {
+ std::cout<<" no type "<<(*it)->name();
+ }
+ std::cout<<std::endl;
+ }
+ } else {
+ GEN_LOG_DEBUG("NO AUTOMATIC TAG for module %s\n",n->name().c_str());
+ }
+}
+
+
+}
--- /dev/null
+#ifndef ASN1_GENERATOR_AUTO_TAG_H__
+#define ASN1_GENERATOR_AUTO_TAG_H__
+#include <iostream>
+#include "asn1_generator.h"
+
+namespace asn1
+{
+
+class gen_auto_tag : public asn1::generator
+{
+ public:
+ gen_auto_tag(module *n = NULL) ;
+
+ gen_auto_tag(module *root_m,asn1::module::modules_type &m_) ;
+
+ virtual ~gen_auto_tag() {};
+
+ // Tells if a the structure should be in the form of templale
+ // or not
+
+ virtual void gen_const(std::ostream &os,node *) {} ;
+
+ virtual void gen_typedef(std::ostream &os,typenode *) ;
+
+ virtual void gen_typeref(std::ostream &os,typeref *) ;
+
+ virtual void gen_object(std::ostream &os,node *) {};
+
+ virtual void gen_module(std::ostream &os,module *) ;
+
+ void gen_seq(std::ostream &os,std::string &scope,asn1::sequence *n,bool priv = false);
+
+ void gen_set(std::ostream &os,std::string &scope,asn1::set *n,bool priv = false);
+
+ void gen_choice(std::ostream &os,std::string &scope,asn1::choice *n,bool priv = false);
+
+ /* Usefull object functions */
+ protected:
+};
+
+}
+
+/*
+ * vim:et:sw=2:ts=2
+ */
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include <fstream>
+
+#include "asn1_gen_config.h"
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <errno.h>
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_DIRECT_H
+#include <direct.h>
+#endif
+
+
+#include "asn1_generator.h"
+
+
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_codec_cpp.h"
+// helper classes to split
+#include "asn1_generator_helper.h"
+#include "cpp/cgcpp_helper.h"
+#include "cpp/cgh_construct.h"
+#include "cpp/cgcpph_sequence.h"
+#include "cpp/cgcpph_set.h"
+#include "cpp/cgcpph_choice.h"
+#include "cpp/cgcpph_primitive.h"
+#include "cpp/cgcpph_enumerated.h"
+#include "cpp/cgcpph_octetstring.h"
+#include "cpp/cgcpph_bitstring.h"
+#include "cpp/cgcpph_integer.h"
+#include "cpp/cgcpph_typeref.h"
+#include "cpp/cgh_object.h"
+#include "cpp/cgcpph_object.h"
+#include "cpp/cgcpph_import.h"
+#include "cpp/cgcpph_boolean.h"
+#include "cpp/cgcpph_oid.h"
+#include "cpp/cgcpph_string.h"
+#include "cpp/cgcpph_sequenceof.h"
+#include "cpp/cgcpph_setof.h"
+#include "adt/asn1_visitor.h"
+
+
+generate_codec_cpp::generate_codec_cpp(asn1::module *n,asn1::module::modules_type &m,gen_constraints &c)
+ : generate_cpp(n,m),m_gen_constraints(c)
+{
+
+}
+/**
+ * generate template instantiation in .hpp file
+ *
+ */
+struct gen_include_hpp
+{
+ gen_include_hpp(std::ostream &os,generate_codec_cpp &g)
+ : m_os(os), m_Gen(g)
+ {
+ }
+
+ void operator ()(asn1::module *n)
+ {
+ if (!std::string("Remote-Operations-Useful-Definitions")
+ .compare(n->name()))
+ {
+ m_os<<"#include \""<<n->cpp_name()<<".h\"\n";
+ }
+ m_os<<"#include \""<<n->cpp_name()<<".hpp\"\n";
+ }
+ protected:
+ std::ostream &m_os;
+ generate_codec_cpp &m_Gen;
+};
+
+class do_gencpp_assignment : public assignment_visitor<do_gencpp_assignment>
+{
+ protected:
+ generate_codec_cpp &m_gen;
+ std::ostream &m_os;
+ std::fstream &m_sep_os; /* separe file for each assignment */
+ std::fstream &m_log;
+ public:
+ do_gencpp_assignment( generate_codec_cpp &_h
+ , std::ostream &os
+ , std::fstream &sos
+ )
+ : m_os(os),m_gen(_h),m_log(_h.logger())
+ , m_sep_os(sos)
+ {};
+ // Main processing function per assignment
+ void operator ()(asn1::node *n)
+ {
+ asn1::typenode *type = n->as_assignment()->get_type();
+ std::string path = n->cpp_name()+".cpp";
+ GEN_LOG_DEBUG( "Process item=%s meta=%d\n"
+ , n->name().c_str()
+ , n->meta_id()());
+ if ( ! type)
+ return;
+
+ if ( n->is_generated())
+ {
+ GEN_LOG_DEBUG("%s already generated\n",n->name().c_str());
+ return;
+ }
+ if (m_gen.with_split_cpp())
+ {
+ m_gen.open_assignment_stream(m_sep_os,n->as_assignment());
+ m_gen.gen_include_header(m_sep_os);
+ }
+ visit(n->as_assignment());
+ if (m_sep_os.is_open())
+ m_sep_os.close();
+
+ n->set_color(asn1::node::CL_RED);
+ }
+#define ASSIGNMENT(Ty,Code) \
+ void visit_##Ty(asn1::Ty##_assignment *a) Code
+
+ ASSIGNMENT(typeref,{
+ int params = (a->parameters() != NULL)?1:0;
+ // Try to create an include file
+ GEN_LOG_DEBUG( "meta of %s is TYPEREF parameterized: %d\n"
+ , a->name().c_str(),params);
+ if (m_sep_os.is_open())
+ {
+ m_gen.gen_typeref(m_sep_os,a->get_type()->as_typeref());
+ } else
+ m_gen.gen_typeref(m_os,a->get_type()->as_typeref());
+ })
+ ASSIGNMENT(type,{
+ int params = (a->parameters() != NULL)?1:0;
+ // Try to create an include file
+ GEN_LOG_DEBUG( "meta of %s is TYPE parameterized: %d\n"
+ , a->name().c_str(),params);
+ if (m_sep_os.is_open())
+ {
+ m_gen.gen_typedef(m_sep_os,a->get_type());
+ } else
+ m_gen.gen_typedef(m_os,a->get_type());
+ })
+ ASSIGNMENT(value,{
+ GEN_LOG_DEBUG("meta of %s is VALUE\n",a->name().c_str());
+ m_gen.gen_const(m_os,a->get_type());
+ })
+ ASSIGNMENT(valueset,{
+ GEN_LOG_DEBUG( "meta of %s is VALUESET do nothing ?\n"
+ , a->name().c_str());
+ m_gen.gen_const(m_os,a->get_type());
+ })
+ ASSIGNMENT(object,{
+ int params = (a->parameters() != NULL)?1:0;
+ // Try to create an include file
+ GEN_LOG_DEBUG( "meta of %s is OBJECT parameterized: %d\n"
+ , a->name().c_str(),params);
+ if (m_sep_os.is_open())
+ {
+ m_gen.gen_object(m_sep_os,a);
+ } else
+ m_gen.gen_object(m_os,a);
+ })
+ ASSIGNMENT(objectclass,{
+ })
+ ASSIGNMENT(objectset,{
+ GEN_LOG_DEBUG("meta of %s is OBJECT SET\n",a->name().c_str());
+ m_gen.gen_objectset(m_os,*a->get_objectset());
+ })
+ ASSIGNMENT(objectfield,{})
+
+};
+
+
+/**
+ * Create directory for cpp files.
+ * current dir"/" module cpp_name
+ */
+bool
+generate_codec_cpp::make_module_dir(asn1::module *_module)
+{
+ struct stat st;
+
+ if (stat(m_module_path.c_str(),&st) == -1) {
+#ifdef WIN32
+ _mkdir(m_module_path.c_str());
+#else
+ mkdir(m_module_path.c_str(),0777);
+#endif
+ }
+ return true;
+}
+
+
+bool
+generate_codec_cpp::open_assignment_stream(std::fstream &_stream,asn1::assignment *_a)
+{
+ std::string f (m_module_path);
+ f+= "/" + _a->cpp_name()+".cpp";
+ _stream.open(f.c_str(),std::fstream::out);
+ return _stream.is_open();
+}
+
+
+void
+generate_codec_cpp::generate_constraints(std::ostream &os)
+{
+ gen_constraints::constraintSetIterator it = m_gen_constraints.begin();
+ os<<"static asn1::types::constraint_desc gConstraints[] = {\n";
+ os<<"\t { asn1::types::un_constrained ,0 ,0 }\n";
+ for (; it != m_gen_constraints.end()
+ ; ++it)
+ {
+ asn1::constraint &_constraint(*(*it).m_constraint);
+
+ switch ( _constraint.type())
+ {
+ case asn1::constraint::CT_SIZE:
+ {
+ asn1::ctype_size *cts = _constraint.as_constraint_size();
+ assert((cts != NULL) && "cts is NULL not good");
+ if (asn1::celt_value *cv = cts->get_value())
+ {
+ assert(cv->get_valuetype() && "get_valuetype returned NULL");
+ os<<"\t, { asn1::types::partial_constrained ,"<<cv->get_valuetype()->value_long()<<" ,0 }\n";
+ } else if (asn1::constraint_range *cr = cts->get_range())
+ {
+ long _min,_max;
+ if (! cr->get_min_max(_min,_max))
+ {
+ std::cerr<<"generate_constraints size get_min_max error !!! "<<cr->name()<<std::endl;
+ }
+ os<<"\t, /*size*/{ asn1::types::fixed_constrained ,"<<_min<<" ,"<<_max<<" }\n";
+ }
+ }
+ break;
+ case asn1::constraint::EL_RANGE:
+ case asn1::constraint::EL_LLRANGE:
+ case asn1::constraint::EL_RLRANGE:
+ case asn1::constraint::EL_ULRANGE:
+ {
+ if (asn1::constraint_range *cr = _constraint.as_constraint_range())
+ {
+ long _min,_max;
+ if (! cr->get_min_max(_min,_max))
+ {
+ std::cerr<<"generate_constraints get_min_max error !!! "<<cr->name()<<std::endl;
+ }
+ os<<"\t, { asn1::types::fixed_constrained ,"<<_min<<" ,"<<_max<<" }\n";
+ }
+ }
+ break;
+ case asn1::constraint::EL_TYPE:
+ {
+ os<<"\t, { asn1::types::un_constrained ,1 ,0 }\n";
+ }
+ default:
+ os<<"\t, { asn1::types::un_constrained ,2 ,"<<_constraint.type()<<"}\n";
+ ;
+ }
+ }
+ os<<"};\n";
+}
+
+/**
+ *
+ */
+void generate_codec_cpp::gen_include_header(std::ostream &os)
+{
+ asn1::module::modules_type modules_with_objects;
+ asn1::import_list *imports = m_module->imports();
+ os<<"//\n// Automatic c++ generated code by asn1p copyright @ Andre EBERSOLD 2018 - 2022\n";
+ os<<"// using namespace "<<m_module->cpp_name()<<""<<std::endl;
+ os<<"// Do NOT MODIFY\n//"<<std::endl;
+ os<<"#include \"assert.h\""<<std::endl;
+ os<<"#include \"rtasn1/asn1_config.h\""<<std::endl;
+ os<<"#include \"rtasn1/asn1.h\""<<std::endl;
+ os<<"#include \"rtasn1/asn1_codec.h\""<<std::endl;
+ os<<"#include \"rtasn1/asn1_codec_ber.h\""<<std::endl;
+
+ if (with_jer())
+ os<<"#include \"rtasn1/asn1_codec_jer.h\""<<std::endl;
+ if (with_oer())
+ os<<"#include \"rtasn1/asn1_codec_oer.h\""<<std::endl;
+ if (with_per())
+ os<<"#include \"rtasn1/asn1_codec_per.h\""<<std::endl;
+ os<<"\n\n";
+
+ if (imports != NULL)
+ {
+ for (asn1::node::iterator it = imports->begin()
+ ; it!= imports->end(); it++)
+ {
+ asn1::import *import = dynamic_cast<asn1::import *>( *it);
+ if (import)
+ {
+ cgcpph_import imp_gen(*this,os,*import);
+ imp_gen.generate();
+ // Keep modules with objects
+ asn1::module *mi = m_resolver.module(import->identifier()->name());
+ if (mi && mi->has_objects())
+ {
+ modules_with_objects.push_back(mi);
+ } else
+ {
+ os<<"// Module "<<import->name()<<" no objects"<<std::endl;
+ }
+ }
+ }
+ }
+
+
+ os<<"#include \""<<m_module->cpp_name()<<".h\""<<std::endl;
+ os<<"\n\n";
+ // Include template header implementation here
+ std::for_each( modules_with_objects.begin()
+ , modules_with_objects.end()
+ , gen_include_hpp(os,*this)
+ );
+ if (m_module->has_objects())
+ os<<"#include \""<<m_module->cpp_name()<<".hpp\""<<std::endl;
+
+}
+/**
+ *
+ */
+void generate_codec_cpp::gen_module(std::ostream &os,asn1::module *n)
+{
+ asn1::module::modules_type modules_with_objects;
+ asn1::import_list *imports = n->imports();
+#ifdef WIN32
+ char *cd = _getcwd(NULL,0);
+#else
+ char *cd = getcwd(NULL,0);
+#endif
+ std::string cdir(cd);
+ m_module_path = cdir+"/"+m_module->cpp_name();
+ delete cd;
+
+ GEN_LOG_DEBUG("MODULE %s path=%s\n"
+ , n->name().c_str()
+ , m_module_path.c_str()
+ );
+ std::cout<<"gen_codec_cpp module "<<n->name()<<std::endl;
+ if (with_split_cpp())
+ {
+ make_module_dir(n);
+ } else {
+ }
+
+ if (with_codec())
+ {
+ m_Streams.open(m_module_path,with_jer(),with_per(),with_oer());
+ m_Streams.m_os_codec_hpp<<"namespace asn1 {\n";
+ gen_include_header(m_Streams.m_os_codec_cpp);
+ m_Streams.m_os_codec_cpp<<"#include \""<<m_module->cpp_name()<<"_codec.hpp\""<<std::endl;
+ m_Streams.m_os_codec_cpp<<"namespace asn1 {\n";
+ }
+ gen_include_header(os);
+ generate_constraints(os);
+ os<<"using namespace asn1;"<<std::endl;
+ os<<"namespace "<<n->cpp_name()<<" {\n"<<std::endl;
+
+ n->sort_childs();
+ // Go through assignments and generate
+ std::fstream sos;
+ do_gencpp_assignment dogen(*this,os,sos);
+
+ std::for_each( n->begin()
+ , n->end()
+ , dogen
+ );
+
+ os<<"}"<<std::endl;
+ os<<"/** "<<std::endl;
+ os<<" * vim: sw=2 ts=2:"<<std::endl;
+ os<<" */"<<std::endl;
+ if (with_codec())
+ {
+ m_Streams.m_os_codec_hpp<<"}\n";
+ m_Streams.m_os_codec_cpp<<"}\n";
+ m_Streams.close();
+ }
+}
+
+/**
+ * gen_typeref
+ */
+void generate_codec_cpp::gen_typeref(std::ostream &os,asn1::typeref *type)
+{
+ std::string scope;
+
+ asn1::typeref *ref = dynamic_cast<asn1::typeref *>(type);
+ assert(type->identifier() != NULL);
+ os<<"// gen_typeref "<<type->name()<<std::endl;
+ cgcpph_typeref gen_ref(*this,os,*ref);
+
+ gen_ref.generate(scope);
+}
+
+/**
+ * gen_bitstring.
+ * calls helper class to generate the appropriate code
+ */
+void
+generate_codec_cpp::gen_bitstring( std::ostream &os
+ , const std::string &scope
+ , asn1::bit_string &bits
+ , bool priv)
+{
+ cgcpph_bit_string set_gen(*this,os,bits);
+ set_gen.generate(scope);
+}
+
+/**
+ *
+ */
+void
+generate_codec_cpp::gen_primitive(std::ostream &os,asn1::typenode &type)
+{
+ if (with_source_comment())
+ os<<"// gen_primitive "<<type.name()<<std::endl;
+ switch (type.type_id()())
+ {
+ case asn1::type::ASN1_OCTET_STRING:
+ {
+ asn1::octet_string &o = dynamic_cast<asn1::octet_string &>(type);
+ cgcpph_octet_string o_gen(*this,os,o);
+ o_gen.generate();
+ }
+ break;
+ case asn1::type::ASN1_NULL:
+ {
+ asn1::primitive &i = dynamic_cast<asn1::primitive &>(type);
+ cgcpph_primitive p_gen(*this,os,i);
+ p_gen.generate();
+ }
+ break;
+ case asn1::type::ASN1_STRING:
+ case asn1::type::ASN1_STRING_UniversalString:
+ break;
+ case asn1::type::ASN1_STRING_UTF8String :
+ case asn1::type::ASN1_STRING_GeneralString:
+ case asn1::type::ASN1_STRING_T61String:
+ case asn1::type::ASN1_STRING_VideotexString:
+ case asn1::type::ASN1_STRING_ObjectDescriptor:
+ break;
+ case asn1::type::ASN1_STRING_GraphicString:
+ case asn1::type::ASN1_STRING_BMPString:
+ case asn1::type::ASN1_STRING_IA5String:
+ case asn1::type::ASN1_STRING_VisibleString:
+ case asn1::type::ASN1_STRING_ISO646String: /* aka VisibleString */
+ case asn1::type::ASN1_STRING_PrintableString:
+ case asn1::type::ASN1_STRING_NumericString:
+ case asn1::type::ASN1_STRING_TeletexString:
+ {
+ asn1::primitive &i = dynamic_cast<asn1::primitive &>(type);
+ cgcpph_string i_gen(*this,os,i);
+ i_gen.generate();
+ }
+ break;
+ //case asn1::type::ASN1_UNIVERSAL: { } break;
+ case asn1::type::ASN1_INTEGER:
+ {
+ asn1::integer &i = dynamic_cast<asn1::integer &>(type);
+ cgcpph_integer i_gen(*this,os,i);
+ i_gen.generate();
+ }
+ break;
+ case asn1::type::ASN1_BIT_STRING:
+ {
+ asn1::bit_string &bs = dynamic_cast<asn1::bit_string &>(type);
+ gen_bitstring(os,"",bs,false);
+ }
+ break;
+ case asn1::type::ASN1_BOOLEAN:
+ {
+ asn1::boolean &i = dynamic_cast<asn1::boolean &>(type);
+ cgcpph_boolean i_gen(*this,os,i);
+ i_gen.generate();
+ }
+ break;
+ case asn1::type::ASN1_OBJECT_IDENTIFIER:
+ {
+ asn1::object_identifier &i = dynamic_cast<asn1::object_identifier &>(type);
+ cgcpph_oid i_gen(*this,os,i);
+ i_gen.generate();
+ }
+ break;
+ default:
+ GEN_LOG_ERROR("type %s default case BAD path=%s\n"
+ , type.name().c_str()
+ , m_module_path.c_str()
+ );
+ ;
+ };
+}
+
+/**
+ * gen_typedef
+ *
+ */
+void generate_codec_cpp::gen_typedef(std::ostream &os,asn1::typenode *type)
+{
+
+ if (type->identifier() != NULL)
+ {
+ GEN_LOG_DEBUG( "identifier_name=%s type_id=%d\n"
+ , type->identifier_name().c_str()
+ , type->type_id()());
+ } else {
+ GEN_LOG_WARN( "ANONYMOUS name=%s type_id=%d\n"
+ , type->name().c_str()
+ , type->type_id()());
+ }
+ switch (type->type_id()())
+ {
+ case asn1::type::INVALID:
+ {
+ std::cerr<<"ERROR UNDEFINED TYPE "<<type->name();
+ std::cerr<<" ident:"<<type->identifier_name()<<std::endl;
+ assert(0);
+ }
+ break;
+ case asn1::type::ASN1_REFERENCE:
+ {
+ //assert(0 && "Should not be possible but is");
+ gen_typeref(os,type->as_typeref());
+ }
+ break;
+ case asn1::type::ASN1_NULL:
+ case asn1::type::ASN1_BIT_STRING:
+ case asn1::type::ASN1_OCTET_STRING:
+ case asn1::type::ASN1_STRING:
+ case asn1::type::ASN1_STRING_VisibleString:
+ case asn1::type::ASN1_STRING_ISO646String: /* aka VisibleString */
+ case asn1::type::ASN1_STRING_UniversalString:
+ case asn1::type::ASN1_STRING_BMPString:
+ case asn1::type::ASN1_STRING_UTF8String :
+ case asn1::type::ASN1_STRING_GeneralString:
+ case asn1::type::ASN1_STRING_GraphicString:
+ case asn1::type::ASN1_STRING_T61String:
+ case asn1::type::ASN1_STRING_VideotexString:
+ case asn1::type::ASN1_STRING_ObjectDescriptor:
+ case asn1::type::ASN1_STRING_IA5String:
+ case asn1::type::ASN1_STRING_PrintableString:
+ case asn1::type::ASN1_STRING_NumericString:
+ case asn1::type::ASN1_STRING_TeletexString:
+ //case asn1::type::ASN1_UNIVERSAL:
+ case asn1::type::ASN1_INTEGER:
+ case asn1::type::ASN1_BOOLEAN:
+ case asn1::type::ASN1_REAL:
+ case asn1::type::ASN1_OBJECT_IDENTIFIER:
+ case asn1::type::ASN1_RELATIVE_OID:
+ {
+ gen_primitive(os,*type);
+ }
+ break;
+ case asn1::type::ASN1_SEQUENCE:
+ {
+ asn1::node *params = type->parameters();
+ GEN_LOG_DEBUG("identifier_name=%s type_id=%d params=%d \n"
+ ,type->identifier_name().c_str()
+ ,type->type_id()()
+ ,(params == NULL)?0:1
+ );
+
+ std::string scope("");
+ if (params == NULL) {
+ gen_seq(os,scope,type,false);
+ } else {
+ GEN_LOG_WARN("%s has parameters don't generate implementation \n"
+ ,type->identifier_name().c_str());
+ }
+
+ }
+ break;
+ case asn1::type::ASN1_SEQUENCE_OF:
+ {
+ asn1::typenode *seqof_type = type->get_eltype();
+ std::cout.flush();
+ if ( seqof_type->type_id()() == asn1::type::ASN1_SEQUENCE
+ || seqof_type->type_id()() == asn1::type::ASN1_CHOICE
+ )
+ {
+ // Generate codec for (private class)
+ // which does not exists in this case
+ if (with_source_comment())
+ os<<"//private /*SEQUENCE_OF "<<seqof_type->cpp_name()<<" */"<<std::endl;
+ os.flush();
+ // Not sure if this is nice
+ gen_typedef(os,seqof_type->as_typenode());
+ }
+ std::string scope("");
+ cgcpph_sequenceof gseqof(*this,os,*dynamic_cast<asn1::sequence_of *>(type));
+ gseqof.generate();
+ }
+ break;
+ case asn1::type::ASN1_SET:
+ {
+ asn1::set *settype = type->as_set();
+ std::string scope("");
+ gen_set(os,scope,settype);
+ }
+ break;
+ case asn1::type::ASN1_SET_OF:
+ {
+ asn1::typenode *setof_type = type->get_eltype();
+ if (with_source_comment())
+ os<<"//typedef /*SET_OF*/ "<<type->identifier_cpp_name()<<std::endl;
+ GEN_LOG_DEBUG("SET OF identifier_name=%s type_id=%d is_priv=%d \n"
+ ,type->identifier_name().c_str()
+ ,type->type_id()()
+ ,type->is_private()
+ );
+ if ( setof_type->type_id()() == asn1::type::ASN1_SEQUENCE
+ || setof_type->type_id()() == asn1::type::ASN1_CHOICE
+ )
+ {
+ GEN_LOG_DEBUG("SET OF type id_name=%s type_id=%d is_priv=%d \n"
+ ,setof_type->identifier_name().c_str()
+ ,setof_type->type_id()()
+ ,setof_type->is_private()
+ );
+ // Generate codec for (private class)
+ // which does not exists in this case
+ if (with_source_comment())
+ os<<"//private /*SET_OF "<<setof_type->cpp_name()<<" is private: "<<setof_type->is_private()<<"*/"<<std::endl;
+ os.flush();
+ // Not sure if this is nice
+ gen_typedef(os,setof_type);
+ }
+
+ cgcpph_setof gensetof(*this,os,*dynamic_cast<asn1::set_of *>(type));
+ gensetof.generate();
+ }
+ break;
+ case asn1::type::ASN1_CHOICE:
+ {
+ std::string scope("");
+ gen_choice(os,scope,type);
+ }
+ break;
+ case asn1::type::ASN1_ENUMERATED:
+ {
+ std::string scope("");
+ gen_enumerated(os,scope,type);
+ }
+ break;
+ case asn1::type::ASN1_ANY:
+ break;
+ default:
+ GEN_LOG_ERROR("UNHANDLED type id_name=%s type_id=%d is_priv=%d \n"
+ ,type->identifier_name().c_str()
+ ,type->type_id()()
+ ,type->is_private()
+ );
+ //exit(0);
+ };
+ os<<"\n";
+
+}
+
+
+/**
+ *
+ */
+void
+generate_codec_cpp::
+gen_attribute_constrained_nencode( std::ostream &os
+ , const std::string &scope
+ , const std::string &indent
+ , asn1::field *attribute)
+{
+ asn1::typenode *attribute_type = (attribute)->get_type();
+ asn1::constraint *c = *(attribute_type->constraint_begin());
+ if (c->type() == asn1::constraint::CA_CRC) {
+ asn1::constraint::const_iterator it = c->begin();
+ asn1::constraint *val = *it; ++it;
+ asn1::constraint *at = *it;
+ if (with_source_comment())
+ {
+ os<<indent<<"//"<<val->value()->cpp_name();
+ os<<" @ "<<at->value()->cpp_name()<<" Type="<<attribute_type->cpp_name()<<"\n";
+ }
+
+ if (attribute_type->as_typeref() && attribute_type->as_typeref()->is_complex())
+ {
+ asn1::node *imp = NULL;
+ asn1::reference *r = attribute_type->as_typeref()->get_reference();
+ std::string lr = r->back().m_identifier;
+ lr[0]='_';
+ std::string lname(r->front().m_identifier);
+ std::string cls;
+ cls.resize(lname.size());
+ std::transform(lname.begin(),lname.end(),cls.begin(),asn1::op_substitute);
+ // Check if pointer exists
+ os<<indent<<"if ( ! "<<attribute->cpp_name()<<".is_nul() )\n";
+ os<<indent<<"{\n";
+ if (type_in_imports(r->front().m_identifier,&imp))
+ {
+ os<<indent<<attribute->cpp_name()<<"->encode"<<lr<<"(ctx); /* constrained CA CRC*/"<<std::endl;
+ } else
+ {
+ os<<""<<attribute->cpp_name()<<"->";
+ os<<"encode"<<lr<<"(ctx); /* constrained CA CRC 1*/"<<std::endl;
+ }
+ os<<indent<<"} else\n"<<indent<<"{\n";
+ os<<indent<<"\tASN1_BER_LOG_ERROR(\"ENCODING ERROR "<<attribute->cpp_name()<<" is NULL\");\n";
+ os<<indent<<"}\n";
+ } else {
+ os<<indent<<"\t"<<val->value()->cpp_name()<<"[i]->";
+ os<<"encode(ctx); /* constrained CA CRC*/"<<std::endl;
+ }
+ } else if (c->type() == asn1::constraint::CT_SIZE)
+ {
+ os<<indent<<"ASN1_BER_LOG_INFO(\"encoding of ";
+ os<<attribute->cpp_name() <<" size constrained to be checked\");\n";
+ os<<""<<indent<<""<<""<<(attribute)->cpp_name();
+ os<<".encode(ctx); /* constrained*/"<<std::endl;
+ } else if (c->type() == asn1::constraint::EL_RANGE)
+ {
+ os<<indent<<"ASN1_BER_LOG_INFO(\"encoding of ";
+ os<<attribute->cpp_name() <<" range constrained to be checked\");\n";
+ os<<""<<indent<<""<<""<<(attribute)->cpp_name();
+ os<<".encode(ctx); /* constrained*/"<<std::endl;
+ }else
+ {
+ os<<indent<<"ASN1_BER_LOG_INFO(\"encode of ";
+ os<<attribute->cpp_name() <<" other constrained to be checked\");\n";
+ os<<""<<indent<<""<<""<<(attribute)->cpp_name();
+ os<<".encode(ctx); /* constrained*/"<<std::endl;
+ }
+}
+
+/**
+ *
+ */
+void
+generate_codec_cpp::
+gen_attribute_constrained_ndecode(std::ostream &os
+ , const std::string &scope
+ , const std::string &indent
+ , asn1::field *attribute)
+{
+ asn1::typenode *attribute_type = attribute->get_type();
+ asn1::constraint *c = *(attribute_type->constraint_begin());
+ if (c->type() == asn1::constraint::CA_CRC)
+ {
+ std::cerr<<"generate_codec_cpp::"<<__FUNCTION__<<" WARN "<<attribute->name()<<" has CRC"<<std::endl;
+ asn1::constraint::const_iterator it = c->begin();
+ asn1::celt_type *val = (*it)->as_celt_type();
+ asn1::typeref *vtr = val->get_type();
+ ++it;
+ asn1::constraint *at = *it;
+ assert(val && "gen_attribute_constraint_ndecode should needs evolution");
+ std::string setname;
+ if ( vtr->is_imported(setname))
+ {
+ setname = asn1::cpp_name(setname);
+ setname.append("::");
+ setname.append(vtr->cpp_name());
+ } else
+ setname = vtr->cpp_name();
+ os<<indent<<"\t//"<<setname;
+ os<<" @ "<<at->value()->cpp_name()<<"\n";
+ os<<indent<<"\tint i = 0;\n";
+ os<<indent<<"\tfor ( i = 0 ; "<<setname<<"[i] != NULL;i++)\n";
+ os<<indent<<"\t{\n";
+ os<<indent<<"\t\tif ( ";
+ // Find attribute at->value() Then get the type to figure out
+ // which attribute in object to use.
+ {
+ asn1::constructed *ccontainer = attribute->get_parent()
+ ->as_constructed();
+ asn1::node::iterator itt =
+ std::find_if( ccontainer->begin()
+ , ccontainer->end()
+ , asn1::find_node(at->value()->name()));
+ assert(itt != ccontainer->end());
+ asn1::field *f = dynamic_cast<asn1::field *>(*itt);
+ asn1::typeref *at_ref = dynamic_cast<asn1::typeref *>(f->get_type());
+ // Not always true
+ std::cerr<<"generate_codec_cpp::"<<__FUNCTION__<<" at_ref "<<at_ref->name();
+ std::cerr<<" Simple: "<<at_ref->is_simple()<<std::endl;
+ asn1::objectclass_reference &ocref = at_ref->get_objectclass();
+ // This is wierd, I don't think the resolver is required here.
+ // I only need the last field
+ std::cerr<<"generate_codec_cpp::"<<__FUNCTION__<<" at_ref "<<at_ref->name();
+ std::cerr<<std::endl;
+ std::string fieldn = ocref.field().substr(1);
+ os<<setname<<"[i]->"<<fieldn<<"Equals(";
+ }
+ os<<" "<<at->value()->cpp_name()<<"))\n";
+ os<<indent<<"\t\t{\n";
+ if (attribute_type->as_typeref() && attribute_type->as_typeref()->is_complex())
+ {
+ asn1::reference *r = attribute_type->as_typeref()->get_reference();
+ std::string lr = r->back().m_identifier;
+ lr[0]='_';
+ os<<indent<<"\t\t\t"<<(attribute)->cpp_name()<<" = ";
+ os<<setname<<"[i]->"<<"clone();\n";
+ os<<indent<<"\t\t\t"<<(attribute)->cpp_name()<<"->decode"<<lr<<"(ctx); "<<std::endl;
+ } else
+ {
+ os<<indent<<"\t\t"<<val->value()->cpp_name()<<"[i]->"<<"codec(ctx,"<<(attribute)->cpp_name()<<",CODEC_DECODE); /* constrained CA CRC*/"<<std::endl;
+ }
+ os<<indent<<"\t\t\tbreak;\n";
+ os<<indent<<"\t\t}\n";
+ os<<indent<<"\t}\n"; // end for
+ os<<indent<<"\tif ("<<setname<<"[i] == NULL)\n";
+ os<<indent<<"\t{\n";
+ os<<indent<<"\t\tASN1_BER_LOG_DEBUG(\"DECODE CONSTRAINT type "<<attribute->cpp_name()<<" Not FOUND\");\n";
+ os<<indent<<"\t}\n";
+ } else
+ {
+ os<<indent<<"\t"<<(attribute)->cpp_name()<<".decode(ctx);";
+ os<<"/* constrained "<<c->type()<<" */"<<std::endl;
+ }
+}
+
+
+void
+generate_codec_cpp::gen_composite_attribute_printf( std::ostream &os
+ , const std::string &scope
+ , asn1::field &attribute
+ , asn1::node *params)
+{
+ asn1::typenode *attr_type = attribute.get_type();
+ int strlen = 4;
+ if (attr_type != NULL)
+ {
+ switch (attr_type->type_id()() )
+ {
+ case asn1::type::ASN1_REFERENCE:
+ {
+ asn1::typeref *tref = dynamic_cast<asn1::typeref *>(attr_type);
+ asn1::node *real_type = m_resolver.resolve(*tref);
+ // New way to handle reference
+ // gen_composite_attribute_ref(os,scope,attr_type);
+ if (tref->is_complex() && !tref->is_external())
+ {
+ os<<"std::setw(indent+"<<attribute.cpp_name().size()+strlen;
+ os<<")<<std::setprecision(indent)<<\""<<attribute.cpp_name()<<" : \";\n";
+ switch( real_type->type_id()())
+ {
+ case asn1::type::ASN1_CLASSFIELD_TF:
+ os<<"\tif ( ! s."<<attribute.cpp_name()<<".is_nul())\n";
+ os<<"\t{\n";
+ os<<"\t\ts."<<attribute.cpp_name()<<"->printf(os); /**/\n";
+ os<<"\t}\n";
+ os<<"\tos<<std::endl;\n";
+ break;
+ case asn1::type::ASN1_CLASSFIELD_FTVF:
+ {
+ os<<"\ts."<<attribute.cpp_name()<<".printf(os);\n";
+ os<<"\tos<<std::endl;\n";
+ }
+ break;
+ case asn1::type::ASN1_REFERENCE:
+ case asn1::type::ASN1_INTEGER:
+ case asn1::type::ASN1_OBJECT_IDENTIFIER:
+ os<<"\tos<<s."<<attribute.cpp_name()<<"<<std::endl;\n";
+ break;
+ default:
+ os<<"\tif ( ! s."<<attribute.cpp_name()<<".is_nul())\n";
+ os<<"\t{\n";
+ os<<"\t\ts."<<attribute.cpp_name()<<"->printf(os);\n";
+ os<<"\t}\n";
+ os<<"\tos<<std::endl;\n";
+ break;
+ }
+
+ } else
+ {
+ os<<"std::setw(indent+"<<attribute.cpp_name().size()+strlen;
+ os<<")<<\""<<attribute.cpp_name();
+ os<<" : \"<<std::setprecision(indent)<<s."<<attribute.cpp_name();
+ os<<"<<std::endl;\n";
+ }
+ }
+ break;
+ default:
+ os<<"std::setw(indent+"<<attribute.cpp_name().size()+strlen;
+ os<<")<<\""<<attribute.cpp_name();
+ os<<" : \"<<std::setprecision(indent)<<s."<<attribute.cpp_name();
+ os<<"<<std::endl;\n";
+ ;
+ }
+ }
+}
+
+
+/**
+ * TODO: Remove
+ */
+void
+generate_codec_cpp::gen_composite_attribute_ref(std::ostream &os
+ ,const std::string &scope
+ ,asn1::field *attribute
+ ,asn1::node *params)
+{
+ generate_cpp::gen_composite_attribute_ref(os,scope,attribute,params);
+}
+
+
+
+void generate_codec_cpp::gen_seq(std::ostream &os
+ , const std::string &scope
+ , asn1::node *_type
+ , bool priv
+ )
+{
+ std::string structName;
+ asn1::sequence *type = _type->as_sequence();
+ assert(type != NULL);
+ asn1::node *ident = type->identifier();
+ asn1::node::iterator lit = (type)->begin();
+ GEN_LOG_DEBUG("gen_seq: \n");
+ assert(type->type_id()() == asn1::type::ASN1_SEQUENCE);
+ // try new helper
+ // New way to handle and isolate sequence code generation
+ asn1::sequence *seq = dynamic_cast<asn1::sequence *>(type);
+ assert(seq != NULL);
+ assert(ident != NULL);
+ GEN_LOG_ERROR("gen_seq: %s\n",ident->cpp_name().c_str());
+ assert(seq->is_private() == priv);
+ // compute strutName
+ struct_name(type,structName);
+
+ if (ident)
+ {
+ GEN_LOG_DEBUG("scope=%s ident= %s type=%s parameters=%d\n",scope.c_str(),
+ ident->cpp_name().c_str(),
+ type->cpp_name().c_str(),
+ ( ident->parameters() == NULL)?0:1
+ );
+ }
+ os<<"//generate_codec_cpp::"<<__FUNCTION__<<" "<<scope<<structName<<" priv="<<priv<<std::endl;
+ gen_private(os,scope,seq);
+ cgcpph_sequence seq_gen(*this,os,*seq);
+ seq_gen.generate(scope);
+}
+
+
+
+static
+char lop_substitute(char c)
+{
+ return (c == ':')?'_':c;
+}
+
+
+/**
+ *
+ *
+ */
+void generate_codec_cpp::gen_choice(std::ostream &os,const std::string &scope,asn1::node *type,bool priv)
+{
+ std::string structName;
+ asn1::choice *choice = dynamic_cast<asn1::choice *>(type);
+ // Pre condition.
+ // - type should not have a type node
+ // - type should not null
+ // - type should be of type choice
+ //
+ assert( (type != NULL) && (type->type_id()() == asn1::type::ASN1_CHOICE));
+ assert( choice != NULL );
+
+ GEN_LOG_DEBUG("type %s scope=%s priv=%d\n",type->cpp_name().c_str(),scope.c_str(),priv);
+
+ os<<"//"<<__FUNCTION__<<" "<<scope<<type->cpp_name()<<" type_id="<<type->type_id()();
+ os<<" ident="<<type->identifier_cpp_name()<<std::endl;
+
+ struct_name(type,structName);
+
+ cgcpph_choice choice_gen(*this,os,*choice);
+
+ choice_gen.generate();
+}
+
+/**
+ *
+ *
+ */
+void generate_codec_cpp::gen_set( std::ostream &os
+ , const std::string &scope
+ , asn1::set *type)
+{
+ bool priv = false;
+ asn1::set *set = dynamic_cast<asn1::set *>(type);
+ assert(set != NULL);
+ // This is the right test that should be performed
+ assert(dynamic_cast<asn1::set *>(type) != NULL);
+
+ cgcpph_set set_gen(*this,os,*set);
+ set_gen.generate(scope);
+}
+
+/**
+ * Dead code below.
+ */
+void generate_codec_cpp::gen_set_of(std::ostream &os,asn1::node *type)
+{
+ assert(0);
+}
+
+/**
+ * const object set is an elemnt_set_spec
+ * which are contraints
+ *
+ */
+void generate_codec_cpp::gen_objectset(std::ostream &os,asn1::objectset &objs)
+{
+ GEN_LOG_ERROR( "generate_codec_cpp:%s %s type=%s\n"
+ , __FUNCTION__
+ , objs.name().c_str()
+ , objs.type_id().name());
+ asn1::typeref *tref = objs.get_classref();
+ std::string otype = tref->get_reference()->name();
+ asn1::node *ns;
+ os<<"\n// "<<__FUNCTION__<<" start "<<objs.name()<<" "<<std::endl;
+ if (objs.has_constraints())
+ {
+ asn1::constraint::const_iterator values = objs.constraint_begin();
+ for (; values != objs.constraint_end(); ++values)
+ {
+ switch( (*values)->type())
+ {
+ case asn1::constraint::EL_VALUE:
+ {
+ std::string type_name((*values)->value()->name());
+ asn1::node::iterator ref = std::find_if(m_module->begin(),
+ m_module->end(),
+ asn1::find_node(type_name));
+ if (ref != m_module->end())
+ {
+ asn1::node *ntype = *ref;
+ std::cerr<<"generate_codec_cpp::"<<__FUNCTION__<<" "<<ntype->name()<<std::endl;
+ if (ntype->parameters())
+ {
+ std::cerr<<"generate_codec_cpp::"<<__FUNCTION__<<" ";
+ std::cerr<<ntype->name()<<" has parameters"<<std::endl;
+ os<<"// "<<__FUNCTION__<<" "<<ntype->name()<<" has parameters NO GEN YET"<<std::endl;
+ return;
+ } else
+ gen_object(os,(*ref)->as_assignment());
+ }
+ }
+ break;
+ default:
+ ;
+ };
+ }
+ } else {
+ GEN_LOG_ERROR( "generate_codec_cpp:%s EMPTY v %s type=%s\n"
+ , __FUNCTION__
+ , objs.name().c_str()
+ , objs.type_id().name());
+ }
+ if (objs.get_assignment()->parameters())
+ {
+ std::cerr<<"generate_codec_cpp::"<<__FUNCTION__<<" "<<objs.name();
+ std::cerr<<" has parameters 1"<<std::endl;
+ os<<"//generate_codec_cpp::"<<__FUNCTION__<<" "<<objs.name();
+ os<<" has parameters NO GEN YET 1"<<std::endl;
+ return;
+ }
+ // begin of definition
+ if (type_in_imports(otype,&ns) )
+ {
+ os<<ns->cpp_name()<<"::I"<<tref->get_reference()->cpp_name()<<" *"<<objs.cpp_name()<<"[] = {";
+ } else {
+ os<<"I"<<tref->get_reference()->cpp_name()<<" *"<<objs.cpp_name()<<"[] = {";
+ }
+
+ // gen code
+ if ( objs.has_constraints() && (*objs.constraint_begin())->type() == asn1::constraint::CA_UNI)
+ {
+ asn1::constraint *first = (*objs.constraint_begin());
+ asn1::constraint::const_iterator values = first->begin();
+ for (; values != first->end(); ++values)
+ {
+ if (values != first->begin())
+ os<<",";
+ switch( (*values)->type())
+ {
+ case asn1::constraint::EL_VALUE:
+ {
+ asn1::node *ns;
+ if (type_in_imports((*values)->value()->name(),&ns)) {
+ os<<" new "<<ns->cpp_name()<<"::"<<(*values)->value()->cpp_name()<<"()\n";
+ } else
+ os<<" new "<<(*values)->value()->cpp_name()<<"()\n";
+ }
+ break;
+ default:
+ ;
+ };
+ os<<"\t";
+ }
+ os<<", NULL\n";
+ }
+ os<<"};";
+}
+
+/**
+ * const encoding and decoding
+ *
+ */
+void generate_codec_cpp::gen_const( std::ostream &os
+ , asn1::node *type)
+{
+ if (with_source_comment())
+ os<<"// generate_codec_cpp::"<<__FUNCTION__<<"\n";
+
+ switch(type->type_id()())
+ {
+ case asn1::type::ASN1_OBJECT_IDENTIFIER:
+ {
+ if (with_source_comment())
+ os<<"// const OID "<<" "<<type->identifier_cpp_name();
+ }
+ break;
+ case asn1::type::ASN1_VALUESET:
+ {
+ GEN_LOG_ERROR("generate_codec_cpp: %s type=%s\n",type->name().c_str(),type->type_id().name());
+ std::cerr<<__FUNCTION__<<" "<<type->name()<<std::endl;
+ assert(0);
+ }
+ break;
+ case asn1::type::ASN1_REFERENCE:
+ {
+ gen_const_reference(os,type);
+ }
+ break;
+ default:
+ if (type->identifier() ) {
+ os<<"//const "<<type->cpp_name()<<"\t\t= "<<type->identifier_cpp_name()<<";";
+ } else {
+ os<<"//const "<<type->cpp_name()<<"\t\t= ? no identifier"<<";";
+ }
+ ;
+ }
+ os<<std::endl;
+
+}
+
+/**
+ *
+ */
+void generate_codec_cpp::gen_const_reference(std::ostream &os,asn1::node *type)
+{
+ asn1::node *ident = type->identifier();
+ asn1::node *real_type =
+ m_resolver.resolve(dynamic_cast<asn1::typeref &>(*type));
+ if (dynamic_cast<asn1::typeref *>(type))
+ {
+ os<<"// ValueSet ref "<<type->name()<<std::endl;
+ return;
+ }
+ os<<ident->cpp_name()<<"::"<<ident->cpp_name()<<"()\n";
+
+ switch (real_type->type_id()())
+ {
+ case asn1::type::ASN1_CHOICE:
+ {
+ os<<"{\n}\n";
+ }
+ break;
+ case asn1::type::ASN1_BOOLEAN:
+ os<<"{\n}\n";
+ break;
+ case asn1::type::ASN1_INTEGER:
+ os<<"{\n}\n";
+ break;
+ default:
+ std::cerr<<"gen_const_reference not handled type"<<std::endl;
+ os<<"{\n}\n";
+ }
+}
+
+/*
+ * Ros generation Code
+ */
+void generate_codec_cpp::gen_object(std::ostream &os,asn1::assignment *n)
+{
+ asn1::typenode *type = n->get_type();
+
+ // New way
+ asn1::node *real_type =
+ m_resolver.resolve(dynamic_cast<asn1::typeref &>(*type));
+ if (real_type != NULL)
+ {
+ asn1::object *obj = dynamic_cast<asn1::object *>(type->get_eltype());
+ asn1::classdef *cdef = dynamic_cast<asn1::classdef *>(real_type);
+ assert( obj != NULL);
+ assert( cdef != NULL);
+
+ cgcpph_object obj_gen(*this,os,*obj,*cdef);
+ if ( ! n->is_generated())
+ obj_gen.generate();
+
+ } else
+ {
+ std::cerr<<"OBJECT CLASS not found "<<type->name()<<std::endl;
+ }
+ n->set_generated(true);
+
+ n->set_color(asn1::node::CL_RED);
+
+}
+
+
+void
+generate_codec_cpp::gen_enumerated(std::ostream &os,const std::string &scope,asn1::node *type )
+{
+ std::string lname;
+ assert(type->type_id()() == asn1::type::ASN1_ENUMERATED );
+
+ asn1::enumerated *enumerated = dynamic_cast<asn1::enumerated *>(type);
+ assert(enumerated != NULL);
+
+ cgcpph_enumerated set_gen(*this,os,*enumerated);
+ set_gen.generate(scope);
+
+}
+
+//
+//
+//
+void generate_codec_cpp::gen_template_params( std::ostream &os
+ , asn1::constructed *params)
+{
+ asn1::node::node_list nl;
+
+ os<<"<";
+ for(asn1::node::iterator p = params->begin(); p != params->end() ;++p)
+ {
+ if (nl.size()>0)
+ {
+ asn1::node::iterator it = std::find_if(nl.begin(),nl.end(),asn1::find_node((*p)->name()));
+ if (it != nl.end() )
+ {
+ //
+ } else {
+ if (p != params->begin()) os<<",";
+ os<<" "<<(*p)->cpp_name();
+ nl.push_back(*p);
+ }
+ } else {
+ if (p != params->begin()) os<<",";
+ os<<" "<<(*p)->cpp_name();
+ nl.push_back(*p);
+ }
+ }
+ os<<"> ";
+}
+
+//
+//
+//
+void generate_codec_cpp::gen_template_signature(std::ostream &os,asn1::node *type)
+{
+ asn1::node::node_list nl;
+ asn1::node *ident = NULL;
+ asn1::constructed *params = NULL;
+ assert(type != NULL);
+
+ ident = type->identifier();
+ if (ident == NULL)
+ {
+ os<<"// no ident not a template"<<std::endl;
+ return;
+ }
+ if (ident && ident->parameters() && is_template(ident->parameters()) )
+ {
+ params = ident->parameters();
+ os<<"template ";
+ } else {
+ return ;
+ }
+
+ os<<"<";
+ for(asn1::node::iterator p = params->begin(); p != params->end() ;++p)
+ {
+ if (nl.size()>0)
+ {
+ asn1::node::iterator it = std::find_if(nl.begin(),nl.end(),asn1::find_node((*p)->name()));
+ if (it != nl.end() )
+ {
+ //
+ } else {
+ if (p != params->begin()) os<<",";
+ os<<" typename "<<(*p)->cpp_name();
+ nl.push_back(*p);
+ }
+ } else {
+ if (p != params->begin()) os<<",";
+ os<<" typename "<<(*p)->cpp_name();
+ nl.push_back(*p);
+ }
+ }
+ os<<"> ";
+ os<<std::endl;
+}
+
+//
+//
+//
+void generate_codec_cpp::gen_template_signature_class(std::ostream &os,asn1::node *type)
+{
+ asn1::node::node_list nl;
+ asn1::node *ident = NULL;
+ asn1::constructed *params = NULL;
+ assert(type != NULL);
+
+ ident = type->identifier();
+ if (ident == NULL)
+ {
+ return;
+ }
+ if (ident && ident->parameters() && is_template(ident->parameters()) )
+ {
+ params = ident->parameters();
+ } else {
+ return ;
+ }
+
+ os<<"<";
+ for(asn1::node::iterator p = params->begin(); p != params->end() ;++p)
+ {
+ if (nl.size()>0)
+ {
+ asn1::node::iterator it = std::find_if(nl.begin(),nl.end(),asn1::find_node((*p)->name()));
+ if (it != nl.end() )
+ {
+ //
+ } else {
+ if (p != params->begin()) os<<",";
+ os<<" "<<(*p)->cpp_name();
+ nl.push_back(*p);
+ }
+ } else {
+ if (p != params->begin()) os<<",";
+ os<<" "<<(*p)->cpp_name();
+ nl.push_back(*p);
+ }
+ }
+ os<<">";
+}
+
+/**
+ *
+ */
+void generate_codec_cpp::gen_private( std::ostream &os
+ , const std::string &scope
+ , asn1::constructed *_type)
+{
+ asn1::constructed *type = _type->as_constructed();
+ std::string structName;
+ asn1::node::iterator attr_it;
+
+ assert( (type != NULL )
+ &&
+ ( (type->type_id()() == asn1::type::ASN1_CHOICE)
+ || (type->type_id()() == asn1::type::ASN1_SET)
+ || (type->type_id()() == asn1::type::ASN1_SEQUENCE)
+ )
+ );
+
+ struct_name(type,structName);
+
+ for ( attr_it = type->begin()
+ ; attr_it != type->end()
+ ; ++attr_it)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*attr_it);
+ asn1::typenode *attr_type = f->get_type();
+ // Extension markers don't have a type
+ // assert( attr_type != NULL);
+ if (attr_type != NULL)
+ {
+ switch (attr_type->type_id()())
+ {
+ case asn1::type::ASN1_SEQUENCE_OF:
+ case asn1::type::ASN1_SET_OF:
+ {
+ asn1::node *softype = attr_type->get_eltype();
+ GEN_LOG_DEBUG("call private seq of %s\n",(*attr_it)->cpp_name().c_str());
+ if (softype->type_id()() >= asn1::type::ASN1_SEQUENCE &&
+ softype->type_id()() <= asn1::type::ASN1_SET_OF)
+ {
+ gen_private_attribute(os,scope,attr_type->get_eltype());
+ }
+ }
+ break;
+ case asn1::type::ASN1_SEQUENCE:
+ case asn1::type::ASN1_SET:
+ case asn1::type::ASN1_ENUMERATED:
+ case asn1::type::ASN1_CHOICE:
+ if (type->identifier() != NULL)
+ {
+ GEN_LOG_DEBUG("call private seq of %s\n",(*attr_it)->cpp_name().c_str());
+ gen_private_attribute(os,scope,attr_type);
+ } else {
+ GEN_LOG_ERROR("did not call private seq of %s\n",(*attr_it)->cpp_name().c_str());
+ assert(0);
+ }
+ break;
+ defatult:
+ GEN_LOG_DEBUG("default not call private seq of %s\n",(*attr_it)->cpp_name().c_str());
+ ;
+ }
+ }
+
+ }
+}
+
+
+/**
+ *
+ * called for each attribute in sequence , choice or set.
+ * n can be of any type ....
+ * I'm missing the function that loops over the attributes.
+ * This function should be called gen private attribute
+ */
+void generate_codec_cpp::gen_private_attribute( std::ostream &os
+ , const std::string &scope
+ , asn1::typenode *n)
+{
+ asn1::node *params = NULL;
+ assert(n!=NULL);
+ if (n)
+ {
+ params = n->parameters();
+ GEN_LOG_DEBUG(" scope=%s node=%s params: %d typeid=%d\n",
+ scope.c_str()
+ ,n->cpp_name().c_str()
+ ,(params==NULL)?0:1
+ ,n->type_id()()
+ );
+ os<<"//generate_codec_cpp::"<<__FUNCTION__<<" "<<scope<<n->cpp_name()<<std::endl;
+ }
+
+ switch (n->type_id()())
+ {
+ case asn1::type::ASN1_CHOICE:
+ gen_choice(os,scope,n,true);
+ break;
+ case asn1::type::ASN1_SEQUENCE:
+ gen_seq(os,scope,n,true);
+ break;
+ case asn1::type::ASN1_SET:
+ gen_set(os,scope,n->as_set());
+ break;
+ case asn1::type::ASN1_SET_OF:
+ case asn1::type::ASN1_SEQUENCE_OF:
+ {
+ asn1::typenode *type = n;
+ asn1::typenode *subtype = type->get_eltype();
+ assert(subtype != NULL);
+ os<<"// gen_private_attribute type SEQUENCE_OF ... \n";
+ if (type->has_constraints())
+ {
+ os<<"// I have constraints\n";
+ }
+ switch (subtype->type_id()())
+ {
+ case asn1::type::ASN1_SEQUENCE:
+ os<<"// gen_private_attribute type SEQUENCE_OF ... launch gen_seq \n";
+ gen_seq(os,scope,subtype,true);
+ os<<"\n//end\n";
+ break;
+ case asn1::type::ASN1_CHOICE:
+ os<<"// gen_private_attribute type SEQUENCE_OF ... launch gen_choice \n";
+ gen_choice(os,scope,subtype,true);
+ os<<"\n//end\n";
+ break;
+ default:
+ os<<"// gen_private_attribute type SEQ or SET OF ... type to be code \n";
+ ;
+ }
+ }
+ break;
+ case asn1::type::ASN1_ENUMERATED :
+ gen_enumerated(os,scope,n);
+ break;
+ default:
+ GEN_LOG_DEBUG("Did not do anything for %s%s type_id=%d\n",scope.c_str(),n->cpp_name().c_str(),n->type_id()());
+ ;
+ }
+}
+
+
+void
+generate_codec_cpp::struct_name(asn1::node *type,std::string &structName)
+{
+ assert(type != NULL);
+
+ if (type->is_private())
+ {
+ structName = type->cpp_name();
+ } else
+ {
+ structName = type->identifier_cpp_name();
+ }
+}
+/*
+ * vim:et sw=2 ts=2 list:
+ */
--- /dev/null
+#ifndef GEN_CODEC_CPP_H__
+#define GEN_CODEC_CPP_H__
+#include <iostream>
+#include <string>
+#include <algorithm>
+
+#include "libparser/asn1_parser_listener.h"
+#include "asn1_gen_constraints.h"
+
+
+/**
+ *
+ */
+class generate_codec_cpp : public generate_cpp
+{
+ protected:
+ generate_codec_cpp(const generate_codec_cpp &c) :
+ generate_cpp(c)
+ , m_gen_constraints(c.m_gen_constraints)
+ { std::cout<<"copy generate_codec_cpp\n"; }
+ public:
+
+ generate_codec_cpp(asn1::module *n,gen_constraints &c) : generate_cpp(n) , m_gen_constraints(c) {};
+ generate_codec_cpp(asn1::module *n,asn1::module::modules_type &m,gen_constraints &c);
+
+ /**/
+ void gen_attribute_constrained_ndecode( std::ostream &os
+ , const std::string &scope
+ , const std::string &indent
+ , asn1::field *attr);
+
+ void gen_attribute_constrained_nencode( std::ostream &os
+ , const std::string &scope
+ , const std::string &indent
+ ,asn1::field *attr);
+
+ /**
+ *
+ */
+ void gen_decode_set(std::ostream &os,asn1::node *attribute);
+
+ /**
+ *
+ */
+ void gen_const(std::ostream &os,asn1::node *n);
+ /**
+ *
+ */
+ void gen_objectset(std::ostream &os,asn1::objectset &n);
+ /**
+ *
+ */
+ void gen_const_reference(std::ostream &os,asn1::node *n);
+
+ /**
+ *
+ */
+ void gen_enumerated(std::ostream &os,const std::string &scope,asn1::node *enum_node);
+
+ //
+ //
+ //
+ void gen_typedef(std::ostream &os,asn1::typenode *n);
+ void gen_typeref(std::ostream &os,asn1::typeref *n);
+ /**
+ * generate structure for primitive typedefs Type ::= INTGER
+ * because integer is under constructed. That's a bit wierd
+ */
+ void gen_primitive(std::ostream &os,asn1::typenode &n);
+
+ void
+ gen_composite_attribute_printf( std::ostream &os
+ , const std::string &scope
+ , asn1::field &attribute
+ , asn1::node *params=NULL);
+ void gen_composite_attribute_ref(std::ostream &os
+ , const std::string &scope
+ , asn1::field *attribute
+ , asn1::node *params = NULL);
+
+ void gen_template_params(std::ostream &os,asn1::constructed *type);
+ void gen_template_signature(std::ostream &os,asn1::node *type);
+ void gen_template_signature_class(std::ostream &os,asn1::node *type);
+ /**
+ *
+ */
+ void gen_seq(std::ostream &os,const std::string &scope,asn1::node *n,bool priv=false);
+
+ // Choice
+
+ void gen_choice(std::ostream &os,const std::string &scope,asn1::node *n,bool priv = false);
+
+ /**
+ *
+ */
+ void gen_set( std::ostream &os
+ , const std::string &scope
+ , asn1::set *n);
+
+ void gen_set_of(std::ostream &os,asn1::node *n);
+ /**
+ * SEQUENCE,CHOICE,SET might contain private SEQUENCE CHOICE or SET.
+ * I need to generate special codecs for these structures
+ * therefore gen_private node is either SEQ, SET, CHOICE container
+ * that loops over each attribute
+ *
+ */
+ void gen_private( std::ostream &os
+ , const std::string &scope
+ , asn1::constructed *n);
+ /**
+ * called within gen_private
+ */
+ void gen_private_attribute( std::ostream &os
+ , const std::string &scope
+ , asn1::typenode *n);
+ // bit string
+ void gen_bitstring( std::ostream &os
+ , const std::string &scope
+ , asn1::bit_string &n,bool priv=false);
+ /*
+ * Ros generation Code
+ */
+ void gen_object(std::ostream &os,asn1::assignment *n);
+
+ void gen_module(std::ostream &os,asn1::module *n);
+ /**
+ *
+ */
+ void gen_include_header(std::ostream &os);
+ // Will be used by helper classes
+ void struct_name(asn1::node *type,std::string &structName);
+ /**
+ * _a (IN) : assignment
+ * _stream (INOUT): opened stream based on m_module_path and assignment cpp_name
+ * return true if stream is open
+ */
+ bool open_assignment_stream(std::fstream &_stream,asn1::assignment *_a);
+ /**
+ *
+ */
+ inline const std::string &get_module_path() const
+ { return m_module_path; }
+ protected:
+ void generate_constraints(std::ostream &os);
+ /**
+ * Create current dir + module cpp_name dir.
+ */
+ bool make_module_dir(asn1::module *_module);
+ protected:
+ std::string m_module_path;
+ gen_constraints &m_gen_constraints;
+};
+
+/**
+ * vim:et:sw=2:ts=2
+ */
+#endif
--- /dev/null
+#cmakedefine HAVE_UNISTD_H
+#cmakedefine HAVE_STDLIB_H
+#cmakedefine HAVE_PTHREAD_H
+#cmakedefine HAVE_DIRECT_H
+#cmakedefine HAVE_STDINT_H
+/* system function check*/
+#cmakedefine HAVE_GETCWD
+#cmakedefine HAVE_MKDIR
+
--- /dev/null
+#include <iostream>
+#include <string>
+#include <sstream>
+#include <assert.h>
+
+#include "asn1_node.h"
+#include "asn1_module.h"
+#include "asn1_generator.h"
+
+#include "libparser/asn1_parser_listener.h"
+#include "asn1_gen_constraints.h"
+
+
+gen_constraints::gen_constraints()
+{
+ ;
+}
+
+gen_constraints::~gen_constraints()
+{
+ std::cout<<"gen_constraints::~gen_contraints"<<std::endl;
+ for ( moduleMapIterator mit = m_map.begin()
+ ; mit != m_map.end()
+ ; ++mit)
+ {
+ std::cout<<"Module "<<mit->first<<" has "<<mit->second.size();
+ std::cout<<" constraints"<<std::endl;
+ for (constraintSetIterator cit = mit->second.begin();
+ cit != mit->second.end();
+ ++cit)
+ {
+ std::cout<<"\t"<<cit->m_count<<" "<<cit->m_constraint->name()<<std::endl;
+ }
+ }
+}
+
+void
+gen_constraints::onConstraint(asn1::constraint *c)
+{
+ constraintSetIterator it;
+ std::pair<gen_constraints::constraintSetIterator,bool > ret;
+
+ local_constraint lc(c);
+ m_constraints.insert(lc);
+ ret = m_map[m_current_module].insert(lc);
+ if (ret.second == false)
+ {
+ it = ret.first;
+ (*it).m_count++;
+ }
+}
+
+void
+gen_constraints::onModule(asn1::module *m)
+{
+ m_current_module = m->name();
+}
--- /dev/null
+#ifndef ASN1_GEN_CONSTRAINTS_H
+#define ASN1_GEN_CONSTRAINTS_H
+
+/**
+ * @brief Constraint collector class
+ * Collect all constrains to generate a unique constraint table.
+ */
+class gen_constraints : public asn1::parser_listener
+{
+ public:
+ /**
+ *
+ *
+ */
+ struct local_constraint
+ {
+ public:
+ local_constraint(asn1::constraint *c = NULL) : m_count(1), m_constraint(c) {};
+
+ bool operator ==(local_constraint &lc)
+ {
+ return !m_constraint->name().compare(lc.m_constraint->name());
+ }
+
+ bool operator ==(asn1::constraint &lc)
+ {
+ return !m_constraint->name().compare(lc.name());
+ }
+
+ bool operator <(const local_constraint &lc) const
+ {
+ return m_constraint->name().compare(lc.m_constraint->name()) > 0 ;
+ }
+
+ void inc() { m_count++; } ;
+ asn1::constraint *m_constraint;
+ mutable long m_count;
+ };
+ //
+ typedef std::set<local_constraint> constraintSet;
+ typedef constraintSet::iterator constraintSetIterator;
+ typedef constraintSet::const_iterator const_constraintSetIterator;
+
+ typedef std::map<std::string,constraintSet> moduleMap;
+ typedef moduleMap::iterator moduleMapIterator;
+
+ // Default constructor
+ gen_constraints();
+ // Destructor
+ ~gen_constraints();
+
+ void onConstraint(asn1::constraint *c);
+
+ void onModule(asn1::module *m);
+ //
+ inline constraintSetIterator begin()
+ { return m_constraints.begin() ; }
+ //
+ inline constraintSetIterator end()
+ { return m_constraints.end() ; }
+
+ //
+ inline const_constraintSetIterator begin() const
+ { return m_constraints.begin() ; }
+ //
+ inline const_constraintSetIterator end() const
+ { return m_constraints.end() ; }
+
+ protected:
+ std::string m_current_module;
+ constraintSet m_constraints;
+ moduleMap m_map;
+};
+
+#endif /*ASN1_GEN_CONSTRAINTS_H*/
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <list>
+#include <assert.h>
+
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+
+
+codecstreams::codecstreams()
+{
+}
+//
+void
+codecstreams::open(const std::string &name,bool jer,bool per,bool oer)
+{
+ std::string filename = name + "_codec.hpp";
+ m_os_codec_hpp.open(filename.c_str(),std::fstream::out);
+ m_os_codec_hpp<<"// Generated do not modifie"<<std::endl;
+ filename = name + "_codec.cpp";
+ m_os_codec_cpp.open(filename.c_str(),std::fstream::out);
+ m_os_codec_cpp<<"// Generated do not modifie"<<std::endl;
+ if (jer)
+ {
+ filename = name + "_codec_jer.cpp";
+ m_os_jer.open(filename.c_str(),std::fstream::out);
+ }
+ if (per)
+ {
+ filename = name + "_codec_per.cpp";
+ m_os_per.open(filename.c_str(),std::fstream::out);
+ }
+ if (oer)
+ {
+ filename = name + "_codec_oer.cpp";
+ m_os_oer.open(filename.c_str(),std::fstream::out);
+ }
+}
+
+void
+codecstreams::close()
+{
+ if (m_os_codec_hpp.is_open())
+ m_os_codec_hpp.close();
+ if (m_os_codec_cpp.is_open())
+ m_os_codec_cpp.close();
+ if (m_os_jer.is_open())
+ m_os_jer.close();
+ if (m_os_per.is_open())
+ m_os_per.close();
+ if (m_os_oer.is_open())
+ m_os_oer.close();
+}
+
+codecstreams::~codecstreams()
+{
+ close();
+}
+
+/**
+ *
+ */
+generate_cpp::generate_cpp(asn1::module *n)
+ : asn1::generator(n)
+{
+}
+
+generate_cpp::generate_cpp(asn1::module *n,asn1::module::modules_type &m)
+ : asn1::generator(n,m)
+{
+
+}
+
+
+generate_cpp::~generate_cpp()
+{
+}
+
+
+void
+generate_cpp::
+gen_template_params(std::ostream &os,asn1::node *_params)
+{
+ asn1::constructed *params = _params->as_constructed();
+ asn1::node::node_list nl;
+
+ os<<"<";
+ for(asn1::node::iterator p = params->begin(); p != params->end() ;++p)
+ {
+ if (nl.size()>0)
+ {
+ asn1::node::iterator it = std::find_if(nl.begin(),nl.end(),asn1::find_node((*p)->name()));
+ if (it != nl.end() )
+ {
+ //
+ } else {
+ if (p != params->begin()) os<<",";
+ os<<" "<<(*p)->cpp_name();
+ nl.push_back(*p);
+ }
+ } else {
+ if (p != params->begin()) os<<",";
+ os<<" "<<(*p)->cpp_name();
+ nl.push_back(*p);
+ }
+ }
+ os<<"> ";
+}
+
+
+void generate_cpp::gen_composite_attribute_ref( std::ostream &os
+ , const std::string &scope
+ , asn1::field *attribute
+ , asn1::node *_params )
+{
+ asn1::constructed *params = _params->as_constructed();
+ asn1::typeref *attr_type = dynamic_cast<asn1::typeref *>(attribute->get_type());
+ assert( attr_type != NULL);
+ asn1::reference *ref = attr_type->get_reference();
+
+ assert(ref != NULL);
+
+ if ( ref && (ref->size() > 1))
+ {
+ gen_comp_attr_complex_ref(os,scope,*attr_type,params);
+ } else
+ {
+ gen_comp_attr_simple_ref(os,scope,*attr_type,params);
+ }
+}
+
+/**
+ *
+ */
+void
+generate_cpp::gen_comp_attr_ref_tplt(std::ostream &os
+ , asn1::typeref *attr_type
+ , asn1::node *real_type
+ , asn1::node *params)
+{
+ // check if attribute has parameters
+ if(attr_type->act_parameters() != NULL
+ && (real_type)
+ && is_template(real_type->identifier()->parameters())
+ )
+ {
+ os << "<";
+ for(asn1::node::iterator it = attr_type->act_parameters()->begin();
+ it != attr_type->act_parameters()->end(); ++it)
+ {
+ asn1::node* ns1 = NULL;
+ if(it != attr_type->act_parameters()->begin())
+ os << ",";
+ // check namespace
+ if(type_in_imports((*it)->name(), &ns1)) {
+ os << ns1->cpp_name() << "::" << (*it)->cpp_name();
+ } else
+ os << (*it)->cpp_name();
+ }
+ os << ">";
+ }
+}
+
+/**
+ * Simple reference attribute. No object or complex reference
+ *
+ */
+void
+generate_cpp::gen_comp_attr_simple_ref(std::ostream &os
+ , const std::string &scope
+ , asn1::typeref &_ref
+ , asn1::node *_params)
+{
+ asn1::constructed *params = _params->as_constructed();
+ asn1::typeref *attr_type = &_ref;
+ asn1::node *attribute = _ref.identifier();
+ asn1::reference *ref = _ref.get_reference();
+ asn1::node::iterator refm = std::find_if(m_module->begin(),
+ m_module->end(),
+ asn1::find_node(ref->name()));
+ asn1::node *real_type = m_resolver.resolve(*attr_type);
+
+ if (refm != m_module->end())
+ {
+ // Here Type in current module I have the type definition. I should add
+ if ( ((*refm)->get_color() == 2)
+ || attribute->flags().is_optional()
+ || ! attribute->get_parent()->identifier()->name().compare(_ref.name())
+ )
+ os<<"ASN1_ATTRIBUTE_OPTIONAL(";
+
+ os<<ref->cpp_name();
+
+ gen_comp_attr_ref_tplt(os,attr_type,real_type,params);
+
+ if ( ((*refm)->get_color() == 2 )
+ || attribute->flags().is_optional()
+ || ! attribute->get_parent()->identifier()->name().compare(_ref.name())
+ )
+ os<<" )";
+ if (with_source_comment())
+ {
+ os<<" /*NR c="<<(*refm)->get_color();
+ os<<" opt="<<attribute->flags().is_optional();
+ os<<" param="<<params<<" */ ";
+ }
+ } else
+ {
+ // Type in import
+ asn1::node *ns = NULL;
+ if (type_in_imports(ref->name(),&ns) )
+ {
+ asn1::reference::component_const_iterator compit = ref->begin();
+ // Simple external Reference
+ if (attribute->flags().is_optional() )
+ {
+ os<<"ASN1_ATTRIBUTE_OPTIONAL("<<ns->cpp_name()<<"::"<<ref->cpp_name()<<")";
+ if (with_source_comment())
+ os<<"/*NR 2 optional="<<attribute->flags().is_optional()<<" */ ";
+ } else
+ {
+ os<<ns->cpp_name()<<"::"<<ref->cpp_name();
+ if (with_source_comment())
+ os<<" /*NR 2 optional="<<attribute->flags().is_optional()<<" */ ";
+ }
+ // check if attribute has parameters
+
+ gen_comp_attr_ref_tplt(os,attr_type,real_type,params);
+
+ } else if (params) // reference in parameters of definition
+ {
+ // Wierd case
+ bool found = false;
+ for ( asn1::node::iterator it = params->begin()
+ ; it != params->end(); ++it)
+ {
+ if (ref->name().compare((*it)->name())== 0)
+ {
+ os<<" "<<(*it)->cpp_name();
+ found = true;
+ }
+ if (!found) {
+ GEN_LOG_ERROR("Parameter %s\n",(*it)->name().c_str());
+ os<<" ERRORNOTPARAMS ";
+ }
+
+ }
+
+ } else
+ {
+ os<<" ERROR ";
+ }
+ }
+}
+
+/**
+ *
+ */
+void
+generate_cpp::gen_comp_attr_complex_ref(std::ostream &os
+ , const std::string &scope
+ , asn1::typeref &_ref
+ , asn1::node *params)
+{
+ asn1::typeref *attr_type = &_ref;
+ asn1::node *attribute = _ref.identifier();
+ asn1::node *real_type = m_resolver.resolve(*attr_type);
+ asn1::node::node_list nl;
+ if (real_type)
+ {
+ real_type->path2module(nl);
+ asn1::module *t_module = m_module;
+ if (!nl.empty())
+ {
+ t_module = dynamic_cast<asn1::module *>(nl.front()->get_parent());
+ } else
+ {
+ }
+
+ if (t_module && ! t_module->name().compare(m_module->name()))
+ {
+ std::string scope("");
+ gen_attr_field_type(os,scope,real_type);
+ } else if (t_module)
+ {
+ // Type in other module
+ //os<<" /* t_module "<<real_type->name()<<" */ ";
+ std::string scope("");
+ scope = t_module->cpp_name() +"::";
+ if (_ref.is_external())
+ {
+ os<<scope<<real_type->identifier()->cpp_name() ;
+ }else
+ gen_attr_field_type(os,scope,real_type);
+ } else
+ { // Error
+ assert(0);
+ }
+ }
+}
+/**
+ * @brief Build the name of the type when is choice or sequence.
+ */
+void generate_cpp::private_attribute_type(asn1::node *type,std::string &structName)
+{
+ asn1::node::node_list lst;
+ assert(type != NULL);
+ assert(type->get_parent() != NULL);
+ std::string ss = type->cpp_name()+"_t";
+ type->path2module(lst);
+
+ for (asn1::node::const_iterator nit = lst.begin()
+ ; nit != lst.end()
+ ; ++nit )
+ {
+ if ( (*nit)->is_private() )
+ {
+ std::string tmp = (*nit)->cpp_name() + "_";
+ ss.insert(0,tmp);
+ } else
+ {
+ std::string tmp = (*nit)->identifier()->cpp_name() + "_";
+ ss.insert(0,tmp);
+ }
+ }
+ structName = ss;
+}
+
+/**
+* @brief
+* Generate field type attribute depending on scope
+* If field is not in current module,
+* scope = modle_cpp_name +"::"
+*/
+void
+generate_cpp::gen_attr_field_type( std::ostream &os
+ , std::string &scope
+ , asn1::node *field_type
+ )
+{
+ // Type in current module
+ // Wow attribute found in class Now I can decide what to do
+ switch( field_type->type_id()())
+ {
+ case asn1::type::ASN1_CLASSFIELD_TF:
+ os<<"asn1::intrusive_ptr<";
+ os<<scope<<"I";
+ os<<field_type->get_parent()->identifier_cpp_name()<<"> ";
+ if (with_source_comment())
+ {
+ os<<"/* CF ";
+ os<<field_type->get_parent()->identifier_cpp_name();
+ os<<" TF "<<field_type->name();
+ //" optional="; os<<attribute->flags().is_optional();
+ os<<" */ ";
+ }
+ break;
+ case asn1::type::ASN1_CLASSFIELD_FTVF:
+ {
+ asn1::classfield_ftvf *f = dynamic_cast<asn1::classfield_ftvf *>(field_type);
+ asn1::typenode *rnode = f->get_type();
+ os<<""<<scope<<rnode->cpp_name();
+ if (with_source_comment())
+ {
+ os<<" /* CF FTVF "<<field_type->name();
+ //os<<" optional:"<<attribute->flags().is_optional();
+ os<<" */ ";
+ }
+ }
+ break;
+ case asn1::type::ASN1_REFERENCE:
+ case asn1::type::ASN1_INTEGER:
+ case asn1::type::ASN1_CHOICE:
+ case asn1::type::ASN1_OBJECT_IDENTIFIER:
+ os<<scope<<field_type->cpp_name()<<" /* "<<field_type->name()<<"*/";
+ break;
+ default:
+ os<<"/* tyid="<<field_type->type_id()();
+ os<<" Field "<<field_type->name()<<"*/";
+ break;
+ }
+}
+
+
+/**
+ *
+ * This function should be used to compute the names of the structures with and without scope.
+ * In order to facilitate nested / unnested
+ * -> ASN1_ENUMERATED returns either cpp_name or indentifier_cpp_name if private or not
+ * -> ASN1_NULL returns Null
+ * -> ASN1_SEQUENCE_OF
+ * -> ASN1_SET_OF
+ * -> ASN1_CHOICE
+ * -> ASN1_SET
+ * -> ASN1_SEQUENCE
+ * TOBE COMPLETED
+ * -> ASN1_REFERNCE
+ * default not working properly
+ */
+bool generate_cpp::type2cppstring( asn1::typenode *type
+ , std::string &strtype
+ , const std::string &scope)
+{
+ asn1::node *ns;
+
+ assert(type != NULL);
+
+ if (type == NULL)
+ {
+ GEN_LOG_ERROR("type2cppstring failes type is nul \n");
+ return false;
+ }
+ switch (type->type_id()() )
+ {
+ case asn1::type::ASN1_SEQUENCE_OF:
+ {
+ asn1::node *seqof_type = type->get_eltype();
+ if (type_in_imports(seqof_type,&ns )) {
+ strtype = type->cpp_name()+"<"+ns->cpp_name()+"::"+seqof_type->cpp_name()+">";
+ } else {
+ switch (seqof_type->type_id()())
+ {
+ case asn1::type::ASN1_SEQUENCE:
+ {
+ asn1::node::node_list lst;
+ std::string ss;
+ type->path2module(lst);
+ for (asn1::node::const_iterator nit = lst.begin()
+ ; nit != lst.end()
+ ; ++nit )
+ {
+ if ( (*nit)->is_private() )
+ {
+ ss += (*nit)->cpp_name() + "::";
+ } else
+ ss += (*nit)->identifier()->cpp_name() + "::";
+ }
+ //TODO compute namespace if type is private or else clang complains
+ strtype="SEQUENCE_OF</*t2cs */ "+ seqof_type->cpp_name()+"> ";
+ }
+ break;
+ default:
+ if (asn1::typeref *tref = seqof_type->as_typeref())
+ {
+ strtype="SEQUENCE_OF</*t2cs2 */"+tref->get_reference()->cpp_name()+"> ";
+ } else
+ {
+ if (seqof_type->is_private())
+ {
+ strtype="SEQUENCE_OF</*t2cs3p*/ ";
+ strtype+=type->get_parent()->identifier()->cpp_name()+"::";
+ strtype+=seqof_type->cpp_name()+"> ";
+ } else
+ strtype="SEQUENCE_OF</*t2cs3*/ "+seqof_type->cpp_name()+"> ";
+ }
+ }
+ }
+ }
+ break;
+ case asn1::type::ASN1_SET_OF:
+ {
+ asn1::node *setof_type = type->get_eltype();
+ if (type_in_imports(setof_type,&ns ))
+ {
+ strtype = type->cpp_name()+"<"+ns->cpp_name()+"::"+setof_type->cpp_name()+">";
+ } else
+ {
+ switch (setof_type->type_id()())
+ {
+ case asn1::type::ASN1_SEQUENCE:
+ {
+ strtype="SET_OF<"+scope+setof_type->cpp_name()+"> ";
+ }
+ break;
+ default:
+ if (
+ asn1::typeref *tref =
+ dynamic_cast<asn1::typeref *>(setof_type)
+ //setof_type->get_reference()
+ )
+ {
+ if (tref->is_objectclass())
+ {
+ asn1::node *rt = m_resolver.resolve(*tref);
+ if (rt->type_node())
+ {
+ strtype = rt->type_node()->cpp_name();
+ return true;
+ }
+ }
+ else if (tref->is_simple())
+ {
+ asn1::node *rt = m_resolver.resolve(*tref);
+ strtype="SET_OF</*t3cs2r*/";
+ strtype +=rt->get_parent()->cpp_name();
+ strtype +="::" +tref->get_reference()->cpp_name()+"> ";
+ return true;
+ }
+ strtype="SET_OF</*t3cs2*/";
+ strtype+= tref->get_reference()->cpp_name()+"> ";
+ } else
+ {
+ strtype="SET_OF</*t3cs3*/"+setof_type->cpp_name()+"> ";
+ }
+ }
+ }
+ }
+ break;
+ case asn1::type::ASN1_NULL:
+ strtype= "Null";
+ break;
+ case asn1::type::ASN1_ENUMERATED:
+ case asn1::type::ASN1_SET:
+ // THIS NEEDS TO BE VALIDATED
+ if (type->is_private())
+ {
+ private_attribute_type(type->identifier(),strtype);
+ } else
+ strtype = type->identifier_cpp_name();
+ break;
+ case asn1::type::ASN1_SELECTION:
+ {
+ strtype = "INTEGER";
+ return true;
+ }
+ break;
+#if defined(_WINDOWS)
+ case asn1::type::ASN1_BOOLEAN:
+ {
+ strtype = std::string("asn1::") + type->cpp_name();
+ return true;
+ }
+#endif
+ break;
+ case asn1::type::ASN1_REFERENCE:
+ {
+ asn1::typeref *tref = dynamic_cast<asn1::typeref *>(type);
+ if (tref->is_objectclass())
+ {
+ asn1::node *rt = m_resolver.resolve(*tref);
+ if (rt->type_node())
+ {
+ strtype = rt->type_node()->cpp_name();
+ return true;
+ }
+ if (!rt)
+ {
+ std::cerr<<"type2cppstring "<<tref->name()<<" Failed"<<std::endl;
+ assert(0);
+ }
+ // important for complex...
+ type = rt->as_typenode();
+ }
+ }
+ //break;
+ default:
+ if (type_in_imports(type->name(),&ns ))
+ {
+ strtype = ns->cpp_name()+ "::"+type->cpp_name();
+ } else
+ {
+ strtype = type->cpp_name();
+ }
+ }
+
+ return true;
+}
+
+/*
+ * vim: et sw=2 ts=2 list
+ */
--- /dev/null
+#ifndef ASN1_GEN_CPP_H__
+#define ASN1_GEN_CPP_H__
+
+
+/**
+ * Generate code in deferent files for simplicity
+ * os_codec_hpp <name>_codec.hpp
+ * os_codec_cpp <name>_codec.cpp
+ * os_jer <name>_codec_jer.cpp
+ * os_per <name>_codec_per.cpp
+ * os_oer <name>_codec_oer.cpp
+ * When created, also create the associated streams
+ */
+struct codecstreams
+{
+ protected:
+ codecstreams(const codecstreams &c)
+ { std::cout<<"codecstreams copy\n";}
+ ;
+ public:
+ codecstreams() ;
+ void open(const std::string &name,bool jer,bool per,bool oer) ;
+ void close() ;
+ ~codecstreams();
+ std::fstream m_os_codec_hpp;
+ std::fstream m_os_codec_cpp;
+ std::fstream m_os_jer;
+ std::fstream m_os_per;
+ std::fstream m_os_oer;
+};
+/**
+ * Common generation function that can be used in header and cpp files has well
+ *
+ * Forseen usage :
+ * - attribute_ref resolution
+ * - value_from object
+ * - constraints
+ * - template signatures
+ */
+class generate_cpp : public asn1::generator
+{
+ protected:
+ generate_cpp(const generate_cpp &g)
+ : asn1::generator(g)
+ {
+ std::cout<<"copy generate_cpp "<<std::endl;
+ };
+ protected:
+ codecstreams m_Streams;
+ public:
+
+ generate_cpp(asn1::module *n);
+ generate_cpp(asn1::module *n,asn1::module::modules_type &m);
+
+ virtual ~generate_cpp();
+
+ inline codecstreams &get_streams() { return m_Streams; };
+ //
+ void gen_template_params(std::ostream &os,asn1::node *params);
+ /**
+ *
+ */
+ void gen_composite_attribute_ref( std::ostream &os
+ , const std::string &scope
+ , asn1::field *attribute
+ , asn1::node *params = NULL);
+ /**
+ * TODO: Needs to be moved to asn1_gen_cpp.cpp
+ */
+ bool type2cppstring( asn1::typenode *type
+ , std::string &strtype
+ , const std::string &scope = "");
+
+ protected:
+ void gen_comp_attr_simple_ref(std::ostream &os
+ , const std::string &scope
+ , asn1::typeref &_ref
+ , asn1::node *params);
+ /**
+ * @brief
+ * Handle the complex case with object class references and
+ * so on.
+ * @param os
+ * @param scope
+ * @param _ref
+ * @param params
+ */
+ void gen_comp_attr_complex_ref(std::ostream &os
+ , const std::string &scope
+ , asn1::typeref &_ref
+ , asn1::node *params);
+ /**
+ * @brief
+ * Output template signature for eventual template parameters
+ *
+ * @param os
+ * @param attr_type
+ * @param real_type
+ * @param params
+ */
+ void gen_comp_attr_ref_tplt(std::ostream &os
+ , asn1::typeref *attr_type
+ , asn1::node *real_type
+ , asn1::node *params);
+ /**
+ * @brief
+ * Generate field type attribute depending on scope
+ * If field is not in current module,
+ * scope = modle_cpp_name +"::"
+ */
+ void gen_attr_field_type( std::ostream &os
+ , std::string &scope
+ , asn1::node *field_type
+ );
+ public:
+ /**
+ * @brief
+ * Compute private attribute cpp struct name for attribute
+ * that use defined types like choice, enum, set sequence...
+ * example Toto ::= SEQUENCE {
+ * x CHOICE { a INTEGER,
+ * b BOOLEAN}
+ * y SET { ab BIT STRING }
+ * }
+ *
+ * type for x should be Toto_x_t
+ */
+ void private_attribute_type(asn1::node *attr,std::string &structName);
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_hpp.h"
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <errno.h>
+#if defined(__APPLE__) || (GCC_VERSION > 40800)
+#include <stdlib.h>
+#include <unistd.h>
+#endif
+#if defined(_WIN32)
+#include <io.h>
+#include <stdlib.h>
+#include <direct.h>
+#define getcwd _getcwd
+#define mkdir _mkdir
+#endif
+#include "asn1_resolver.h"
+#include "asn1_generator_helper.h"
+#include "cpp/cghpp_helper.h"
+#include "cpp/cgh_hconstruct.h"
+#include "cpp/cghpph_primitive.h"
+#include "cpp/cghpph_bitstring.h"
+#include "cpp/cghpph_octetstring.h"
+#include "cpp/cghpph_classdef.h"
+#include "cpp/cghpph_enumerated.h"
+#include "cpp/cghpph_integer.h"
+#include "cpp/cghpph_sequence.h"
+#include "cpp/cghpph_sequenceof.h"
+#include "cpp/cghpph_setof.h"
+#include "cpp/cghpph_choice.h"
+#include "cpp/cghpph_set.h"
+#include "cpp/cghpph_typeref.h"
+#include "cpp/cgh_object.h"
+#include "cpp/cghpph_object.h"
+#include "cpp/cghpph_import.h"
+#include "cpp/cghpph_string.h"
+#include "cpp/cghpph_boolean.h"
+#include "cpp/cghpph_oid.h"
+#include "asn1_visitor.h"
+
+/**
+ * generate template instantiation in .hpp file
+ *
+ */
+struct gen_tplt
+{
+ gen_tplt(std::ostream &os,generate_header &g)
+ : m_os(os), m_Gen(g)
+ {
+ }
+
+ void operator ()(asn1::node *n)
+ {
+ asn1::typenode *type = n->as_assignment()->get_type();
+
+ assert(type->type_id()() == asn1::type::ASN1_REFERENCE);
+ asn1::node *real_type =
+ m_Gen.resolver().resolve(dynamic_cast<asn1::typeref &>(*type));
+ if (real_type != NULL)
+ {
+ asn1::object *obj = dynamic_cast<asn1::object *>(type->get_eltype());
+ asn1::classdef *cdef = dynamic_cast<asn1::classdef *>(real_type);
+ assert( obj != NULL);
+ assert( cdef != NULL);
+
+ cghpph_object obj_gen(m_Gen,m_os,*obj,*cdef);
+ obj_gen.generate_hpp();
+ } else
+ {
+ std::cerr<<"gen_tplt::OBJECT CLASS not found "<<type->name()<<std::endl;
+ }
+ }
+ protected:
+ std::ostream &m_os;
+ generate_header &m_Gen;
+};
+
+/**
+ * Default Constructor
+ */
+generate_header::generate_header(asn1::module *n) : generate_cpp(n)
+{}
+
+generate_header::generate_header(asn1::module *n,asn1::module::modules_type &m)
+ : generate_cpp(n,m)
+{
+}
+
+/**
+ * Helper function to look for missing prototypes
+ * Most complicated function that needs to be reworked.
+ * n is either an assignment or a typenode
+ */
+void generate_header::gen_missing(std::ostream &os,asn1::node *n)
+{
+ asn1::node::iterator it;
+
+ switch (n->type_id()())
+ {
+ case asn1::type::ASN1_SEQUENCE_OF:
+ case asn1::type::ASN1_SET_OF:
+ {
+#ifdef DEBUG
+ GEN_LOG_DEBUG("find sequence of or set of %s\n",n->name().c_str());
+#endif
+ asn1::node *type = n->as_typenode()->get_eltype();
+ assert( (n->identifier() != NULL) && (type != NULL));
+ if ( ! type->is_primitive() )
+ type->name(n->identifier()->cpp_name()+std::string("_type"));
+
+ if (asn1::typeref *tref = type->as_typeref())
+ {
+ it = std::find_if(m_module->begin(),
+ m_module->end(),
+ asn1::find_node(tref->get_reference()->name()));
+ } else {
+ it = std::find_if(m_module->begin(),
+ m_module->end(),
+ asn1::find_node(type->name()));
+ }
+ // might be true if it's a private sequence or choice
+ if (it == m_module->end())
+ {
+ os<<"//generate_header::"<<__FUNCTION__;
+ os<<" WARNING Found sequence of or set of:";
+ os<<n->name()<<" private element \n";
+ gen_missing(os,type);
+
+ }
+
+ }
+ break;
+ case asn1::type::ASN1_ENUMERATED:
+ {
+ assert(n->identifier() != NULL);
+ asn1::node * attribute = n->identifier();
+ n->name(attribute->cpp_name()+"_t");
+ os<<"//gen_missing not nested ENUM "<<n->name();
+ os<<" "<<attribute->name()<<std::endl;
+
+ gen_enumerated(os,n,attribute->cpp_name()+"_t");
+
+ os<<";\n";
+ // TODO MAY BE SET it to m_module->end();
+ // There is nothing to generated behind enumerated
+ it = std::find_if(m_module->begin(),m_module->end(),asn1::find_node(n->name()));
+ }
+ break;
+ case asn1::type::ASN1_SEQUENCE:
+ case asn1::type::ASN1_CHOICE:
+ case asn1::type::ASN1_SET:
+ {
+ asn1::constructed *cons = dynamic_cast<asn1::constructed *>(n);
+ asn1::node::iterator lit = cons->begin();
+ assert(0);
+ GEN_LOG_DEBUG("gen_missing::found sequence or choice, set %s\n"
+ ,n->name().c_str());
+ // Loop over the children and lookup for missing
+ for (; lit != cons->end() ; lit++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*lit);
+ if ( asn1::typenode *tn = f->get_type())
+ {
+ gen_missing(os,tn);
+ }
+ }
+ }
+ return;
+ break;
+ case asn1::type::ASN1_NULL:
+ return;
+ case asn1::type::ASN1_REFERENCE:
+ {
+ asn1::typeref *tref = n->as_typeref();
+ // Try to check references
+ if (tref->act_parameters() != NULL)
+ {
+ asn1::constructed *params = tref->act_parameters();
+ GEN_LOG_DEBUG("%s have parameters\n",tref->name().c_str());
+ //os<<"//generate_header::"<<__FUNCTION__<<" "<<n->name()<<" Have parameters\n";
+ for( asn1::node::iterator p = params->begin()
+ ; p != params->end()
+ ; ++p)
+ {
+ GEN_LOG_DEBUG( "%s have parameter : %s\n"
+ , tref->name().c_str()
+ , (*p)->name().c_str());
+ it = std::find_if( m_module->begin()
+ , m_module->end()
+ , asn1::find_node((*p)->name()));
+
+ if (it != m_module->end())
+ {
+ // yes in h323
+ //assert(0 && " is this used ?");
+ gen_missing(os,(*it));
+ }
+ }
+ }
+ //
+ if (tref->get_reference())
+ {
+ GEN_LOG_DEBUG( "Ref %s color=%d\n"
+ , tref->get_reference()->name().c_str()
+ , n->get_color());
+ if (std::string("TYPE-IDENTIFIER::&Type").compare(tref->get_reference()->name()) == 0)
+ {
+ std::cerr<<"TYPE-IDENTIFIER types shall OCTET STREAMS or open Types. I'm going too far here"<<std::endl;
+ asn1::constraint::iterator c = tref->constraint_begin();
+ if ((*c)->type() == asn1::constraint::EL_TYPE)
+ {
+ asn1::node *ctype = (*c)->value();
+ it = std::find_if(m_module->begin(),
+ m_module->end(),
+ asn1::find_node(ctype->name()));
+ }
+ } else
+ {
+ it = std::find_if(m_module->begin(),
+ m_module->end(),
+ asn1::find_node(tref->get_reference()->name()));
+ if ( it == m_module->end() )
+ {
+ GEN_LOG_WARN( "Reference %s not found use lookup ?\n"
+ , tref->get_reference()->name().c_str());
+ } else
+ {
+ GEN_LOG_INFO("Reference %s found in current module. node %s\n"
+ ,tref->get_reference()->name().c_str()
+ , (*it)->name().c_str());
+ }
+ }
+ } else
+ {
+ it = std::find_if( m_module->begin()
+ , m_module->end()
+ , asn1::find_node(n->name()));
+ }
+ }
+ break;
+ case asn1::type::ASN1_BOOLEAN: // Do nothing for primary types
+ it = std::find_if( m_module->begin()
+ , m_module->end()
+ , asn1::find_node(n->name()));
+ break;
+ default:
+ //os<<"//generate_header::"<<__FUNCTION__<<" WAR def case Ref "<<n->name()<<" type="<<n->type_id()()<<"not found\n";
+ it = std::find_if( m_module->begin()
+ , m_module->end()
+ , asn1::find_node(n->name()));
+ }
+ // Found a element to be generated
+ if ( it != m_module->end())
+ {
+ asn1::assignment *ltype = (*it)->as_assignment();
+ if ( (ltype->is_generated() != true))
+ {
+ if (ltype->get_color() == asn1::node::CL_GREEN)
+ {
+ ltype->set_generated(true);
+ GEN_LOG_DEBUG( "do gen missing for %s color=%d\n"
+ , ltype->name().c_str()
+ , ltype->get_color());
+ switch(ltype->get_type()->type_id()())
+ {
+ case asn1::type::ASN1_REFERENCE:
+ gen_typeref(os,ltype->get_type()->as_typeref());
+ break;
+ default:
+ {
+ gen_typedef(os,ltype->get_type()->as_typenode());
+ }
+ }
+ ltype->set_color(asn1::node::CL_RED);
+ } else if (ltype->get_color() == asn1::node::CL_ORANGE)
+ {
+ GEN_LOG_WARN( "gen_missing type %s of color=%d\n"
+ , ltype->name().c_str()
+ , ltype->get_color());
+ if (ltype->get_type()->type_id()() == asn1::type::ASN1_SEQUENCE ||
+ ltype->get_type()->type_id()() == asn1::type::ASN1_CHOICE
+ )
+ os<<"struct "<<ltype->cpp_name()<<";"<<std::endl;
+ ltype->set_color(asn1::node::CL_REENTRANT);
+ }else
+ {
+ GEN_LOG_DEBUG( "gen_missing type %s of color=%d\n"
+ , ltype->name().c_str()
+ , ltype->get_color());
+ ltype->set_color(asn1::node::CL_REENTRANT);
+ }
+ }
+ }
+}
+
+/**
+ * This is only valid for OID where we use 7 bits for each octet.
+ */
+void generate_header::encode_integer(long value,std::vector<unsigned char> &v)
+{
+ long integer = value;
+ long intsize = 4;
+ long mask = 0x1FF <<23; // Shift 8 *3 - 1 ? 0xFF800000
+#ifdef DEBUG
+ GEN_LOG_DEBUG("encode %ld\n",value);
+#endif
+ while ( (((integer & mask) == 0) || ((integer & mask) == mask))
+ && (intsize > 1)) {
+ intsize--;
+ integer <<=7;
+#ifdef DEBUG
+ GEN_LOG_DEBUG("is: integer = %ld\n",integer);
+#endif
+ }
+#ifdef DEBUG
+ GEN_LOG_DEBUG("integer size = %ld\n",intsize);
+#endif
+ mask = (0x7f << ((intsize-1)*7));
+ long decal = (intsize -1)*7;
+ while ((value & mask ) != 0)
+ {
+ long treat = ((value & mask)>>decal);
+ v.push_back (( treat & 0x7F) |0x80 );
+#ifdef DEBUG
+ std::cout<<"\tpushed :";
+ std::cout<<std::hex<<(int)v.back()<<" integer was:"<<value;
+ std::cout<<" Mask=0x"<<mask<<" treat="<<treat;
+ std::cout<<std::dec<<std::endl;
+#endif
+ value<<=7;
+ }
+ v.back() = v.back() & 0x7F;
+}
+
+/**
+ *
+ *
+ */
+void generate_header::gen_oid_value(std::ostream &os,asn1::object_identifier *tp)
+{
+#ifdef DEBUG
+ GEN_LOG_DEBUG("node name %s\n",tp->identifier()->name().c_str());
+#endif
+ asn1::object_identifier::arcsType v;
+ tp->arcs(v);
+ os<<"\tinline "<<tp->identifier()->cpp_name()<<"(int s="<<v.size()<<",const char *v=";
+ tp->print_strhex(os,v);
+ os<<")\n\t\t\t : OBJECT_IDENTIFIER(s,v)\n\t{};\n";
+ os<<std::dec;
+}
+
+/**
+ * @brief generate constant definition in header
+ * TODO : function needs to be reworked. The value information
+ * should be process not the type !!!
+ *
+ */
+void generate_header::gen_const(std::ostream &os,asn1::node *n)
+{
+ asn1::typenode *type = n->as_assignment()->get_type();
+
+ assert( n->meta_id()() == asn1::meta::VALUE
+ || n->meta_id()() == asn1::meta::VALUESET
+ );
+ switch(type->type_id()())
+ {
+ case asn1::type::ASN1_OBJECT_IDENTIFIER:
+ {
+ os<<"struct "<<type->identifier_cpp_name();
+ os<<"\t : public OBJECT_IDENTIFIER\n{\n";
+ gen_oid_value(os,type->as_object_identifier());
+ os<<"\n};\n";
+ }
+ break;
+ case asn1::type::ASN1_OBJECTSET:
+ {
+ asn1::objectset *objs = dynamic_cast<asn1::objectset *>(type);
+ assert(0); // Is this called ! No only is CPP
+ GEN_LOG_DEBUG("in OBJECTSET type=%s ident name=%s:\n"
+ ,type->name().c_str()
+ ,type->identifier_name().c_str());
+ }
+ break;
+ case asn1::type::ASN1_VALUESET:
+ {
+ GEN_LOG_DEBUG("in VALUESET type=%s ident name=%s:\n"
+ ,type->name().c_str()
+ ,type->identifier_name().c_str());
+ assert(0); // Is this called ? No Only in CPP
+ }
+ break;
+ case asn1::type::ASN1_INTEGER:
+ {
+ GEN_LOG_DEBUG( "value integer %s\n"
+ , type->identifier_name().c_str());
+ os<<"#define "<<type->identifier_cpp_name();
+ os<<"\t "<<n->value()->cpp_name()<<"";
+ }
+ break;
+ case asn1::type::ASN1_REFERENCE:
+ GEN_LOG_DEBUG( "value reference %s\n"
+ , type->identifier_name().c_str());
+ gen_missing(os,type);
+
+ os<<"struct "<<type->identifier()->cpp_name()<<" : public ";
+ os<<type->cpp_name()<<"\n{\n";
+ os<<"\t"<<type->identifier()->cpp_name()<<"();\n";
+ os<<"};";
+ break;
+ default:
+ {
+ asn1::value *v = n->value();
+ GEN_LOG_DEBUG("default case %s\n",type->identifier_name().c_str());
+ assert(v != NULL);
+ switch (v->type)
+ {
+ case asn1::value::VT_INTEGER:
+ os<<"const "<<type->cpp_name()<<" "<<type->identifier_cpp_name()<<"\t\t= ";
+ os<<v->cpp_name();
+ os<<";";
+ break;
+ case asn1::value::VT_COLON:
+ default:
+ ;
+ }
+ }
+ }
+ os<<std::endl;
+
+}
+
+/**
+ *
+ *
+ */
+void generate_header::gen_bitstring(std::ostream &os,asn1::bit_string &bs )
+{
+ cghpph_bit_string ebs(*this,os,bs);
+ ebs.generate();
+}
+
+
+/**
+ *
+ *
+ */
+void generate_header::gen_enumerated( std::ostream &os
+ , asn1::node *type
+ , const std::string &name)
+{
+ std::string indent("");
+ asn1::enumerated *e = dynamic_cast<asn1::enumerated *>(type);
+ assert( (type->type_id()() == asn1::type::ASN1_ENUMERATED) && (e != NULL));
+
+ cghpph_enumerated egen(*this,os,*e);
+ egen.generate();
+}
+
+//
+// gen_typeref
+//
+void generate_header::gen_typeref(std::ostream &os,asn1::typeref *type)
+{
+ std::string type_name;
+ bool resolved = false;
+ asn1::node *real_type = NULL;
+ asn1::typeref *ref = dynamic_cast<asn1::typeref *>(type);
+ // Pre requisit
+ assert( (type != NULL) && (type->type_id()() == asn1::type::ASN1_REFERENCE));
+ assert( type->get_reference() != NULL);
+ assert( ref != NULL);
+
+ if (with_source_comment())
+ {
+ GEN_LOG_DEBUG( "type identifier=%s type_id=%d\n"
+ , type->identifier_name().c_str()
+ , type->type_id()());
+ os<<"//generate_header::"<<__FUNCTION__;
+ os<<" "<<type->identifier_name()<<" id="<<type->type_id()()<<" ";
+
+ if (type->has_constraints())
+ {
+ asn1::constraint *c = *(type->constraint_begin());
+ if (c)
+ os<<c->name();
+ }
+
+ GEN_LOG_DEBUG("type is %s \n",type->name().c_str());
+
+ if (type->parameters() != NULL)
+ {
+ GEN_LOG_DEBUG("type %s has parameters \n",type->name().c_str());
+ os<<" parameterized ";
+ }
+ os<<"\n";
+ }
+
+ type_name = type->cpp_name();
+ asn1::resolver resolver(*m_module,m_modules);
+
+ if ( (real_type = ref->get_real_type()) == NULL)
+ real_type = resolver.resolve(*ref);
+
+ if (real_type != NULL && real_type->type_node())
+ {
+ GEN_LOG_DEBUG("gen_typeref found Reference %s of type : %s color : %d\n"
+ , real_type->name().c_str()
+ , real_type->type_node()->name().c_str()
+ , real_type->get_color()
+ );
+ }
+ // TODO Don't understand
+ // PkIx does not compile. Because the referenced type is not yet declared.
+ // As I play with typedefs and classes I'm no easely able to figure out what to
+ // do. An Idea is to generated the referenced type first if it's not generated
+ // Where is the Color ?
+ gen_missing(os,type);
+ asn1::node *ns = NULL;
+ os<<"//\n//"<<type->identifier_name()<<"\n//\n";
+
+ cghpph_typeref gen_ref(*this,os,*ref);
+ gen_ref.generate();
+}
+
+/**
+ *
+ */
+void generate_header::gen_typedef_integer( std::ostream &os
+ , asn1::node *type)
+{
+ asn1::integer *i = dynamic_cast<asn1::integer *>(type);
+
+ assert( (type->type_id()() == asn1::type::ASN1_INTEGER) && (i != NULL));
+
+ cghpph_integer igen(*this,os,*i);
+ igen.generate();
+}
+
+//
+//
+void
+generate_header::gen_sequence_of( std::ostream &os
+ , asn1::sequence_of &_seqof)
+{
+ asn1::node *ns = NULL;
+ asn1::typenode *seqof_type = _seqof.get_eltype();
+
+ if (seqof_type->get_parent() == NULL)
+ {
+ GEN_LOG_ERROR("gen_sequence_of type->get_parent() is NULL\n");
+ }
+ assert(seqof_type->get_parent() != NULL);
+
+ gen_missing(os,seqof_type);
+
+ if (type_in_imports(seqof_type,&ns) )
+ {
+ cghpph_sequenceof genso(*this,os,_seqof);
+ genso.generate();
+ } else
+ {
+ switch (seqof_type->type_id()())
+ {
+ case asn1::type::ASN1_SEQUENCE:
+ {
+ assert(0 && "gen_seq_of type should be reference not sequence");
+ }
+ break;
+ case asn1::type::ASN1_CHOICE:
+ {
+ assert(0 && "gen_seq_of type should be reference not choice");
+ }
+ break;
+ case asn1::type::ASN1_ENUMERATED:
+ {
+ assert(0 && "gen_seq_of type should be reference not enumr");
+ }
+ break;
+ default:
+ cghpph_sequenceof genso(*this,os,_seqof);
+ genso.generate();
+ }
+ }
+}
+
+//
+//
+void
+generate_header::gen_set_of(std::ostream &os,asn1::set_of &_seqof)
+{
+ asn1::node *ns = NULL;
+ asn1::typenode *seqof_type = _seqof.get_eltype();
+
+ gen_missing(os,seqof_type);
+ std::cout<<"gen_set_of "<<_seqof.identifier_cpp_name()<<" "<<seqof_type->cpp_name()<<std::endl;
+ if (type_in_imports(seqof_type,&ns) )
+ {
+ cghpph_setof gensetof(*this,os,_seqof);
+ gensetof.generate();
+ } else
+ {
+ switch (seqof_type->type_id()())
+ {
+ case asn1::type::ASN1_SEQUENCE:
+ {
+ assert(0 && "gen_set_of type should be reference not sequence");
+ }
+ break;
+ case asn1::type::ASN1_CHOICE:
+ {
+ assert(0 && "gen_set_of type should be reference not choice");
+ }
+ break;
+ case asn1::type::ASN1_ENUMERATED:
+ {
+ assert(0 && "gen_set_of type should be reference not enum");
+ }
+ break;
+ default:
+ cghpph_setof gensetof(*this,os,_seqof);
+ gensetof.generate();
+ }
+ }
+}
+
+
+//
+//
+//
+void generate_header::gen_typedef( std::ostream &os
+ , asn1::typenode *type)
+{
+ assert(type != NULL);
+ // Text cosmetic
+ GEN_LOG_DEBUG( "type %s ident=%s\n"
+ , type->name().c_str()
+ , type->identifier_name().c_str());
+ if (with_source_comment() )
+ {
+ os<<"// gen_typedef : "<<type->identifier_name();
+ os<<" id="<<type->type_id()()<<" color="<<type->get_color();
+ if (type->has_constraints())
+ {
+ asn1::constraint *c = *(type->constraint_begin());
+ if (c)
+ os <<c->name();
+
+ }
+ if ( type->identifier() && type->identifier()->parameters())
+ {
+ os<<" parameterized ";
+ }
+ os<<"\n";
+ }
+ // start the real work
+ if (type != NULL)
+ switch (type->type_id()())
+ {
+ case asn1::type::ASN1_REFERENCE:
+ {
+ GEN_LOG_ERROR("type %s is reference\n",type->name().c_str());
+ assert(0);
+ }
+ break;
+ case asn1::type::ASN1_INTEGER:
+ {
+ gen_typedef_integer(os,type);
+ return ;
+ }
+ break;
+ case asn1::type::ASN1_SEQUENCE:
+ {
+ asn1::sequence *seq = dynamic_cast<asn1::sequence *>(type);
+ if (with_source_comment())
+ {
+ os<<"// start SEQUENCE GENERATION ";
+ os<<type->identifier()->name()<<"\n";
+ }
+ std::string scope("");
+ // Genenerate missing before generating structure
+ asn1::node::iterator lit = seq->begin();
+ for (; lit != seq->end() ; ++lit)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*lit);
+ asn1::typenode *attr_type = f->get_type() ;
+ if ( attr_type != NULL)
+ {
+ gen_missing(os,attr_type);
+ } else if (asn1::extension_field *ef = dynamic_cast<asn1::extension_field *>(f) )
+ {
+ os<<"// SEQUENCE GENERATION has extension field"<<std::endl;
+ } else
+ {
+ if (with_source_comment())
+ {
+ os<<"// SEQUENCE GENERATION ERROR on attribute ";
+ os<<(*lit)->name()<<" Does not have type node cannot call gen_missing"<<std::endl;
+
+ }
+ }
+ }
+ gen_seq(os,scope,seq);
+ os<<";\n";
+ if (with_source_comment())
+ os<<"// end SEQUENCE GENERATION "<<type->identifier()->name()<<"\n";
+ os<<"\n"<<std::endl;
+ return ;
+ }
+ break;
+ case asn1::type::ASN1_SEQUENCE_OF:
+ gen_sequence_of(os,dynamic_cast<asn1::sequence_of &>(*type));
+ return ;
+ break;
+ case asn1::type::ASN1_SET:
+ {
+ asn1::set *col = dynamic_cast<asn1::set *>(type);
+ asn1::node::iterator lit = col->begin();
+ for (; lit != col->end() ; lit++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*lit);
+ if ( asn1::typenode *tn = f->get_type() ) {
+ gen_missing(os,tn);
+ }
+ }
+ gen_set(os,type);
+ os<<";\n";
+ return ;
+ }
+ break;
+ case asn1::type::ASN1_SET_OF:
+ {
+ gen_set_of(os,dynamic_cast<asn1::set_of &>(*type));
+ return;
+ }
+ break;
+ case asn1::type::ASN1_CHOICE:
+ {
+ asn1::choice *choix = dynamic_cast<asn1::choice *>(type);
+ asn1::node::iterator lit = choix->begin();
+ for (; lit != choix->end() ; lit++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*lit);
+ if ( asn1::typenode *tn = f->get_type() ) {
+ gen_missing(os,tn);
+ }
+ }
+ gen_choice(os,choix);
+ os<<";\n";
+ return;
+ }
+ break;
+ case asn1::type::ASN1_ENUMERATED:
+ {
+ gen_enumerated(os,(type),type->identifier_cpp_name());
+ os<<";\n";
+ return;
+ }
+ break;
+ ;
+ case asn1::type::ASN1_BIT_STRING:
+ {
+ asn1::bit_string *bs = dynamic_cast<asn1::bit_string *>(type);
+ assert(bs != NULL);
+ gen_bitstring(os,*bs);
+ return ;
+ }
+ break;
+ case asn1::type::ASN1_OCTET_STRING:
+ {
+ asn1::octet_string *o = dynamic_cast<asn1::octet_string *>(type);
+
+ assert( (type->type_id()() == asn1::type::ASN1_OCTET_STRING)
+ && (o != NULL));
+
+ cghpph_octet_string ogen(*this,os,*o);
+ ogen.generate();
+ return ;
+ }
+ case asn1::type::ASN1_BOOLEAN:
+ {
+ asn1::boolean *o = dynamic_cast<asn1::boolean *>(type);
+
+ assert( (type->type_id()() == asn1::type::ASN1_BOOLEAN)
+ && (o != NULL));
+
+ cghpph_boolean ogen(*this,os,*o);
+ ogen.generate();
+ return ;
+ }
+
+ case asn1::type::ASN1_NULL:
+ {
+ asn1::primitive *o = dynamic_cast<asn1::primitive *>(type);
+ GEN_LOG_ERROR("type %s NULL is reference\n",type->name().c_str());
+
+ assert( (o != NULL));
+ std::cerr<<__FUNCTION__<<" GENERATE "<<o->identifier()->cpp_name();
+ std::cerr<<" type::ASN1_NULL"<<std::endl;
+ cghpph_primitive pgen(*this,os,*o);
+ pgen.generate();
+ GEN_LOG_ERROR("type %s end is reference\n",type->name().c_str());
+ return ;
+ }
+
+
+ case asn1::type::ASN1_STRING_BMPString:
+ case asn1::type::ASN1_STRING_IA5String:
+ case asn1::type::ASN1_STRING_VisibleString:
+ case asn1::type::ASN1_STRING_GraphicString:
+ case asn1::type::ASN1_STRING_ISO646String: /* aka VisibleString */
+ case asn1::type::ASN1_STRING_PrintableString:
+ case asn1::type::ASN1_STRING_NumericString:
+ case asn1::type::ASN1_STRING_TeletexString:
+ {
+ asn1::primitive *o = dynamic_cast<asn1::primitive *>(type);
+
+ assert( (o != NULL));
+
+ cghpph_string ogen(*this,os,*o);
+ ogen.generate();
+ return ;
+ }
+
+ break;
+ case asn1::type::ASN1_OBJECT_IDENTIFIER:
+ {
+ asn1::object_identifier *o =
+ dynamic_cast<asn1::object_identifier *>(type);
+
+ assert( (o != NULL));
+
+ cghpph_oid ogen(*this,os,*o);
+ ogen.generate();
+ return ;
+ }
+
+ break;
+ case asn1::type::ASN1_STRING:
+ case asn1::type::ASN1_STRING_UniversalString:
+ case asn1::type::ASN1_STRING_UTF8String :
+ case asn1::type::ASN1_STRING_GeneralString:
+ case asn1::type::ASN1_STRING_T61String:
+ case asn1::type::ASN1_STRING_VideotexString:
+ case asn1::type::ASN1_STRING_ObjectDescriptor:
+ //case asn1::type::ASN1_UNIVERSAL:
+ default:
+ {
+ std::string cppType;
+ if ( ! type2cppstring(type,cppType))
+ {
+ std::cerr<<"Failed get cpp type for "<<type->name()<<std::endl;
+ assert(0);
+ }
+ gen_missing(os,type);
+ asn1::node *ns = NULL;
+ os<<"//\n// gen_typdef default case "<<type->identifier_name()<<"\n//\n";
+ os<<"typedef ";
+ if (type_in_imports(type,&ns) ) {
+ os<<"\t"<<ns->cpp_name()<<"::";
+ os<<type->cpp_name()<<" ";
+ } else {
+ if (type->tagged())
+ {
+ os<<"asn1::types::";
+ if (type->tag().m_mode == asn1::node::tag_type::TM_IMPLICIT)
+ {
+ os<<"IMPLICIT<";
+ } else
+ os<<"EXPLICIT<";
+ os<<type->tag().m_class<<","<<type->tag().m_value<<",";
+ if (type_in_imports(type,&ns) ) {
+ os<<"\t"<<ns->cpp_name()<<"::";
+ os<<type->cpp_name()<<"> ";
+ } else
+ os<<" /**/ "<<type->cpp_name()<<"> ";
+ } else
+ {
+ if (with_source_comment())
+ os<<" /*gtdef*/ ";
+ os<<cppType<<" ";
+ }
+ }
+ }
+ }
+ os<<"\t\t"<<type->identifier_cpp_name()<<";\n\n";
+
+}
+
+/**
+ *
+ */
+void generate_header::gen_seq( std::ostream &os
+ , std::string &scope
+ , asn1::sequence *type)
+{
+ asn1::node * ident = type->identifier();
+
+ assert(type->type_id()() == asn1::type::ASN1_SEQUENCE);
+
+ // New way to handle and isolate sequence code generation
+ asn1::sequence *seq = dynamic_cast<asn1::sequence *>(type);
+ assert(seq != NULL);
+
+ cghpph_sequence seq_gen(*this,os,*seq);
+ seq_gen.generate();
+}
+
+
+//
+//
+//
+void generate_header::gen_template_params(std::ostream &os,asn1::node *_params)
+{
+ asn1::constructed *params = dynamic_cast<asn1::constructed *>(_params);
+ asn1::node::node_list nl;
+
+ os<<"<";
+ for(asn1::node::iterator p = params->begin(); p != params->end() ;++p)
+ {
+ if (nl.size()>0)
+ {
+ asn1::node::iterator it = std::find_if(nl.begin()
+ , nl.end()
+ , asn1::find_node((*p)->name()));
+ if (it != nl.end() )
+ {
+ //
+ } else {
+ if (p != params->begin()) os<<",";
+ os<<" "<<(*p)->cpp_name();
+ nl.push_back(*p);
+ }
+ } else {
+ if (p != params->begin()) os<<",";
+ os<<" "<<(*p)->cpp_name();
+ nl.push_back(*p);
+ }
+ }
+ os<<"> ";
+}
+//
+//
+//
+void generate_header::gen_template_signature( std::ostream &os
+ , asn1::node *_params)
+{
+ asn1::constructed *params = dynamic_cast<asn1::constructed *>(_params);
+ asn1::node::node_list nl;
+
+ assert(params != NULL);
+ os<<"<";
+ for(asn1::node::iterator p = params->begin(); p != params->end() ;++p)
+ {
+ if (nl.size()>0)
+ {
+ asn1::node::iterator it = std::find_if(nl.begin()
+ ,nl.end()
+ ,asn1::find_node((*p)->name()));
+ if (it != nl.end() )
+ {
+ //
+ } else {
+ if (p != params->begin()) os<<",";
+ os<<" typename "<<(*p)->cpp_name();
+ nl.push_back(*p);
+ }
+ } else {
+ if (p != params->begin()) os<<",";
+ os<<" typename "<<(*p)->cpp_name();
+ nl.push_back(*p);
+ }
+ }
+ os<<"> ";
+}
+
+/**
+ *
+ *
+ */
+void generate_header::struct_name(asn1::node *type,std::string &structName)
+{
+ if (type->identifier() == NULL)
+ {
+ structName = type->cpp_name();
+ } else
+ {
+ if (type->is_private())
+ {
+ std::cerr<<"struct_name : "<<type->identifier()->cpp_name()<<std::endl;
+ GEN_LOG_ERROR("struct_name %s \n",type->identifier()->cpp_name().c_str());
+ assert(type->identifier()->get_parent() != NULL);
+ private_attribute_type(type->identifier(),structName);
+ } else
+ structName = type->identifier()->cpp_name();
+ }
+}
+
+/**
+ *
+ *
+ */
+void generate_header::gen_choice( std::ostream &os
+ , asn1::choice *type
+ , asn1::node *pparams)
+{
+ std::string scope("");
+ std::string structName;
+ asn1::node::iterator it;
+
+ assert(type != NULL);
+ assert(type->get_parent() != NULL);
+ struct_name(type,structName);
+
+ m_Stack.push_back(structName);
+
+ cghpph_choice choice_gen(*this,os,*type);
+ choice_gen.generate();
+
+ m_Stack.pop_back();
+}
+
+/**
+ * TODO: Remove
+ */
+void
+generate_header::gen_composite_attribute_ref(std::ostream &os
+ , std::string &scope
+ , asn1::field *attribute
+ , asn1::node *params)
+{
+ generate_cpp::gen_composite_attribute_ref(os,scope,attribute,params);
+}
+
+/**
+ *
+ * What means attributes ?
+ * TODO 2017/05/17 review this function it's too complicated.
+ *
+ */
+void
+generate_header::gen_composite_attribute(std::ostream &os
+ , std::string &scope
+ , asn1::field &attribute
+ , asn1::node *params
+ , bool attributes)
+{
+ asn1::typenode *attr_type = attribute.get_type();
+ if (attr_type != NULL)
+ {
+ std::string structName = attribute.cpp_name() +"_t";
+ private_attribute_type(&attribute,structName);
+ switch (attr_type->type_id()())
+ {
+ case asn1::type::ASN1_ENUMERATED:
+ {
+ if (attributes)
+ {
+ if (attribute.flags().is_optional() )
+ {
+ os<<"\n\tASN1_ATTRIBUTE_OPTIONAL( struct ";
+ os<<structName<<" )\t";
+ os<<"\t\t"<<attribute.cpp_name()<<";\n";
+ }else
+ {
+ os<<"\t"<<structName<<"\t";
+ os <<attribute.cpp_name()<<";"<<std::endl;
+ }
+ } else {
+ os<<""<<std::endl;
+ }
+ }
+ break;
+ case asn1::type::ASN1_SET:
+ {
+ attr_type->name(structName);
+ gen_set(os,attr_type);
+ if (attributes)
+ {
+ os<<"\t\t"<<attribute.cpp_name()<<";\n";
+ } else {
+ os<<"\t;\n";
+ }
+ }
+ break;
+ case asn1::type::ASN1_CHOICE:
+ {
+ attr_type->name(structName);
+ if (attributes)
+ {
+ if (attribute.flags().is_optional() )
+ {
+ os<<"\n\tASN1_ATTRIBUTE_OPTIONAL( struct ";
+ os<<attr_type->cpp_name()<<" )\t";
+ os<<"\t\t"<<attribute.cpp_name()<<";\n";
+ }else
+ {
+ os<<"\t"<<structName;
+ os<<"\t\t"<<attribute.cpp_name()<<";\n";
+ }
+ } else
+ {
+ }
+ }
+ break;
+ case asn1::type::ASN1_SEQUENCE:
+ {
+ std::string scope("\t");
+ attr_type->name(structName);
+ if ( ! attributes)
+ {
+ return;
+ }
+ if (attribute.flags().is_optional() )
+ {
+ os<<";\n\tASN1_ATTRIBUTE_OPTIONAL( struct ";
+ os<<attr_type->cpp_name()<<" )\t";
+ os<<"\t\t"<<attribute.cpp_name()<<";\n";
+ }else
+ {
+ os<<"\t"<<structName;
+ os<<"\t\t"<<attribute.cpp_name()<<";\n";
+ }
+ }
+ break;
+ case asn1::type::ASN1_SELECTION:
+ {
+ assert(0 && " Selection should have been solved in optimizer");
+ if ( ! attributes)
+ return;
+ os<<"\t\tINTEGER "<<attribute.cpp_name()<<"; //SEL ?\n";
+ }
+ break;
+ case asn1::type::ASN1_SET_OF:
+ case asn1::type::ASN1_SEQUENCE_OF:
+ {
+ asn1::typenode *type = attribute.get_type();
+ asn1::node *subtype = type->get_eltype();
+ if (type->has_constraints())
+ {
+ os<<"//"<<__FUNCTION__;
+ os<<" I have constraints type SET_OF or SEQUENCE_OF\n";
+ }
+ switch (subtype->type_id()())
+ {
+ case asn1::type::ASN1_SEQUENCE:
+ subtype->name(attribute.cpp_name()+std::string("_type"));
+ if ( ! attributes)
+ {
+ return;
+ }
+ if (attribute.flags().is_optional() ) {
+ os<<"\tASN1_ATTRIBUTE_OPTIONAL(";
+ }
+ os<<type->name()<<"<"<<std::string( attribute.cpp_name()+"_type")<<">";
+ if (attribute.flags().is_optional() ) {
+ os<<") ";
+ }
+ break;
+ // Missing SET
+ case asn1::type::ASN1_CHOICE:
+ subtype->name(structName);
+ if ( ! attributes)
+ {
+ return;
+ }
+ if (attribute.flags().is_optional() )
+ {
+ os<<"\tASN1_ATTRIBUTE_OPTIONAL(";
+ }
+ // TOBE CONSISTENT, this should be _type
+ os<<type->name()<<"<";
+ os<<std::string( attribute.cpp_name()+"_t")<<">";
+ if (attribute.flags().is_optional() )
+ {
+ os<<") ";
+ }
+ break;
+ default:
+ asn1::node *ns;
+ if ( ! attributes)
+ {
+ return;
+ }
+ if (attribute.flags().is_optional() )
+ {
+ os<<"\tASN1_ATTRIBUTE_OPTIONAL(";
+ }
+ if (type_in_imports(subtype,&ns) )
+ {
+ os<<"\t"<<type->name()<<"<";
+ os<<ns->cpp_name()<<"::"<<subtype->cpp_name()<<">";
+ } else
+ {
+ if (asn1::typeref *stref = subtype->as_typeref())
+ {
+ os<<"\t"<<type->name()<<"</*r*/"<<stref->get_reference()->cpp_name()<<">";
+ } else {
+ os<<"\t"<<type->name()<<"</*nr*/"<<subtype->cpp_name()<<">";
+ }
+ }
+ if (attribute.flags().is_optional() ) {
+ os<<") ";
+ }
+ } // end switch
+ // common to all switch
+ os<<"\t"<<attribute.cpp_name()<<";\n";
+ }
+ break;
+ case asn1::type::ASN1_REFERENCE:
+ {
+ asn1::typeref *tref = attr_type->as_typeref();
+ if ( ! attributes)
+ return;
+ os<<"\t";
+ if (tref->get_reference())
+ {
+ // New way to handle reference
+ gen_composite_attribute_ref(os,scope,&attribute,params);
+ } else
+ {
+ assert(0);
+ }
+ os<<"\t"<<attribute.cpp_name()<<";";
+ os<<std::endl;
+ }
+ break;
+ default:
+ {
+ asn1::node *ns = NULL;
+ if ( ! attributes)
+ return;
+ // Imported attribute
+ if (type_in_imports(attr_type,&ns) )
+ {
+ if ( attribute.flags().is_default() )
+ {
+ os<<scope<<"\t"<<ns->cpp_name()<<"::";
+ os<<attr_type->cpp_name()<<" ";
+ } else if ( attribute.flags().is_optional() ) {
+ os<<scope<<"\tASN1_ATTRIBUTE_OPTIONAL("<<ns->cpp_name()<<"::";
+ os<<attr_type->cpp_name()<<") ";
+ } else
+ {
+ os<<scope<<"\t"<<ns->cpp_name()<<"::";
+ os<<attr_type->cpp_name()<<" ";
+ }
+ } else
+ {
+ // Local attribute
+ //std::cout<<"HERE ?"<<std::endl;
+ std::string cppType;
+ if (! type2cppstring(attr_type,cppType))
+ {
+ std::cerr<<"Failed convert type ("<<attr_type->name();
+ os<<") 2cpp string "<<std::endl;
+ assert(0);
+ }
+ if ( attribute.flags().is_default() )
+ {
+ os<<scope<<"\t"<<cppType<<" ";
+ } else if ( attribute.flags().is_optional() )
+ {
+ os<<scope<<"\tASN1_ATTRIBUTE_OPTIONAL("<<cppType<<") ";
+ }
+ else {
+ os<<scope<<"\t"<<cppType<<" ";
+ }
+ }
+ os<<"\t"<<attribute.cpp_name()<<";";
+ if (with_source_comment())
+ {
+ if (attribute.get_type()->has_constraints())
+ {
+ os<<"\t//"<<__FUNCTION__<<" default case I have constraints";
+ } else
+ {
+ os<<" //"<<__FUNCTION__<<" ";
+ os<<attr_type->type_id()()<<" default without constraints";
+ }
+ }
+ os<<"\n";
+ }
+ }
+ }
+}
+
+
+/**
+ *
+ */
+void generate_header::gen_set(std::ostream &os,asn1::node *type)
+{
+ std::string scope("");
+ std::string structName;
+ asn1::node *n = type->identifier();
+
+ // New way to handle and isolate sequence code generation
+ asn1::set *set = dynamic_cast<asn1::set *>(type);
+ assert(set != NULL);
+
+ cghpph_set set_gen(*this,os,*set);
+ set_gen.generate();
+}
+
+/**
+ *
+ */
+class genh_oc_tplt : public node_visitor<genh_oc_tplt>
+{
+ protected:
+ asn1::classdef &m_classdef;
+ generate_header &m_gen;
+ bool m_param;
+ std::ostringstream m_result;
+ long m_count;
+ public:
+ genh_oc_tplt( generate_header &_gen
+ , asn1::classdef &_cdef
+ , bool is_param=false)
+ : m_classdef(_cdef),m_gen(_gen) , m_count(0), m_param(is_param)
+ { m_result.str(""); };
+
+ inline std::string result() { return m_result.str(); } ;
+
+#define ASN1_CLASSFIELD_TYPE(cf,code) \
+ void visit_##cf(asn1::cf *field) code
+
+ASN1_CLASSFIELD_TYPE(classfield_tf,{
+ if (m_count++)
+ m_result<<",";
+ if (! m_param)
+ m_result<<"typename ";
+ std::string fieldname = field->cpp_name();
+ fieldname[0] = '_';
+ m_result<<fieldname;
+ })
+ASN1_CLASSFIELD_TYPE(classfield_ftvf,{
+ })
+ASN1_CLASSFIELD_TYPE(classfield_vtvf,{})
+ASN1_CLASSFIELD_TYPE(classfield_ftvsf,{})
+ASN1_CLASSFIELD_TYPE(classfield_vtvsf,{})
+ASN1_CLASSFIELD_TYPE(classfield_of,{})
+ASN1_CLASSFIELD_TYPE(classfield_osf,{})
+#undef ASN1_CLASSFIELD_TYPE
+};
+
+/**
+ *
+ */
+void
+generate_header::gen_object_class_tplt(std::ostream &os,asn1::classdef *type)
+{
+ std::list<std::string> l;
+ genh_oc_tplt gt(*this,*type);
+ os<<"template<";
+ for ( asn1::node::iterator it = type->begin()
+ ; it != type->end(); ++it)
+ {
+ gt.visit(*it);
+ }
+ os<<gt.result();
+ os<<", int _uuid = 0 /*uuid */";
+ os<<">\n";
+}
+
+void
+generate_header::gen_object_class_tplt_params(std::ostream &os,asn1::classdef *type)
+{
+ assert(type != NULL);
+ asn1::node::iterator it = type->begin();
+ std::list<std::string> l;
+
+ for ( ; it != type->end(); ++it)
+ {
+ std::string fieldname = (*it)->cpp_name();
+ fieldname[0] = '_';
+ /* Type Field */
+ if ( (*it)->type_id()() == asn1::type::ASN1_CLASSFIELD_TF)
+ {
+ l.push_back(fieldname);
+ }
+ }
+
+ if (l.size()>0)
+ {
+ os<<"<";
+ for ( std::list<std::string>::const_iterator it = l.begin()
+ ; it != l.end()
+ ; ++it)
+ {
+ if (it != l.begin()) {
+ os<<",";
+ }
+ os<<" "<<(*it)<<"";
+ }
+ os<<", _uuid /*uuid */";
+ os<<">";
+ }
+}
+
+/**
+ *
+ *
+ */
+void generate_header::gen_object_class_missing(std::ostream &os,asn1::classdef *type)
+{
+ asn1::node::iterator it = type->begin();
+
+ // cosntructors
+
+ // public methods
+ for ( ; it != type->end(); ++it)
+ {
+ asn1::classfield *ltype = dynamic_cast<asn1::classfield *>(*it);
+ std::string fieldname = (*it)->cpp_name();
+ fieldname[0] = '_';
+ os<<"//"<<(*it)->cpp_name()<<" type_id="<<(*it)->type_id()();
+ //<<std::endl;
+ switch(ltype->type_id()())
+ {
+ case asn1::type::ASN1_CLASSFIELD_FTVF: /* Fixed Type Value Field */
+ os<<std::endl;
+ // call missing here
+ gen_missing(os,ltype->get_type());
+ break;
+ case asn1::type::ASN1_CLASSFIELD_TF: /* Type Field */
+ os<<std::endl;
+ break;
+ case asn1::type::ASN1_CLASSFIELD_VTVF: /* Variable Type Value Field */
+ os<<std::endl;
+ break;
+ case asn1::type::ASN1_CLASSFIELD_FTVSF: /* Fixed Type Value Set Field */
+ os<<std::endl;
+ gen_missing(os,ltype->get_type());
+ break;
+ case asn1::type::ASN1_CLASSFIELD_VTVSF: /* Variable Type Value Set Field*/
+ os<<std::endl;
+ break;
+ case asn1::type::ASN1_CLASSFIELD_OF: /* Object Field */
+ os<<std::endl;
+ break;
+ case asn1::type::ASN1_CLASSFIELD_OSF: /* Object Set Field */
+ os<<std::endl;
+ break;
+ break;
+ default:
+ os<<std::endl;
+ };
+ }
+}
+
+/**
+ *
+ *
+ */
+void generate_header::gen_object_class(std::ostream &os,asn1::assignment *n)
+{
+ asn1::classdef *type = dynamic_cast<asn1::classdef *>(n->get_type());
+ assert(type != NULL);
+ cghpph_classdef cdef(*this,os,*type);
+ cdef.generate();
+}
+
+/**
+ *
+ *
+ */
+void generate_header::gen_object(std::ostream &os,asn1::assignment *n)
+{
+ asn1::typenode *type = n->get_type();
+
+ os<<"// generate_header::"<<__FUNCTION__<<" "<<n->name()<<"\n";
+ os.flush();
+
+ assert(type->type_id()() == asn1::type::ASN1_REFERENCE);
+ asn1::node *real_type =
+ m_resolver.resolve(dynamic_cast<asn1::typeref &>(*type));
+ if (real_type != NULL)
+ {
+ asn1::object *obj = dynamic_cast<asn1::object *>(type->get_eltype());
+ asn1::classdef *cdef = dynamic_cast<asn1::classdef *>(real_type);
+ assert( obj != NULL);
+ assert( cdef != NULL);
+ // Check Done at optimization level
+ cghpph_object obj_gen(*this,os,*obj,*cdef);
+ obj_gen.generate();
+ } else
+ {
+ std::cerr<<"OBJECT CLASS not found "<<type->name()<<std::endl;
+ os<<"// object class not found "<<n->name()<<"\n";
+ }
+}
+
+
+
+
+
+void
+generate_header::gen_include(std::string fname,asn1::assignment *type)
+{
+ struct stat st;
+ char *cd = getcwd(NULL,0);
+ std::string cdir( cd);
+
+
+ std::fstream inc;
+ std::string module_path = cdir+"/include/"+m_module->cpp_name();
+ std::string f;
+ if (type->meta_id()() == asn1::meta::OBJECTCLASS ) {
+ f = "./include/"+m_module->cpp_name()+"/I"+fname;
+ } else {
+ f = "./include/"+m_module->cpp_name()+"/"+fname;
+ }
+
+ if (stat("./include",&st) == -1) {
+#ifdef WIN32
+ mkdir("include");
+#else
+ mkdir("include",0777);
+#endif
+ }
+
+ if (stat(module_path.c_str(),&st) == -1) {
+#ifdef WIN32
+ mkdir(module_path.c_str());
+#else
+ mkdir(module_path.c_str(),0777);
+#endif
+ }
+
+ inc.open(f.c_str(),std::fstream::out);
+ inc<<"#ifndef __"<<m_module->cpp_name()<<"_H__"<<std::endl;
+ inc<<"#define __"<<m_module->cpp_name()<<"_H__"<<std::endl;
+ inc<<"#include \""<<m_module->cpp_name()<<".h\""<<std::endl;
+ inc<<"#endif"<<std::endl;
+ inc.close();
+ delete cd;
+}
+
+class do_genh_assignment : public assignment_visitor<do_genh_assignment>
+{
+ protected:
+ generate_header &m_gen;
+ std::ostream &m_os;
+ std::fstream &m_log;
+ std::vector<asn1::node *> &m_objects;
+ std::string path ;
+ public:
+ do_genh_assignment( generate_header &_h
+ , std::ostream &os
+ , std::vector<asn1::node *> &_objects
+ )
+ : m_os(os),m_gen(_h),m_log(_h.logger()) ,m_objects(_objects) {};
+ // Main processing function per assignment
+ void operator ()(asn1::node *n)
+ {
+ asn1::typenode *type = n->as_assignment()->get_type();
+ path = n->cpp_name()+".h";
+ GEN_LOG_DEBUG( "Process item=%s meta=%d\n"
+ , n->name().c_str()
+ , n->meta_id()());
+ if ( ! type)
+ return;
+ if ( n->is_generated())
+ {
+ GEN_LOG_DEBUG("%s already generated\n",n->name().c_str());
+ return;
+ }
+ visit(n->as_assignment());
+ n->set_color(asn1::node::CL_RED);
+ }
+#define ASSIGNMENT(Ty,Code) \
+ void visit_##Ty(asn1::Ty##_assignment *a) Code
+
+ ASSIGNMENT(typeref,{
+ int params = (a->parameters() != NULL)?1:0;
+ // Try to create an include file
+ GEN_LOG_DEBUG( "meta of %s is TYPEREF parameterized: %d\n"
+ , a->name().c_str(),params);
+ m_gen.gen_include(path,a);
+ m_gen.gen_typeref(m_os,a->get_type()->as_typeref());
+ })
+ ASSIGNMENT(type,{
+ int params = (a->parameters() != NULL)?1:0;
+ // Try to create an include file
+ GEN_LOG_DEBUG( "meta of %s is TYPE parameterized: %d\n"
+ , a->name().c_str(),params);
+ m_gen.gen_include(path,a);
+ m_gen.gen_typedef(m_os,a->get_type());
+ })
+ ASSIGNMENT(value,{
+ GEN_LOG_DEBUG("meta of %s is VALUE\n",a->name().c_str());
+ m_gen.gen_const(m_os,a);
+ })
+ ASSIGNMENT(valueset,{
+ GEN_LOG_DEBUG( "meta of %s is VALUESET do nothing ?\n"
+ , a->name().c_str());
+ })
+ ASSIGNMENT(object,{
+ int params = (a->parameters() != NULL)?1:0;
+ // Try to create an include file
+ GEN_LOG_DEBUG( "meta of %s is OBJECT parameterized: %d\n"
+ , a->name().c_str(),params);
+ m_gen.gen_object(m_os,a);
+ m_objects.push_back(a);
+ })
+ ASSIGNMENT(objectclass,{
+ int params = (a->parameters() != NULL)?1:0;
+ GEN_LOG_DEBUG( "meta of %s is OBJECT CLASS parameterized: %d\n"
+ , a->name().c_str(),params);
+ m_gen.gen_object_class(m_os,a);
+ })
+ ASSIGNMENT(objectset,{})
+ ASSIGNMENT(objectfield,{})
+
+};
+/**
+ *
+ */
+void generate_header::gen_module(std::ostream &os,asn1::module *n)
+{
+ asn1::import_list *imports = n->imports();
+ os<<"#ifndef "<<n->cpp_name()<<"_H__"<<std::endl;
+ os<<"#define "<<n->cpp_name()<<"_H__"<<std::endl;
+ os<<"#include \"rtasn1/asn1.h\"\n"<<std::endl;
+ // Add include for external dependencies
+ if (imports != NULL)
+ {
+ for (asn1::node::iterator it = imports->begin(); it!= imports->end(); it++)
+ {
+ asn1::import *import = dynamic_cast<asn1::import *>( *it);
+ if (import)
+ {
+ cghpph_import imp_gen(*this,os,*import);
+ imp_gen.generate();
+ }
+ }
+ }
+
+ os<<"using namespace asn1;\n"<<std::endl;
+ os<<"namespace "<<n->cpp_name()<<" {\n"<<std::endl;
+
+ n->sort_childs();
+
+ do_genh_assignment dogen(*this,os,m_objects);
+ std::for_each( n->begin()
+ , n->end()
+ , dogen
+ );
+
+ os<<"}\n\n"<<std::endl;
+ os<<"#endif "<<std::endl;
+ os<<"/** "<<std::endl;
+ os<<" * vim: sw=2 ts=2:"<<std::endl;
+ os<<" */"<<std::endl;
+
+ m_template_codec.erase(m_template_codec.begin(),m_template_codec.end());
+ /**
+ * Alright gen template code for
+ * objects in a separated file
+ */
+ if (m_module->has_objects())
+ {
+ std::string fname = m_module->cpp_name() + ".hpp";
+ std::fstream ost;
+ ost.open(fname.c_str(),std::fstream::out);
+ if (!m_module->name().compare("Remote-Operations-Useful-Definitions"))
+ {
+ ost<<"// Dont generate anything\n";
+ } else
+ {
+ std::for_each( m_objects.begin()
+ , m_objects.end()
+ , gen_tplt(ost,*this)
+ );
+ }
+ ost.close();
+ }
+}
+
+
+/**
+* vim:et:sw=2:ts=2
+*/
--- /dev/null
+#ifndef GEN_HEADER_H__
+#define GEN_HEADER_H__
+#include <iostream>
+#include <algorithm>
+
+
+/**
+ *
+ */
+class generate_header : public generate_cpp
+{
+ public:
+
+ typedef std::vector<asn1::node *> template_list_type;
+
+ generate_header(asn1::module *n);
+
+ generate_header(asn1::module *n,asn1::module::modules_type &m);
+
+ /**
+ * This is a recursive function
+ * In no nested context, it generates all private classes
+ *
+ */
+ void gen_missing(std::ostream &os,asn1::node *n) ;
+
+ void encode_integer(long value,std::vector<unsigned char> &v);
+
+ void gen_oid_value(std::ostream &os,asn1::object_identifier *n);
+ /**
+ *
+ *
+ */
+ void gen_const(std::ostream &os,asn1::node *n);
+ /**
+ *
+ *
+ */
+ void gen_enumerated(std::ostream &os,asn1::node *n ,const std::string &name);
+ /**
+ *
+ */
+ void gen_bitstring(std::ostream &os,asn1::bit_string &type );
+ //
+ // called for ntype ::= SEQUENCE OF
+ virtual void gen_sequence_of(std::ostream &os,asn1::sequence_of &) ;
+ // called for ntype ::= SEQUENCE OF
+ virtual void gen_set_of(std::ostream &os,asn1::set_of &) ;
+ //
+ void gen_typedef(std::ostream &os,asn1::typenode *n);
+
+ void gen_typedef_integer(std::ostream &os,asn1::node *n);
+
+ void gen_typeref(std::ostream &os,asn1::typeref *n);
+
+ /**
+ *
+ */
+ void gen_seq(std::ostream &os,std::string &scope,asn1::sequence *n);
+
+ void gen_choice(std::ostream &os,asn1::choice *n,asn1::node *params = NULL);
+ /**
+ *
+ * attributes flags is for choice case. We only generate internal structures in that case.
+ */
+ void gen_composite_attribute( std::ostream &os
+ , std::string &scope
+ , asn1::field &attribute
+ , asn1::node *params = NULL,bool attributes = true);
+ void gen_composite_attribute_ref(std::ostream &os
+ , std::string &scope
+ , asn1::field *attribute
+ , asn1::node *params = NULL);
+ void gen_template_params(std::ostream &os,asn1::node *params);
+ void gen_template_signature(std::ostream &os,asn1::node *params);
+
+ /**
+ *
+ */
+ void gen_set(std::ostream &os,asn1::node *n);
+
+ /*
+ * Ros generation Code
+ */
+ void gen_object_class(std::ostream &os,asn1::assignment *n);
+ void gen_object_class_missing(std::ostream &os,asn1::classdef *n);
+ void gen_object_class_tplt(std::ostream &os,asn1::classdef *n);
+ void gen_object_class_tplt_params(std::ostream &os,asn1::classdef *n);
+
+
+ void gen_object(std::ostream &os,asn1::assignment *n);
+ /**
+ *
+ */
+ void gen_module(std::ostream &os,asn1::module *n);
+ void gen_include(std::string fname,asn1::assignment *type);
+ /**
+ * Helper method to compute structName
+ */
+ void struct_name(asn1::node *type,std::string &sn);
+
+ /**
+ * TODO Must be removed after migration with EXPLICT /IMPLICIT
+ *
+ */
+ template_list_type &get_template_list()
+ {
+ return m_template_codec;
+ }
+ protected:
+ std::fstream m_tplt_os;
+ std::vector<std::string> m_Stack;
+ std::vector<asn1::node *> m_template_codec;
+ std::vector<asn1::node *> m_objects;
+};
+/**
+ * vim:et:sw=2:ts=2
+ */
+#endif
--- /dev/null
+#include <iostream>
+#include <fstream>
+#include <algorithm>
+#include <map>
+#include <iterator>
+#include <list>
+#include <assert.h>
+#include "asn1_generator.h"
+#include "asn1_gen_optimizer.h"
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <errno.h>
+#if defined(__APPLE__) || (GCC_VERSION > 40800)
+#include <stdlib.h>
+#include <unistd.h>
+#endif
+#if defined(_WIN32)
+#include <stdlib.h>
+#endif
+#include "asn1_resolver.h"
+#include "asn1_generator_helper.h"
+
+#include "asn1_recursive_visitor.h"
+
+/**
+ *
+ */
+struct find_type
+{
+ find_type(asn1::type::id t)
+ : m_type(t)
+ { }
+ bool operator ()(asn1::node *t)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(t);
+ if (f->get_type() &&
+ t->type_id()() == m_type)
+ {
+ return true;
+ }
+ return false;
+ }
+ asn1::type::id m_type;
+};
+
+/**
+ * Works for :
+ * components of are integrated in new class
+ * selection type is replaced with real type
+ * object defined syntax is checked
+ *
+ */
+class optimize_phase1 : public asn1::recursive_visitor<optimize_phase1>
+{
+ public:
+ optimize_phase1(asn1::resolver &r,std::fstream &l)
+ : resolver(r) , m_log(l)
+ {
+ }
+
+ bool traverse_module(asn1::module *m)
+ {
+ m_module = m ;
+ asn1::recursive_visitor<optimize_phase1>::traverse_module(m);
+ return true;
+ }
+
+ bool visit_typeref(asn1::node *tref)
+ {
+ tref->as_typeref()->resolve(resolver);
+ return true;
+ }
+ bool visit_sequence(asn1::sequence *n)
+ {
+ asn1::node::iterator it = std::find_if( n->begin()
+ , n->end()
+ , find_type(asn1::type::ASN1_COMPONENTS_OF));
+
+ if ( it != n->end())
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*it);
+ asn1::typeref *type = dynamic_cast<asn1::typeref *>(f->get_type());
+ asn1::constructed *rtype = resolver.resolve(*type)->as_constructed();
+ if (rtype)
+ {
+ GEN_LOG_INFO("%s COMPONENTS OF %s transformed \n"
+ ,n->identifier()->name().c_str()
+ ,type->name().c_str()
+ );
+ std::insert_iterator<asn1::node::node_list> iit(n->nodes(),it);
+ std::copy(rtype->begin(),rtype->end(),iit);
+ n->nodes().erase(it);
+ }
+ }
+ return true;
+ }
+ bool visit_selection(asn1::selection *n)
+ {
+ GEN_LOG_ERROR("SELECTION TO BE HANDLED %s\n",n->type_node()->name().c_str());
+ return true;
+ }
+
+ /**
+ * @brief handle selection type
+ *
+ */
+ bool visit_component_type(asn1::field *n)
+ {
+ GEN_LOG_INFO("phase1 Visite %s\n"
+ ,n->name().c_str());
+ process_selection(n);
+ return true;
+ }
+ //
+ bool visit_alternative_choice(asn1::field *n)
+ {
+ GEN_LOG_INFO("phase1 Visite %s\n"
+ ,n->name().c_str());
+#if 0
+ if (asn1::typeref *_rf = n->get_type()->as_typeref())
+ {
+ std::cerr<<"visit_alternative_choice "<<n->name()<<std::endl;
+ GEN_LOG_INFO("phase1 Visite alternative %s resolve type %s\n"
+ ,n->name().c_str()
+ ,n->get_type()->name().c_str()
+ );
+ _rf->resolve(resolver);
+ // Trying to understand what's going on
+ if (! n->get_type()->name().compare("DistinguishedName"))
+ {
+ std::cerr<<"visit_alternative_choice real type "<<_rf->get_real_type()->from_module()->name();
+ std::cerr<<"::"<<_rf->get_real_type()->name()<<std::endl;
+ assert( 0);
+ }
+ }
+#endif
+ process_selection(n);
+ return true;
+ }
+ //
+ bool process_selection(asn1::field *n)
+ {
+ asn1::typenode *stype = n->get_type();
+ if (stype && stype->type_id()() == asn1::type::ASN1_SELECTION)
+ {
+ asn1::typeref *ref = dynamic_cast<asn1::typeref *>(stype->get_eltype());
+ asn1::constructed *rtype = resolver.resolve(*ref)->as_constructed();
+
+ GEN_LOG_INFO("SELECTION HANDLED %s < %s\n"
+ ,stype->name().c_str()
+ ,ref->name().c_str()
+ );
+ // Check if rtype is CHOICE and lookup for n->name type.
+ // Replace n->type with new type and delete selection
+ // Keep tag and other stuff from selection before delete
+ asn1::node::iterator it = std::find_if(rtype->begin()
+ ,rtype->end()
+ ,asn1::find_node(stype->name()));
+ if (it != rtype->end())
+ {
+ asn1::field *a = dynamic_cast<asn1::field *>(*it);
+ asn1::typenode *ntype = a->get_type();
+ asn1::typenode *t = ntype->clone();
+ t->set_parent(n->get_parent());
+ if (stype->tagged())
+ {
+ t->tag(stype->tag());
+ }
+ if (t->identifier())
+ {
+ t->identifier(n);
+ }
+ n->set_type(t);
+ delete (stype);
+ GEN_LOG_INFO("TYPE IS : %s\n"
+ , a->get_type()->name().c_str());
+ } else
+ {
+ GEN_LOG_INFO("ERROR Type not found : %s\n"
+ , n->name().c_str());
+ }
+ }
+ return true;
+ }
+ /**
+ * Parse defined syntax and check object
+ */
+ bool visit_assign_object(asn1::object_assignment *n)
+ {
+ asn1::typenode *type = n->get_type();
+
+ assert(type->type_id()() == asn1::type::ASN1_REFERENCE);
+ asn1::node *real_type =
+ resolver.resolve(dynamic_cast<asn1::typeref &>(*type));
+ if (real_type != NULL)
+ {
+ asn1::object *obj = dynamic_cast<asn1::object *>(type->type_node());
+ asn1::classdef *cdef = dynamic_cast<asn1::classdef *>(real_type);
+ assert( obj != NULL);
+ assert( cdef != NULL);
+ if ( cdef->check_object_syntax(obj) )
+ {
+ GEN_LOG_INFO("OBJECT syntax OK %s\n",n->name().c_str());
+ obj->set_classdef(cdef);
+ } else
+ {
+ GEN_LOG_ERROR("OBJECT syntax error %s\n",n->name().c_str());
+ std::cerr<<"Syntax ERROR for object "<<n->name()<<std::endl;
+ }
+ } else
+ {
+ GEN_LOG_ERROR("OBJECT CLASS not found %s\n",type->name().c_str());
+ std::cerr<<"OBJECT CLASS not found "<<type->name()<<std::endl;
+ }
+ return true;
+ }
+
+ bool visit_object_classfield_tf(asn1::classfield_tf *S,asn1::node *f)
+ {
+ if (f->is_constructed())
+ {
+ asn1::object *obj = dynamic_cast<asn1::object *>(f->get_parent());
+ std::string type_name = S->name().substr(1) + "_"+ obj->identifier()->cpp_name();
+ asn1::assignment *nt = new asn1::type_assignment(type_name);
+ asn1::typeref *tr = new asn1::typeref(
+ new asn1::simple_reference(type_name));
+ tr->set_parent(f->get_parent());
+ //
+ nt->set_type(f);
+ nt->set_parent(m_module);
+ //nt->parameters(pi->parameters());
+ f->set_parent(m_module);
+ f->identifier(nt);
+ m_module->append(nt);
+ obj->update_field(S->name(),tr);
+ GEN_LOG_INFO( "VISIT OBJECT FIELD %s NOT REF FIXED TO %s\n"
+ , S->name().c_str()
+ , type_name.c_str()
+ );
+ }
+ return true;
+ }
+ /*
+ *
+ */
+ bool visit_object_classfield_osf(asn1::classfield_osf *S,asn1::node *f)
+ {
+ asn1::object *obj = dynamic_cast<asn1::object *>(f->get_parent());
+ std::string tname = S->name().substr(1) + "_"+ obj->identifier()->cpp_name();
+ GEN_LOG_INFO( "VISIT OBJECT FIELD %s TO BE FIXED %s\n"
+ , S->name().c_str()
+ , tname.c_str()
+ );
+ return true;
+ }
+ /**
+ *
+ */
+ bool visit_object_classfield_ftvf(asn1::classfield_ftvf *ftvf,asn1::node *f)
+ {
+ asn1::valuetype *vt = dynamic_cast<asn1::valuetype *>(f);
+ asn1::typenode *type= ftvf->get_type();
+ asn1::object *obj = dynamic_cast<asn1::object *>(f->get_parent());
+ asn1::classdef *cdef = obj->get_classdef();
+ std::string tname = ftvf->name().substr(1) + "_"+ obj->identifier()->cpp_name();
+ GEN_LOG_INFO( "VISIT OBJECT FIELD ftvf %s TO BE FIXED %s %s\n"
+ , ftvf->name().c_str()
+ , tname.c_str()
+ , f->cpp_name().c_str()
+ );
+ assert((cdef != NULL) && "cdef should be set");
+ //assert( (vt != NULL) && "fixed type value field should be value type node");
+ if (! vt )
+ {
+ return true;
+ }
+ asn1::value *v = vt->value();
+ GEN_LOG_INFO( "ftvf %s value is %s\n"
+ , ftvf->name().c_str()
+ , v->cpp_name().c_str()
+ );
+ // Get real type instead of typeref
+ if (type->as_typeref())
+ {
+ asn1::node *real_type =
+ resolver.resolve(dynamic_cast<asn1::typeref &>(*type));
+ type = real_type->as_typenode();
+ }
+ // Check value node !!!
+ if (asn1::choice *c = type->as_choice())
+ {
+ asn1::field *field = c->get_field(f->name());
+ if (! field )
+ {
+ GEN_LOG_ERROR("ftvf: field %s 0x0x",f->name().c_str()
+ , c->get_field(f->name()));
+ std::cerr<<"ftvf: "<<c->cpp_name()<<" "<<c<<" field "<<f->name()<<" 0x"<<c->get_field(f->name())<<std::endl;
+ return true;
+ }
+ asn1::typenode *ct = c->get_field(f->name())->get_type();
+ GEN_LOG_INFO( "ftvf %s type is %s id=%d\n"
+ , ftvf->name().c_str()
+ , ct->cpp_name().c_str()
+ , ct->type_id()()
+ );
+ if (v && v->m_node->type_id()() == 0)
+ {
+ asn1::constructed *vn = v->m_node->value()->m_node->as_constructed();
+ std::cerr<<__FUNCTION__<<" Proccess ftvf because of wrong id ";
+ std::cerr<<"<"<<v->m_node->cpp_name()<<"> "<<typeid(*(v->m_node)).name()<<std::endl;
+ assert((vn != NULL) && " VN should be constructed ");
+ switch (ct->type_id()())
+ {
+ case asn1::type::ASN1_INTEGER:
+ break;
+ case asn1::type::ASN1_OBJECT_IDENTIFIER:
+ {
+ #if 1
+ asn1::object_identifier *oid = new asn1::object_identifier();
+ std::copy (vn->begin(),vn->end(),
+ std::back_inserter(oid->nodes()));
+ delete vn;
+ oid->set_parent(cdef->from_module());
+ //v->m_node->value()->m_node = oid;
+ v->m_node= oid;
+ #endif
+ }
+ break;
+ default:
+ std::cerr<<__FUNCTION__<<" Proccess ftvf AIIIIIII"<<std::endl;
+ ;
+ }
+ }
+ }
+ return true;
+ }
+ protected:
+ asn1::module *m_module;
+ asn1::resolver &resolver;
+ std::fstream &m_log;
+};
+
+/**
+ * OPTIMIZE NESTED
+ */
+
+
+/**
+ *
+ *
+ */
+class optimize_nested : public asn1::recursive_visitor<optimize_nested>
+{
+ public:
+ optimize_nested(asn1::resolver &r,std::fstream &l)
+ : resolver(r) , m_log(l)
+ {
+ }
+
+ bool traverse_module(asn1::module *m)
+ {
+ m_module = m ;
+ asn1::recursive_visitor<optimize_nested>::traverse_module(m);
+ return true;
+ }
+
+
+ bool visit_sequence(asn1::sequence *n)
+ {
+ GEN_LOG_INFO("optimize_nested %s set of %s transformed \n"
+ ,n->identifier()->name().c_str()
+ ,n->name().c_str()
+ );
+ asn1::node::iterator it = std::find_if( n->begin()
+ , n->end()
+ , find_type(asn1::type::ASN1_COMPONENTS_OF));
+
+ if ( it != n->end())
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*it);
+ asn1::typeref *type = dynamic_cast<asn1::typeref *>(f->get_type());
+ asn1::constructed *rtype = resolver.resolve(*type)->as_constructed();
+ if (rtype)
+ {
+ GEN_LOG_INFO("optimize_nested ident: %s COMPONENTS OF %s transformed\n"
+ ,n->identifier()->name().c_str()
+ ,type->name().c_str()
+ );
+ std::insert_iterator<asn1::node::node_list> iit(n->nodes(),it);
+ std::copy(rtype->begin(),rtype->end(),iit);
+ n->nodes().erase(it);
+ }
+ }
+ return true;
+ }
+
+ /**
+ * @brief handle selection type
+ *
+ */
+ bool visit_alternative_choice(asn1::field *ident)
+ {
+ GEN_LOG_INFO("optimize_nested field: %s type: %s process\n"
+ ,ident->name().c_str()
+ ,(ident->get_type())?ident->get_type()->name().c_str():"..."
+ );
+ process(ident);
+ process_reference(ident);
+ return true;
+ }
+ /**
+ * @brief handle selection type
+ *
+ */
+ bool visit_component_type(asn1::field *ident)
+ {
+ GEN_LOG_INFO("optimize_nested field: %s type: %s process\n"
+ ,ident->name().c_str()
+ ,(ident->get_type())?ident->get_type()->name().c_str():"..."
+ );
+ process(ident);
+ process_reference(ident);
+ return true;
+ }
+ //
+ bool visit_set_of(asn1::set_of *so)
+ {
+ asn1::typenode *stype = so->get_eltype();
+ GEN_LOG_INFO("optimize_nested TODO %s set of %s transformed \n"
+ ,so->identifier()->name().c_str()
+ ,stype->name().c_str()
+ );
+ switch (stype->type_id()())
+ {
+ case asn1::type::ASN1_SEQUENCE:
+ case asn1::type::ASN1_SET:
+ case asn1::type::ASN1_CHOICE:
+ process(so);
+ break;
+ default:
+ ;
+ }
+ return true;
+ }
+ //
+ bool visit_sequence_of(asn1::sequence_of *so)
+ {
+ asn1::typenode *stype = so->get_eltype();
+ GEN_LOG_INFO("TODO %s sequence of %s transformed \n"
+ ,so->identifier()->name().c_str()
+ ,stype->name().c_str()
+ );
+ switch (stype->type_id()())
+ {
+ case asn1::type::ASN1_SEQUENCE:
+ case asn1::type::ASN1_SET:
+ case asn1::type::ASN1_CHOICE:
+ process(so);
+ break;
+ default:
+ ;
+ }
+ return true;
+ }
+ /**
+ * Parse defined syntax and check object
+ */
+ bool visit_assign_object(asn1::object_assignment *n)
+ {
+ return true;
+ }
+
+ void process_reference(asn1::field *n)
+ {
+ asn1::typenode *stype = n->get_type();
+ if (! stype)
+ return;
+
+ GEN_LOG_INFO( "optimize_nested start field: %s type: %s \n"
+ , n->name().c_str()
+ , stype->name().c_str()
+ );
+ if (asn1::typeref *_ref = stype->as_typeref())
+ {
+ _ref->resolve(resolver);
+ } else {
+ GEN_LOG_INFO("optimize_nested FAILED type: %s not typeref !!!\n"
+ ,stype->name().c_str()
+ );
+ }
+ }
+
+ bool visit_assign_typeref(asn1::typeref_assignment *n)
+ {
+ asn1::typenode *stype = n->get_type();
+ if (! stype)
+ return true;
+ GEN_LOG_INFO(" %s \n"
+ ,stype->name().c_str()
+ );
+ if (asn1::typeref *_ref = stype->as_typeref())
+ {
+ _ref->resolve(resolver);
+ }
+ return true;
+ }
+ /**
+ * Needs to be split into two prototypes.
+ * one for asn1::field types
+ * one for asn1::typenode types eg elements in set_of / seq_of
+ */
+ void process(asn1::node *ident)
+ {
+ asn1::node::node_list pm;
+ asn1::node *type = ident->type_node();
+ GEN_LOG_DEBUG(" %s %s\n"
+ , __FUNCTION__
+ ,ident->name().c_str()
+ );
+ if (type && type->is_constructed())
+ {
+ asn1::node * pi = ident->get_parent()->identifier();
+ std::string type_name;
+ if (pi)
+ {
+ type_name = pi->cpp_name() +"_" + ident->name();
+ } else
+ { // It seams that parent for set_of subtypes are NULL !!!:
+ type_name = ident->identifier()->cpp_name() +"_type" ;
+ }
+ GEN_LOG_INFO("PROCESS %s -> %s\n",ident->name().c_str(),type_name.c_str());
+ asn1::assignment *nt = new asn1::type_assignment(type_name);
+ asn1::typeref *tr = new asn1::typeref(
+ new asn1::simple_reference(type_name));
+ nt->set_type(type);
+ nt->set_parent(m_module);
+ if (pi)
+ nt->parameters(pi->parameters());
+ type->set_parent(m_module);
+ type->identifier(nt);
+ m_module->append(nt);
+ //
+ asn1::node *subtype = type->type_node();
+ if ( subtype
+ && subtype->identifier()
+ && subtype->identifier()->get_parent() == NULL)
+ {
+ GEN_LOG_INFO( "PROCESS ERROR %s -> %s type-type->get_parent is NULL\n"
+ , ident->name().c_str()
+ , type_name.c_str());
+ } else if (subtype)
+ {
+ GEN_LOG_INFO("PROCESS WARN %s -> %s Maybe change parent of subtype \n",ident->name().c_str(),type_name.c_str());
+ }
+ //
+ if (ident->get_parent() == NULL)
+ {
+ GEN_LOG_INFO("PROCESS ERROR %s -> %s ident->get_parent is NULL\n",ident->name().c_str(),type_name.c_str());
+ }
+ tr->set_parent(ident->get_parent());
+ tr->identifier(ident);
+ ident->type_node(tr);
+ } else {
+ GEN_LOG_INFO( " Nothing field: %s -> type:%s DONE\n"
+ , ident->name().c_str()
+ , (type)?type->name().c_str():"NULL");
+ }
+ }
+ protected:
+ asn1::module *m_module;
+ asn1::resolver &resolver;
+ std::fstream &m_log;
+};
+
+
+/**
+ * OPTIMIZE params
+ */
+class replace_params : public asn1::recursive_visitor<replace_params>
+{
+ public:
+ replace_params(asn1::resolver &r,std::fstream &l,asn1::module *m,asn1::parameters &p,asn1::act_parameters &ap)
+ : resolver(r) , m_log(l), m_actual_params(ap),m_parameters(p),m_module(m)
+ {
+ }
+ /**
+ * @brief handle replacements in alternative_choice
+ *
+ */
+ bool visit_alternative_choice(asn1::field *ident)
+ {
+ asn1::typenode *type = ident->get_type();
+ asn1::module *m = ident->from_module();
+ std::string type_name = type->name();
+
+ if ( (type->type_id()() == asn1::type::ASN1_REFERENCE)
+ && m_module != m )
+ {
+ asn1::typeref *typeref = dynamic_cast<asn1::typeref *>(type);
+ if (typeref->is_simple())
+ {
+ process_reference(ident);
+ } else
+ {
+ GEN_LOG_INFO("no process reference %s -> %s wp\n",ident->name().c_str(),type_name.c_str());
+ }
+ }
+ if ( type->parameters())
+ {
+ asn1::act_parameters &act_params = dynamic_cast<asn1::act_parameters &>(*type->parameters());
+
+ GEN_LOG_INFO("check %s -> %s wp\n",ident->name().c_str(),type_name.c_str());
+ }
+ return true;
+ }
+
+ /**
+ *
+ */
+ void process_reference(asn1::field *ident)
+ {
+ asn1::typenode *type = ident->get_type();
+ asn1::module *m = ident->from_module();
+ asn1::node::iterator it;
+ asn1::external_type_reference *etr =
+ new asn1::external_type_reference(m->name(),type->name());
+ asn1::typeref *nref = new asn1::typeref(type->name(),etr);
+ GEN_LOG_INFO("check process_reference %s -> %s with %s\n"
+ ,ident->name().c_str()
+ ,type->name().c_str()
+ ,etr->name().c_str());
+
+ nref->set_parent(type->get_parent());
+ nref->identifier(ident);
+
+ if (type->parameters())
+ nref->parameters(type->parameters()->clone());
+
+ ident->set_type(nref);
+ }
+ /**
+ * @brief handle remplacement in component_type
+ *
+ */
+ bool visit_component_type(asn1::field *ident)
+ {
+ std::string type_name = ident->get_type()->name();
+ asn1::typenode *type = ident->get_type();
+ asn1::module *m = ident->from_module();
+ asn1::node::iterator it;
+ GEN_LOG_INFO("check ct %s:%s -> %s:%s\n"
+ , m_module->name().c_str()
+ ,ident->name().c_str()
+ , m->name().c_str()
+ ,type_name.c_str());
+
+ if ( (type->type_id()() == asn1::type::ASN1_REFERENCE)
+ && m_module != m )
+ {
+ asn1::typeref *typeref = dynamic_cast<asn1::typeref *>(type);
+ if (typeref->is_simple())
+ {
+ process_reference(ident);
+ } else
+ {
+ GEN_LOG_INFO("no process reference %s -> %s wp\n",ident->name().c_str(),type_name.c_str());
+ }
+ }
+
+ if (m_parameters.have_reference(type->name(),it))
+ {
+ size_t l = std::distance(m_parameters.begin(),it);
+ asn1::typenode *rtype = m_actual_params[l]->clone()->as_typenode();
+ GEN_LOG_INFO("check ct HOHO %s -> %s %s %ld\n"
+ , ident->name().c_str()
+ , type_name.c_str()
+ , rtype->name().c_str()
+ , l
+ );
+ ident->set_type(rtype);
+ rtype->identifier(ident);
+ rtype->set_parent(ident->get_parent());
+ }
+ return true;
+ }
+
+ protected:
+ asn1::module *m_module;
+ asn1::resolver &resolver;
+ std::fstream &m_log;
+ asn1::act_parameters &m_actual_params;
+ asn1::parameters &m_parameters;
+};
+
+/**
+ *
+ *
+ */
+class optimize_params : public asn1::recursive_visitor<optimize_params>
+{
+ public:
+ optimize_params(asn1::resolver &r,std::fstream &l)
+ : resolver(r) , m_log(l)
+ {
+ }
+
+ bool traverse_module(asn1::module *m)
+ {
+ m_module = m ;
+ asn1::recursive_visitor<optimize_params>::traverse_module(m);
+ return true;
+ }
+
+ /**
+ * @brief handle selection type
+ *
+ */
+ bool visit_alternative_choice(asn1::field *ident)
+ {
+ asn1::node *parent = ident->get_parent();
+ if (parent->identifier()->parameters())
+ {
+ GEN_LOG_ERROR( "PROCESS ALTERNATIVE TYPE WP %s -> forget\n"
+ ,ident->name().c_str());
+ return true;
+ }
+ if (ident->get_type() && ident->get_type()->parameters())
+ {
+ asn1::typeref *type = dynamic_cast<asn1::typeref *>(ident->get_type());
+ asn1::act_parameters &act_params = dynamic_cast<asn1::act_parameters &>(*type->parameters());
+ asn1::node *rtype = resolver.resolve(*type);
+ std::string type_name = ident->get_type()->name();
+ if (rtype == NULL)
+ {
+ std::cerr<<"rtpye NULL === "<<type->name()<<std::endl;
+ GEN_LOG_ERROR("PROCESS ALTERNATIVE TYPE WP %s -> %s\n"
+ ,ident->name().c_str()
+ ,type_name.c_str());
+ } else
+ {
+ asn1::parameters &p = dynamic_cast<asn1::parameters &>
+ (*rtype->identifier()->parameters());
+ std::cerr<<"visit_alternative_choice before clone "<<ident->name()<<"rtype="<<rtype->name()<<std::endl;
+ asn1::node *ctype = rtype->clone();
+ std::cerr<<"visit_alternative_choice after clone :"<<ident->name()<<std::endl;
+ GEN_LOG_INFO("PROCESS ALTERNATIVE TYPE WP %s -> %s\n"
+ ,ident->name().c_str(),type_name.c_str());
+ // Process replacing parameters ....
+ replace_params replace(resolver,m_log,m_module,p,act_params);
+ replace.traverse_type(ctype);
+ process_component(ident,ctype->as_typenode());
+ }
+ } else if (ident->get_type())
+ {
+ std::string type_name = ident->get_type()->name();
+ GEN_LOG_INFO("PROCESS ALTERNATIVE TYPE NP %s -> %s\n"
+ ,ident->name().c_str(),type_name.c_str());
+ }
+ return true;
+ }
+ /**
+ * @brief handle selection type
+ *
+ */
+ bool visit_component_type(asn1::field *ident)
+ {
+ if (ident->get_type() && ident->get_type()->parameters())
+ {
+ asn1::typeref *type = dynamic_cast<asn1::typeref *>(ident->get_type());
+ std::string type_name = type->name();
+ GEN_LOG_INFO("PROCESS COMPONENT TYPE WP %s -> %s\n"
+ ,ident->name().c_str(),type_name.c_str());
+ } else
+ {
+ }
+ return true;
+ }
+ /**
+ * Parse defined syntax and check object
+ */
+ bool visit_assign_type(asn1::type_assignment *n)
+ {
+ if (! n->parameters( ) && n->get_type()->parameters())
+ {
+ std::string type_name = n->get_type()->name();
+ GEN_LOG_INFO("visit_assign_type %s -> %s\n"
+ ,n->name().c_str()
+ ,type_name.c_str());
+ }
+ return true;
+ }
+ /**
+ * Parse typerefs and see if there are parameter instantiated classes
+ * If so process with the instantiation
+ * -> Replace typeref with the real type This can be bad for generator if
+ * the global type is not changed !!!!
+ * -> We should also replace all parameters with the actual parameters
+ */
+ bool visit_assign_typeref(asn1::typeref_assignment *n)
+ {
+ asn1::typeref *type = dynamic_cast<asn1::typeref *>(n->get_type());
+ if (! n->parameters( ) && type->parameters())
+ {
+ asn1::act_parameters &act_params = dynamic_cast<asn1::act_parameters &>(*type->parameters());
+ asn1::node *rtype = resolver.resolve(*type);
+ asn1::parameters &p = dynamic_cast<asn1::parameters &>
+ (*rtype->identifier()->parameters());
+ std::string type_name = type->name();
+ GEN_LOG_INFO("visit_assign_typeref TYPEREF %s -> %s\n"
+ ,n->name().c_str(),type_name.c_str());
+ std::cerr<<"visit_assign_typeref "<<n->name()<<std::endl;
+ asn1::node *ctype = rtype->clone();
+ // temp
+ //ctype->identifier(type->identifier());
+ //ctype->set_parent(m_module);
+
+ // Process replacing parameters ....
+ std::cerr<<"visit_assign_typeref before replace "<<n->name()<<std::endl;
+ }
+ return true;
+ }
+
+
+ void process(asn1::assignment *ident,asn1::node *ntype)
+ {
+ asn1::node::node_list pm;
+ asn1::node *type = ident->get_type();
+
+ GEN_LOG_INFO("PROCESS %s -> type\n",ident->name().c_str());
+ asn1::assignment *nt = new asn1::type_assignment(ident->name());
+ nt->set_type(ntype);
+ nt->set_parent(m_module);
+ //nt->parameters(pi->parameters());
+ ntype->set_parent(m_module);
+ ntype->identifier(nt);
+ m_module->append(nt);
+ //
+ }
+ /**
+ *
+ */
+ void process_component(asn1::field *ident,asn1::typenode *ntype)
+ {
+ asn1::node::node_list pm;
+ asn1::node *type = ident->get_type();
+ GEN_LOG_INFO("PROCESS COMPONENT %s -> type %s\n"
+ , ident->name().c_str()
+ , ntype->name().c_str());
+ assert( (ntype != NULL) && "ntype must not be NULL");
+ //nt->parameters(pi->parameters());
+ ntype->set_parent(ident->get_parent());
+ ntype->identifier(ident);
+ //
+ ident->set_type(ntype);
+ // If properly cloned, I should delete type from ident before replacing it
+ }
+ protected:
+ asn1::module *m_module;
+ asn1::resolver &resolver;
+ std::fstream &m_log;
+};
+
+
+
+namespace asn1
+{
+
+/**
+ *
+ */
+gen_optimizer::gen_optimizer(asn1::module *n,asn1::module::modules_type &m)
+ : generator(n,m)
+{
+}
+
+
+/**
+ *
+ */
+void
+gen_optimizer::gen_module(std::ostream &os,module *m)
+{
+ optimize_phase1 opt1(m_resolver,m_log);
+
+ os<<"*"<<std::endl;
+ os<<"* OPTIMIZE MODULE "<<m->name()<<std::endl;
+ os<<"*"<<std::endl;
+ os<<"-- Phase 1 --"<<std::endl;
+ os<<"\t-> Parse Object Defined Syntax"<<std::endl;
+ os<<"\t-> Replace components of"<<std::endl;
+ os<<"\t-> Replace selection with real type"<<std::endl;
+ os<<"Processing ....";
+ opt1.traverse_module(m);
+ os<<" done."<<std::endl;
+ m_log.flush();
+
+ optimize_nested opt2(m_resolver,m_log);
+ os<<"-- Phase 2 --"<<std::endl;
+ os<<"\t-> nested types made global "<<std::endl;
+ os<<"\t-> typeref resolution. Set real_type adjust reference "<<std::endl;
+ os<<"Processing ....";
+ opt2.traverse_module(m);
+ os<<" done."<<std::endl;
+
+ optimize_params params(m_resolver,m_log);
+ os<<"-- Phase 3 --"<<std::endl;
+ os<<"\t-> Process parameterized types ..."<<std::endl;
+ os<<"\t-> Check/Correct values eg v1 Toto ::= { mib 2 }"<<std::endl;
+ os<<"Processing ....";
+ params.traverse_module(m);
+ os<<" done."<<std::endl;
+}
+
+}
+/**
+ * vim:et sw=2 ts=2 list:
+ */
--- /dev/null
+#ifndef ASN1_GEN_OPTIMIZER_H
+#define ASN1_GEN_OPTIMIZER_H
+
+#include <iostream>
+#include "asn1_generator.h"
+
+namespace asn1
+{
+
+/**
+ * @brief this generator does not produce any output.
+ * It processes the module and performs AST transformation
+ * in order to facilitate the generators work.
+ * -> COMPONENTS OF and SELECTION replacement
+ * -> Object with defined syntax parsing
+ * -> Inner private types are set global with typeref
+ * example : G ::= SEQUENCE { a SEQUENCE { b INTEGER } }
+ * while be transormed G_a ::= SEQUENCE { b INTEGER }
+ * G ::= SEQUENCE { a G_a }
+ *
+ */
+class gen_optimizer : public asn1::generator
+{
+ public:
+ gen_optimizer(asn1::module *n,asn1::module::modules_type &m);
+
+ virtual void gen_module(std::ostream &os,module *) ;
+
+ void gen_const(std::ostream &os,asn1::node *n) {};
+ //
+ void gen_typedef(std::ostream &os,asn1::typenode *n) {};
+ private:
+};
+
+
+}
+/**
+ * vim:et:sw=2:ts=2
+ */
+#endif /*ASN1_GEN_OPTIMIZER_H*/
--- /dev/null
+#include <iostream>
+#include <string>
+#include <sstream>
+#include <assert.h>
+
+#include "asn1_node.h"
+#include "asn1_module.h"
+#include "asn1_generator.h"
+#include "adt/asn1_recursive_visitor.h"
+
+namespace asn1
+{
+
+
+generator::generator(module *root_m)
+ : m_module(root_m)
+ , m_config()
+ , m_resolver(*root_m,asn1::module::modules_type())
+{
+}
+
+generator::generator(module *root_m,asn1::module::modules_type &m_)
+ : m_module(root_m)
+ , m_config()
+ , m_resolver(*root_m,m_)
+{
+ asn1::module::modules_type::iterator it;
+ GEN_LOG_DEBUG("generator::generator m_.size=%lu ",m_.size());
+ m_modules.resize(m_.size());
+ m_modules = m_;
+ // Debuging code
+#if 0
+ for ( it = m_.begin()
+ ; it != m_.end()
+ ; ++it)
+ {
+ std::cerr<<"generator::generator "<<(*it)->name()<<" "<<(*it)->size()<<std::endl;
+ GEN_LOG_DEBUG("generator::generator m_ *it.name=%s size=%lu "
+ ,(*it)->name().c_str()
+ ,(*it)->size());
+ }
+ for ( it = m_modules.begin()
+ ; it != m_modules.end()
+ ; ++it)
+ {
+ std::cerr<<"generator::generator "<<(*it)->name()<<" "<<(*it)->size()<<std::endl;
+ GEN_LOG_DEBUG("generator::generator m_ *it.name=%s size=%lu "
+ ,(*it)->name().c_str()
+ ,(*it)->size());
+ }
+#endif
+}
+
+// If a parameter is of type without value, it's template
+// otherwise it's normal structure
+//
+bool
+generator::is_template(asn1::node *_params)
+{
+ bool ret = false;
+ asn1::parameters *params = dynamic_cast<asn1::parameters *>(_params);
+ if (_params)
+ assert(params != NULL);
+ if (params)
+ {
+ asn1::node::iterator it = params->begin();
+ if (params->name().compare("SIGNED") == 0)
+ {
+ std::cerr<<"generator::is_template "<<params->name()<<" Should be yes "<<(it== params->end())<<std::endl;
+ assert(0);
+ }
+ for (; it != params->end(); ++it)
+ {
+ asn1::parameter ¶m = dynamic_cast<asn1::parameter &>(*(*it));
+ if (params->name().compare("SIGNED") == 0)
+ {
+ std::cerr<<"generator::is_template "<<params->name()<<" "<<param.get_governor()<<std::endl;
+ assert(0);
+ }
+ if ( param.get_governor() == NULL)
+ {
+ // Presence if identifier means typed value or ValueSet
+ ret = true;
+ break;
+ }
+ }
+ if (params->name().compare("SIGNED") == 0)
+ {
+ std::cerr<<"generator::is_template "<<params->name()<<" but is false"<<std::endl;
+ assert(0);
+ }
+ return ret;
+ } else
+ return false;
+}
+
+/**
+ * This is only valid for OID where we use 7 bits for each octet.
+ */
+void generator::encode_integer(long value,std::vector<unsigned char> &v)
+{
+ long integer = value;
+ long intsize = 4;
+ long mask = 0x1FF <<23; // Shift 8 *3 - 1 ? 0xFF800000
+#ifdef DEBUG
+ GEN_LOG_DEBUG("generator::encode_integer %ld %lx",value,value);
+ // std::cout<<"encode_integer: "<<value<<" 0x"<<std::hex<<value<<std::dec<<"\n";
+#endif
+ while ( (((integer & mask) == 0) || ((integer & mask) == mask))
+ && (intsize > 1)) {
+ intsize--;
+ integer <<=8;
+#ifdef DEBUG
+ GEN_LOG_DEBUG("generator::encode_integer step 1 %lx",integer);
+ // std::cout<<"is: "<<std::hex<<integer<<std::dec<<" ";
+#endif
+ }
+ mask = (0x7f << ((intsize-1)*7));
+ long decal = (intsize -1)*7;
+#ifdef DEBUG
+ GEN_LOG_DEBUG("generator::encode_integer step 1 intsize=%ld mask=0x%lx decal=%ld",intsize,mask,decal);
+ //std::cout<<" intsize="<<intsize<<" mask="<<std::hex<<mask<<std::dec<<" decal="<<decal<<std::endl;
+#endif
+ while ((value & mask ) != 0)
+ {
+ long treat = ((value & mask)>>decal);
+ v.push_back (( treat & 0x7F) |0x80 );
+#ifdef DEBUG
+ std::cout<<"\tpushed :";
+ std::cout<<std::hex<<(int)v.back()<<" integer was:"<<value;
+ std::cout<<" Mask=0x"<<mask<<" treat="<<treat;
+ std::cout<<std::dec<<std::endl;
+#endif
+ value<<=7;
+ }
+ v.back() = v.back() & 0x7F;
+}
+
+
+void
+generator::oid_value(asn1::node *type,int *pos,std::vector<unsigned char> *v)
+{
+ asn1::object_identifier *oid = type->as_object_identifier();
+ assert(oid != NULL);
+ oid->arcs(reinterpret_cast<asn1::object_identifier::arcsType &>(*v));
+ *pos = v->size();
+}
+
+
+/**
+ *
+ *
+ */
+void generator::gen(std::ostream &os,const std::string &suf)
+{
+ if (m_module)
+ {
+ std::string fn("./log/");
+ fn.append(m_module->name());
+ fn.append(suf);
+ fn.append(".gen.log");
+ m_log.open(fn.c_str(),std::fstream::out);
+ gen_module(os,m_module);
+ m_log.close();
+ }
+}
+
+int generator::tag_mode(asn1::node *node) const
+{
+ assert((m_module != NULL) && "generator::tag_mode m_module should not be NULL");
+ asn1::node::tag_type t = node->tag();
+ if (node->tagged())
+ {
+ if (t.m_mode == asn1::node::tag_type::TM_DEFAULT)
+ {
+ asn1::node::tag_type mt = m_module->tag();
+ if (mt.m_mode == asn1::node::tag_type::TM_DEFAULT)
+ {
+ return asn1::node::tag_type::TM_EXPLICIT;
+ } else {
+ return mt.m_mode;
+ }
+ } else {
+ return t.m_mode;
+ }
+ } else {
+ return asn1::node::tag_type::TM_DEFAULT;
+ }
+}
+
+
+bool
+generator::is_tag_explicit(asn1::typenode &_type) const
+{
+ return tag_mode(&_type) == asn1::node::tag_type::TM_EXPLICIT;
+}
+/**
+* For the generator classes We provide a methode to convert types::ASN1_<type> to ASN1 tags ids
+*/
+int generator::type2tagid(int v) const
+{
+ switch (v) {
+ case asn1::type::ASN1_BOOLEAN:
+ return 1;
+ break;
+ case asn1::type::ASN1_INTEGER:
+ return 2;
+ break;
+ case asn1::type::ASN1_BIT_STRING:
+ return 3;
+ break;
+ case asn1::type::ASN1_OCTET_STRING:
+ return 4;
+ break;
+ case asn1::type::ASN1_NULL:
+ return 5;
+ break;
+ case asn1::type::ASN1_OBJECT_IDENTIFIER:
+ return 6;
+ break;
+ case asn1::type::ASN1_OBJECT_DESCRIPTOR:
+ return 7;
+ break;
+ case asn1::type::ASN1_EXTERNAL:
+ return 8;
+ break;
+ case asn1::type::ASN1_REAL:
+ return 9;
+ break;
+ case asn1::type::ASN1_ENUMERATED:
+ return 10;
+ break;
+ case asn1::type::ASN1_EMBEDDED_PDV:
+ return 11;
+ break;
+ case asn1::type::ASN1_UTCTime:
+ return 23;
+ break;
+ case asn1::type::ASN1_GeneralizedTime:
+ return 24;
+ break;
+ case asn1::type::ASN1_STRING_IA5String:
+ return 22;
+ break;
+ case asn1::type::ASN1_STRING_PrintableString:
+ return 19;
+ break;
+ case asn1::type::ASN1_STRING_VisibleString:
+ return 26;
+ break;
+ case asn1::type::ASN1_STRING_ISO646String:
+ return 29;
+ break; /* aka VisibleString */
+ case asn1::type::ASN1_STRING_NumericString:
+ return 18;
+ break;
+ case asn1::type::ASN1_STRING_UniversalString:
+ return 28;
+ break;
+ case asn1::type::ASN1_STRING_BMPString:
+ return 30;
+ break;
+ case asn1::type::ASN1_STRING_UTF8String:
+ return 12;
+ break;
+ case asn1::type::ASN1_STRING_GeneralString:
+ return 27;
+ break;
+ case asn1::type::ASN1_STRING_GraphicString:
+ return 25;
+ break;
+ case asn1::type::ASN1_STRING_TeletexString:
+ return 22;
+ break;
+ case asn1::type::ASN1_STRING_T61String:
+ return 20;
+ break;
+ case asn1::type::ASN1_STRING_VideotexString:
+ return 21;
+ break;
+ case asn1::type::ASN1_STRING_ObjectDescriptor:
+ return 7;
+ break;
+ default: return 0;
+ }
+}
+/**
+ *
+ */
+bool generator::type_in_imports(asn1::node *type,asn1::node **ns)
+{
+ return type_in_imports(type->name(),ns);
+}
+
+bool generator::type_in_imports(const std::string &type,asn1::node **ns)
+{
+ bool ret = false;
+ asn1::import_list *imports = m_module->imports();
+ if (imports == NULL)
+ {
+ GEN_LOG_ERROR("type %s not in imports no imports\n",type.c_str());
+ return ret;
+ }
+ asn1::import *import;
+ asn1::typeref *ref;
+ if (ret = imports->get_item(type,import,ref))
+ {
+ GEN_LOG_DEBUG("found %s in %s\n",type.c_str(),import->identifier()->name().c_str());
+ *ns = import->identifier();
+ }
+ return ret;
+}
+
+bool
+generator::get_type_in_module(const std::string &mod_name,const std::string &typ_name,asn1::node **n)
+{
+ GEN_LOG_INFO("generator::get_type_in_module mod=%s cur_module=%s name=%s modules=%lu\n"
+ ,mod_name.c_str()
+ ,m_module->name().c_str()
+ ,typ_name.c_str()
+ ,m_modules.size());
+ asn1::module::modules_type::iterator mit = std::find_if(m_modules.begin(),m_modules.end(),
+ asn1::find_module(mod_name));
+ if (mit != m_modules.end())
+ {
+ asn1::node::iterator nit =
+ std::find_if((*mit)->begin(),(*mit)->end(),asn1::find_node(typ_name));
+ if (nit != (*mit)->end())
+ {
+ *n = (*nit);
+ return true;
+ } else
+ {
+ GEN_LOG_ERROR("get_type_in_module type %s not in module %s\n"
+ ,typ_name.c_str()
+ ,mod_name.c_str());
+ return false;
+ }
+ } else {
+ GEN_LOG_ERROR("get_type_in_module did not find module %s\n",mod_name.c_str());
+ return false;
+ }
+}
+
+/**
+ *
+ */
+void generator::path2modulestring(asn1::node *type,std::string &ss)
+{
+ asn1::node::node_list lst;
+
+ type->path2module(lst);
+ for (asn1::node::const_iterator nit = lst.begin()
+ ; nit != lst.end()
+ ; ++nit )
+ {
+ if ( (*nit)->is_private() )
+ {
+ ss += (*nit)->cpp_name() + "::";
+ } else
+ ss += (*nit)->identifier()->cpp_name() + "::";
+ }
+}
+
+/**
+ * Find a referenced value
+ */
+bool
+generator::loockup_value(const std::string &_v,asn1::node **ov)
+{
+ bool ret = false;
+ asn1::node *ns = NULL;
+ if (type_in_imports(_v,&ns)) {
+ GEN_LOG_ERROR("Value %s in import %s not yet handled\n",_v.c_str(),ns->name().c_str());
+ } else {
+ asn1::node::iterator it = std::find_if( m_module->begin()
+ , m_module->end()
+ ,asn1::find_value(_v));
+ if ( it != m_module->end())
+ {
+ // Ok, found the value, return it
+ *ov = (*it);
+ ret = true;
+ }
+ }
+ return ret;
+}
+
+/**
+ * Find the appropriate class node
+ */
+bool
+generator::loockup_class(const std::string &_v,asn1::node **ov)
+{
+ bool ret = false;
+ GEN_LOG_ERROR("To be coded %s\n",_v.c_str());
+ return ret;
+}
+
+/**
+ * Find the primary type for a typeref type
+ */
+bool
+generator::loockup_prim_type(const std::string &_v,asn1::node **ov)
+{
+ bool ret = false;
+ GEN_LOG_ERROR("To be coded %s \n",_v.c_str());
+ return ret;
+}
+
+
+
+
+bool
+generator::have_attributes_to_init(const asn1::constructed *type) const
+{
+ bool result = false;
+ asn1::node::const_iterator attr_it = type->begin();
+
+ for (; attr_it != type->end() ; ++attr_it)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*attr_it);
+ asn1::typenode *attr_type = f->get_type();
+ if (attr_type != NULL && attr_type->type_id()() != asn1::type::ASN1_EXTENSIBLE ) {
+ result = true;
+ break;
+ }
+ }
+ return result;
+}
+
+void
+generator::reference_chaine(asn1::typeref *type, std::list<asn1::node *> &lst)
+{
+ //asn1::node *t = type;
+ asn1::node *ns = NULL;
+ // add the first reference in case it's tagged Explicitly
+ //lst.push_back(type);
+ if ( type == NULL)
+ return;
+ //
+ asn1::node *t = type->get_real_type();
+ while (t && t->as_typeref() )
+ {
+ lst.push_back(t);
+ t = t->as_typeref()->get_real_type();
+ }
+ if (t)
+ lst.push_back(t);
+}
+
+
+bool
+generator::add_symbol(std::string &name,asn1::node *type)
+{
+ SymbolMap_iterator it = m_symbols.find(name);
+
+ if (it == m_symbols.end())
+ {
+ m_symbols[name] = type;
+ return true;
+ } else
+ {
+ GEN_LOG_WARN("generator::add_symbol %s are equal %d\n",name.c_str(),((*((it)->second)) == *type));
+ return false;
+ }
+}
+
+}
+/*
+ * vim: et sw=2 ts=2 list:
+ */
--- /dev/null
+#ifndef ASN1_GENERATOR_H__
+#define ASN1_GENERATOR_H__
+#include <iostream>
+#include <fstream>
+#include <map>
+#include <string.h>
+#include "asn1_node.h"
+#include "asn1_module.h"
+#include "asn1_resolver.h"
+
+#if defined(_WIN32)
+#define GEN_LOG_DEBUG(fmt,...) do {\
+ } while (0)
+#define GEN_LOG_INFO(fmt,...) do {\
+ } while (0)
+#define GEN_LOG_WARN(fmt,...) do {\
+ } while (0)
+#define GEN_LOG_ERROR(fmt,...) do {\
+ } while (0)
+#else
+#define GEN_LOG_DEBUG(fmt,args...) do {\
+ char _lbuf[1024]; \
+ const char *fn = strrchr(const_cast<char *>(__FILENAME__),'/'); \
+ fn = (fn == NULL)?__FILENAME__:fn+1; \
+ if (m_log.is_open()) { \
+ m_log<<"DEBUG "<<__FUNCTION__<<" "; \
+ sprintf(_lbuf," (%s : %d) ",fn,__LINE__); m_log<<_lbuf; \
+ sprintf(_lbuf,fmt,##args); m_log<<_lbuf; \
+ } \
+ } while (0)
+
+#define GEN_LOG_INFO(fmt,args...) do {\
+ char _lbuf[1024]; \
+ const char *fn = strrchr(const_cast<char *>(__FILENAME__),'/'); \
+ fn = (fn == NULL)?__FILENAME__:fn+1; \
+ if (m_log.is_open()) { \
+ m_log<<"INFO "<<__FUNCTION__<<" "; \
+ sprintf(_lbuf," (%s : %d) ",fn,__LINE__); m_log<<_lbuf; \
+ sprintf(_lbuf,fmt,##args); m_log<<_lbuf; \
+ } \
+ } while (0)
+
+#define GEN_LOG_WARN(fmt,args...) do {\
+ char _lbuf[1024]; \
+ if (m_log.is_open()) { \
+ m_log<<"WARN "<<__FUNCTION__<<" "; \
+ sprintf(_lbuf," (%s : %d) ",__FILENAME__,__LINE__); m_log<<_lbuf; \
+ sprintf(_lbuf,fmt,##args); m_log<<_lbuf; \
+ } \
+ } while (0)
+
+#define GEN_LOG_ERROR(fmt,args...) do {\
+ char _lbuf[1024]; \
+ if (m_log.is_open()) { \
+ m_log<<"ERROR "<<__FUNCTION__<<" "; \
+ sprintf(_lbuf," (%s : %d) ",__FILENAME__,__LINE__); m_log<<_lbuf; \
+ sprintf(_lbuf,fmt,##args); m_log<<_lbuf; \
+ } \
+ } while (0)
+#endif
+namespace asn1
+{
+
+
+struct generator_config
+{
+ generator_config()
+ : m_printf(true)
+ , m_ber(true)
+ , m_per(false)
+ , m_xer(false)
+ , m_jer(false)
+ , m_ots(false)
+ , m_oer(false)
+ , m_template(false)
+ , m_debug(true)
+ , m_source_comment(true)
+ , m_source_debug(false)
+ , m_codec(false)
+ , m_split_cpp(false)
+ {};
+#define WITH_CODEC(nm) \
+ bool with_##nm() { return m_##nm; } ; \
+ void with_##nm(bool b) { m_##nm = b ; } ;
+ WITH_CODEC(ber)
+ WITH_CODEC(per)
+ WITH_CODEC(xer)
+ WITH_CODEC(jer)
+ WITH_CODEC(printf)
+ WITH_CODEC(oer)
+ WITH_CODEC(template)
+ WITH_CODEC(debug)
+ WITH_CODEC(source_comment)
+ WITH_CODEC(source_debug)
+ WITH_CODEC(nested)
+ WITH_CODEC(codec)
+ WITH_CODEC(split_cpp)
+#undef WITH_CODEC
+ // generator configuration flags
+ bool m_printf;
+ bool m_ber;
+ bool m_per;
+ bool m_xer;
+ bool m_ots;
+ bool m_jer;
+ bool m_oer;
+ bool m_template; // tells if we generate template file or cpp file
+ bool m_debug;
+ bool m_source_comment;
+ bool m_source_debug;
+ bool m_nested;
+ bool m_codec; // Remove codec function code
+ bool m_split_cpp; // Implementation in separated cpp files
+
+};
+
+/**
+ *
+ */
+class generator
+{
+ protected:
+ generator(const generator &g) : m_resolver(g.m_resolver) {};
+ public:
+ typedef std::map<std::string,asn1::node * > SymbolMap;
+ typedef SymbolMap::iterator SymbolMap_iterator;
+ typedef SymbolMap::const_iterator SymbolMap_const_iterator;
+
+ generator(module *n = NULL);
+
+ generator(module *root_m,asn1::module::modules_type &m_) ;
+
+ virtual ~generator() {};
+
+ void set_config(const generator_config &c) { m_config = c; }
+
+ generator_config &get_config() { return m_config; }
+
+ // Set and getters
+ //
+ module *get_module() const { return m_module ; };
+
+ asn1::module::modules_type &get_module_list() { return m_modules;};
+
+ //
+ void oid_value(asn1::node *n,int *pos,std::vector<unsigned char> *v);
+
+ void encode_integer(long value,std::vector<unsigned char> &v);
+
+ // Tells if a the structure should be in the form of templale
+#define WITH_CODEC(nm) \
+ bool with_##nm() { return m_config.m_##nm; } ;
+ WITH_CODEC(ber)
+ WITH_CODEC(per)
+ WITH_CODEC(xer)
+ WITH_CODEC(jer)
+ WITH_CODEC(printf)
+ WITH_CODEC(oer)
+ WITH_CODEC(template)
+ WITH_CODEC(debug)
+ WITH_CODEC(source_comment)
+ WITH_CODEC(source_debug)
+ WITH_CODEC(codec)
+ WITH_CODEC(split_cpp)
+#undef WITH_CODEC
+ // generator configuration flags
+ // or not
+ bool is_template(asn1::node *params);
+
+ virtual void gen_const(std::ostream &os,node *) = 0;
+
+ virtual void gen_typedef(std::ostream &os,typenode *) = 0;
+
+ virtual void gen_set_of(std::ostream &os,set_of &) {};
+
+ virtual void gen_sequence_of(std::ostream &os,sequence_of &) {};
+
+ virtual void gen_seq(std::ostream &os,sequence &) {};
+
+ virtual void gen_choice(std::ostream &os,choice &) {};
+
+ virtual void gen_object(std::ostream &os,node *) {};
+
+ virtual void gen_module(std::ostream &os,module *) = 0;
+
+ virtual void gen(std::ostream &os,const std::string &s = "gen");
+ // return the choosen tagging mode
+ int tag_mode(asn1::node *node) const;
+ /**
+ *
+ */
+ bool is_tag_explicit(asn1::typenode &_type) const ;
+ /**
+ * This function loops over alll childs in module and
+ * depending on the meta type call gen_typedef,gen_const,
+ */
+ int type2tagid(int v) const;
+
+ //bool size_range(asn1::node * type,long &start ,long &end);
+ /**
+ * Generic function that is going to check if
+ * a type is imported.
+ * DEPRECATED. Use resolver
+ */
+ bool type_in_imports(asn1::node *type,asn1::node **ns) ;
+ bool type_in_imports(const std::string &type,asn1::node **ns) ;
+ /**
+ * Find a referenced value
+ */
+ bool loockup_value(const std::string &_v,asn1::node **ov) ;
+ /**
+ * Find the appropriate class node
+ */
+ bool loockup_class(const std::string &_v,asn1::node **ov) ;
+ /**
+ * Find the primary type for a typeref type
+ */
+ bool loockup_prim_type(const std::string &_v,asn1::node **ov) ;
+
+ /**
+ * DEPRECATED, use resolver
+ */
+ bool get_type_in_module(const std::string &mod_name,const std::string &typ_name,asn1::node **n) ;
+
+ /**
+ * Usefull object functions
+ */
+ inline void set_gen_printf(bool _b) { m_config.m_printf = _b;};
+ inline bool do_gen_printf() {return m_config.m_printf;};
+
+ bool have_attributes_to_init(const asn1::constructed *type) const ;
+ // for optimization purpose
+ void reference_chaine(asn1::typeref *type, std::list<asn1::node *> &lst);
+
+ void path2modulestring(asn1::node *type,std::string &s);
+ /**
+ *
+ */
+ std::fstream &logger() { return m_log; };
+ /**
+ * Give access to the resolver for helper classes
+ */
+ asn1::resolver &resolver() { return m_resolver; };
+ /**
+ * if the symbol does not exists, add it and return true.
+ * if the symbol exists in the map, return false;
+ */
+ bool add_symbol(std::string &name,asn1::node *);
+ protected:
+ std::fstream m_log;
+ module *m_module;
+ SymbolMap m_symbols;
+ asn1::module::modules_type m_modules;
+ generator_config m_config;
+ asn1::resolver m_resolver;
+};
+
+}
+
+/*
+ * vim:et:sw=2:ts=2
+ */
+#endif
--- /dev/null
+#ifndef ASN1_GENERATOR_HELPER_H
+#define ASN1_GENERATOR_HELPER_H
+
+/**
+ * This class defines the interface that each
+ * asn1 type generation should implement ....
+ * -- typedef sequence generator
+ * -- typedef choice generator
+ * -- typedef set generator
+ * -- typedef set of generator
+ * -- typedef sequ of generator
+ *
+ * This allows us to split and isolate the generation
+ * code .... and simplifity the readability
+ */
+class generator_helper
+{
+ public:
+ generator_helper(std::ostream &os) : m_os(os) { } ;
+
+ // generate entry point
+ virtual void generate() {};
+ // generate codec part
+ virtual void generate_per() = 0;
+ //
+ virtual void generate_ber() = 0;
+ //
+ virtual void generate_oer() = 0;
+ //
+ virtual void generate_jer() = 0;
+ //
+ virtual void generate_xer() = 0;
+
+ // generate encoder
+ // generate decoder
+ // generate constructor
+ // generate
+ protected:
+ std::ostream &m_os;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_codec_cpp.h"
+#include "asn1_generator_helper.h"
+#include "cgcpp_helper.h"
+
+
+/**
+ * constructor
+ */
+cgcpp_helper::cgcpp_helper( generate_codec_cpp &g
+ , std::ostream &os
+ )
+ : m_gencpp(g), generator_helper(os),m_log(g.logger())
+{
+}
+
+/**
+ *
+ * @brief common way to generate the required code depending
+ * on the global settings given to the asn1 parser.
+ */
+void
+cgcpp_helper::generate()
+{
+ generate_descriptor();
+
+ generate_members();
+
+ generate_ctors();
+
+ generate_operators();
+
+ generate_printf();
+ /* codec function generators */
+ if (m_gencpp.with_ber())
+ {
+ generate_ber();
+ }
+ if (m_gencpp.with_oer())
+ {
+ generate_oer();
+ }
+ if (m_gencpp.with_jer())
+ {
+ generate_jer();
+ }
+ if (m_gencpp.with_per())
+ {
+ generate_per();
+ }
+}
+
+void
+cgcpp_helper::generate_descriptor()
+{
+}
+
+
--- /dev/null
+#ifndef CODE_GEN_CPP_HELPER_H
+#define CODE_GEN_CPP_HELPER_H
+
+/**
+ * This class defines the interface that each
+ * asn1 type generation should implement ....
+ * Unlike generator_helper, this class provides a first
+ * level of functions dedicated to c++ code generation. The goal is
+ * to move the generation from one unique file to one file per type.
+ * -> provide streams for cpp,h and hpp.
+ * -> provide generic preamble et epilog
+ * -> open /close stream
+ */
+class cgcpp_helper : public generator_helper
+{
+ public:
+ cgcpp_helper( generate_codec_cpp &g
+ , std::ostream &os
+ );
+
+ // generate entry point
+ virtual void generate() ;
+ // generate codec part
+ virtual void generate_per() {};
+ //
+ virtual void generate_ber() {};
+ //
+ virtual void generate_oer() {};
+ //
+ virtual void generate_jer() {};
+ //
+ virtual void generate_xer() {};
+
+ // Type of code generated in CPP files
+ virtual void generate_ctors() {};
+
+ virtual void generate_printf() {};
+
+ virtual void generate_descriptor() ;
+
+ virtual void generate_members() {};
+
+ virtual void generate_operators() {};
+ // generate encoder
+ // generate decoder
+ // generate constructor
+ // generate
+ protected:
+ std::fstream &m_log;
+ generate_codec_cpp &m_gencpp;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_codec_cpp.h"
+#include "asn1_generator_helper.h"
+#include "cgcpp_helper.h"
+#include "cgh_construct.h"
+#include "cgcpph_bitstring.h"
+
+
+/**
+ *
+ *
+ */
+cgcpph_bit_string::cgcpph_bit_string(generate_codec_cpp &g,std::ostream &os,asn1::bit_string &s)
+ : cgh_construct(g,os,s) , m_bit_string(s)
+{
+}
+
+/**
+ *
+ *
+ */
+cgcpph_bit_string::~cgcpph_bit_string()
+{
+}
+
+
+/** Helper functions
+ *
+ */
+void cgcpph_bit_string::generate(const std::string &scope)
+{
+ if (m_gencpp.with_source_comment())
+ m_os<<"// cgcpph_bit_string helper launched "<<std::endl;
+
+ cgcpp_helper::generate();
+}
+
+//
+void cgcpph_bit_string::generate_ctors( )
+{
+ m_os<<m_structName;
+ m_os<<"::"<<m_structName<<"(const "<<m_structName<<" &c) : BIT_STRING()\n{\n}\n";
+ // With tag
+ m_os<<m_structName;
+ m_os<<"::"<<m_structName<<"(const asn1::tag &t) : BIT_STRING(t)\n{\n}\n";
+}
+
+
+//
+void cgcpph_bit_string::generate_printf( )
+{
+ // std::string structName = type->identifier()->cpp_name();
+
+ m_os<<"std::ostream & operator <<(std::ostream &os,const ";
+ m_os<<m_structName<<" &s)\n{\n";
+ m_os<<"\tos<<(BIT_STRING)s;\n";
+ m_os<<"\treturn os;\n";
+ m_os<<"}\n";
+}
+
+// generate codec part
+void cgcpph_bit_string::generate_per()
+{
+ if (m_gencpp.with_codec())
+ {
+ std::string ns( m_gencpp.get_module()->cpp_name() );
+ std::string structName ( ns + "::" + m_bit_string.identifier_cpp_name() );
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ /* template specialisation hpp */
+ // m_gencpp.gen_template_signature(m_os,type);
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void codecPER::encode(streams::per &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int codecPER::decode(streams::per &c,"<<structName<<" &_t);\n";
+
+ /* Implementation part */
+ cpp<<"// bit_string generator todo"<<std::endl;
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecPER::encode(asn1::streams::per &c,const "<<structName<<" &_t)\n{\n";
+ cpp<<"\tc.encode_bitstring(_t);";
+ cpp<<"}\n";
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecPER::decode(asn1::streams::per &c,"<<structName<<" &_t)\n{\n";
+ cpp<<"\treturn c.decode_bitstring(_t);\n";
+ cpp<<"}\n";
+ }
+
+}
+
+//
+void cgcpph_bit_string::generate_ber()
+{
+ std::string scope;
+ std::string structName = m_bit_string.identifier_cpp_name();
+
+
+
+ //
+ if (m_bit_string.tagged())
+ {
+ if ( m_gencpp.tag_mode(&m_bit_string) == asn1::node::tag_type::TM_EXPLICIT)
+ {
+ m_os<<scope<<"void "<<structName<<"::encode(asn1::context &ctx)\n{\n"<<std::endl;
+ m_os<<"\tunsigned long pos = ctx.bytes();\n";
+ m_os<<"\tunsigned char *b = ctx.buffer();\n";
+ m_os<<"\tASN1_BER_LOG_DEBUG(\""<<structName<<"::encode(ctx) tag=%d \",this->tag().byte());\n";
+ m_os<<"\tb[pos++] = tag().byte();\n";
+ m_os<<"\tctx.nb_bits(16);\n";
+ m_os<<"\tasn1::tag t("<<m_bit_string.tag().m_class<<","<<m_bit_string.tag().m_value<<",true);\n";
+ m_os<<"\tset_tag(asn1::tag(0,3));\n";
+ m_os<<"\tctx.encode_bitstring(*this);\n";
+ m_os<<"\tset_tag(t);\n";
+ m_os<<"\tb[pos] = ctx.bytes() -pos -1;\n";
+ m_os<<"}\n\n";
+ m_os<<scope<<"int "<<structName<<"::decode(asn1::context &ctx)\n{\n"<<std::endl;
+ m_os<<"\tasn1::tag t("<<m_bit_string.tag().m_class<<","<<m_bit_string.tag().m_value<<",true);\n";
+ m_os<<"\tASN1_BER_LOG_DEBUG(\""<<structName<<"::decode(ctx) exp tag= %d tag=%d \",t.byte(),this->tag().byte());\n";
+ m_os<<"\tif (ctx.decode_tag(t))\n\t{\n";
+ m_os<<"\t\tBIT_STRING tmp;\n";
+ m_os<<"\t\tint rest = tmp.decode(ctx);\n";
+ m_os<<"\t\tthis->get_value() = tmp.get_value();\n";
+ m_os<<"\t\treturn rest;\n";
+ m_os<<"\t}\n";
+ m_os<<"\treturn asn1::wrong_tag;\n";
+ m_os<<"}\n";
+ }
+ }
+ if (m_gencpp.with_codec())
+ {
+ std::string ns( m_gencpp.get_module()->cpp_name() );
+ std::string structName ( ns + "::" + m_bit_string.identifier_cpp_name() );
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ /* template specialisation hpp */
+ // m_gencpp.gen_template_signature(m_os,type);
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void codecBER::encode(streams::ber &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int codecBER::decode(streams::ber &c,"<<structName<<" &_t);\n";
+
+ /* Implementation part */
+ cpp<<"// bit_string generator todo"<<std::endl;
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecBER::encode(asn1::streams::ber &c,const "<<structName<<" &_t)\n{\n";
+ if ( m_bit_string.tagged()
+ && ( m_gencpp.is_tag_explicit(m_bit_string)))
+ {
+ //cpp<<"\tint len;\n";
+ cpp<<"\tasn1::tag t("<<m_bit_string.tag().m_class<<","<<m_bit_string.tag().m_value<<",true);\n";
+ //cpp<<"\tstd::cout<<\"codecBER::encode "<<structName<<" TODO\"<<std::endl;\n"<<std::endl;
+ cpp<<"\tencode_tag(c,t,_t.get_length());\n";
+ }
+ cpp<<"\tc.encode_bitstring(_t);\n";
+ cpp<<"}\n";
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecBER::decode(asn1::streams::ber &c,"<<structName<<" &_t)\n{\n";
+ if ( m_bit_string.tagged()
+ && ( m_gencpp.is_tag_explicit(m_bit_string) ))
+ {
+ cpp<<"\tstd::cout<<\"codecBER::decode "<<structName<<" TODO\"<<std::endl;\n"<<std::endl;
+ }
+ cpp<<"\treturn c.decode_bitstring(_t);\n";
+ cpp<<"}\n";
+ }
+
+}
+
+//
+void cgcpph_bit_string::generate_oer()
+{
+ if (m_gencpp.with_codec())
+ {
+ std::string ns( m_gencpp.get_module()->cpp_name() );
+ std::string structName ( ns + "::" + m_bit_string.identifier_cpp_name() );
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ /* template specialisation hpp */
+ // m_gencpp.gen_template_signature(m_os,type);
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void codecOER::encode(streams::oer &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int codecOER::decode(streams::oer &c,"<<structName<<" &_t);\n";
+
+ /* Implementation part */
+ cpp<<"// bit_string generator todo"<<std::endl;
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecOER::encode(asn1::streams::oer &c,const "<<structName<<" &_t)\n{\n";
+ cpp<<"\tc.encode_integer(_t);";
+ cpp<<"}\n";
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecOER::decode(asn1::streams::oer &c,"<<structName<<" &_t)\n{\n";
+ cpp<<"\treturn asn1::ok;\n";
+ cpp<<"}\n";
+ }
+
+}
+
+//
+void cgcpph_bit_string::generate_jer()
+{
+ if (m_gencpp.with_codec())
+ {
+ std::string ns( m_gencpp.get_module()->cpp_name() );
+ std::string structName ( ns + "::" + m_bit_string.identifier_cpp_name() );
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ /* template specialisation hpp */
+ // m_gencpp.gen_template_signature(m_os,type);
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void codecJER::encode(streams::jer &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int codecJER::decode(streams::jer &c,"<<structName<<" &_t);\n";
+
+ /* Implementation part */
+ cpp<<"// bit_string generator todo"<<std::endl;
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecJER::encode(asn1::streams::jer &c,const "<<structName<<" &_t)\n{\n";
+ cpp<<"\tc.encode_bitstring(_t);";
+ cpp<<"}\n";
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecJER::decode(asn1::streams::jer &c,"<<structName<<" &_t)\n{\n";
+ cpp<<"\treturn c.decode_bitstring(_t);\n";
+ cpp<<"}\n";
+ }
+
+}
+
+//
+void cgcpph_bit_string::generate_xer()
+{
+}
+/* vi: set ts=2 sw=2 sts=2 et: */
--- /dev/null
+#ifndef CGCPPH_BITSTRING_H
+#define CGCPPH_BITSTRING_H
+
+
+/**
+ *
+ */
+class cgcpph_bit_string : public cgh_construct
+{
+ protected:
+ cgcpph_bit_string(const cgcpph_bit_string &s) : cgh_construct(s)
+ , m_bit_string(s.m_bit_string) {}
+ public:
+ cgcpph_bit_string(generate_codec_cpp &g,std::ostream &os,asn1::bit_string &s) ;
+ ~cgcpph_bit_string();
+
+ // Helper functions
+ virtual void generate(const std::string &scope) ;
+
+ // generate codec part
+ virtual void generate_per() ;
+ //
+ virtual void generate_ber() ;
+ //
+ virtual void generate_oer() ;
+ //
+ virtual void generate_jer() ;
+ //
+ virtual void generate_xer() ;
+ protected:
+ virtual void generate_ctors();
+
+ virtual void generate_printf( );
+ protected:
+ asn1::bit_string &m_bit_string;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_codec_cpp.h"
+#include "asn1_generator_helper.h"
+#include "cgcpp_helper.h"
+#include "cgcpph_primitive.h"
+#include "cgcpph_boolean.h"
+
+
+cgcpph_boolean::cgcpph_boolean(generate_codec_cpp &g,std::ostream &os,asn1::boolean &s)
+ : cgcpph_primitive(g,os,s)
+ , m_boolean(s)
+{
+}
+
+cgcpph_boolean::~cgcpph_boolean()
+{
+}
+
+/** Helper functions
+ *
+ *
+ */
+void cgcpph_boolean::generate_ctors()
+{
+ if (m_gencpp.with_source_comment())
+ {
+ m_os<<"// cgcpph_boolean helper launched ";
+ m_os<<m_structName<<"\n";
+ }
+ GEN_LOG_DEBUG("cgcpph_boolean::generate node=%s\n",m_boolean.identifier_cpp_name().c_str());
+ // May be just include each module ...
+ m_os<<"\n"<<m_structName;
+ m_os<<"::"<<m_structName<<"(const asn1::tag &t) : BOOLEAN(t)\n{\n}\n";
+ m_os<<"\n// Copy Constructor "<<m_structName<<"\n//\n";
+ m_os<<m_structName;
+ m_os<<"::"<<m_structName<<"(const "<<m_structName<<" &c) : BOOLEAN()\n{\n}\n";
+}
+
+/**
+ *
+ */
+void cgcpph_boolean::generate_operators()
+{
+ gen_equal();
+}
+
+/**
+ *
+ */
+void cgcpph_boolean::gen_equal()
+{
+ m_os<<"\n// comparaison "<<m_structName<<"\n//\n";
+ m_os<<"bool\n"<<m_structName;
+ m_os<<"::operator =="<<"( "<<m_structName<<" &t)\n{\n";
+ m_os<<"\treturn get_value() == t.get_value();\n";
+ m_os<<"}\n";
+}
+
+ /**
+ *
+ */
+void cgcpph_boolean::generate_printf()
+{
+ m_os<<"\nstd::ostream & operator <<(std::ostream &os,const ";
+ m_os<<m_structName<<" &s)\n{\n";
+ m_os<<"\tos<<(BOOLEAN)s;\n";
+ m_os<<"\treturn os;\n";
+ m_os<<"}\n";
+}
+
+// generate codec part
+void cgcpph_boolean::generate_per()
+{
+ //
+ std::string ns = m_gencpp.get_module()->cpp_name();
+ std::string structName(ns + "::" + m_boolean.identifier_cpp_name());
+
+ if (m_gencpp.with_codec())
+ {
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void codecPER::encode(streams::per &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int codecPER::decode(streams::per &c,"<<structName<<" &_t);\n";
+
+ /* Implementation part */
+ cpp<<"// boolean generator"<<std::endl;
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecPER::encode(asn1::streams::per &c,const "<<structName<<" &_t)\n{\n";
+ cpp<<"\tc.encode_boolean(_t);";
+ cpp<<"}\n";
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecPER::decode(asn1::streams::per &c,"<<structName<<" &_t)\n{\n";
+ cpp<<"\treturn c.decode_boolean(_t);\n";
+ cpp<<"}\n";
+
+ }
+}
+
+//
+void cgcpph_boolean::generate_ber()
+{
+ //
+ if (m_boolean.tagged())
+ {
+ std::string structName = m_boolean.identifier_cpp_name();
+ if ( m_gencpp.tag_mode(&m_boolean) == asn1::node::tag_type::TM_EXPLICIT)
+ {
+ m_os<<"void "<<structName<<"::encode(asn1::context &ctx)\n{\n"<<std::endl;
+ m_os<<"\tunsigned long pos = ctx.bytes();\n";
+ m_os<<"\tunsigned char *b = ctx.buffer();\n";
+ m_os<<"\tASN1_BER_LOG_DEBUG(\""<<structName<<"::encode(ctx) tag=%d \",this->tag().byte());\n";
+ m_os<<"\tb[pos++] = tag().byte();\n";
+ m_os<<"\tctx.nb_bits(16);\n";
+ m_os<<"\tasn1::tag t("<<m_boolean.tag().m_class<<","<<m_boolean.tag().m_value<<",true);\n";
+ m_os<<"\tset_tag(asn1::tag(0,1));\n";
+ m_os<<"\tctx.encode_boolean(*this);\n";
+ m_os<<"\tset_tag(t);\n";
+ m_os<<"\tb[pos] = ctx.bytes() -pos -1;\n";
+ m_os<<"}\n\n";
+ m_os<<"int "<<structName<<"::decode(asn1::context &ctx)\n{\n"<<std::endl;
+ m_os<<"\tasn1::tag t("<<m_boolean.tag().m_class<<","<<m_boolean.tag().m_value<<",true);\n";
+ m_os<<"\tASN1_BER_LOG_DEBUG(\""<<structName<<"::decode(ctx) exp tag= %d tag=%d \",t.byte(),this->tag().byte());\n";
+ m_os<<"\tif (ctx.decode_tag(t))\n\t{\n";
+ m_os<<"\t\tBOOLEAN tmp;\n";
+ m_os<<"\t\tint rest = tmp.decode(ctx);\n";
+ m_os<<"\t\tthis->get_value() = tmp.get_value();\n";
+ m_os<<"\t\treturn rest;\n";
+ m_os<<"\t}\n";
+ m_os<<"\treturn asn1::wrong_tag;\n";
+ m_os<<"}\n";
+ }
+ }
+ /**
+ * New way with codec ....
+ */
+ if (m_gencpp.with_codec())
+ {
+ std::string structName;
+ std::string ns = m_gencpp.get_module()->cpp_name();
+ structName = ns + "::" + m_boolean.identifier_cpp_name();
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ /* header template specialisation */
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void codecBER::encode(streams::ber &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int codecBER::decode(streams::ber &c,"<<structName<<" &_t);\n";
+ /* Implementation part */
+ cpp<<"// boolean generator"<<std::endl;
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecBER::encode(asn1::streams::ber &c,const "<<structName<<" &_t)\n{\n";
+ if (m_boolean.tagged()
+ && (m_gencpp.tag_mode(&m_boolean) == asn1::node::tag_type::TM_EXPLICIT))
+ {
+ // I should encode explicit tag here
+ cpp<<"\tasn1::tag t("<<m_boolean.tag().m_class<<","<<m_boolean.tag().m_value<<",true);\n";
+ cpp<<"\tstd::cerr<<\"encode explicit tagging for BER TODO\"<<std::endl;\n";
+ cpp<<"\tc.encode_boolean(_t);";
+ } else
+ cpp<<"\tc.encode_boolean(_t);";
+ cpp<<"}\n";
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecBER::decode(asn1::streams::ber &c,"<<structName<<" &_t)\n{\n";
+ cpp<<"\treturn c.decode_boolean(_t);\n";
+ cpp<<"}\n";
+ }
+}
+
+//
+void cgcpph_boolean::generate_oer()
+{
+ //
+ std::string ns = m_gencpp.get_module()->cpp_name();
+ std::string structName(ns + "::" + m_boolean.identifier_cpp_name());
+
+ if (m_gencpp.with_codec())
+ {
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void codecOER::encode(streams::oer &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int codecOER::decode(streams::oer &c,"<<structName<<" &_t);\n";
+
+ /* Implementation part */
+ cpp<<"// boolean generator"<<std::endl;
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecOER::encode(asn1::streams::oer &c,const "<<structName<<" &_t)\n{\n";
+ cpp<<"\tc.encode_boolean(_t);";
+ cpp<<"}\n";
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecOER::decode(asn1::streams::oer &c,"<<structName<<" &_t)\n{\n";
+ cpp<<"\treturn c.decode_boolean(_t);\n";
+ cpp<<"}\n";
+
+ }
+}
+
+//
+void cgcpph_boolean::generate_jer()
+{
+ std::string structName = m_gencpp.get_module()->cpp_name();
+ std::string ns = m_gencpp.get_module()->cpp_name();
+ structName = ns + "::" + m_boolean.identifier_cpp_name();
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+
+
+ if (m_gencpp.with_codec())
+ {
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void codecJER::encode(streams::jer &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int codecJER::decode(streams::jer &c,"<<structName<<" &_t);\n";
+
+ /* Implementation part */
+ cpp<<"// boolean generator"<<std::endl;
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecJER::encode(asn1::streams::jer &c,const "<<structName<<" &_t)\n{\n";
+ cpp<<"\tc.encode_boolean(_t);";
+ cpp<<"}\n";
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecJER::decode(asn1::streams::jer &c,"<<structName<<" &_t)\n{\n";
+ cpp<<"\treturn c.decode_boolean(_t);\n";
+ cpp<<"}\n";
+
+ }
+}
+
+//
+void cgcpph_boolean::generate_xer()
+{
+}
+
--- /dev/null
+#ifndef CGCPPH_BOOLEAN_H
+#define CGCPPH_BOOLEAN_H
+
+
+/**
+ *
+ */
+class cgcpph_boolean : public cgcpph_primitive
+{
+ protected:
+ cgcpph_boolean(const cgcpph_boolean &s) : cgcpph_primitive(s)
+ , m_boolean(s.m_boolean)
+ {}
+ public:
+ cgcpph_boolean(generate_codec_cpp &g,std::ostream &os,asn1::boolean &s) ;
+
+ ~cgcpph_boolean();
+
+ // Helper functions
+
+ // generate codec part
+ virtual void generate_per() ;
+ //
+ virtual void generate_ber() ;
+ //
+ virtual void generate_oer() ;
+ //
+ virtual void generate_jer() ;
+ //
+ virtual void generate_xer() ;
+ protected:
+ virtual void generate_ctors();
+ virtual void generate_operators();
+
+ void gen_equal();
+
+ virtual void generate_printf();
+ protected:
+ asn1::boolean &m_boolean;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_codec_cpp.h"
+#include "asn1_generator_helper.h"
+#include "cgcpp_helper.h"
+#include "asn1_visitor.h"
+#include "cgh_construct.h"
+#include "cgcpph_choice.h"
+
+
+cgcpph_choice::cgcpph_choice(generate_codec_cpp &g,std::ostream &os,asn1::choice &s)
+ : cgh_construct(g,os,s)
+ , m_choice(s)
+{
+}
+
+cgcpph_choice::~cgcpph_choice()
+{
+}
+
+
+/** Helper functions
+ *
+ * It seems that the choice does not always have an identifier. Examples
+ * - SEQUENCE OF CHOICE {}
+ * - Test ::= CHOICE { toto INTEGER, CHOICE { } }
+ * these sequences are anonymous definitions ...
+ */
+void cgcpph_choice::generate()
+{
+
+ GEN_LOG_DEBUG("cgcpph_choice::generate node=%s\n",m_choice.identifier_cpp_name().c_str());
+
+ // End generate private ...
+
+ cgcpp_helper::generate();
+
+ if (m_gencpp.with_codec())
+ gen_codec();
+ // Generate encoders and decoders
+}
+
+/**
+ *
+ */
+void cgcpph_choice::generate_descriptor()
+{
+ if (m_gencpp.with_source_comment())
+ m_os<<"// cgcpph_choice helper launched "<<m_structName<<std::endl;
+
+ gen_member_table();
+ gen_tag2el_table();
+
+ m_os<<"static asn1::types::descriptor CHOICE_"<<m_structName<<" = {\n";
+ m_os<<" NULL,0,";
+ m_os<<" MEMBER_"<<m_structName<<",\n";
+ m_os<<" "<<m_elcount<<",\n";
+ m_os<<" MAP_"<<m_structName<<"_tag2el,\n";
+ m_os<<" "<<m_t2elcount<<",\n";
+ m_os<<"};\n";
+ m_os<<std::endl;
+}
+/**
+ *
+ */
+void cgcpph_choice::generate_ctors()
+{
+ // Generate functions constructors and so on
+ gen_ctor( );
+
+ m_os<<std::endl;
+ gen_create_object( );
+
+ m_os<<std::endl;
+ gen_clone( );
+}
+/**
+ *
+ */
+void cgcpph_choice::generate_members()
+{
+ // Generate setters and getters, private and missing
+ // Loop over all attributes
+ for (asn1::node::iterator lit = m_choice.begin()
+ ; lit != m_choice.end()
+ ; ++lit)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*lit);
+ asn1::typenode *ft = f->get_type();
+
+ if (m_gencpp.with_source_comment())
+ {
+ m_os<<"//gen_choice preproc="<<f->cpp_name();
+ m_os<<" private="<<m_choice.is_private()<<std::endl;
+ }
+ if ( ft != NULL)
+ {
+ GEN_LOG_DEBUG("call gen_private_attribute for %s type=%s\n",
+ f->cpp_name().c_str()
+ , ft->name().c_str());
+ if (m_gencpp.with_source_comment())
+ m_os<<"// gen_choice call gen_private_attribute: "<<f->cpp_name()<<std::endl;
+
+ m_gencpp.gen_private_attribute( m_os
+ , std::string("")
+ , ft);
+
+ } else
+ {
+ m_os<<"// priv? extension "<<f->cpp_name()<<std::endl;
+ }
+ // May here
+ asn1::node *params = m_choice.act_parameters();
+
+ gen_attribute_setter( m_structName+"::"
+ , m_structName
+ , f
+ , params
+ , m_choice.is_private());
+ }
+}
+
+/**
+ *
+ */
+void cgcpph_choice::generate_operators()
+{
+ gen_equal(m_structName);
+}
+
+
+// Old codec function. Will probably be removed
+void cgcpph_choice::gen_codec( )
+{
+ std::string ns = m_gencpp.get_module()->cpp_name();
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ //m_gencpp.gen_template_signature(m_os,type);
+ hpp<<"\n// choice type "<<"::"<<m_structName<<"\n";
+ if (m_gencpp.with_jer())
+ {
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void codecJER::encode(streams::jer &c,const "<<ns<<"::"<<m_structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int codecJER::decode(streams::jer &c,"<<ns<<"::"<<m_structName<<" &_t);\n";
+ }
+
+
+}
+/**
+ *
+ * Choice code and decode
+ *
+ */
+void cgcpph_choice::gen_codec_decode(const std::string &scope)
+{
+ asn1::node *type = &m_choice;
+
+ asn1::node *n = type->identifier();
+
+ m_os<<"\t\tunsigned long pos = ctx.bytes();"<<std::endl;
+ m_os<<"\t\tunsigned char *b = ctx.buffer();"<<std::endl;
+
+ if (m_gencpp.with_source_debug())
+ {
+ m_os<<"\t\tASN1_BER_LOG_DEBUG(\"DECODE CHOICE start ";
+ m_os<<n->cpp_name()<<" tag = %02x \",(unsigned short)b[pos]);"<<std::endl;
+ }
+ m_os<<"\t\treturn decode(ctx);"<<std::endl;
+
+ // Now add an enum to identifie type
+ // m_os<<"\t\tASN1_BER_LOG_DEBUG(\"DECODE CHOICE END "<<n->cpp_name()<<" none selected tag = %02x WRONG\",(unsigned short)b[pos]);"<<std::endl;
+ m_os<<"\t\treturn asn1::wrong_tag;\n";
+}
+
+/**
+ *
+ */
+void cgcpph_choice::gen_codec_encode(const std::string &scope)
+{
+ asn1::node *type = &m_choice;
+
+ asn1::node *n = type->identifier();
+
+ if (n == NULL )
+ {
+ std::cerr<<"gen_choice_encode n == NULL"; return;
+ }
+
+ m_os<<"\t\tint _ret = asn1::ok;\n";
+ m_os<<"\t\tif (m_choice)\n";
+ m_os<<"\t\t{\n";
+ if (m_gencpp.with_source_debug())
+ {
+ m_os<<"\t\t\tASN1_BER_LOG_DEBUG(\""<<type->cpp_name();
+ m_os<<"::codec ENCODE tag=%d \",m_choice->tag().byte());\n";
+ }
+ m_os<<"\t\t\tencode(ctx);"<<std::endl;
+ m_os<<"\t\t}\n";
+ m_os<<"\t\treturn _ret;\n";
+
+}
+
+//
+void
+cgcpph_choice::gen_setter_ref( const std::string &scope
+ , const std::string &structName
+ , asn1::field *attribute
+ , asn1::typeref &tref
+ , asn1::node *params
+ , bool priv)
+{
+ asn1::node *rt = m_gencpp.resolver().resolve(tref);
+
+ if (tref.is_simple()
+ || (rt && rt->type_node())
+ )
+ {
+ m_os<<"// Reference"<<std::endl;
+ m_os<<"void "<<scope<<"set_"<<attribute->cpp_name()<<"(const ";
+ m_gencpp.gen_composite_attribute_ref(m_os,scope,attribute,params);
+ m_os<<" &s)\n{\n";
+ m_os<<"\tif (m_kind != typeof_"<<attribute->cpp_name()<<" )\n";
+ m_os<<"\t{\n";
+#if 1
+ asn1::node::tag_type o_tag = tref.otag(m_gencpp.resolver());
+ m_os<<"\t\tchoice_type::set_tag(asn1::tag(";
+ m_os<<o_tag.m_class<<","<<o_tag.m_value<<"));\n";
+#else
+ m_os<<"\t\t"<<"if (m_choice)\n\t\t\tdelete m_choice;\n";
+ m_os<<"\t\tm_kind = typeof_"<<attribute->cpp_name()<<";\n";
+ m_os<<"\t\tcreate_object();\n";
+#endif
+ m_os<<"\t}\n";
+
+ m_os<<"\tget_"<<attribute->cpp_name()<<"() = s;\n";
+ m_os<<"};\n"<<std::endl;
+ } else
+ {
+ m_os<<"// setter to DO set_"<<attribute->cpp_name()<<std::endl;
+ m_os<<"void "<<scope<<"set_"<<attribute->cpp_name()<<"(const ";
+ m_gencpp.gen_composite_attribute_ref(m_os,scope,attribute,params);
+ m_os<<" *s)\n{\n";
+ m_os<<"\tassert(0);\n";
+ m_os<<"};\n"<<std::endl;
+ }
+}
+
+//
+void
+cgcpph_choice::gen_getter_ref( const std::string &scope
+ , const std::string &structName
+ , asn1::field *attribute
+ , asn1::typeref &tref
+ , asn1::node *params
+ , bool priv)
+{
+ asn1::node *rt = m_gencpp.resolver().resolve(tref);
+ if (tref.is_simple()
+ || (rt && rt->type_node())
+ )
+ {
+ // getter
+ m_gencpp.gen_composite_attribute_ref( m_os
+ ,scope
+ ,attribute
+ ,params);
+ m_os<<" &"<<scope<<"get_"<<attribute->cpp_name()<<"()\n{\n";
+ // Debug Version
+ m_os<<"#ifdef DEBUG"<<std::endl;
+ if (m_gencpp.with_source_debug())
+ {
+ m_os<<"\tASN1_BER_LOG_DEBUG(\"get_"<<attribute->cpp_name();
+ m_os<<"(%p) "<<attribute->cpp_name()<<" k=%d tag=%ld\",this,m_kind,m_tag.get_tag());\n";
+ }
+ /**/
+ asn1::node::tag_type o_tag = tref.otag(m_gencpp.resolver());
+ m_os<<"\t"<<"if ( m_kind != typeof_"<<attribute->cpp_name()<<")\n\t{\n";
+ m_os<<"\t\t"<<"set_tag( asn1::tag(";
+ m_os<<o_tag.m_class<<","<<o_tag.m_value<<"));\n";
+ m_os<<"\t}\n";
+ /**/
+ m_os<<"\tassert(check_create());"<<std::endl;
+ m_os<<"\tassert(dynamic_cast<";
+ m_gencpp.gen_composite_attribute_ref(m_os,scope,attribute,params);
+ m_os<<" *>(m_choice) != NULL);"<<std::endl;
+ //os<<"\tif (m_kind == typeof_"<<attribute->cpp_name()<<") {\n";
+ m_os<<"\treturn dynamic_cast<";
+ m_gencpp.gen_composite_attribute_ref(m_os,scope,attribute,params);
+ m_os<<" &>(*m_choice);\n";
+ // Release Version
+ m_os<<"#else"<<std::endl;
+ m_os<<"\t"<<"if ( m_kind != typeof_"<<attribute->cpp_name()<<")\n";
+ m_os<<"\t\t"<<"set_tag( asn1::tag(";
+ m_os<<o_tag.m_class<<","<<o_tag.m_value<<"));\n";
+ m_os<<"\treturn dynamic_cast<";
+ m_gencpp.gen_composite_attribute_ref(m_os,scope,attribute,params);
+ m_os<<" &>(*m_choice);\n";
+ m_os<<"#endif"<<std::endl;
+ // m_os<<"/* TODO unfinished*/
+ m_os<<"}\n";
+ /* const getter */
+ m_os<<"const ";
+ m_gencpp.gen_composite_attribute_ref( m_os
+ ,scope
+ ,attribute
+ ,params);
+ m_os<<" &"<<scope<<"get_"<<attribute->cpp_name()<<"() const\n{\n";
+ m_os<<"\treturn dynamic_cast<const ";
+ m_gencpp.gen_composite_attribute_ref(m_os,scope,attribute,params);
+ m_os<<" &>(*m_choice);\n";
+ m_os<<"}\n";
+ } else
+ {
+ m_os<<"// getter to DO get_"<<attribute->cpp_name()<<std::endl;
+ m_gencpp.gen_composite_attribute_ref(m_os,scope,attribute,params);
+ m_os<<" *"<<scope<<"get_"<<attribute->cpp_name()<<"()\n{\n";
+ m_os<<"assert(0);\n";
+ //m_os<<"\t\treturn dynamic_cast<";
+ //m_gencpp.gen_composite_attribute_ref(m_os,scope,attribute,params);
+ //m_os<<" &>(*m_choice);\n";
+ m_os<<"}\n";
+ }
+}
+
+
+
+//
+void
+cgcpph_choice::gen_attribute_setter( const std::string &scope
+ , const std::string &structName
+ , asn1::field *attribute
+ , asn1::node *params
+ , bool priv)
+{
+ asn1::typenode *attr_type = attribute->get_type();
+
+ if (attr_type != NULL)
+ {
+ switch (attr_type->type_id()())
+ {
+ case asn1::type::ASN1_ENUMERATED:
+ case asn1::type::ASN1_CHOICE:
+ case asn1::type::ASN1_SET:
+ case asn1::type::ASN1_SEQUENCE:
+ {
+ m_os<<"//\nvoid "<<scope<<"set_"<<attribute->cpp_name();
+ m_os<<"(const "<<attribute->cpp_name()<<"_t";
+ m_os<<" &s)\n{\n\tm_kind = typeof_"<<attribute->cpp_name();
+ m_os<<";\n";
+ m_os<<"\tget_"<<attribute->cpp_name()<<"()=s;\n}\n\n"<<std::endl;
+ std::string strtype;
+
+ if (m_gencpp.type2cppstring(attr_type,strtype) )
+ {
+ m_os<<scope<<strtype<<" &"<<scope<<"get_"<<attribute->cpp_name()<<" ()\n{\n";
+ m_os<<"\tassert(check_create());\n";
+ m_os<<"\tif (m_kind == typeof_"<<attribute->cpp_name()<<")\n\t{\n";
+ m_os<<"\t\treturn static_cast<"<<strtype<<" &>(*m_choice);\n";
+ m_os<<"\t} else {\n";
+ m_os<<"\t\tif (m_choice)\n\t\t{\n";
+ m_os<<"\t\t\tdelete m_choice;\n\t\t\t m_choice = NULL;\n";
+ m_os<<"\t\t\tm_kind = typeof_"<<attribute->cpp_name()<<";\n";
+ m_os<<"\t\t\tcreate_object();\n";
+ m_os<<"\t\t\tassert( m_choice != NULL);\n";
+ m_os<<"\t\t}\n";
+ m_os<<"\t\treturn static_cast<"<<strtype<<" &>(*m_choice);\n";
+ m_os<<"\t}\n";
+ m_os<<"}\n";
+ }
+ }
+ break;
+ case asn1::type::ASN1_REFERENCE:
+ {
+ asn1::typeref *tref = dynamic_cast<asn1::typeref *>(attr_type);
+ gen_setter_ref(scope,structName,attribute,*tref,params,priv);
+ gen_getter_ref(scope,structName,attribute,*tref,params,priv);
+ }
+ break;
+ default:
+ {
+ std::string strtype;
+ if (m_gencpp.type2cppstring(attr_type,strtype,scope) )
+ {
+ m_os<<"//cgcpph_choice::"<<__FUNCTION__<<" default: "<<attribute->cpp_name()<<std::endl;
+ m_os<<"void "<<scope<<"set_"<<attribute->cpp_name()<<"(const ";
+ m_os<<strtype;
+ m_os<<" &s)\n {\n";
+ m_os<<"\tif (m_kind != typeof_"<<attribute->cpp_name()<<" )\n";
+ m_os<<"\t{";
+ if (attr_type->tagged())
+ { // Tagged value
+ asn1::node::tag_type tg = attr_type->tag();
+ m_os<<"\t\tset_tag(asn1::tag("<<tg.m_class<<","<<tg.m_value<<"));\n";
+ }
+ else
+ {
+ //assert(0 && "Attribute in choice should have a tag");
+ asn1::node::tag_type tg = attr_type->tag();
+ //std::cerr<<"attribute "<<attribute->cpp_name()<<" not tagged(0,"<<tg.m_value<<") !!!"<<std::endl;
+ m_os<<"\t\tset_tag(asn1::tag("<<tg.m_class<<","<<tg.m_value<<"));\n";
+ }
+ m_os<<"\t\t"<<"if (m_choice) {\n\t\t\tdelete m_choice;\n";
+ m_os<<"\t\t\tm_choice = NULL;\n\t\t}"<<std::endl;
+ m_os<<"\t\tm_kind = typeof_"<<attribute->cpp_name()<<";\n";
+ m_os<<"\t\tcreate_object();\n";
+ m_os<<"\t}\n";
+ //os<<"\t"<<attribute->cpp_name()<<"\t=\ts;\n";
+ m_os<<"\tget_"<<attribute->cpp_name()<<"() = s;\n";
+ m_os<<"}\n"<<std::endl;
+ // get function
+ m_os<<strtype<<" &"<<scope<<"get_"<<attribute->cpp_name()<<" ()\n{\n";
+ m_os<<"\tif (m_kind != typeof_"<<attribute->cpp_name()<<" )\n";
+ m_os<<"\t{";
+ if (attr_type->tagged())
+ { // Tagged value
+ asn1::node::tag_type tg = attr_type->tag();
+ m_os<<"\t\tset_tag(asn1::tag("<<tg.m_class<<","<<tg.m_value<<"));\n";
+ }
+ else
+ {
+ //assert(0 && "Attribute in choice should have a tag");
+ asn1::node::tag_type tg = attr_type->tag();
+ std::cerr<<"attribute "<<attribute->cpp_name()<<" not tagged(0,"<<tg.m_value<<") !!!"<<std::endl;
+ m_os<<"\t\tset_tag(asn1::tag("<<tg.m_class<<","<<tg.m_value<<"));\n";
+ }
+ m_os<<"\t}\n";
+ m_os<<"\tassert(check_create());"<<std::endl;
+ m_os<<"\tif (m_kind == typeof_"<<attribute->cpp_name()<<")\n\t{\n";
+ m_os<<"\t\treturn static_cast<"<<strtype<<" &>(*m_choice);\n";
+ m_os<<"\t} else\n\t{\n";
+ m_os<<"\t\tif (m_choice)\n";
+ m_os<<"\t\t{\n";
+ m_os<<"\t\t\tdelete m_choice;\n";
+ m_os<<"\t\t\tm_choice = NULL;\n";
+ m_os<<"\t\t\tm_kind = typeof_";
+ m_os<<attribute->cpp_name()<<"; create_object() ;\n";
+ m_os<<"\t\t}\n";
+ m_os<<"\t\treturn static_cast<"<<strtype<<" &>(*m_choice);\n";
+ m_os<<"\t}\n";
+ m_os<<"}\n";
+ /* const*/
+ m_os<<"const "<<strtype<<" &"<<scope<<"get_"<<attribute->cpp_name()<<" () const\n{\n";
+ m_os<<"\treturn dynamic_cast<const "<<strtype<<" &>(*m_choice);\n";
+ m_os<<"}\n";
+ }
+ }
+ break;
+ }
+ } else
+ {
+ GEN_LOG_ERROR("attr_type is NULL\n");
+ }
+
+}
+
+// Helper function to replace :: with _ in scope
+static
+char lop_substitute(char c)
+{
+ return (c == ':')?'_':c;
+}
+
+//
+void cgcpph_choice::generate_printf()
+{
+ asn1::node::iterator lit;
+ asn1::node *ident = m_choice.identifier();
+
+
+ // FIND ANOTHER NAME FOR THAT DEFINE ASN1_WITH_PRINTF
+ m_os<<"#if 1\n";
+ // ostream function
+ m_os<<"std::ostream &operator <<(std::ostream &os,const "<<m_structName;
+
+ if (ident->parameters() && m_gencpp.is_template(ident->parameters()))
+ {
+ m_gencpp.gen_template_params(m_os,ident->parameters());
+ }
+ m_os<<" &s)\n";
+
+ m_os<<"{\n";
+ // Ok, Now, deal with the attributes and so on
+ //
+ //os<<"\tif (s.m_choice != NULL)"<<std::endl;
+ m_os<<"\ts.printf(os);"<<std::endl;
+ m_os<<"\treturn os;\n";
+ m_os<<"}\n";
+ m_os<<"#endif\n";
+}
+
+// generate codec part
+void cgcpph_choice::generate_per()
+{
+}
+
+//
+void cgcpph_choice::generate_ber()
+{
+ std::string ns = m_gencpp.get_module()->cpp_name();
+ std::string structName( ns + "::" + m_choice.identifier_cpp_name() );
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ bool priv = m_choice.is_private();
+
+ // Generator for encode en decode wrong place
+ gen_ber_encode("",m_choice.identifier_cpp_name(),priv);
+ gen_ber_decode("",m_choice.identifier_cpp_name(),priv)
+ ;
+ if (m_gencpp.with_codec())
+ {
+ //m_gencpp.gen_template_signature(m_os,type);
+ hpp<<"\n// choice type "<<structName<<"\n";
+ hpp<<"template<>\n";
+ hpp<<"void asn1::codecBER::encode(asn1::streams::ber &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int asn1::codecBER::decode(asn1::streams::ber &c,"<<structName<<" &_t);\n";
+ /**
+ * Implementation part codec encode
+ */
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void asn1::codecBER::encode(asn1::streams::ber &c,const "<<structName<<" &_t)\n{\n";
+ if (m_gencpp.with_source_debug())
+ {
+ }
+ cpp<<"}\n";
+ /**
+ * Implementation part codec decode
+ */
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int asn1::codecBER::decode(asn1::streams::ber &c,"<<structName<<" &_t)\n{\n";
+ cpp<<"\tasn1::tag t(0,0);\n";
+ cpp<<"\tunsigned long m_pos = c.bytes();\n";
+ cpp<<"\tint len = 0;\n";
+ cpp<<"\tif (c.decode_tag(t,len) )\n";
+ cpp<<"\t{\n";
+ cpp<<"\t\t_t.set_tag(t);\n";
+ cpp<<"\t\tif (_t.check_create())\n";
+ cpp<<"\t\t{\n";
+ // What do I do here
+ cpp<<"\t\t\tswitch (_t.m_kind)\n\t\t\t{\n";
+ for (asn1::node::iterator it = m_choice.begin(); it != m_choice.end() ; it++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*it);
+ asn1::typenode *attr_type = f->get_type();
+ if (attr_type != NULL)
+ {
+ if (attr_type->type_id()() == asn1::type::ASN1_EXTENSIBLE)
+ {
+ cpp<<"\t// Extensible marker"<<std::endl;
+ } else
+ {
+ cpp<<"\t\t\tcase "<<structName<<"::typeof_"<<f->cpp_name()<<": ";
+ cpp<<"return decode(c,_t.get_"<<f->cpp_name()<<"());\n";
+ }
+ }
+ }
+ cpp<<"\t\t\t}\n";
+ cpp<<"\t\t}\n";
+ cpp<<"\t}\n";
+ cpp<<"\treturn asn1::ok;\n";
+ cpp<<"}\n";
+ }
+//
+ if (m_choice.tagged())
+ {
+ if ( m_gencpp.is_tag_explicit(m_choice) )
+ {
+ }
+ }
+}
+
+/**
+ *
+ *
+ */
+void cgcpph_choice::gen_ctor( )
+{
+ asn1::node *type = &m_choice;
+ // Constructor
+ //
+ m_os<<""<<m_structName<<"::"<<m_structName;
+ m_os<<"(unsigned int k,const asn1::tag t)\n\t\t: asn1::types::";
+ m_os<<"choice_type(k,t,&CHOICE_"<<m_structName<<")\n{\n";
+ if (m_gencpp.with_source_debug())
+ {
+ m_os<<"\tASN1_BER_LOG_DEBUG(\""<<type->identifier_name();
+ m_os<<"(%p) choice:: 1 "<<type->identifier_name()<<" k=%d tag=%ld\",this,k,t.get_tag());\n";
+ }
+ m_os<<"\tset_tag(t);\n";
+ m_os<<"}\n";
+
+ // New constructor without k
+ m_os<<""<<m_structName<<"::"<<m_structName;
+ m_os<<"(const asn1::tag &t)\n\t\t: asn1::types::choice_type(t.get_tag(),t";
+ m_os<<",&CHOICE_"<<m_structName<<")\n{\n";
+ if (m_gencpp.with_source_debug())
+ {
+ m_os<<"\tASN1_BER_LOG_DEBUG(\""<<type->identifier_name();
+ m_os<<"(%p) choice:: 2 "<<type->identifier_name()<<" m_choice=%p tag=%ld\",this,m_choice,t.get_tag());\n";
+ }
+ m_os<<"\tset_tag(t);\n";
+ m_os<<"}\n";
+
+ // Needed for clone
+ m_os<<""<<m_structName<<"::"<<m_structName<<"(const "<<m_structName;
+ m_os<<" &s)\n\t\t: asn1::types::choice_type(s) \n{\n";
+ if (m_gencpp.with_source_debug())
+ {
+ m_os<<"\tASN1_BER_LOG_DEBUG(\""<<type->identifier_name();
+ m_os<<"(%p) copy ctor "<<type->identifier_name()<<" s.m_kind=%d s.tag=%ld\",this,s.m_kind,s.m_tag.get_tag());\n";
+ }
+ m_os<<"}\n";
+ // destructor
+}
+//
+void
+cgcpph_choice::gen_clone( )
+{
+ asn1::node *ident = m_choice.identifier();
+ asn1::constructed *params = NULL;
+
+ if (ident != NULL)
+ {
+ params = ident->parameters();
+ }
+
+ m_os<<m_structName;;
+ if (params && m_gencpp.is_template(params))
+ {
+ m_gencpp.gen_template_params(m_os,params);
+ }
+ m_os<<"* "<<m_structName;
+ if (params && m_gencpp.is_template(params))
+ {
+ m_gencpp.gen_template_params(m_os,params);
+ }
+ m_os<<"::clone()\n";
+ m_os<<"{\n";
+
+ if (m_gencpp.with_source_debug())
+ {
+ m_os<<"\t\tASN1_BER_LOG_DEBUG(\""<<m_choice.identifier_name();
+ m_os<<"::clone "<<m_choice.identifier_name()<<" \");\n";
+ }
+ m_os<<"\treturn new "<<m_structName;
+ if (params && m_gencpp.is_template(params))
+ {
+ m_gencpp.gen_template_params(m_os,params);
+ }
+ m_os<<"(*this);\n}\n"<<std::endl;
+}
+
+//
+void
+cgcpph_choice::gen_equal( const std::string &structName)
+{
+ std::string lscope;
+ asn1::choice *type = &m_choice;
+ asn1::node::iterator lit = m_choice.begin();
+ //
+
+ lscope = structName;
+ m_os<<"bool "<<structName<<"::"<<"operator ==";
+ m_os<<"("<<structName<<" &o) \n{\n";
+ m_os<<"\tif (m_kind == o.m_kind)\n";
+ m_os<<"\t{\n";
+ //m_os<<"\t\treturn m_choice->equal(*(o.m_choice));\n";
+ /**
+ * Handle choices for down casting ...
+ */
+ m_os<<"\t\tswitch (m_kind)\n";
+ m_os<<"\t\t{\n";
+ for (; lit != (type)->end() ; lit++)
+ {
+ std::string strtype;
+ asn1::field *field = dynamic_cast<asn1::field *>(*lit);
+ asn1::typenode *attribute_type = field->get_type();
+ if (attribute_type == NULL)
+ continue;
+ asn1::type type_id = attribute_type->type_id();
+
+ if (type_id() == asn1::type::ASN1_EXTENSIBLE)
+ {
+ m_os<<"\t\t// Extensible marker"<<std::endl;
+ } else
+ {
+ m_os<<"\t\tcase typeof_"<<field->cpp_name()<<":\n";
+ m_os<<"\t\t\treturn get_"<<field->cpp_name()<<"() ==";
+ m_os<<" o.get_"<<field->cpp_name()<<"();\n";
+ }
+ }
+ m_os<<"\t\tdefault: return false;\n;";
+ m_os<<"\t\t}\n"; /* End switch */
+
+ m_os<<"\t}\n";
+ m_os<<"\treturn false;\n";
+ m_os<<"}\n\n";
+}
+//
+
+//
+void cgcpph_choice::gen_ber_encode( const std::string &scope
+ , const std::string &structName
+ , bool priv)
+{
+ std::string lscope;
+ asn1::node *type = &m_choice;
+ if ( m_gencpp.with_ber()
+ && type->tagged()
+ && m_gencpp.is_tag_explicit(m_choice) )
+ {
+ lscope = scope + structName;
+
+ m_os<<"void "<<scope<<""<<structName<<"::";
+ m_os<<"encode_ber(asn1::streams::ber &ctx)\n{"<<std::endl;
+ m_os<<"\tunsigned long m_pos = ctx.bytes();"<<std::endl;
+ m_os<<"\tunsigned char *m_buffer = ctx.buffer();"<<std::endl;
+ // This is not good at all
+ m_os<<"\tm_buffer[m_pos++] = MAKE_TAG(";
+ m_os<<type->tag().m_class<<",1,"<<type->tag().m_value<<");"<<std::endl;
+ m_os<<"\tctx.nb_bits(16);"<<std::endl;
+ m_os<<"\tif (m_choice)"<<std::endl;
+ m_os<<"\t\tm_choice->encode(ctx);"<<std::endl;
+ m_os<<"\tif (ctx.bytes() - m_pos > 127)"<<std::endl;
+ m_os<<"\t\tASN1_BER_LOG_ERROR(\""<<lscope<<"::encode_ber too long\");"<<std::endl;
+ m_os<<"\tm_buffer[m_pos] = ctx.bytes() - m_pos-1;"<<std::endl;
+ m_os<<"\n}\n"<<std::endl;
+ }
+}
+
+//
+void
+cgcpph_choice::gen_ber_decode( const std::string &scope
+ , const std::string &structName
+ , bool priv)
+{
+ std::string lscope;
+ asn1::node *type = &m_choice;
+
+ if ( m_gencpp.with_ber()
+ && type->tagged()
+ && m_gencpp.is_tag_explicit(m_choice) )
+ {
+ lscope = scope + structName;
+ // decode
+ m_os<<"int "<<scope<<""<<structName<<"::";
+ m_os<<"decode_ber(asn1::streams::ber &ctx)\n{\n"<<std::endl;
+ m_os<<"\tunsigned char *m_buffer = ctx.buffer();"<<std::endl;
+ m_os<<"\tint len = 0;"<<std::endl;
+ if (m_gencpp.with_source_debug())
+ m_os<<"\tASN1_BER_LOG_DEBUG(\""<<lscope<<"::decode_ber \");\n";
+ //m_os<<"\tassert(0);\n";
+ m_os<<"\tif (ctx.decode_header( asn1::tag("<<type->tag().m_class<<",";
+ m_os<<type->tag().m_value<<",true),len) ) {"<<std::endl;
+ m_os<<"\t\tasn1::tag t(0,0);"<<std::endl;
+ m_os<<"\tunsigned long m_pos = ctx.bytes();"<<std::endl;
+ // Decode Header,
+ m_os<<"\t\tif (ctx.decode_tag(t,len) ) {"<<std::endl;
+ m_os<<"\t\t\tctx.bytes(m_pos);"<<std::endl;
+ m_os<<"\t\t\tset_tag(t);"<<std::endl;
+ m_os<<"\t\t\tif (check_create()) "<<std::endl;
+ m_os<<"\t\t\t\treturn m_choice->decode(ctx);"<<std::endl;
+ m_os<<"\t\t}"<<std::endl;
+ // Check and create
+ // if ok, call decode
+ m_os<<"\t}\n"<<std::endl;
+ m_os<<"\treturn asn1::unknown;"<<std::endl;
+ m_os<<"\n}\n"<<std::endl;
+
+ }
+}
+
+/**
+ *
+ */
+void cgcpph_choice::generate_oer()
+{
+ std::string MName = m_gencpp.get_module()->cpp_name();
+ std::string structName = MName + "::" + m_choice.identifier()->cpp_name();
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ // TODO
+ if (m_gencpp.with_codec())
+ {
+ std::string ns = m_gencpp.get_module()->cpp_name();
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ //m_gencpp.gen_template_signature(m_os,type);
+ hpp<<"\n// choice type "<<structName<<"\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void codecOER::encode(streams::oer &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int codecOER::decode(streams::oer &c,"<<structName<<" &_t);\n";
+ }
+}
+
+/**
+ *
+ */
+void cgcpph_choice::generate_jer()
+{
+ std::string MName = m_gencpp.get_module()->cpp_name();
+ std::string structName = MName + "::" + m_choice.identifier()->cpp_name();
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+
+ if (m_gencpp.with_codec())
+ {
+ std::string ns = m_gencpp.get_module()->cpp_name();
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ //m_gencpp.gen_template_signature(m_os,type);
+ hpp<<"\n// choice type "<<structName<<"\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void codecJER::encode(streams::jer &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int codecJER::decode(streams::jer &c,"<<structName<<" &_t);\n";
+
+ /** Implementation for encoder */
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void asn1::codecJER::encode(asn1::streams::jer &c,const "<<structName<<" &_t)\n{\n";
+ cpp<<"\tc.put_char(\"{\",1);\n";
+ /* get should have the const version ! */
+ cpp<<"\tswitch (_t.get_kind())\n\t{\n";
+ for (asn1::node::iterator it = m_choice.begin(); it != m_choice.end() ; it++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*it);
+ asn1::typenode *attr_type = f->get_type();
+ if (attr_type != NULL)
+ {
+ if (attr_type->type_id()() == asn1::type::ASN1_EXTENSIBLE)
+ {
+ cpp<<"\t// Extensible marker"<<std::endl;
+ } else
+ {
+ cpp<<"\t\tcase "<<structName<<"::typeof_"<<f->cpp_name()<<":\n";
+ cpp<<"\t\t{\n";
+ cpp<<"\t\t\tc.put_char(\"\\\"\",1);\n";
+ cpp<<"\t\t\tc.put_char(_t.get_member()->m_name,"<<f->cpp_name().size()<<");\n";
+ cpp<<"\t\t\tc.put_char(\"\\\": \",3);\n";
+ cpp<<"\t\t\tencode(c,_t.get_"<<f->cpp_name()<<"());\n";
+ cpp<<"\t\t\tbreak;\n";
+ cpp<<"\t\t}\n";
+ }
+ }
+ }
+ cpp<<"\t\tdefault: ;\n";
+ cpp<<"\t}\n";
+ cpp<<"\tc.put_char(\"}\",1);\n";
+ cpp<<"}\n";
+
+ /** Implementation for decoder */
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int asn1::codecJER::decode(asn1::streams::jer &c,"<<structName<<" &_t)\n{\n";
+ cpp<<"std::string field;\n";
+ cpp<<"\tif (!c.get_token(asn1::streams::jer::jer_tok_left_bracket))\n";
+ cpp<<"\t\treturn asn1::wrong_type;\n";
+ cpp<<"\tif ( c.get_token(field))\n\t{\n";
+ cpp<<"\t\tif (!c.get_token(asn1::streams::jer::jer_tok_colon))\n\t\treturn asn1::wrong_type;\n";
+ for (asn1::node::iterator it = m_choice.begin(); it != m_choice.end() ; it++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*it);
+ asn1::typenode *attr_type = f->get_type();
+ if (attr_type != NULL)
+ {
+ if (attr_type->type_id()() == asn1::type::ASN1_EXTENSIBLE)
+ {
+ cpp<<"\t// Extensible marker"<<std::endl;
+ } else
+ {
+ cpp<<"\t\tif (! field.compare(\""<<f->cpp_name()<<"\"))\n";
+ cpp<<"\t\t{\n";
+ cpp<<"\t\t\tdecode(c,_t.get_"<<f->cpp_name()<<"());\n";
+ cpp<<"\t\t\tgoto choice_end;\n";
+ cpp<<"\t\t}\n";
+ }
+ }
+ }
+ cpp<<"\t}\n";
+ cpp<<"choice_end:\n";
+ cpp<<"\tif (!c.get_token(asn1::streams::jer::jer_tok_right_bracket))\n";
+ cpp<<"\t\treturn asn1::wrong_type;\n";
+ cpp<<"\treturn asn1::ok;\n";
+ cpp<<"}\n";
+ }
+
+}
+
+//
+void cgcpph_choice::generate_xer()
+{
+}
+
+/**
+ * Helper class to generate parameter
+ * initialization per attribute.
+ */
+class gco_actp : public node_visitor<gco_actp>
+{
+ public:
+ gco_actp(std::ostream &_os,generate_codec_cpp &_g,asn1::choice &_c)
+ : m_os(_os) , m_log(_g.logger()), m_gencpp(_g), m_choice(_c)
+ {
+ m_assign = m_choice.identifier()->as_assignment();
+ assert( (m_assign != NULL ) && " m_assign should not be NULL for choice type");
+ }
+
+
+ void visit_valueset(asn1::valueset *v)
+ {
+ long pos;
+ asn1::typeref *g = NULL; // governor
+ m_os<<"\t\t// Ok "<<__FUNCTION__<<" todo ";
+ if (asn1::typeref *tref = v->get_typeref())
+ {
+ m_os<<tref->name()<<" ";
+ if (asn1::parameter *p = m_assign->have_parameter(tref,pos) )
+ {
+ if (asn1::node *gov = p->get_governor())
+ g = dynamic_cast<asn1::typeref *>(gov);
+ m_os<<" yes have parameter "<<pos<<" ... "<<p->name()<<"\n";
+ // If gorvernor is not simple,
+ if ( g && (! g->is_simple()))
+ {
+ asn1::parameters &cparams = *m_rt->identifier()->parameters()->as_parameters();
+ m_os<<"\t\tinstance."<<cparams[pos]->name()<<" = "<<p->name()<<";\n";
+ }
+ }
+ }
+ m_os<<std::endl;
+ }
+ void visit_objectset(asn1::objectset *v)
+ {
+ m_os<<"\t// Ok "<<__FUNCTION__<<" todo"<<std::endl;
+ }
+ void visit_reference(asn1::reference *v)
+ {
+ m_os<<"\t// Ok "<<__FUNCTION__<<" todo"<<std::endl;
+ }
+ void do_act_parameters(asn1::node *_type,asn1::node *rt)
+ {
+ m_rt = rt;
+ if ( ! _type)
+ return;
+ asn1::constructed *aplist = _type->act_parameters();
+ if ( ! aplist)
+ return;
+ for ( asn1::node::iterator it = aplist->begin() ;
+ it != aplist->end(); ++it)
+ {
+ /* either value_set, object_set value, typeref */
+ if ((*it))
+ visit((*it));
+ }
+ }
+ protected:
+ asn1::node *m_rt;
+ asn1::assignment *m_assign;
+ std::fstream &m_log;
+ std::ostream &m_os;
+ generate_codec_cpp &m_gencpp;
+ asn1::choice &m_choice;
+};
+
+void cgcpph_choice::gen_create_object( )
+{
+ std::string scope(""); // Needs to be removed in the futur
+ // There is a possibility to optimize here. count the types ....
+ asn1::choice *type = &m_choice;
+ asn1::node *ident = m_choice.identifier();
+ asn1::node::iterator lit;
+ std::list<asn1::node *> choice_nodes;
+
+ asn1::node *params = ident->parameters();
+
+ m_os<<"bool "<<m_structName<<"::create_object()\n{\n";
+ // Ok, Now, deal with the attributes and so on
+ //
+ if (m_gencpp.with_source_debug())
+ {
+ m_os<<"\tASN1_BER_LOG_DEBUG(\""<<m_structName;
+ m_os<<"::create_object m_kind=%d tag=%ld\",m_kind,tag().get_tag());"<<std::endl;
+ }
+ m_os<<"\tswitch (m_kind )\n\t{\n";
+ lit = type->begin();
+ for (; lit != type->end() ; lit++)
+ {
+ std::string strtype;
+ asn1::field *f = dynamic_cast<asn1::field *>(*lit);
+ asn1::typenode *attr_type = f->get_type();
+ if (attr_type == NULL)
+ continue;
+ asn1::type type_id = attr_type->type_id();
+ std::list<asn1::node *> refs;
+
+ m_gencpp.reference_chaine(attr_type->as_typeref(),refs);
+
+ if (type_id() == asn1::type::ASN1_EXTENSIBLE)
+ {
+ m_os<<"\t\t// Extensible marker"<<std::endl;
+ } else if (type_id() == asn1::type::ASN1_CHOICE )
+ {
+ // In case of Choice
+ choice_nodes.push_back(f);
+ } else if ( (refs.size() > 0)
+ && ! (refs.back()->tagged() )
+ && attr_type
+ && (!attr_type->tagged() )
+ && (refs.back()->tag().m_value < 0)
+ && (type_id() == asn1::type::ASN1_REFERENCE) )
+ {
+ choice_nodes.push_back(f);
+ } else
+ {
+ asn1::node::tag_type tg ;
+ m_os<<"\tcase "<<m_structName<<"::typeof_"<<f->cpp_name()<<":\n";
+
+ // In ber mode, also check tag (for CSTA ...)
+ if (m_gencpp.with_ber() && attr_type->tagged() )
+ {
+ tg = attr_type->tag();
+ m_os<<"\tif ( tag() == MAKE_LONG_TAG(";
+ m_os<<tg.m_class<<",0,"<<tg.m_value<<"))"<<std::endl;
+ m_os<<"\t{"<<std::endl;
+ } else
+ {
+ m_os<<"\t// with_ber()="<<m_gencpp.with_ber();
+ m_os<<" tagged ="<<attr_type->tagged()<<std::endl;
+ if ((refs.size() > 0) && refs.back() != NULL)
+ {
+ if (refs.back()->tag().m_value >= 0)
+ {
+ tg = refs.back()->tag();
+ m_os<<"\tif ( tag() == MAKE_LONG_TAG(";
+ m_os<<tg.m_class<<",0,"<<tg.m_value<<")) /*ref tag*/"<<std::endl;
+ m_os<<"\t{"<<std::endl;
+ }
+ }
+
+ }
+ // Handle tag stuff
+ if (attr_type->tagged())
+ {
+ asn1::node::tag_type tg = attr_type->tag();
+ m_os<<"\t\t";
+ if (attr_type->type_id()() == asn1::type::ASN1_REFERENCE)
+ {
+ asn1::typeref *tref = dynamic_cast<asn1::typeref *>(attr_type);
+ asn1::node *rt = m_gencpp.resolver().resolve(*tref);
+ if (tref->is_simple()
+ || (rt && rt->type_node()))
+ {
+ m_gencpp.gen_composite_attribute_ref(m_os,scope,f,params);
+ m_os<<" instance( asn1::tag(";
+ m_os<<tg.m_class<<","<<tg.m_value<<")";
+ m_os<<") ;\n";
+ // Process actual parameters ....
+ gco_actp gen_actual_param_init(m_os,m_gencpp,m_choice);
+ gen_actual_param_init.do_act_parameters(attr_type,rt);
+ m_os<<"\t\tm_choice = instance.clone();\n";
+ } else
+ {
+ m_os<<"\t\tm_choice = NULL;\n";
+ }
+ }
+ else if (m_gencpp.type2cppstring(attr_type,strtype) )
+ {
+ if (m_gencpp.is_tag_explicit(*attr_type) )
+ {
+ m_os<<"\tm_choice = new "<<strtype<<"(); /* Explicit tagged*/\n";
+ } else
+ {
+ m_os<<strtype;
+ m_os<<" instance( asn1::tag(";
+ m_os<<tg.m_class<<","<<tg.m_value<<")";
+ m_os<<") ;\n";
+ m_os<<"\t\tm_choice = instance.clone();\n";
+ }
+
+ } else
+ {
+ m_os<<attr_type->cpp_name();
+ m_os<<" instance( asn1::tag(";
+ m_os<<tg.m_class<<","<<tg.m_value<<")";
+ m_os<<") ;\n";
+ m_os<<"\t\tm_choice = instance.clone();\n";
+ }
+ } else
+ {
+ m_os<<"\t\tm_choice = new ";
+ if (m_gencpp.type2cppstring(attr_type,strtype) )
+ {
+ m_os<<strtype<<"(); /*untg 1*/\n";
+ } else
+ m_os<<attr_type->cpp_name()<<"(); /*untg 2*/\n";
+ }
+ m_os<<"\t\treturn true; \n";
+ // In ber mode, also check tag (for CSTA ...)
+ if (m_gencpp.with_ber() && attr_type->tagged() )
+ {
+ asn1::node::tag_type tg = attr_type->tag();
+ m_os<<"\t} else {"<<std::endl;
+ //os<<"\treturn false;"<<std::endl;
+ m_os<<"\t\tASN1_BER_LOG_ERROR(\"create_object ";
+ m_os<<type->identifier_name()<<" tag=%ld expected ";
+ m_os<<tg.m_value<<" FAILED \",tag().get_tag());\n";
+ m_os<<"\t}"<<std::endl;
+ } else
+ {
+ std::list<asn1::node *>lst;
+ m_gencpp.reference_chaine(attr_type->as_typeref(),lst);
+
+ if ((lst.size() > 0) && lst.back() != NULL)
+ {
+ if (lst.back()->tag().m_value >= 0)
+ {
+ asn1::node::tag_type tg = lst.back()->tag();
+ m_os<<"\t}"<<std::endl;
+ }
+ }
+ }
+ m_os<<"\t\tbreak;\n";
+ }
+ refs.erase(refs.begin(),refs.end());
+ } /* End for attributes */
+
+ m_os<<"\tdefault:\n\t;\n";
+ m_os<<"\t}\n";
+ // Alright handle inner choices
+ for (lit = choice_nodes.begin() ; lit != choice_nodes.end(); ++lit)
+ {
+ std::string strtype;
+ asn1::field *f = dynamic_cast<asn1::field *>(*lit);
+ asn1::typenode *attribute_type = f->get_type();
+ m_os<<"\tm_choice = new ";
+ if (m_gencpp.type2cppstring(attribute_type,strtype) )
+ {
+ m_os<<strtype<<"(m_tag.get_tag(),m_tag);\n";
+ } else
+ m_os<<attribute_type->cpp_name()<<"(m_tag.get_tag(),m_tag);\n";
+
+ m_os<<"\tif (static_cast<asn1::types::choice_type *>(m_choice)->create_object())\n";
+ m_os<<"\t{"<<std::endl;
+ m_os<<"\t\tm_kind = typeof_"<<f->cpp_name()<<";\n";
+ m_os<<"\t\treturn true;"<<std::endl;
+ m_os<<"\t}"<<std::endl;
+ m_os<<"\tdelete m_choice;\n\tm_choice = NULL;"<<std::endl;
+ } /* End second for */
+
+ m_os<<"\tASN1_BER_LOG_ERROR(\""<<m_structName;
+ m_os<<"::create_object failed m_kind=%d tag=%ld\",m_kind,tag().get_tag());"<<std::endl;
+ m_os<<"\treturn false;\n";
+ m_os<<"}\n";
+}
+
+/*
+ * vim: et sw=2 ts=2 list:
+ */
--- /dev/null
+#ifndef CGCPPH_CHOICE_H
+#define CGCPPH_CHOICE_H
+
+
+/**
+ *
+ */
+class cgcpph_choice : public cgh_construct
+{
+ protected:
+ cgcpph_choice(const cgcpph_choice &s) :
+ cgh_construct(s.m_gencpp,s.m_os,s.m_choice)
+ , m_choice(s.m_choice)
+ {}
+ public:
+ cgcpph_choice(generate_codec_cpp &g,std::ostream &os,asn1::choice &s) ;
+
+ ~cgcpph_choice();
+
+ // Helper functions
+ virtual void generate() ;
+
+ // generate codec part
+ virtual void generate_per() ;
+ //
+ virtual void generate_ber() ;
+ //
+ virtual void generate_oer() ;
+ //
+ virtual void generate_jer() ;
+ //
+ virtual void generate_xer() ;
+ protected:
+ // Generate descriptor code
+ //
+ virtual void generate_descriptor();
+ // generator entry points
+ virtual void generate_ctors();
+
+ virtual void generate_members();
+
+
+ virtual void generate_operators();
+ //
+ virtual void generate_printf();
+ protected:
+ //
+ void gen_ctor( );
+ //
+ void gen_create_object( );
+ //
+ void
+ gen_ber_encode( const std::string &scope
+ , const std::string &structName
+ , bool priv);
+ void
+ gen_ber_decode( const std::string &scope
+ , const std::string &structName
+ , bool priv);
+ //
+ void gen_attribute_setter( const std::string &scope
+ , const std::string &structName
+ , asn1::field *attribute
+ , asn1::node *params
+ , bool priv);
+ //
+ void gen_setter_ref( const std::string &scope
+ , const std::string &structName
+ , asn1::field *attribute
+ , asn1::typeref &tref
+ , asn1::node *params
+ , bool priv);
+ //
+ void gen_getter_ref( const std::string &scope
+ , const std::string &structName
+ , asn1::field *attribute
+ , asn1::typeref &tref
+ , asn1::node *params
+ , bool priv);
+
+
+ //
+ void gen_codec( );
+ //
+ void gen_clone( );
+ //
+ void gen_equal( const std::string &structName );
+ //
+ //
+ //
+ void gen_codec_decode(const std::string &scope);
+ //
+ void gen_codec_encode(const std::string &scope);
+ // loop over the attributes of SEQUENCE or CHOICE
+ // and check if there are some type of SEQUENCE or CHOICE
+ // launch generation for these types first.
+ protected:
+ asn1::choice &m_choice;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_codec_cpp.h"
+#include "asn1_generator_helper.h"
+#include "cgcpp_helper.h"
+#include "cgh_construct.h"
+#include "cgcpph_enumerated.h"
+
+static
+char lop_substitute(char c)
+{
+ return (c == ':')?'_':c;
+}
+
+
+cgcpph_enumerated::cgcpph_enumerated(generate_codec_cpp &g,std::ostream &os,asn1::enumerated &s)
+ : cgh_construct(g,os,s) , m_enumerated(s)
+{
+}
+
+cgcpph_enumerated::~cgcpph_enumerated()
+{
+}
+
+
+/** Helper functions
+ *
+ * It seems that the choice does not always have an identifier. Examples
+ * - SEQUENCE OF CHOICE {}
+ * - Test ::= CHOICE { toto INTEGER, CHOICE { } }
+ * these sequences are anonymous definitions ...
+ */
+void cgcpph_enumerated::generate(const std::string &scope)
+{
+ asn1::node *ident = m_enumerated.identifier();
+
+ if (m_gencpp.with_source_comment())
+ m_os<<"//\n// cgcpph_enumerated helper launched\n//"<<std::endl;
+
+ cgcpp_helper::generate();
+}
+
+//
+//
+void
+cgcpph_enumerated::generate_ctors()
+{
+ asn1::node::iterator it = m_enumerated.begin();
+
+ m_os<<""<<m_structName<<"::"<<m_structName<<"(const asn1::tag &t)\n";
+ m_os<<" : asn1::ENUMERATED(t)\n";
+ m_os<<"{\n\tm_Prim = "<<(*it)->cpp_name()<<";\n}\n"<<std::endl;
+ // Copy ctor
+ m_os<<"\n"<<m_structName<<"::"<<m_structName;
+ m_os<<"(const "<<m_structName<<" &t) : asn1::ENUMERATED(t)\n{\n}\n";
+ // clone
+ m_os<<"\n"<<m_structName<<"* "<<m_structName;
+ m_os<<"::clone()\n{\n\treturn new "<<m_structName<<"(*this);\n}\n"<<std::endl;
+
+ // operator =
+ m_os<<m_structName<<" & "<<m_structName<<"::operator = (unsigned int v)\n{\n";
+ m_os<<"\tm_Prim = v;"<<std::endl;
+ m_os<<"\treturn *this;"<<std::endl;
+ m_os<<"}"<<std::endl;
+}
+//
+//
+void
+cgcpph_enumerated::generate_operators( )
+{
+ //std::string structName;
+ //m_gencpp.type2cppstring(&m_enumerated,structName,scope);
+ m_os<<"bool "<<m_structName<<"::operator ==(const "<<m_structName<<" &v) const\n";
+ m_os<<"{\n\treturn v.get_value() == get_value();\n}\n";
+ m_os<<"bool "<<m_structName<<"::operator ==(const e"<<m_structName<<" v) const\n";
+ m_os<<"{\n\treturn m_Prim == v ;\n}\n";
+ m_os<<"\nbool "<<m_structName<<"::operator !=(const e"<<m_structName<<" v) const\n";
+ m_os<<"{\n\treturn m_Prim != v ;\n}\n";
+}
+
+//
+//
+void cgcpph_enumerated::generate_printf( )
+{
+ std::string fname(m_structName);
+ asn1::enumerated *type = &m_enumerated;
+
+ assert(type->type_id()() == asn1::type::ASN1_ENUMERATED );
+
+ m_os<<"#if 1 /* ASN1_PRINTF*/"<<std::endl;
+
+ //m_gencpp.type2cppstring(&m_enumerated,structName,scope);
+#if 0
+ m_os<<"std::string Names_"<<lscope<<"[] = {"<<std::endl;
+ it = type->begin();
+ for (; it != type->end(); it++)
+ {
+ asn1::value *num = (*it)->value();
+ if (it != type->begin() )
+ {
+ m_os<<"\t,\""<<(*it)->cpp_name()<<"\"\n";
+ } else
+ {
+ m_os<<"\t \""<<(*it)->cpp_name()<<"\"\n";
+ }
+
+ }
+ m_os<<"};\n"<<std::endl;
+#endif
+ // printf function
+ m_os<<"void "<<fname<<"::printf(std::ostream &os) const\n{\n\tos<<*this;\n}\n"<<std::endl;
+
+ // stream operator function
+ m_os<<"std::ostream &operator <<(std::ostream &os,const ";
+ m_os<<" "<<fname;
+ m_os<<" &s)\n{\n";
+
+ for ( asn1::node::iterator it = m_enumerated.begin()
+ ; it != m_enumerated.end(); ++it)
+ {
+ if (it != m_enumerated.begin() )
+ {
+ m_os<<"\telse if (s.m_Prim == "<<fname<<"::"<<(*it)->cpp_name()<<")\n";
+ m_os<<"\t\tos<<\""<<(*it)->cpp_name()<<"\";\n";
+ } else
+ {
+ m_os<<"\tif (s.m_Prim == "<<fname<<"::"<<(*it)->cpp_name()<<")\n";
+ m_os<<"\t\tos<<\""<<(*it)->cpp_name()<<"\";\n";
+ }
+
+ }
+ m_os<<"\t\tos<<\" (\"<<s.m_Prim<<\")\";\n";
+ m_os<<"\t\treturn os;\n";
+
+ m_os<<"}\n"<<std::endl;
+ m_os<<"#endif"<<std::endl;
+}
+
+// generate codec part
+void cgcpph_enumerated::generate_per()
+{
+ //
+ m_os<<"\tvirtual void encode_per(asn1::context &ctx);"<<std::endl;
+ m_os<<"\tvirtual int decode_per(asn1::context &ctx);"<<std::endl;
+}
+
+//
+void cgcpph_enumerated::generate_ber()
+{
+ std::string scope;
+ asn1::node *type = &m_enumerated;
+#if 0
+ //
+ m_os<<scope<<"\tvirtual void encode(asn1::context &ctx);"<<std::endl;
+ m_os<<scope<<"\tvirtual int decode(asn1::context &ctx);"<<std::endl;
+ //
+ if (m_enumerated.tagged()) {
+ if ( m_gencpp.tag_mode(type) == asn1::node::tag_type::TM_EXPLICIT)
+ {
+ m_os<<scope<<"\tvirtual void encode_preamble_ber(asn1::context &ctx);"<<std::endl;
+ m_os<<scope<<"\tvirtual void encode_epilogue_ber(asn1::context &ctx);"<<std::endl;
+ m_os<<scope<<"\tvirtual int decode_preamble_ber(asn1::streams::ber &ctx);"<<std::endl;
+ m_os<<scope<<"\tvirtual int decode_epilogue_ber(asn1::streams::ber &ctx);"<<std::endl;
+ }
+ }
+#endif
+ //m_Gen.gen_template_signature(m_os,type);
+ if (m_gencpp.with_codec())
+ {
+ std::string ns( m_gencpp.get_module()->cpp_name() );
+ std::string structName( ns + "::" + m_enumerated.identifier_cpp_name() );
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void codecBER::encode(streams::ber &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int codecBER::decode(streams::ber &c,"<<structName<<" &_t);\n";
+
+ cpp<<"// typeref generator todo"<<std::endl;
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecBER::encode(asn1::streams::ber &c,const "<<structName<<" &_t)\n{\n";
+ cpp<<"\tstd::cout<<\"encode typeref "<<structName<<"\"<<std::endl;\n";
+ //cpp<<"\tc.encode_octetstring(_t);";
+ cpp<<"}\n";
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecBER::decode(asn1::streams::ber &c,"<<structName<<" &_t)\n{\n";
+ cpp<<"\tstd::cout<<\"decode typeref "<<structName<<"\"<<std::endl;\n";
+ cpp<<"\treturn asn1::ok;\n";
+ cpp<<"}\n";
+ }
+
+}
+
+//
+void cgcpph_enumerated::generate_oer()
+{
+ //
+ std::string scope;
+ m_os<<scope<<"\tvirtual void encode_oer(asn1::context &ctx);"<<std::endl;
+ m_os<<scope<<"\tvirtual int decode_oer(asn1::context &ctx);"<<std::endl;
+}
+
+//
+void cgcpph_enumerated::generate_jer()
+{
+ std::string fname;
+ std::string ns( m_gencpp.get_module()->cpp_name() );
+ std::string structName ( ns + "::" + m_enumerated.identifier_cpp_name());
+
+ //m_gencpp.type2cppstring(&m_enumerated,structName,scope);
+ fname = structName;
+
+ if (m_gencpp.with_codec())
+ {
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ //m_gencpp.gen_template_signature(m_os,type);
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void codecJER::encode(streams::jer &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int codecJER::decode(streams::jer &c,"<<structName<<" &_t);\n";
+ /* */
+ cpp<<"// typeref generator todo"<<std::endl;
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecJER::encode(asn1::streams::jer &c,const "<<structName<<" &_t)\n{\n";
+ /**/
+ cpp<<"\tswitch (_t.get_sys_value())\n\t{\n";
+ asn1::node::iterator it = m_enumerated.begin();
+ for (; it != m_enumerated.end(); it++)
+ {
+ if ( (*it)->is_extensible()) continue;
+ cpp<<"\t\tcase "<<fname<<"::"<<(*it)->cpp_name()<<": ";
+ cpp<<"c.put_field(\""<<(*it)->cpp_name()<<"\","<<(*it)->cpp_name().size()<<"); break;\n";
+ }
+ cpp<<"\t};\n";
+ /**/
+ cpp<<"}\n";
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecJER::decode(asn1::streams::jer &c,"<<structName<<" &_t)\n{\n";
+ cpp<<"\treturn asn1::ok;\n";
+ cpp<<"}\n";
+ }
+
+}
+
+//
+void cgcpph_enumerated::generate_xer()
+{
+}
+
+/**
+ * private structures are generated before the current on.
+ * outside the scope of the current type.
+ * This code could be factorized and generator level
+ */
+void cgcpph_enumerated::gen_private()
+{
+ asn1::node *type = &m_enumerated;
+}
--- /dev/null
+#ifndef CGCPPH_ENUMERATED_H
+#define CGCPPH_ENUMERATED_H
+
+
+/**
+ *
+ */
+class cgcpph_enumerated : public cgh_construct
+{
+ protected:
+ cgcpph_enumerated(const cgcpph_enumerated &s) : cgh_construct(s)
+ , m_enumerated(s.m_enumerated) {}
+ public:
+ cgcpph_enumerated(generate_codec_cpp &g,std::ostream &os,asn1::enumerated &s) ;
+ ~cgcpph_enumerated();
+
+ // Helper functions
+ virtual void generate(const std::string &scope) ;
+
+ // generate codec part
+ virtual void generate_per() ;
+ //
+ virtual void generate_ber() ;
+ //
+ virtual void generate_oer() ;
+ //
+ virtual void generate_jer() ;
+ //
+ virtual void generate_xer() ;
+ protected:
+ virtual void generate_printf( );
+ virtual void generate_ctors( );
+ virtual void generate_operators( );
+ // loop over the attributes of SEQUENCE or CHOICE
+ // and check if there are some type of SEQUENCE or CHOICE
+ // launch generation for these types first.
+ void gen_private();
+ protected:
+ asn1::enumerated &m_enumerated;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_codec_cpp.h"
+#include "asn1_generator_helper.h"
+#include "cgcpp_helper.h"
+#include "cgcpph_import.h"
+
+
+cgcpph_import::cgcpph_import(generate_codec_cpp &g,std::ostream &os,asn1::import &s)
+ : m_Gen(g), generator_helper(os) , m_import(s) , m_log(g.logger())
+{
+}
+
+cgcpph_import::~cgcpph_import()
+{
+}
+
+
+/** Helper functions
+ *
+ *
+ */
+void cgcpph_import::generate()
+{
+ asn1::node::iterator items,end;
+ asn1::node::iterator it = m_import.begin();
+
+ m_os<<"// cgcpph_import helper launched ";
+
+ // GEN_LOG_DEBUG("cgcpph_import::generate node=%s\n",type->identifier_cpp_name().c_str());
+ m_os<<"\n#if 0\n";
+ // May be just include each module ...
+
+ items = m_import.begin();
+ end = m_import.end();
+ // Loop over items and check if OPERATION is imported
+ for ( items = m_import.begin()
+ ; items != end
+ ; ++items)
+ {
+ //os <<"//#include \""<<(*it)->identifier_cpp_name()<<"/"<<(*items)->cpp_name()<<".h\" /*item "<<(*items)->name()<<"*/\n";
+ if (std::string("OPERATION").compare((*items)->name()) == 0 )
+ {
+ m_os<<"#include \"rtasn1/asn1_rose.h\"\n";
+ }
+ }
+ m_os<<"#include \""<<m_import.identifier()->cpp_name()<<".h\"\n";
+
+ m_os<<"#endif\n";
+}
+
+//
+void cgcpph_import::gen_printf(const std::string &scope)
+{
+}
+
+// generate codec part
+void cgcpph_import::generate_per()
+{
+}
+
+//
+void cgcpph_import::generate_ber()
+{
+}
+
+//
+void cgcpph_import::generate_oer()
+{
+ //
+}
+
+//
+void cgcpph_import::generate_jer()
+{
+}
+
+//
+void cgcpph_import::generate_xer()
+{
+}
+
--- /dev/null
+#ifndef CGCPPH_IMPORT_H
+#define CGCPPH_IMPORT_H
+
+
+/**
+ *
+ */
+class cgcpph_import : public generator_helper
+{
+ protected:
+ cgcpph_import(const cgcpph_import &s) : generator_helper(s.m_os)
+ , m_Gen(s.m_Gen)
+ , m_import(s.m_import)
+ , m_log(s.m_log)
+ {}
+ public:
+ cgcpph_import(generate_codec_cpp &g,std::ostream &os,asn1::import &s) ;
+
+ ~cgcpph_import();
+
+ // Helper functions
+ virtual void generate() ;
+
+ void gen_printf(const std::string &scope);
+ // generate codec part
+ virtual void generate_per() ;
+ //
+ virtual void generate_ber() ;
+ //
+ virtual void generate_oer() ;
+ //
+ virtual void generate_jer() ;
+ //
+ virtual void generate_xer() ;
+
+ // loop over the attributes of SEQUENCE or CHOICE
+ // and check if there are some type of SEQUENCE or CHOICE
+ // launch generation for these types first.
+ protected:
+ std::fstream &m_log;
+ generate_codec_cpp &m_Gen;
+ asn1::import &m_import;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_codec_cpp.h"
+#include "asn1_generator_helper.h"
+#include "cgcpp_helper.h"
+#include "cgh_construct.h"
+#include "cgcpph_integer.h"
+
+
+cgcpph_integer::cgcpph_integer(generate_codec_cpp &g,std::ostream &os,asn1::integer &s)
+ : cgh_construct(g,os,s)
+ , m_integer(s)
+{
+}
+
+cgcpph_integer::~cgcpph_integer()
+{
+}
+
+
+/** Helper functions
+ *
+ * It seems that the choice does not always have an identifier. Examples
+ * - SEQUENCE OF CHOICE {}
+ * - Test ::= CHOICE { toto INTEGER, CHOICE { } }
+ * these sequences are anonymous definitions ...
+ */
+void cgcpph_integer::generate()
+{
+ m_os<<"// cgcpph_integer helper launched "<<m_integer.identifier()->name()<<std::endl;
+
+ cgcpp_helper::generate();
+}
+
+void cgcpph_integer::generate_ctors()
+{
+ m_os<<m_structName<<"::"<<m_structName<<"(const asn1::tag &t )\n";
+ if (m_integer.is_unsigned())
+ {
+ m_os<<"\t: UInt64(t)\n{\n}\n"<<std::endl;
+ } else
+ m_os<<"\t: INTEGER(t)\n{\n}\n"<<std::endl;
+}
+void cgcpph_integer::generate_operators()
+{
+ m_os<<"bool "<<m_structName<<"::operator ==(const "<<m_integer.identifier_cpp_name()<<" &v)";
+ m_os<<" const\n{\n\treturn v.get_value() == get_value();\n}\n";
+ if (m_integer.is_unsigned())
+ {
+ m_os<<"void "<<m_structName<<"::operator =(const unsigned long v)";
+ m_os<<"\n{\n\tm_Prim = v;\n}\n";
+ m_os<<"void "<<m_structName<<"::operator =(const asn1::prim::types::UInt64 &v)";
+ m_os<<"\n{\n\tm_Prim = v;\n}\n";
+ }else
+ {
+ m_os<<"void "<<m_structName<<"::operator =(const long v)";
+ m_os<<"\n{\n\tm_Prim = v;\n}\n";
+ m_os<<"void "<<m_structName<<"::operator =(const asn1::prim::types::Integer &v)";
+ m_os<<"\n{\n\tm_Prim = v;\n}\n";
+ }
+ m_os<<"\n";
+ if (m_integer.size() > 0)
+ {
+ m_os<<"bool "<<m_structName<<"::operator ==(const e"<<m_integer.identifier_cpp_name()<<" v)";
+ m_os<<" const\n{\n\treturn m_Prim == v;\n}\n";
+ m_os<<"void "<<m_structName<<"::operator =(const e"<<m_integer.identifier_cpp_name()<<" v)";
+ m_os<<"\n{\n\tm_Prim = v;\n}\n";
+ }
+
+
+}
+
+
+//
+void cgcpph_integer::generate_printf( )
+{
+}
+
+// generate codec part
+void cgcpph_integer::generate_per()
+{
+ if (m_gencpp.with_codec())
+ {
+ std::string ns(m_gencpp.get_module()->cpp_name());
+ std::string structName(ns + "::" +m_integer.identifier_cpp_name());
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ //m_Gen.gen_template_signature(m_os,type);
+ hpp<<"\n// construct type "<<structName<<""<<"\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void codecPER::encode(streams::per &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int codecPER::decode(streams::per &c,"<<structName<<" &_t);\n";
+ /* Implementation part */
+ cpp<<"// integer generator todo"<<std::endl;
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecPER::encode(asn1::streams::per &c,const "<<structName<<" &_t)\n{\n";
+ cpp<<"\tc.encode_integer(_t);";
+ cpp<<"}\n";
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecPER::decode(asn1::streams::per &c,"<<structName<<" &_t)\n{\n";
+ cpp<<"\treturn c.decode_integer(_t);\n";
+ cpp<<"}\n";
+ }
+}
+
+//
+void cgcpph_integer::generate_ber()
+{
+ asn1::node *type = &m_integer;
+ std::string structName = m_integer.identifier_cpp_name();
+ //
+ //
+ if (m_integer.tagged())
+ {
+ if ( m_gencpp.tag_mode(type) == asn1::node::tag_type::TM_EXPLICIT)
+ {
+ m_os<<"void "<<structName<<"::encode(asn1::context &ctx)"<<std::endl;
+ m_os<<"{\n";
+ m_os<<"\tunsigned long pos = ctx.bytes();\n";
+ m_os<<"\tunsigned char *b = ctx.buffer();\n";
+ m_os<<"\tASN1_BER_LOG_DEBUG(\""<<structName<<"::encode(ctx) tag=%d BIG Issue \",this->tag().byte());\n";
+ m_os<<"\tb[pos++] = tag().byte();\n";
+ m_os<<"\tctx.nb_bits(16);\n";
+ m_os<<"\tasn1::tag t("<<m_integer.tag().m_class<<","<<m_integer.tag().m_value<<",true);\n";
+ m_os<<"\tset_tag(asn1::tag(0,2));\n";
+ m_os<<"\tctx.encode_integer(*this);\n";
+ m_os<<"\tset_tag(t);\n";
+ m_os<<"\tb[pos] = ctx.bytes() -pos -1;\n";
+ m_os<<"}\n\n";
+ // Decode function
+ m_os<<"int "<<structName<<"::decode(asn1::context &ctx)\n{\n"<<std::endl;
+ m_os<<"\tasn1::tag t("<<m_integer.tag().m_class<<","<<m_integer.tag().m_value<<",true);\n";
+ m_os<<"\tASN1_BER_LOG_DEBUG(\""<<structName<<"::decode(ctx) exp tag= %d tag=%d \",t.byte(),this->tag().byte());\n";
+ m_os<<"\tif (ctx.decode_tag(t))\n\t{\n";
+ if (m_integer.is_unsigned())
+ {
+ m_os<<"\t\tUInt64 tmp;\n";
+ } else
+ {
+ m_os<<"\t\tINTEGER tmp;\n";
+ }
+ m_os<<"\t\tint rest = tmp.decode(ctx);\n";
+ m_os<<"\t\tthis->get_value() = tmp.get_value();\n";
+ m_os<<"\t\treturn rest;\n";
+ m_os<<"\t}\n";
+ m_os<<"\treturn asn1::wrong_tag;\n";
+ m_os<<"}\n";
+ }
+ }
+ /* Handle codec aspect */
+ if (m_gencpp.with_codec())
+ {
+ std::string ns(m_gencpp.get_module()->cpp_name());
+ std::string structName(ns + "::" +m_c.identifier()->cpp_name());
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ //m_Gen.gen_template_signature(m_os,type);
+ hpp<<"\n// construct type "<<structName<<""<<"\n";
+ hpp<<"template<>\n";
+ hpp<<"void asn1::codecBER::encode(asn1::streams::ber &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int asn1::codecBER::decode(asn1::streams::ber &c,"<<structName<<" &_t);\n";
+ /* Handle implementation part */
+ cpp<<"// integer generator todo"<<std::endl;
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecBER::encode(asn1::streams::ber &c,const "<<structName<<" &_t)\n{\n";
+ if ( m_integer.tagged()
+ && ( m_gencpp.tag_mode(type) == asn1::node::tag_type::TM_EXPLICIT))
+ {
+ cpp<<"\tasn1::tag t("<<m_integer.tag().m_class<<","<<m_integer.tag().m_value<<",true);\n";
+ //cpp<<"\tstd::cout<<\"encode "<<structName<<" explicit tag TODO\"<<std::endl;\n";
+ cpp<<"\tencode_tag(c,t,_t.get_length());\n";
+ }
+ cpp<<"\tc.encode_integer(_t);\n";
+ cpp<<"}\n";
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecBER::decode(asn1::streams::ber &c,"<<structName<<" &_t)\n{\n";
+ if ( m_integer.tagged()
+ && ( m_gencpp.tag_mode(type) == asn1::node::tag_type::TM_EXPLICIT))
+ {
+ cpp<<"\tasn1::tag t("<<m_integer.tag().m_class<<","<<m_integer.tag().m_value<<",true);\n";
+ cpp<<"\tif (c.decode_tag(t))\n\t{\n";
+ cpp<<"\t\treturn c.decode_integer(_t);\n";
+ cpp<<"\t}\n";
+ cpp<<"\treturn asn1::wrong_tag;\n";
+ } else
+ cpp<<"\treturn c.decode_integer(_t);\n";
+ cpp<<"}\n";
+ }
+}
+
+//
+void cgcpph_integer::generate_oer()
+{
+ if (m_gencpp.with_codec())
+ {
+ std::string ns(m_gencpp.get_module()->cpp_name());
+ std::string structName(ns + "::" +m_integer.identifier_cpp_name());
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ //m_Gen.gen_template_signature(m_os,type);
+ hpp<<"\n// construct type "<<structName<<""<<"\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void codecOER::encode(streams::oer &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int codecOER::decode(streams::oer &c,"<<structName<<" &_t);\n";
+ /* Implementation part */
+ cpp<<"// integer generator todo"<<std::endl;
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecOER::encode(asn1::streams::oer &c,const "<<structName<<" &_t)\n{\n";
+ cpp<<"\tc.encode_integer(_t);";
+ cpp<<"}\n";
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecOER::decode(asn1::streams::oer &c,"<<structName<<" &_t)\n{\n";
+ cpp<<"\treturn c.decode_integer(_t);\n";
+ cpp<<"}\n";
+ }
+}
+
+//
+void cgcpph_integer::generate_jer()
+{
+ if (m_gencpp.with_codec())
+ {
+ std::string ns(m_gencpp.get_module()->cpp_name());
+ std::string structName(ns + "::" +m_integer.identifier_cpp_name());
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ //m_Gen.gen_template_signature(m_os,type);
+ hpp<<"\n// construct type "<<structName<<""<<"\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void codecJER::encode(streams::jer &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int codecJER::decode(streams::jer &c,"<<structName<<" &_t);\n";
+ /* Implementation part */
+ cpp<<"// integer generator todo"<<std::endl;
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecJER::encode(asn1::streams::jer &c,const "<<structName<<" &_t)\n{\n";
+ cpp<<"\tc.encode_integer(_t);";
+ cpp<<"}\n";
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecJER::decode(asn1::streams::jer &c,"<<structName<<" &_t)\n{\n";
+ cpp<<"\treturn c.decode_integer(_t);\n";
+ cpp<<"}\n";
+ }
+}
+
+//
+void cgcpph_integer::generate_xer()
+{
+ std::string structName = m_integer.identifier_cpp_name();
+ m_os<<"void"<<structName<<"::encode_jer(asn1::context &ctx)\n{"<<std::endl;
+ m_os<<"\n}"<<std::endl;
+ m_os<<"int "<<structName<<"::decode_jer(asn1::context &ctx)\n{"<<std::endl;
+ m_os<<"\treturn asn1::wrong_tag;\n";
+ m_os<<"\n}"<<std::endl;
+}
+
--- /dev/null
+#ifndef CGCPPH_INTEGER_H
+#define CGCPPH_INTEGER_H
+
+
+/**
+ *
+ */
+class cgcpph_integer : public cgh_construct
+{
+ protected:
+ cgcpph_integer(const cgcpph_integer &s) : cgh_construct(s)
+ , m_integer(s.m_integer) {}
+ public:
+ cgcpph_integer(generate_codec_cpp &g,std::ostream &os,asn1::integer &s) ;
+ ~cgcpph_integer();
+
+ // Helper functions
+ virtual void generate() ;
+
+ // generate codec part
+ virtual void generate_per() ;
+ //
+ virtual void generate_ber() ;
+ //
+ virtual void generate_oer() ;
+ //
+ virtual void generate_jer() ;
+ //
+ virtual void generate_xer() ;
+
+ protected:
+ virtual void generate_ctors( );
+ virtual void generate_operators( );
+ virtual void generate_printf( );
+ protected:
+ asn1::integer &m_integer;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_codec_cpp.h"
+#include "asn1_generator_helper.h"
+#include "cgcpp_helper.h"
+#include "asn1_recursive_visitor.h"
+#include "cgh_object.h"
+#include "cgcpph_object.h"
+#include "adt/asn1_node.h"
+#include "adt/asn1_constraint.h"
+#include "asn1_visitor.h"
+
+/**
+ * Generate Missing Objects before instanciating them in the set.
+ */
+class missing_object : public asn1::recursive_visitor<missing_object>
+{
+ public:
+ missing_object(std::ostream &os,cgcpph_object &h,generate_codec_cpp &g)
+ : m_os(os), m_cgh(h) , m_Gen(g), m_count(0)
+ {}
+
+ bool visit_celt_value(asn1::celt_value *cv)
+ {
+ asn1::node::iterator ref = std::find_if(m_Gen.get_module()->begin(),
+ m_Gen.get_module()->end(),
+ asn1::find_node(cv->value()->name()));
+ if (ref != m_Gen.get_module()->end())
+ {
+ asn1::node *ntype = *ref;
+ if (ntype->parameters())
+ {
+ std::cerr<<"generate_codec_cpp::gen_const "<<ntype->name()<<" has parameters"<<std::endl;
+ m_os<<"//gen_const "<<ntype->name()<<" has parameters NO GEN YET"<<std::endl;
+ return true;
+ } else
+ {
+ m_count++;
+ m_Gen.gen_object(m_os,(*ref)->as_assignment());
+ }
+ }
+ return true;
+ }
+
+ long m_count;
+ std::ostream &m_os;
+ cgcpph_object &m_cgh;
+ generate_codec_cpp &m_Gen;
+};
+
+/**
+ * Generate Object sets in class:
+ */
+class gen_objectset : public asn1::recursive_visitor<gen_objectset>
+{
+ public:
+ gen_objectset( std::ostream &os
+ , const std::string field
+ , const std::string sname
+ , const long nbelems
+ , cgcpph_object &h
+ , generate_codec_cpp &g)
+ : m_os(os), m_cgh(h) , m_Gen(g),m_count(0),m_struct_name(sname),m_nb_elems(nbelems)
+ {}
+
+ bool visit_celt_value(asn1::celt_value *cv)
+ {
+ asn1::node::iterator ref = std::find_if(m_Gen.get_module()->begin(),
+ m_Gen.get_module()->end(),
+ asn1::find_node(cv->value()->name()));
+ if (ref != m_Gen.get_module()->end())
+ {
+ asn1::node *ntype = *ref;
+ if (ntype->parameters())
+ {
+ std::cerr<<"generate_codec_cpp::gen_const "<<ntype->name()<<" has parameters"<<std::endl;
+ m_os<<"//gen_const "<<ntype->name()<<" has parameters NO GEN YET"<<std::endl;
+ return true;
+ } else
+ {
+ if (m_count++)
+ m_os<<",";
+ m_os<<" {";
+ if (m_count< m_nb_elems)
+ {
+ m_os<<" &"<<m_struct_name<<"["<<m_count<<"]";
+ }else
+ m_os<<" NULL";
+ m_os<<",new "<<ntype->cpp_name()<<"()}\n";
+ }
+ }
+ return true;
+ }
+ /**
+ *
+ */
+ bool traverse_objectset(asn1::objectset *S)
+ {
+ bool ret = asn1::recursive_visitor<gen_objectset>::traverse_objectset(S);
+ if (m_count)
+ {
+ m_os<<",{NULL,NULL}";
+ }else
+ {
+ m_os<<"{NULL,NULL} ";
+ }
+ return ret;
+ }
+
+ bool traverse_valueset(asn1::valueset *S)
+ {
+ bool ret = asn1::recursive_visitor<gen_objectset>::traverse_valueset(S);
+ if (m_count)
+ {
+ m_os<<",{NULL,NULL}";
+ }else
+ {
+ m_os<<"{NULL,NULL} ";
+ }
+ return ret;
+ }
+ long m_count;
+ long m_nb_elems;
+ std::string m_field;
+ std::string m_struct_name;
+ std::ostream &m_os;
+ cgcpph_object &m_cgh;
+ generate_codec_cpp &m_Gen;
+};
+
+/**
+* INTERNAL HELPER CLASS
+*/
+struct g_objectset
+{
+ g_objectset(std::ostream &os,cgcpph_object &h,generate_codec_cpp &g)
+ : m_os(os) , m_cgh(h) , m_Gen(g)
+ {
+ }
+
+ void operator ()(asn1::node *n)
+ {
+ if (n->type_id()() == asn1::type::ASN1_CLASSFIELD_OSF )
+ {
+ asn1::typeref *tref = dynamic_cast<asn1::classfield_osf *>(n)->get_typeref();
+ std::string name = n->cpp_name().substr(1);
+ asn1::node *ident = m_Gen.resolver().resolve(*tref);
+ // Get field Loop over union ...
+ m_os<<"// OBJECTSET "<<n->name()<<std::endl;
+ asn1::objectset *type = NULL;
+ if ( (type = m_cgh.get_object().get_objectset(n->name()) ) != NULL )
+ {
+ std::string sname = m_cgh.get_object().identifier()->cpp_name()+"_"+name;
+ m_os<<"// HAVE VALUES "<<n->name()<<" object set is element_set_spect "<<std::endl;
+ missing_object mo(m_os,m_cgh,m_Gen);
+ //mo.traverse_valueset(type);
+ mo.traverse_objectset(type);
+ // Now generate the set
+ if (! m_Gen.get_module()->name().compare(ident->get_parent()->name()))
+ {
+ m_os<<"struct ";
+ //<<name<<"Set ";
+ } else
+ m_os<<"struct "<<ident->get_parent()->cpp_name()<<"::";
+ m_os<<tref->cpp_name()<<"Set ";
+ m_os<<m_cgh.get_object().identifier()->cpp_name()<<"_"<<name;
+ m_os<<"[] = {\n";
+ gen_objectset gset(m_os,n->name(),sname,mo.m_count,m_cgh,m_Gen);
+ gset.traverse_objectset(type);
+ m_os<<"};\n";
+ }
+ }
+ }
+ std::ostream &m_os;
+ cgcpph_object &m_cgh;
+ generate_codec_cpp &m_Gen;
+};
+
+
+/*
+* CLASS chgpph_object IMPLEMENTATION
+*/
+
+cgcpph_object::cgcpph_object( generate_codec_cpp &g
+ , std::ostream &os
+ , asn1::object &s
+ , asn1::classdef &cdef)
+: m_Gen(g)
+, cgh_object(g,os,s,cdef)
+, m_log(g.logger())
+{
+}
+
+cgcpph_object::~cgcpph_object()
+{
+}
+
+
+/** Helper functions
+* generate object template code
+*/
+void cgcpph_object::generate()
+{
+ asn1::node *n = m_object.identifier();
+ asn1::node *type = &m_object;
+ asn1::node *params = NULL;
+ std::string structName;
+
+ m_os<<"\n//\n// cgcpph_object helper launched "<<n->name()<<"\n";
+ if (!m_Gen.get_module()->name().compare("Remote-Operations-Useful-Definitions"))
+ {
+ m_os<<"// Dont generate anything For this module\n";
+ return;
+ }
+ gen_objectset();
+ // Generate template_specialisation
+ if (m_classdef.get_parent() == m_Gen.get_module())
+ {
+ m_os<<"template <>\n";
+ m_os<<m_classdef.cpp_name();
+ m_os<<"<";
+ gen_template_args(true);
+ m_os<<">::"<<m_classdef.cpp_name()<<"();\n";
+ // Test project passes through here
+ //assert(0 && " CLASS and OBJECT in same module");
+ } else
+ {
+ m_os<<"}\n"; // Close current namespace
+ // Open template namespace
+ m_os<<"namespace "<<m_classdef.get_parent()->cpp_name()<<" {\n";
+ gen_ctors() ;
+ m_os<<"} // close namespace\n"; // Close template namespace
+ // Reopen current namespace
+ m_os<<"namespace "<<m_Gen.get_module()->cpp_name()<<" {\n";
+#if defined(_WINDOWS)
+ // Solve link issue in cstav1
+ m_os<<"static "<<n->cpp_name()<<" "<<n->cpp_name()<<"_instance;\n";
+#endif
+ }
+
+ m_os<<"\n";
+
+}
+
+void
+cgcpph_object::gen_ctors()
+{
+ asn1::node *n = m_object.identifier();
+ m_os<<"template <>\n";
+ m_os<<m_classdef.identifier()->cpp_name();
+ m_os<<"<";
+ gen_template_args(true);
+ m_os<<">::"<<m_classdef.identifier()->cpp_name()<<"()\n";
+ m_os<<"{\n"; // Open function content
+ if (m_Gen.with_source_debug())
+ m_os<<"\tASN1_BER_LOG_DEBUG(\"ctor::"<<n->name()<<"\");\n";
+ gen_ctor_set_ftvf();
+ m_os<<"}\n"; // Close function content
+ // Add copy ctor even if private
+ m_os<<"template <>\n";
+ m_os<<m_classdef.identifier()->cpp_name();
+ m_os<<"<";
+ gen_template_args(true);
+ m_os<<">::"<<m_classdef.identifier()->cpp_name()<<"(const ";
+ m_os<<m_classdef.identifier()->cpp_name();
+ m_os<<"<";
+ gen_template_args(true);
+ m_os<<"> &o )\n";
+ m_os<<"{\n"; // Open function content
+ if (m_Gen.with_source_debug())
+ m_os<<"\tASN1_BER_LOG_DEBUG(\"cpctor::"<<n->name()<<"\");\n";
+ gen_ctor_set_ftvf();
+ m_os<<"}\n"; // Close function content
+ // Add Create static function to check if yes or not
+
+}
+
+//
+void cgcpph_object::gen_printf(const std::string &scope)
+{
+}
+
+// generate codec part
+void cgcpph_object::generate_per()
+{
+ std::string scope;
+ //
+ m_os<<scope<<"\tvirtual void encode_per(asn1::context &ctx);"<<std::endl;
+ m_os<<scope<<"\tvirtual int decode_per(asn1::context &ctx);"<<std::endl;
+}
+
+//
+void cgcpph_object::generate_ber()
+{
+ std::string scope;
+ asn1::node *type = &m_object;
+ //
+ m_os<<scope<<"\tvirtual void encode(asn1::context &ctx);"<<std::endl;
+ m_os<<scope<<"\tvirtual int decode(asn1::context &ctx);"<<std::endl;
+ //
+ if (m_object.tagged())
+ {
+ if ( m_Gen.tag_mode(type) == asn1::node::tag_type::TM_EXPLICIT)
+ {
+ m_os<<scope<<"\tvirtual void encode_preamble_ber(asn1::context &ctx);"<<std::endl;
+ m_os<<scope<<"\tvirtual void encode_epilogue_ber(asn1::context &ctx);"<<std::endl;
+ m_os<<scope<<"\tvirtual int decode_preamble_ber(asn1::streams::ber &ctx);"<<std::endl;
+ m_os<<scope<<"\tvirtual int decode_epilogue_ber(asn1::streams::ber &ctx);"<<std::endl;
+ }
+ }
+}
+
+//
+void cgcpph_object::generate_oer()
+{
+ //
+ std::string scope;
+ m_os<<scope<<"\tvirtual void encode_oer(asn1::context &ctx);"<<std::endl;
+ m_os<<scope<<"\tvirtual int decode_oer(asn1::context &ctx);"<<std::endl;
+}
+
+//
+void cgcpph_object::generate_jer()
+{
+}
+
+//
+void cgcpph_object::generate_xer()
+{
+}
+
+/**
+ *
+ */
+class ftvf_init : public node_visitor<ftvf_init>
+{
+ public:
+ ftvf_init(std::ostream &os,const std::string &s) : m_s(s),m_os(os) {};
+
+ void visit_integer(asn1::integer *_int)
+ {
+ //TODO This is wrong code
+ m_os<<"\t"<<m_s<<".set_local( INTEGER(asn1::prim::types::Integer(";
+ m_os<<_int->cpp_name();
+ m_os<<")));\n";
+ }
+
+ void visit_object_identifier(asn1::object_identifier *_oid)
+ {
+ asn1::object_identifier::arcsType v;
+ _oid->arcs(v);
+ m_os<<"\t"<<m_s<<".set_global ( OBJECT_IDENTIFIER("<<v.size()<<",";
+ _oid->print_strhex(m_os,v);
+ m_os<<") ) ;\n";
+ }
+
+ void visit_choice(asn1::choice *type)
+ {
+ asn1::value *val = type->value();
+ m_os<<"\t// FTVF CHOICE "<<type->cpp_name()<<" "<<val->cpp_name()<<std::endl;
+ switch (val->m_node->type_id()())
+ {
+ case asn1::type::ASN1_OBJECT_IDENTIFIER:
+ {
+ asn1::object_identifier::arcsType v;
+ asn1::object_identifier *_oid = val->m_node->as_object_identifier();
+ _oid->arcs(v);
+ m_os<<"\t"<<m_s<<".set_"<<type->cpp_name();
+ m_os<<" ( OBJECT_IDENTIFIER("<<v.size()<<",";
+ _oid->print_strhex(m_os,v);
+ m_os<<") ) ;\n";
+ }
+ break;
+ case asn1::type::ASN1_INTEGER:
+ {
+ m_os<<"\t"<<m_s<<".set_"<<type->cpp_name();
+ m_os<<"( INTEGER(";
+ m_os<<val->cpp_name();
+ m_os<<") );\n";
+ }
+ default:
+ ;
+ }
+ }
+ // Default unhandled case
+ void visit_node(asn1::node *type)
+ {
+ m_os<<"\t// FTVF "<<type->cpp_name()<<" ID="<<type->type_id()()<<std::endl;
+ }
+ protected:
+ std::string m_s;
+ std::ostream &m_os;
+};
+
+/**
+ * Set Fixed Type Value Field values in CTOR
+ */
+void cgcpph_object::gen_ctor_set_ftvf()
+{
+ asn1::node::iterator fit = m_classdef.begin();
+ int count = 0;
+
+ for ( ; fit != m_classdef.end()
+ ; ++fit)
+ {
+ if ( (*fit)->type_id()() == asn1::type::ASN1_CLASSFIELD_OSF )
+ {
+ asn1::objectset *type = NULL;
+ if ( (type = m_object.get_objectset((*fit)->name()) ) != NULL )
+ {
+ std::string s = (*fit)->name();
+ s[0] = '_';
+ m_os<<"\t// SET OBJECT SET "<<s<<std::endl;
+ }
+ }
+ // Try to get code
+ if ( (*fit)->type_id()() == asn1::type::ASN1_CLASSFIELD_FTVF )
+ {
+ asn1::valuetype *type = NULL;
+ if ( (type = m_object.get_ftvf((*fit)->name()) ) != NULL )
+ {
+ std::string s = (*fit)->name();
+ s[0] = '_';
+ ftvf_init vint(m_os,s);
+ vint.visit(type);
+ }
+ }
+ }
+}
+
+
+/**
+ *
+ */
+void cgcpph_object::gen_objectset()
+{
+ std::for_each(m_classdef.begin()
+ , m_classdef.end()
+ , g_objectset(m_os,*this,m_Gen));
+}
+
+/*
+ * vim: et sw=2 ts=2 list:
+ */
--- /dev/null
+#ifndef CGCPPH_OBJECT_H
+#define CGCPPH_OBJECT_H
+
+
+/**
+ *
+ */
+class cgcpph_object : public cgh_object
+{
+ protected:
+ cgcpph_object(const cgcpph_object &s) : cgh_object(s.m_Gencpp
+ , s.m_os
+ , s.m_object
+ , s.m_classdef
+ )
+ , m_Gen(s.m_Gen)
+ // , m_object(s.m_object)
+ // , m_classdef(s.m_classdef)
+ , m_log(s.m_log)
+ {}
+ public:
+ cgcpph_object( generate_codec_cpp &g
+ , std::ostream &os
+ , asn1::object &s
+ , asn1::classdef &c
+ ) ;
+
+ ~cgcpph_object();
+
+ // Helper functions
+ virtual void generate() ;
+
+ void gen_printf(const std::string &scope);
+ // generate codec part
+ virtual void generate_per() ;
+ //
+ virtual void generate_ber() ;
+ //
+ virtual void generate_oer() ;
+ //
+ virtual void generate_jer() ;
+ //
+ virtual void generate_xer() ;
+
+ // loop over the attributes of SEQUENCE or CHOICE
+ // and check if there are some type of SEQUENCE or CHOICE
+ // launch generation for these types first.
+ protected:
+ //void gen_template_args(bool with_scope);
+ //
+ void gen_ctor_set_ftvf();
+
+ void gen_ctors();
+ /**
+ * CLASS might have object sets
+ */
+ void gen_objectset();
+ protected:
+ std::fstream &m_log;
+ generate_codec_cpp &m_Gen;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_codec_cpp.h"
+#include "asn1_generator_helper.h"
+#include "cgcpp_helper.h"
+#include "cgh_object.h"
+#include "cgcpph_objectset.h"
+
+
+/**
+ * INTERNAL HELPER CLASS
+ */
+struct g_object
+{
+ g_object(std::ostream &os,cgcpph_objectset &h)
+ : m_os(os) , m_cgh(h)
+ {
+ }
+
+ void operator ()(asn1::node *n)
+ {
+ if (n->type_id()() == asn1::type::ASN1_CLASSFIELD_OSF )
+ {
+ // Get field Loop over union ...
+ asn1::node *type = NULL;
+ if ( (type = m_cgh.get_object().get_field(n->name()) ) != NULL )
+ {
+ m_os<<"// HAVE VALUES "<<n->name()<<std::endl;
+ }
+ }
+ }
+ std::ostream &m_os;
+ cgcpph_objectset &m_cgh;
+};
+
+
+/*
+ * CLASS chgpph_objectset IMPLEMENTATION
+ */
+cgcpph_objectset::cgcpph_objectset( generate_codec_cpp &g
+ , std::ostream &os
+ , asn1::object &s
+ , asn1::classdef &cdef)
+ : m_Gen(g)
+ , cgh_object(g,os,s,cdef)
+ , m_log(g.logger())
+{
+}
+
+cgcpph_objectset::~cgcpph_objectset()
+{
+}
+
+
+/** Helper functions
+ * generate object template code
+ */
+void cgcpph_objectset::generate()
+{
+ asn1::node *n = m_object.identifier();
+ asn1::node *type = &m_object;
+ asn1::node *params = NULL;
+ std::string structName;
+
+ m_os<<"\n//\n// cgcpph_objectset helper launched "<<n->name()<<"\n";
+ if (!m_Gen.get_module()->name().compare("Remote-Operations-Useful-Definitions"))
+ {
+ m_os<<"// Dont generate anything For this module\n";
+ return;
+ }
+ gen_objectset();
+ // Generate template_specialisation
+ if (m_classdef.get_parent() == m_Gen.get_module())
+ {
+ m_os<<"template <>\n";
+ m_os<<m_classdef.cpp_name();
+ m_os<<"<";
+ gen_template_args(true);
+ m_os<<">::"<<m_classdef.cpp_name()<<"();\n";
+ } else
+ {
+ m_os<<"}\n"; // Close current namespace
+ // Open template namespace
+ m_os<<"namespace "<<m_classdef.get_parent()->cpp_name()<<" {\n";
+ m_os<<"template <>\n";
+ m_os<<m_classdef.identifier()->cpp_name();
+ m_os<<"<";
+ gen_template_args(true);
+ m_os<<">::"<<m_classdef.identifier()->cpp_name()<<"()\n";
+ m_os<<"{\n"; // Open function content
+ m_os<<"\tASN1_BER_LOG_DEBUG(\"ctor::"<<n->name()<<"\");\n";
+ gen_ctor_set_ftvf();
+ m_os<<"}\n"; // Close function content
+
+ m_os<<"} // close namespace\n"; // Close template namespace
+ // Reopen current namespace
+ m_os<<"namespace "<<m_Gen.get_module()->cpp_name()<<" {\n";
+ }
+
+ m_os<<"\n";
+
+}
+
+//
+void cgcpph_objectset::gen_printf(const std::string &scope)
+{
+}
+
+
+/**
+ *
+ */
+void cgcpph_objectset::gen_objectset()
+{
+ std::for_each(m_classdef.begin()
+ , m_classdef.end()
+ , g_objectset(m_os,*this));
+}
--- /dev/null
+#ifndef CGCPPH_OBJECTSET_H
+#define CGCPPH_OBJECTSET_H
+
+
+/**
+ *
+ */
+class cgcppg_objectset : public cgh_object
+{
+ protected:
+ cgcppg_objectset(const cgcppg_objectset &s) : cgh_object(s.m_Gencpp
+ , s.m_os
+ , s.m_object
+ , s.m_classdef
+ )
+ , m_Gen(s.m_Gen)
+ , m_log(s.m_log)
+ {}
+ public:
+ cgcppg_objectset( generate_codec_cpp &g
+ , std::ostream &os
+ , asn1::object &s
+ , asn1::classdef &c
+ ) ;
+
+ ~cgcppg_objectset();
+
+ // Helper functions
+ virtual void generate() ;
+
+ void gen_printf(const std::string &scope);
+ // generate codec part
+
+ protected:
+ std::fstream &m_log;
+ generate_codec_cpp &m_Gen;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_codec_cpp.h"
+#include "asn1_generator_helper.h"
+#include "cgcpp_helper.h"
+#include "cgcpph_primitive.h"
+#include "cgcpph_octetstring.h"
+
+
+cgcpph_octet_string::cgcpph_octet_string(generate_codec_cpp &g,std::ostream &os,asn1::octet_string &s)
+ : cgcpph_primitive(g,os,s)
+ , m_octet_string(s)
+{
+}
+
+cgcpph_octet_string::~cgcpph_octet_string()
+{
+}
+
+
+/** Helper functions
+ *
+ * It seems that the choice does not always have an identifier. Examples
+ * - SEQUENCE OF CHOICE {}
+ * - Test ::= CHOICE { toto INTEGER, CHOICE { } }
+ * these sequences are anonymous definitions ...
+ */
+void cgcpph_octet_string::generate_ctors()
+{
+ if (m_gencpp.with_source_comment())
+ m_os<<"// cgcpph_octet_string helper launched "<<std::endl;
+
+ m_os<<m_structName<<"::"<<m_structName<<"(const asn1::tag &t)\n";
+ m_os<<"\t: OCTET_STRING(t)\n";
+ m_os<<"{\n";
+ m_os<<"}\n";
+
+ m_os<<m_structName<<"::~"<<m_structName<<"()\n";
+ m_os<<"{\n";
+ m_os<<"}\n";
+ // copy
+ m_os<<m_structName<<"::"<<m_structName<<"(const "<<m_structName<<" &c)\n";
+ m_os<<" : OCTET_STRING(c)\n";
+ m_os<<"{\n";
+ m_os<<"}\n";
+
+ // Assignement
+ m_os<<"\n"<<m_structName<<"&\n";
+ m_os<<m_structName<<"::operator =(const "<<m_structName<<" &c)\n";
+ m_os<<"{\n";
+ m_os<<"\tif ( &c != this)\n";
+ m_os<<"\t\t"<<"m_Prim = c.m_Prim;\n";
+ m_os<<"\treturn *this;\n";
+ m_os<<"}\n";
+
+ m_os<<"\n"<<m_structName<<" &\n";
+ m_os<<m_structName<<"::operator =(const asn1::prim::types::String &t"<<") \n";
+ m_os<<"{\n";
+ //m_os<<"\tif ( &t != this)\n";
+ m_os<<"\t"<<"m_Prim = t ;\n";
+ m_os<<"\treturn *this;\n";
+ m_os<<"}\n";
+
+}
+
+//
+void cgcpph_octet_string::generate_printf()
+{
+ m_os<<"\nstd::ostream & operator <<(std::ostream &os,const ";
+ m_os<<m_structName<<" &s)\n{\n";
+ m_os<<"\tos<<(OCTET_STRING)s;\n";
+ m_os<<"\treturn os;\n";
+ m_os<<"}\n";
+}
+
+// generate codec part
+void cgcpph_octet_string::generate_per()
+{
+ std::string scope;
+ //
+ m_os<<scope<<"\tvirtual void encode_per(asn1::context &ctx);"<<std::endl;
+ m_os<<scope<<"\tvirtual int decode_per(asn1::context &ctx);"<<std::endl;
+}
+
+//
+void cgcpph_octet_string::generate_ber()
+{
+ std::string scope;
+ std::string structName = m_octet_string.identifier_cpp_name();
+ asn1::node *type = &m_octet_string;
+ //
+ //
+ if (m_octet_string.tagged()) {
+ if ( m_gencpp.tag_mode(type) == asn1::node::tag_type::TM_EXPLICIT)
+ {
+ m_os<<scope<<"void "<<structName<<"::encode(asn1::context &ctx)\n{\n"<<std::endl;
+ m_os<<"\tunsigned long pos = ctx.bytes();\n";
+ m_os<<"\tunsigned char *b = ctx.buffer();\n";
+ m_os<<"\tASN1_BER_LOG_DEBUG(\""<<structName<<"::encode(ctx) tag=%d BIG Issue \",this->tag().byte());\n";
+ m_os<<"\tb[pos++] = tag().byte();\n";
+ m_os<<"\tctx.nb_bits(16);\n";
+ m_os<<"\tasn1::tag t("<<m_octet_string.tag().m_class<<","<<m_octet_string.tag().m_value<<",true);\n";
+ m_os<<"\tset_tag(asn1::tag(0,4));\n";
+ m_os<<"\tctx.encode_octetstring(*this);\n";
+ m_os<<"\tset_tag(t);\n";
+ m_os<<"\tb[pos] = ctx.bytes() -pos -1;\n";
+ m_os<<"}\n\n";
+ m_os<<scope<<"int "<<structName<<"::decode(asn1::context &ctx)\n{\n"<<std::endl;
+ m_os<<"\tasn1::tag t("<<m_octet_string.tag().m_class<<","<<m_octet_string.tag().m_value<<",true);\n";
+ m_os<<"\tASN1_BER_LOG_DEBUG(\""<<structName<<"::decode(ctx) exp tag= %d tag=%d \",t.byte(),this->tag().byte());\n";
+ m_os<<"\tif (ctx.decode_tag(t))\n\t{\n";
+ m_os<<"\t\tOCTET_STRING tmp;\n";
+ m_os<<"\t\tint rest = tmp.decode(ctx);\n";
+ m_os<<"\t\tthis->get_value() = tmp.get_value();\n";
+ m_os<<"\t\treturn rest;\n";
+ m_os<<"\t}\n";
+ m_os<<"\treturn asn1::wrong_tag;\n";
+ m_os<<"}\n";
+ }
+ }
+ /* Handler BER Codec */
+ if (m_gencpp.with_codec())
+ {
+ std::string ns(m_gencpp.get_module()->cpp_name());
+ std::string structName(ns + "::" + m_octet_string.identifier_cpp_name());
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ //m_gencpp.gen_template_signature(m_os,type);
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void codecBER::encode(streams::ber &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int codecBER::decode(streams::ber &c,"<<structName<<" &_t);\n";
+
+
+ cpp<<"// octet_string generator todo"<<std::endl;
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecBER::encode(asn1::streams::ber &c,const "<<structName<<" &_t)\n{\n";
+ if ( m_octet_string.tagged()
+ && ( m_gencpp.tag_mode(type) == asn1::node::tag_type::TM_EXPLICIT)
+ )
+ {
+ cpp<<"\tasn1::tag t("<<m_octet_string.tag().m_class<<","<<m_octet_string.tag().m_value<<",true);\n";
+ cpp<<"\tstd::cout<<\"encode "<<structName<<" with BER explicit tag TODO \"<<std::endl;\n";
+ }
+ cpp<<"\tc.encode_octetstring(_t);\n";
+ cpp<<"}\n";
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecBER::decode(asn1::streams::ber &c,"<<structName<<" &_t)\n{\n";
+ cpp<<"\treturn c.decode_octetstring(_t);\n";
+ cpp<<"}\n";
+ }
+
+}
+
+//
+void cgcpph_octet_string::generate_oer()
+{
+ if (m_gencpp.with_codec())
+ {
+ std::string ns(m_gencpp.get_module()->cpp_name());
+ std::string structName(ns + "::" + m_octet_string.identifier_cpp_name());
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ //m_gencpp.gen_template_signature(m_os,type);
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void codecOER::encode(streams::oer &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int codecOER::decode(streams::oer &c,"<<structName<<" &_t);\n";
+
+
+ cpp<<"// octet_string generator todo"<<std::endl;
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecOER::encode(asn1::streams::oer &c,const "<<structName<<" &_t)\n{\n";
+ cpp<<"\tc.encode_octetstring(_t);";
+ cpp<<"}\n";
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecOER::decode(asn1::streams::oer &c,"<<structName<<" &_t)\n{\n";
+ cpp<<"\treturn c.decode_octetstring(_t);\n";
+ cpp<<"}\n";
+ }
+
+}
+//
+void cgcpph_octet_string::generate_jer()
+{
+ std::string ns(m_gencpp.get_module()->cpp_name());
+ std::string structName(ns + "::" + m_octet_string.identifier_cpp_name());
+ if (m_gencpp.with_codec())
+ {
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ //m_gencpp.gen_template_signature(m_os,type);
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void codecJER::encode(streams::jer &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int codecJER::decode(streams::jer &c,"<<structName<<" &_t);\n";
+
+
+ cpp<<"// octet_string generator todo"<<std::endl;
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecJER::encode(asn1::streams::jer &c,const "<<structName<<" &_t)\n{\n";
+ cpp<<"\tc.encode_octetstring(_t);";
+ cpp<<"}\n";
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecJER::decode(asn1::streams::jer &c,"<<structName<<" &_t)\n{\n";
+ cpp<<"\treturn c.decode_octetstring(_t);\n";
+ cpp<<"}\n";
+ }
+
+}
+
+//
+void cgcpph_octet_string::generate_xer()
+{
+}
+
--- /dev/null
+#ifndef CGCPPH_OCTETSTRING_H
+#define CGCPPH_OCTETSTRING_H
+
+
+/**
+ *
+ */
+class cgcpph_octet_string : public cgcpph_primitive
+{
+ protected:
+ cgcpph_octet_string(const cgcpph_octet_string &s) : cgcpph_primitive(s)
+ , m_octet_string(s.m_octet_string) {}
+ public:
+ //
+ cgcpph_octet_string(generate_codec_cpp &g,std::ostream &os,asn1::octet_string &s) ;
+ //
+ ~cgcpph_octet_string();
+
+ // generate codec part
+ virtual void generate_per() ;
+ //
+ virtual void generate_ber() ;
+ //
+ virtual void generate_oer() ;
+ //
+ virtual void generate_jer() ;
+ //
+ virtual void generate_xer() ;
+ protected:
+ virtual void generate_printf();
+
+ virtual void generate_ctors();
+
+ virtual void generate_operators() {};
+ protected:
+ asn1::octet_string &m_octet_string;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_codec_cpp.h"
+#include "asn1_generator_helper.h"
+#include "cgcpp_helper.h"
+#include "cgh_construct.h"
+#include "cgcpph_oid.h"
+
+
+cgcpph_oid::cgcpph_oid( generate_codec_cpp &g
+ , std::ostream &os
+ , asn1::object_identifier &s)
+ : cgh_construct(g,os,s) , m_oid(s)
+{
+}
+
+cgcpph_oid::~cgcpph_oid()
+{
+}
+
+
+/** Helper functions
+ *
+ *
+ */
+void cgcpph_oid::generate()
+{
+
+ GEN_LOG_DEBUG("cgcpph_oid::generate node=%s\n",m_oid.identifier_cpp_name().c_str());
+ // May be just include each module ...
+ // Handles the call with condition of the different generate_xxx
+ cgcpp_helper::generate();
+}
+
+//
+void cgcpph_oid::generate_ctors()
+{
+ std::string structName = m_oid.identifier_cpp_name();
+
+ if (m_gencpp.with_source_comment())
+ m_os<<"// cgcpph_oid helper launched \n";
+
+ // With tag
+ m_os<<"\n"<<structName;
+ m_os<<"::"<<structName<<"(const asn1::tag &t) : OBJECT_IDENTIFIER(t)\n{\n}\n";
+ if (m_gencpp.with_source_comment())
+ {
+ m_os<<"\n// Copy Constructor "<<structName<<"\n//\n";
+ } else
+ m_os<<"\n";
+
+ m_os<<structName;
+ m_os<<"::"<<structName<<"(const "<<structName<<" &c) : OBJECT_IDENTIFIER(c)\n{\n}\n";
+ // Copy Assignment
+ m_os<<structName<<"& ";
+ m_os<<structName;
+ m_os<<"::operator =(const "<<structName<<" &c) \n";
+ m_os<<"{\n";
+ m_os<<"\t"<<m_oid.cpp_name()<<"::operator=(c);\n";
+ m_os<<"\treturn *this;\n";
+ m_os<<"}\n";
+ // Copy Assignment
+ m_os<<structName<<"& ";
+ m_os<<structName;
+ m_os<<"::operator =(const "<<m_oid.cpp_name()<<" &c) \n";
+ m_os<<"{\n";
+ m_os<<"\t"<<m_oid.cpp_name()<<"::operator=(c);\n";
+ m_os<<"\treturn *this;\n";
+ m_os<<"}\n";
+}
+
+
+
+//
+void cgcpph_oid::generate_printf()
+{
+ std::string structName = m_oid.identifier_cpp_name();
+
+ m_os<<"\nstd::ostream & operator <<(std::ostream &os,const ";
+ m_os<<structName<<" &s)\n{\n";
+ m_os<<"\tos<<(OBJECT_IDENTIFIER)s;\n";
+ m_os<<"\treturn os;\n";
+ m_os<<"}\n";
+}
+
+//
+void cgcpph_oid::generate_operators()
+{
+ std::string structName = m_oid.identifier_cpp_name();
+
+ // With tag
+ m_os<<"\n// comparaison "<<structName<<"\n//\n";
+ m_os<<"bool\n"<<structName;
+ m_os<<"::operator =="<<"( "<<structName<<" &t)\n{\n";
+ m_os<<"\treturn "<<m_oid.cpp_name()<<"::operator == (t);\n";
+ m_os<<"}\n";
+}
+
+
+// generate codec part
+void cgcpph_oid::generate_per()
+{
+}
+
+//
+void cgcpph_oid::generate_ber()
+{
+ std::string structName = m_oid.identifier_cpp_name();
+ //
+ if (m_oid.tagged()
+ && m_gencpp.is_tag_explicit(m_oid))
+ {
+ m_os<<"void "<<structName<<"::encode(asn1::context &ctx)\n{\n"<<std::endl;
+ m_os<<"\tunsigned long pos = ctx.bytes();\n";
+ m_os<<"\tunsigned char *b = ctx.buffer();\n";
+ m_os<<"\tASN1_BER_LOG_DEBUG(\""<<structName<<"::encode(ctx) tag=%d \",this->tag().byte());\n";
+ m_os<<"\tb[pos++] = tag().byte();\n";
+ m_os<<"\tctx.nb_bits(16);\n";
+ m_os<<"\tasn1::tag t("<<m_oid.tag().m_class<<","<<m_oid.tag().m_value<<",true);\n";
+ m_os<<"\tset_tag(asn1::tag(0,6));\n";
+ m_os<<"\tctx.encode_boolean(*this);\n";
+ m_os<<"\tset_tag(t);\n";
+ m_os<<"\tb[pos] = ctx.bytes() -pos -1;\n";
+ m_os<<"}\n\n";
+ m_os<<"int "<<structName<<"::decode(asn1::context &ctx)\n{\n"<<std::endl;
+ m_os<<"\tasn1::tag t("<<m_oid.tag().m_class<<","<<m_oid.tag().m_value<<",true);\n";
+ m_os<<"\tASN1_BER_LOG_DEBUG(\""<<structName<<"::decode(ctx) exp tag= %d tag=%d \",t.byte(),this->tag().byte());\n";
+ m_os<<"\tif (ctx.decode_tag(t))\n\t{\n";
+ m_os<<"\t\tOBJECT_IDENTIFIER tmp;\n";
+ m_os<<"\t\tint rest = tmp.decode(ctx);\n";
+ m_os<<"\t\tthis->get_value() = tmp;\n";
+ m_os<<"\t\treturn rest;\n";
+ m_os<<"\t}\n";
+ m_os<<"\treturn asn1::wrong_tag;\n";
+ m_os<<"}\n";
+ }
+ //
+ if (m_gencpp.with_codec())
+ {
+ std::string ns (m_gencpp.get_module()->cpp_name());
+ std::string structName ( ns + "::" +m_oid.identifier_cpp_name() );
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void codecBER::encode(streams::ber &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int codecBER::decode(streams::ber &c,"<<structName<<" &_t);\n";
+ // Generate Implementation
+ // Implementation part
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecBER::encode(asn1::streams::ber &c,const "<<structName<<" &_t)\n{\n";
+ cpp<<"\tstd::cout<<\"codecBER::encode "<<structName<<" TODO\"<<std::endl;\n";
+ if ( m_oid.tagged()
+ && m_gencpp.is_tag_explicit(m_oid))
+ {
+ cpp<<"\tstd::cout<<\"codecBER::encode "<<structName<<" explicitly tagged\"<<std::endl;\n";
+ }
+ cpp<<"}\n";
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecBER::decode(asn1::streams::ber &c,"<<structName<<" &_t)\n{\n";
+ cpp<<"\tstd::cout<<\"codecBER::decode "<<structName<<" TODO\"<<std::endl;\n";
+ if ( m_oid.tagged()
+ && m_gencpp.is_tag_explicit(m_oid))
+ {
+ cpp<<"\tstd::cout<<\"codecBER::decode "<<structName<<" explicitly tagged\"<<std::endl;\n";
+ }
+ cpp<<"\treturn asn1::ok;\n";
+ cpp<<"}\n";
+ }
+}
+
+//
+void cgcpph_oid::generate_oer()
+{
+ //
+ if (m_gencpp.with_codec())
+ {
+ std::string ns (m_gencpp.get_module()->cpp_name());
+ std::string structName ( ns + "::" +m_oid.identifier_cpp_name() );
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void codecOER::encode(streams::oer &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int codecOER::decode(streams::oer &c,"<<structName<<" &_t);\n";
+ // Generate Implementation
+ // Implementation part
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecOER::encode(asn1::streams::oer &c,const "<<structName<<" &_t)\n{\n";
+ cpp<<"\tstd::cout<<\"codecOER::encode "<<structName<<" TODO\"<<std::endl;\n";
+ cpp<<"}\n";
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecOER::decode(asn1::streams::oer &c,"<<structName<<" &_t)\n{\n";
+ cpp<<"\tstd::cout<<\"codecOER::decode "<<structName<<" TODO\"<<std::endl;\n";
+ cpp<<"\treturn asn1::ok;\n";
+ cpp<<"}\n";
+ }
+}
+
+//
+void cgcpph_oid::generate_jer()
+{
+ //m_gencpp.gen_template_signature(m_os,type);
+ if (m_gencpp.with_codec())
+ {
+ std::string ns (m_gencpp.get_module()->cpp_name());
+ std::string structName ( ns + "::" +m_oid.identifier_cpp_name() );
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void codecJER::encode(streams::jer &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int codecJER::decode(streams::jer &c,"<<structName<<" &_t);\n";
+ // Generate Implementation
+ // Implementation part
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecJER::encode(asn1::streams::jer &c,const "<<structName<<" &_t)\n{\n";
+ cpp<<"\tstd::cout<<\"codecJER::encode "<<structName<<" TODO\"<<std::endl;\n";
+ cpp<<"}\n";
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecJER::decode(asn1::streams::jer &c,"<<structName<<" &_t)\n{\n";
+ cpp<<"\tstd::cout<<\"codecJER::decode "<<structName<<" TODO\"<<std::endl;\n";
+ cpp<<"\treturn asn1::ok;\n";
+ cpp<<"}\n";
+ }
+}
+
+//
+void cgcpph_oid::generate_xer()
+{
+}
+
--- /dev/null
+#ifndef CGCPPH_OBJECT_IDENTIFIER_H
+#define CGCPPH_OBJECT_IDENTIFIER_H
+
+
+/**
+ *
+ */
+class cgcpph_oid : public cgh_construct
+{
+ protected:
+ cgcpph_oid(const cgcpph_oid &s) : cgh_construct(s.m_gencpp,s.m_os,s.m_c)
+ , m_oid(s.m_oid)
+ {}
+ public:
+ cgcpph_oid( generate_codec_cpp &g
+ , std::ostream &os
+ , asn1::object_identifier &s) ;
+
+ ~cgcpph_oid();
+
+ // Helper functions
+ virtual void generate() ;
+
+ // generate codec part
+ virtual void generate_per() ;
+ //
+ virtual void generate_ber() ;
+ //
+ virtual void generate_oer() ;
+ //
+ virtual void generate_jer() ;
+ //
+ virtual void generate_xer() ;
+ protected:
+ virtual void generate_printf();
+ virtual void generate_ctors();
+ virtual void generate_operators();
+ protected:
+ asn1::object_identifier &m_oid;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_codec_cpp.h"
+#include "asn1_generator_helper.h"
+#include "cgcpp_helper.h"
+#include "cgcpph_primitive.h"
+
+
+cgcpph_primitive::cgcpph_primitive( generate_codec_cpp &g
+ , std::ostream &os
+ , asn1::primitive &s)
+ : cgcpp_helper(g,os) , m_primitive(s)
+{
+ m_structName = m_primitive.identifier_cpp_name();
+}
+
+cgcpph_primitive::~cgcpph_primitive()
+{
+}
+
+
+/** Helper functions
+ *
+ *
+ */
+void cgcpph_primitive::generate()
+{
+
+ GEN_LOG_DEBUG("cgcpph_primitive::generate node=%s\n",m_primitive.identifier_cpp_name().c_str());
+ cgcpp_helper::generate();
+}
+
+
+/**
+ *
+ */
+void
+cgcpph_primitive::generate_descriptor()
+{
+ std::string cn(m_primitive.identifier_cpp_name());
+ unsigned int _count = 0;
+
+ m_os<<"static asn1::tag TAGS_"<<m_primitive.identifier_cpp_name()<<"[] = {\n";
+ if (m_primitive.tagged())
+ {
+ m_os<<"asn1::tag("<<m_primitive.tag().m_class<<","<<m_primitive.tag().m_value;
+ if (m_gencpp.is_tag_explicit(m_primitive))
+ m_os<<",true";
+ m_os<<")\n";
+ } else {
+ m_os<<"asn1::tag("<<m_primitive.tag().m_class<<","<<m_primitive.tag().m_value;
+ m_os<<")\n";
+ }
+ m_os<<"};\n";
+
+ m_os<<"const asn1::types::descriptor "<<m_structName<<"::_meta = {\n";
+ if (m_primitive.tagged())
+ {
+ }
+ m_os<<" TAGS_"<<cn<<",";
+ m_os<<"sizeof(TAGS_"<<cn<<")/sizeof(TAGS_"<<cn<<"[0]),\n"; /* Tag List */
+ m_os<<" NULL,\n"; /* MEMBER List */
+ m_os<<" 0,\n"; /* Member list count */
+ m_os<<" NULL,\n"; /*tag to element */
+ m_os<<" 0\n"; /* tag to element count*/
+ m_os<<"};\n";
+ m_os<<std::endl;
+}
+
+void
+cgcpph_primitive::generate_operators()
+{
+ gen_equal();
+}
+//
+void cgcpph_primitive::generate_ctors()
+{
+ if (m_gencpp.with_source_comment())
+ m_os<<"// cgcpph_primitive helper launched ";
+ // With tag
+ m_os<<"\n"<<m_structName;
+ m_os<<"::"<<m_structName<<"(const asn1::tag &t)\n";
+ m_os<<"\t\t: "<<m_primitive.cpp_name()<<"(t)\n{\n}\n";
+ m_os<<"\n// Copy Constructor "<<m_structName<<"\n//\n";
+ m_os<<m_structName;
+ m_os<<"::"<<m_structName<<"(const "<<m_structName<<" &c)\n";
+ m_os<<"\t\t: "<<m_primitive.cpp_name()<<"()\n{\n}\n";
+ //clone
+ m_os<<m_structName<<" *";
+ m_os<<m_structName;
+ m_os<<"::clone()\n";
+ m_os<<"{\n";
+ m_os<<"\treturn new "<<m_structName<<"(*this);\n";
+ m_os<<"}\n";
+
+}
+//
+void cgcpph_primitive::gen_equal()
+{
+ m_os<<"\n// comparaison "<<m_structName<<"\n//\n";
+ m_os<<"bool\n"<<m_structName;
+ m_os<<"::operator =="<<"( "<<m_structName<<" &t)\n{\n";
+ m_os<<"\treturn get_value() == t.get_value();\n";
+ m_os<<"}\n";
+}
+
+
+//
+void cgcpph_primitive::generate_printf()
+{
+ m_os<<"\nstd::ostream & operator <<(std::ostream &os,const ";
+ m_os<<m_structName<<" &s)\n{\n";
+ m_os<<"\tos<<("<<m_primitive.cpp_name()<<")s;\n";
+ m_os<<"\treturn os;\n";
+ m_os<<"}\n";
+}
+
+// generate codec part
+void cgcpph_primitive::generate_per()
+{
+}
+
+//
+void cgcpph_primitive::generate_ber()
+{
+ std::string scope;
+ std::string structName = m_primitive.identifier_cpp_name();
+ //
+ if (m_primitive.tagged())
+ {
+ if ( m_gencpp.tag_mode(&m_primitive) == asn1::node::tag_type::TM_EXPLICIT)
+ {
+ m_os<<scope<<"void "<<structName<<"::encode(asn1::context &ctx)\n{\n"<<std::endl;
+ m_os<<"\tunsigned long pos = ctx.bytes();\n";
+ m_os<<"\tunsigned char *b = ctx.buffer();\n";
+ m_os<<"\tASN1_BER_LOG_DEBUG(\""<<structName<<"::encode(ctx) tag=%d \",this->tag().byte());\n";
+ m_os<<"\tb[pos++] = tag().byte();\n";
+ m_os<<"\tctx.nb_bits(16);\n";
+ m_os<<"\tasn1::tag t("<<m_primitive.tag().m_class<<","<<m_primitive.tag().m_value<<",true);\n";
+ // Why isn't the tag id in the class ?
+ // It is but than it can be modified.
+ m_os<<"\tset_tag(asn1::tag(0,"<<m_primitive.primitive_tag()<<"));\n";
+ // !!!!!!!!!! WARNING
+ m_os<<"\tctx.encode_boolean(*this);\n";
+ m_os<<"\tset_tag(t);\n";
+ m_os<<"\tb[pos] = ctx.bytes() -pos -1;\n";
+ m_os<<"}\n\n";
+ m_os<<scope<<"int "<<structName<<"::decode(asn1::context &ctx)\n{\n"<<std::endl;
+ m_os<<"\tasn1::tag t("<<m_primitive.tag().m_class<<","<<m_primitive.tag().m_value<<",true);\n";
+ m_os<<"\tASN1_BER_LOG_DEBUG(\""<<structName<<"::decode(ctx) exp tag= %d tag=%d \",t.byte(),this->tag().byte());\n";
+ m_os<<"\tif (ctx.decode_tag(t))\n\t{\n";
+ //m_os<<"\t\tBOOLEAN tmp;\n";
+ m_os<<"\t\t"<<m_primitive.cpp_name()<<" tmp;\n";
+ m_os<<"\t\tint rest = tmp.decode(ctx);\n";
+ m_os<<"\t\tthis->get_value() = tmp;\n";
+ m_os<<"\t\treturn rest;\n";
+ m_os<<"\t}\n";
+ m_os<<"\treturn asn1::wrong_tag;\n";
+ m_os<<"}\n";
+ }
+ }
+ if (m_gencpp.with_codec())
+ {
+ std::string ns(m_gencpp.get_module()->cpp_name());
+ std::string structName(ns + "::" + m_primitive.identifier()->cpp_name());
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ //m_gencpp.gen_template_signature(m_os,type);
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void codecBER::encode(streams::ber &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int codecBER::decode(streams::ber &c,"<<structName<<" &_t);\n";
+
+ cpp<<"// primitive generator todo"<<std::endl;
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecBER::encode(asn1::streams::ber &c,const "<<structName<<" &_t)\n{\n";
+ switch (m_primitive.type_id()())
+ {
+ case asn1::type::ASN1_NULL:
+ cpp<<"\tc.encode_null(_t);\n"; break;
+ case asn1::type::ASN1_BIT_STRING:
+ cpp<<"\tc.encode_bitstring(_t);\n"; break;
+ case asn1::type::ASN1_OCTET_STRING:
+ cpp<<"\tc.encode_octetstring(_t);\n"; break;
+ case asn1::type::ASN1_STRING:
+ case asn1::type::ASN1_STRING_VisibleString:
+ case asn1::type::ASN1_STRING_ISO646String: /* aka VisibleString */
+ case asn1::type::ASN1_STRING_UniversalString:
+ case asn1::type::ASN1_STRING_BMPString:
+ case asn1::type::ASN1_STRING_UTF8String :
+ case asn1::type::ASN1_STRING_GeneralString:
+ case asn1::type::ASN1_STRING_GraphicString:
+ case asn1::type::ASN1_STRING_T61String:
+ case asn1::type::ASN1_STRING_VideotexString:
+ case asn1::type::ASN1_STRING_ObjectDescriptor:
+ case asn1::type::ASN1_STRING_IA5String:
+ case asn1::type::ASN1_STRING_PrintableString:
+ case asn1::type::ASN1_STRING_NumericString:
+ case asn1::type::ASN1_STRING_TeletexString:
+ cpp<<"\tc.encode_string(_t);\n"; break;
+ //case asn1::type::ASN1_UNIVERSAL:
+ case asn1::type::ASN1_INTEGER:
+ case asn1::type::ASN1_BOOLEAN:
+ case asn1::type::ASN1_REAL:
+ case asn1::type::ASN1_OBJECT_IDENTIFIER:
+ case asn1::type::ASN1_RELATIVE_OID:
+ defautl:
+ ;
+ }
+ cpp<<"}\n";
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecBER::decode(asn1::streams::ber &c,"<<structName<<" &_t)\n{\n";
+ cpp<<"\treturn asn1::ok;\n";
+ cpp<<"}\n";
+ }
+}
+
+//
+void cgcpph_primitive::generate_oer()
+{
+ //
+}
+
+//
+void cgcpph_primitive::generate_jer()
+{
+ if (m_gencpp.with_codec())
+ {
+ std::string ns(m_gencpp.get_module()->cpp_name());
+ std::string structName(ns + "::" + m_primitive.identifier()->cpp_name());
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ //m_gencpp.gen_template_signature(m_os,type);
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void codecJER::encode(streams::jer &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int codecJER::decode(streams::jer &c,"<<structName<<" &_t);\n";
+
+ cpp<<"// primitive generator todo"<<std::endl;
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecJER::encode(asn1::streams::jer &c,const "<<structName<<" &_t)\n{\n";
+ switch (m_primitive.type_id()())
+ {
+ case asn1::type::ASN1_NULL:
+ cpp<<"\tc.encode_null(_t);\n"; break;
+ case asn1::type::ASN1_BIT_STRING:
+ cpp<<"\tc.encode_bitstring(_t);\n"; break;
+ case asn1::type::ASN1_OCTET_STRING:
+ cpp<<"\tc.encode_octetstring(_t);\n"; break;
+ case asn1::type::ASN1_STRING:
+ case asn1::type::ASN1_STRING_VisibleString:
+ case asn1::type::ASN1_STRING_ISO646String: /* aka VisibleString */
+ case asn1::type::ASN1_STRING_UniversalString:
+ case asn1::type::ASN1_STRING_BMPString:
+ case asn1::type::ASN1_STRING_UTF8String :
+ case asn1::type::ASN1_STRING_GeneralString:
+ case asn1::type::ASN1_STRING_GraphicString:
+ case asn1::type::ASN1_STRING_T61String:
+ case asn1::type::ASN1_STRING_VideotexString:
+ case asn1::type::ASN1_STRING_ObjectDescriptor:
+ case asn1::type::ASN1_STRING_IA5String:
+ case asn1::type::ASN1_STRING_PrintableString:
+ case asn1::type::ASN1_STRING_NumericString:
+ case asn1::type::ASN1_STRING_TeletexString:
+ cpp<<"\tc.encode_string(_t);\n"; break;
+ //case asn1::type::ASN1_UNIVERSAL:
+ case asn1::type::ASN1_INTEGER:
+ case asn1::type::ASN1_BOOLEAN:
+ case asn1::type::ASN1_REAL:
+ case asn1::type::ASN1_OBJECT_IDENTIFIER:
+ case asn1::type::ASN1_RELATIVE_OID:
+ defautl:
+ ;
+ }
+ cpp<<"}\n";
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecJER::decode(asn1::streams::jer &c,"<<structName<<" &_t)\n{\n";
+ cpp<<"\treturn asn1::ok;\n";
+ cpp<<"}\n";
+ }
+
+}
+
+//
+void cgcpph_primitive::generate_xer()
+{
+}
--- /dev/null
+#ifndef CGCPPH_PRIMITIVE_H
+#define CGCPPH_PRIMITIVE_H
+
+
+/**
+ * Generic code generation for all primitive types.
+ * boolean, integer, object_identifier, all strings,
+ * real, bit_string, octet_string
+ * all primitive generators should inherit from this
+ * class. This will simplify the code generation.
+ * Provides lesser specificities
+ */
+class cgcpph_primitive : public cgcpp_helper
+{
+ protected:
+ cgcpph_primitive(const cgcpph_primitive &s) : cgcpp_helper(s.m_gencpp,s.m_os)
+ , m_primitive(s.m_primitive)
+ , m_structName(s.m_structName)
+ {}
+ public:
+ cgcpph_primitive(generate_codec_cpp &g
+ , std::ostream &os
+ , asn1::primitive &s) ;
+
+ ~cgcpph_primitive();
+
+ // Helper functions
+ virtual void generate() ;
+
+ // generate codec part
+ virtual void generate_per() ;
+ //
+ virtual void generate_ber() ;
+ //
+ virtual void generate_oer() ;
+ //
+ virtual void generate_jer() ;
+ //
+ virtual void generate_xer() ;
+ protected:
+ virtual void generate_descriptor();
+
+ virtual void generate_printf();
+
+ virtual void generate_ctors();
+
+ virtual void generate_operators();
+
+ void gen_equal();
+
+ protected:
+ asn1::primitive &m_primitive;
+ std::string m_structName;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_codec_cpp.h"
+#include "asn1_generator_helper.h"
+#include "cgcpp_helper.h"
+#include "cgcpph_primitive.h"
+#include "cgcpph_real.h"
+
+
+cgcpph_real::cgcpph_real(generate_codec_cpp &g,std::ostream &os,asn1::real &s)
+ : cgcpph_primitive(g,os,s)
+ , m_real(s)
+{
+}
+
+cgcpph_real::~cgcpph_real()
+{
+}
+
+
+//
+void cgcpph_real::generate_ctors()
+{
+ if (m_gencpp.with_source_comment())
+ {
+ m_os<<"// cgcpph_real ctors helper launched ";
+ m_os<<m_structName<<"\n";
+ }
+ GEN_LOG_DEBUG("cgcpph_real::generate node=%s\n",m_real.identifier_cpp_name().c_str());
+ // May be just include each module ...
+ m_os<<"\n"<<m_structName;
+ m_os<<"::"<<m_structName<<"(const asn1::tag &t) : REAL(t)\n{\n}\n";
+ m_os<<"\n// Copy Constructor "<<m_structName<<"\n//\n";
+ m_os<<m_structName;
+ m_os<<"::"<<m_structName<<"(const "<<m_structName<<" &c) : REAL()\n{\n}\n";
+}
+
+void cgcpph_real::generate_operators()
+{
+ gen_equal();
+}
+//
+void cgcpph_real::gen_equal()
+{
+ m_os<<"\n// comparaison "<<m_structName<<"\n//\n";
+ m_os<<"bool\n"<<m_structName;
+ m_os<<"::operator =="<<"( "<<m_structName<<" &t)\n{\n";
+ m_os<<"\treturn get_value() == t.get_value();\n";
+ m_os<<"}\n";
+}
+
+
+//
+void cgcpph_real::generate_printf()
+{
+ m_os<<"\nstd::ostream & operator <<(std::ostream &os,const ";
+ m_os<<m_structName<<" &s)\n{\n";
+ m_os<<"\tos<<(REAL)s;\n";
+ m_os<<"\treturn os;\n";
+ m_os<<"}\n";
+}
+
+// generate codec part
+void cgcpph_real::generate_per()
+{
+}
+
+//
+void cgcpph_real::generate_ber()
+{
+ //
+ if (m_real.tagged())
+ {
+ if ( m_gencpp.is_tag_explicit(m_real) )
+ {
+ m_os<<"void "<<m_structName<<"::encode(asn1::context &ctx)\n{\n"<<std::endl;
+ m_os<<"\tunsigned long pos = ctx.bytes();\n";
+ m_os<<"\tunsigned char *b = ctx.buffer();\n";
+ m_os<<"\tASN1_BER_LOG_DEBUG(\""<<m_structName<<"::encode(ctx) tag=%d \",this->tag().byte());\n";
+ m_os<<"\tb[pos++] = tag().byte();\n";
+ m_os<<"\tctx.nb_bits(16);\n";
+ m_os<<"\tasn1::tag t("<<m_real.tag().m_class<<","<<m_real.tag().m_value<<",true);\n";
+ m_os<<"\tset_tag(asn1::tag(0,1));\n";
+ m_os<<"\tctx.encode_real(*this);\n";
+ m_os<<"\tset_tag(t);\n";
+ m_os<<"\tb[pos] = ctx.bytes() -pos -1;\n";
+ m_os<<"}\n\n";
+ m_os<<"int "<<m_structName<<"::decode(asn1::context &ctx)\n{\n"<<std::endl;
+ m_os<<"\tasn1::tag t("<<m_real.tag().m_class<<","<<m_real.tag().m_value<<",true);\n";
+ m_os<<"\tASN1_BER_LOG_DEBUG(\""<<m_structName<<"::decode(ctx) exp tag= %d tag=%d \",t.byte(),this->tag().byte());\n";
+ m_os<<"\tif (ctx.decode_tag(t))\n\t{\n";
+ m_os<<"\t\tBOOLEAN tmp;\n";
+ m_os<<"\t\tint rest = tmp.decode(ctx);\n";
+ m_os<<"\t\tthis->get_value() = tmp.get_value();\n";
+ m_os<<"\t\treturn rest;\n";
+ m_os<<"\t}\n";
+ m_os<<"\treturn asn1::wrong_tag;\n";
+ m_os<<"}\n";
+ }
+ }
+}
+
+//
+void cgcpph_real::generate_oer()
+{
+ //
+}
+
+//
+void cgcpph_real::generate_jer()
+{
+}
+
+//
+void cgcpph_real::generate_xer()
+{
+}
+
--- /dev/null
+#ifndef CGCPPH_REAL_H
+#define CGCPPH_REAL_H
+
+
+/**
+ *
+ */
+class cgcpph_real : public cgcpph_primitive
+{
+ protected:
+ cgcpph_real(const cgcpph_real &s) : cgcpph_primitive(s)
+ , m_real(s.m_real)
+ {}
+ public:
+ cgcpph_real(generate_codec_cpp &g,std::ostream &os,asn1::real &s) ;
+
+ ~cgcpph_real();
+
+ // generate codec part
+ virtual void generate_per() ;
+ //
+ virtual void generate_ber() ;
+ //
+ virtual void generate_oer() ;
+ //
+ virtual void generate_jer() ;
+ //
+ virtual void generate_xer() ;
+ protected:
+ virtual void generate_ctors();
+
+ virtual void generate_operators();
+
+ void gen_equal();
+
+ virtual void generate_printf();
+ protected:
+ asn1::real &m_real;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_codec_cpp.h"
+#include "asn1_generator_helper.h"
+#include "cgcpp_helper.h"
+#include "asn1_visitor.h"
+#include "cgh_construct.h"
+#include "cgcpph_sequence.h"
+
+
+cgcpph_sequence::cgcpph_sequence(generate_codec_cpp &g,std::ostream &os,asn1::sequence &s)
+ : m_seq(s)
+ , cgh_construct(g,os,s)
+{
+}
+
+cgcpph_sequence::~cgcpph_sequence()
+{
+}
+
+
+// Helper functions
+void cgcpph_sequence::generate(const std::string &scope)
+{
+ bool priv = m_seq.is_private() ;
+
+ if (m_gencpp.with_source_comment())
+ {
+ m_os<<"\n//\n// cgcpph_sequence helper launched ";
+ m_os<<"\n//\n";
+ }
+ /* Issue with parameterized types */
+
+ cgcpp_helper::generate();
+
+ if (m_gencpp.with_ber())
+ gen_data_length();
+
+ m_os<<std::endl;
+}
+
+/**
+ * @note if there are parameters,
+ * don't generate the tables it does not work
+ * here.
+ * I need to review the parameterized types.
+ * Introduce the notion of instance of parameterized type.
+ * It make more sense.
+ */
+void cgcpph_sequence::generate_descriptor()
+{
+ if (m_seq.identifier()->parameters())
+ return ;
+ cgh_construct::gen_desc_seqset();
+}
+
+/**
+ *
+ */
+void cgcpph_sequence::generate_ctors()
+{
+ std::string scope("");
+ bool priv( m_seq.is_private() );
+ gen_ctor(scope,priv);
+
+ gen_clone(scope,priv);
+}
+
+/**
+ * generate codec part
+ */
+void cgcpph_sequence::generate_per()
+{
+}
+
+//
+void cgcpph_sequence::generate_ber()
+{
+ bool priv( m_seq.is_private() );
+
+ gen_nencode("",priv);
+ gen_ndecode("",priv);
+
+ if (m_gencpp.with_codec())
+ {
+ std::string ns ( m_gencpp.get_module()->cpp_name() ) ;
+ std::string structName ( ns + "::" +m_seq.identifier_cpp_name() );
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ //m_gencpp.gen_template_signature(m_os,type);
+ hpp<<"\n// sequence type "<<structName<<" priv="<<priv<<"\n";
+ hpp<<"template<>\n";
+ hpp<<"void asn1::codecBER::encode(asn1::streams::ber &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int asn1::codecBER::decode(asn1::streams::ber &c,"<<structName<<" &_t);\n";
+ /* Generate implementation */
+ gen_codec_ber_encode();
+ /* Implementation of decoding stream */
+#if 1
+ gen_codec_ber_decode();
+#else
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecBER::decode(asn1::streams::ber &c,"<<structName<<" &_t)\n{\n";
+ cpp<<"\tif ( c.decode_sequence_preamble(_t) != asn1::ok)\n";
+ cpp<<"\t\treturn asn1::wrong_type;\n";
+ /* loop over fields */
+ for (asn1::node::iterator it = m_c.begin(); it != m_c.end() ; it++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*it);
+ asn1::typenode *attr_type = f->get_type();
+ if (attr_type != NULL)
+ {
+ if (attr_type->type_id()() == asn1::type::ASN1_EXTENSIBLE)
+ {
+ cpp<<"\t// Extensible marker"<<std::endl;
+ } else
+ {
+ if (f->flags().is_optional() && (! f->flags().is_default()))
+ {
+ cpp<<"\tdecode(c,_t."<<f->cpp_name()<<".get());\n";
+ } else
+ {
+ cpp<<"\tdecode(c,_t."<<f->cpp_name()<<");\n";
+ }
+ //cpp<<"\t}\n";
+ }
+ }
+ }
+ cpp<<"\tif ( c.decode_sequence_epilogue(_t) != asn1::ok)\n";
+ cpp<<"\t\treturn asn1::wrong_type;\n";
+ cpp<<"\treturn asn1::ok;\n";
+ cpp<<"}\n";
+#endif
+
+ /**/
+ }
+}
+
+//
+void cgcpph_sequence::generate_oer()
+{
+}
+
+//
+void cgcpph_sequence::generate_xer()
+{
+}
+
+
+/**
+* Generate ctor code
+*/
+void
+cgcpph_sequence::gen_ctor(const std::string &scope,bool priv)
+{
+ asn1::node::iterator lit = m_seq.begin();
+ std::string structName;
+
+ m_gencpp.gen_template_signature(m_os,&m_seq);
+
+ if (!priv)
+ {
+ structName = m_seq.identifier_cpp_name();
+ } else
+ {
+ structName = m_seq.cpp_name();
+ }
+
+ m_os<<structName;
+ m_gencpp.gen_template_signature_class(m_os,&m_seq);
+ m_os<<"::"<<structName<<"( ";
+ m_os<<"const asn1::tag &t) "<<std::endl;
+
+ m_os<<" : asn1::types::sequence_type(t)\n";
+
+ for ( asn1::node::iterator it = m_seq.begin()
+ ; it != m_seq.end() ; ++it)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*it);
+ asn1::typenode *attr_type = f->get_type();
+ if (attr_type != NULL)
+ {
+ m_os<<" , ";
+ if (attr_type->meta_id()() == asn1::meta::OBJECT)
+ {
+ m_os<<f->cpp_name()<<"(NULL)";
+ }
+ //std::cout<<"1 and HERE "<<(*it)->name()<<std::endl;
+ if ( f->flags().is_default() )
+ {
+ gen_ctor_init(f);
+ } else
+ {
+ switch(attr_type->type_id()())
+ {
+ case asn1::type::ASN1_INTEGER:
+ if ( attr_type && attr_type->tagged())
+ { // Ok tagged value
+ if(attr_type->tag().m_mode == asn1::node::tag_type::TM_IMPLICIT)
+ {
+ asn1::node::tag_type lt = attr_type->tag();
+ m_os<<(*it)->cpp_name()<<"(asn1::tag("<<lt.m_class<<","<<lt.m_value<<"))";
+ } else
+ m_os<<(*it)->cpp_name()<<"(/*Explicit tag*/)";
+ } else
+ m_os<<(*it)->cpp_name()<<"()";
+ //os<<(*it)->cpp_name()<<"(asn1::prim::types::Integer(0))";
+ break;
+ case asn1::type::ASN1_BOOLEAN:
+ m_os<<(*it)->cpp_name()<<"()";
+ //os<<(*it)->cpp_name()<<"(asn1::prim::types::Boolean(false))";
+ break;
+ default:
+ {
+ if ( attr_type && attr_type->tagged())
+ { // Ok tagged value
+ if(attr_type->tag().m_mode == asn1::node::tag_type::TM_IMPLICIT)
+ {
+ asn1::node::tag_type lt = attr_type->tag();
+ m_os<<(*it)->cpp_name()<<"(asn1::tag("<<lt.m_class<<","<<lt.m_value<<"))";
+ } else
+ m_os<<(*it)->cpp_name()<<"(/*Explicit tag*/)";
+ } else
+ m_os<<(*it)->cpp_name()<<"(/*def no tag*/)";
+ }
+
+ } /* end switch */
+ }
+ if ( (*it)->flags().is_optional() )
+ {
+ m_os<<"/*optional*/";
+ }
+ m_os<<"\n";
+ }
+
+ } /* end for */
+
+ m_os<<"{"<<std::endl;
+ if (m_gencpp.with_source_debug())
+ {
+ m_os<<"\tASN1_BER_LOG_DEBUG(\""<<m_seq.identifier_name();
+ m_os<<"(%p) seq CREATE "<<m_seq.identifier_name()<<" \",this);\n";
+ }
+ m_os<<"}\n\n";
+ gen_copy_ctor(scope,priv);
+}
+
+/**
+* Initialize member attributes in ctor
+*/
+void
+cgcpph_sequence::gen_ctor_init(asn1::field *field)
+{
+ asn1::typenode *attr_type = field->get_type();
+ switch(attr_type->type_id()()) {
+ case asn1::type::ASN1_INTEGER:
+ {
+ asn1::value::ptr val = field->flags().m_value1;
+ if (! val.is_nul()) {
+ m_os<<field->cpp_name()<<"(INTEGER("<< val->m_integer <<"))";
+ } else
+ m_os<<field->cpp_name()<<"()";
+ }
+ break;
+#if 0
+ case asn1::type::ASN1_BOOLEAN:
+ if ( ! (field->flags().m_value1).is_nul() )
+ {
+ switch ((field->flags().m_value1)->type)
+ {
+ case asn1::value::VT_TRUE:
+ m_os<<field->cpp_name()<<"(BOOLEAN(asn1::prim::types::Boolean(true)))";
+ break;
+ case asn1::value::VT_FALSE:
+ m_os<<field->cpp_name()<<"(BOOLEAN(asn1::prim::types::Boolean(false)))";
+ break;
+ default:
+ m_os<<field->cpp_name()<<"(false) /*no*/";
+ }
+ } else
+ m_os<<field->cpp_name()<<"(false) /*m_value1 NULL "<<field->name()<<"*/";
+ break;
+#endif
+ case asn1::type::ASN1_STRING:
+ case asn1::type::ASN1_STRING_IA5String:
+ case asn1::type::ASN1_STRING_PrintableString:
+ case asn1::type::ASN1_STRING_VisibleString:
+ case asn1::type::ASN1_STRING_ISO646String:
+ case asn1::type::ASN1_STRING_NumericString:
+ case asn1::type::ASN1_STRING_UniversalString:
+ case asn1::type::ASN1_STRING_BMPString:
+ case asn1::type::ASN1_STRING_UTF8String :
+ case asn1::type::ASN1_STRING_GeneralString:
+ case asn1::type::ASN1_STRING_GraphicString:
+ case asn1::type::ASN1_STRING_TeletexString:
+ case asn1::type::ASN1_STRING_T61String:
+ case asn1::type::ASN1_STRING_VideotexString:
+ case asn1::type::ASN1_STRING_ObjectDescriptor:
+ {
+ asn1::value::ptr val = field->flags().m_value1;
+ if (! val.is_nul()) {
+ m_os<<field->cpp_name()<<"(asn1::prim::types::String("<< val->m_string <<"))";
+ } else
+ m_os<<field->cpp_name()<<"()";
+ }
+ break;
+
+ default:
+ {
+ if ( attr_type && attr_type->tagged())
+ { // Ok tagged value
+ if(attr_type->tag().m_mode == asn1::node::tag_type::TM_IMPLICIT)
+ {
+ asn1::node::tag_type lt = attr_type->tag();
+ m_os<<field->cpp_name()<<"(asn1::tag("<<lt.m_class<<","<<lt.m_value<<"))";
+ } else
+ m_os<<field->cpp_name()<<"(/*Explicit tag*/)";
+ } else
+ m_os<<field->cpp_name()<<"(/*def no tag*/)";
+ }
+ }
+}
+#if 1
+
+/**
+ * Helper class to generate parameter
+ * initialization per attribute.
+ */
+class gco_pc
+{
+ public:
+ gco_pc(std::ostream &_os,generate_codec_cpp &_g,asn1::sequence &_c)
+ : m_os(_os) , m_log(_g.logger()), m_Gen(_g), m_seq(_c)
+ {
+ m_assign = m_seq.identifier()->as_assignment();
+ assert( (m_assign != NULL ) && " m_assign should not be NULL for choice type");
+ }
+
+ void do_parameters(asn1::assignment *_a)
+ {
+ if ( ! _a)
+ return;
+ asn1::constructed *aplist = _a->parameters();
+ if ( ! aplist)
+ return;
+ for ( asn1::node::iterator it = aplist->begin() ;
+ it != aplist->end(); ++it)
+ {
+ /* either value_set, object_set value, typeref */
+ asn1::parameter *p = dynamic_cast<asn1::parameter *>(*it);
+ if (asn1::node *g = p->get_governor())
+ {
+ asn1::typeref *objr = dynamic_cast<asn1::typeref *>(g);
+ if (objr)
+ {
+ m_os<<"\t// "<<g->name()<<" "<<p->name()<<std::endl;
+ if (!objr->is_simple())
+ {
+ m_os<<"\t"<<p->cpp_name()<<" = t."<<p->cpp_name()<<";"<<std::endl;
+ }
+ }else
+ {
+ m_os<<"\t// "<<g->name()<<" "<<p->name()<<std::endl;
+ }
+ }
+ }
+ }
+ protected:
+ asn1::node *m_rt;
+ asn1::assignment *m_assign;
+ std::fstream &m_log;
+ std::ostream &m_os;
+ generate_codec_cpp &m_Gen;
+ asn1::sequence &m_seq;
+};
+
+#endif
+/**
+*
+* Generate code for copy ctor
+*/
+void
+cgcpph_sequence::gen_copy_ctor(const std::string &scope,bool priv)
+{
+ std::string name;
+ asn1::node::iterator lit = m_seq.begin();
+ asn1::assignment *ident = m_seq.identifier()->as_assignment();
+ asn1::sequence *type = &m_seq;
+ bool first = true;
+
+ m_gencpp.gen_template_signature(m_os,&m_seq);
+ if (!priv)
+ {
+ name=type->identifier_cpp_name();
+ m_os<<""<<type->identifier_cpp_name();
+ m_gencpp.gen_template_signature_class(m_os,type);
+ m_os<<"::"<<type->identifier_cpp_name()<<"(const ";
+ m_os<<type->identifier_cpp_name()<<" &t)"<<"\t"<<std::endl;
+ } else
+ {
+ name = type->cpp_name();
+ m_os<<""<<type->cpp_name();
+ m_gencpp.gen_template_signature_class(m_os,type);
+ m_os<<"::"<<type->cpp_name()<<"(const ";
+ m_os<<type->cpp_name()<<" &t)"<<"\t"<<std::endl;
+ }
+
+ m_os<<" : asn1::types::sequence_type(t)\n";
+
+ for (asn1::node::iterator it = type->begin(); it != type->end() ; it++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*it);
+ asn1::typenode *attr_type = f->get_type();
+
+ if (attr_type != NULL)
+ {
+ m_os<<" , ";
+ m_os<<(*it)->cpp_name()<<"(t."<<(*it)->cpp_name()<<")";
+ if ( (*it)->flags().is_optional() ) {
+ m_os<<"/*optional*/";
+ }
+ m_os<<"\n";
+ }
+
+ }
+
+ m_os<<"{"<<std::endl;
+ if (m_gencpp.with_source_debug())
+ m_os<<"\tASN1_BER_LOG_DEBUG(\""<<name<<" copy ctor\");"<<std::endl;
+ if (ident->parameters() && ident->parameters()->size()>0)
+ {
+ gco_pc docp_params(m_os,m_gencpp,m_seq);
+ docp_params.do_parameters(m_seq.identifier()->as_assignment());
+ }
+ m_os<<"}\n\n";
+}
+
+/**
+ *
+ */
+void
+cgcpph_sequence::gen_clone(const std::string &scope,bool priv)
+{
+ std::string lscope;
+ asn1::node *type = &m_seq;
+ asn1::node *ident = m_seq.identifier();
+ asn1::constructed *params = NULL;
+ std::string structName ;
+
+ if (ident != NULL)
+ {
+ params = ident->parameters();
+ }
+
+ if (!priv)
+ {
+ structName = type->identifier_cpp_name();
+ } else
+ {
+ structName = type->cpp_name();
+ }
+
+ m_os<<"\n";
+ m_gencpp.gen_template_signature(m_os,type);
+
+ m_os<<""<<scope<<structName;
+ m_gencpp.gen_template_signature_class(m_os,type);
+ m_os<<"* ";
+
+ m_os<<scope<<structName;
+ m_gencpp.gen_template_signature_class(m_os,type);
+ m_os<<"::clone()\n";
+ m_os<<"{\n";
+
+ if (m_gencpp.with_source_debug())
+ {
+ m_os<<"\t\tASN1_BER_LOG_DEBUG(\""<<type->identifier_name();
+ m_os<<"::clone "<<type->identifier_name()<<" \");\n";
+ }
+ m_os<<"\treturn new "<<structName;
+ if (params && m_gencpp.is_template(params))
+ {
+ m_gencpp.gen_template_params(m_os,params);
+ }
+ m_os<<"(*this);\n}\n"<<std::endl;
+}
+
+/**
+ *
+ */
+void
+cgcpph_sequence::generate_operators( )
+{
+ cgh_construct::gen_equal();
+}
+
+
+/**
+ * Generate printf code
+ */
+void
+cgcpph_sequence::generate_printf( )
+{
+ std::string scope("");
+ asn1::sequence *type = &m_seq;
+ m_os<<"#if 1\n";
+ /*
+ * Try to handler sequence of sequence
+ */
+ m_gencpp.gen_template_signature(m_os,type);
+ m_os<<"\nvoid\n";
+ m_os<<m_structName;
+ m_gencpp.gen_template_signature_class(m_os,type);
+ m_os<<"::printf(std::ostream &os) const\n{\n";
+ m_os<<"\tos<<*this;\n"<<std::endl;
+ m_os<<"}\n";
+
+ // friend operator <<
+ m_gencpp.gen_template_signature(m_os,type);
+ m_os<<"std::ostream &operator <<(std::ostream &os,const ";
+
+ m_os<<m_gencpp.get_module()->cpp_name();
+ m_os<<"::"<<m_structName;
+
+ m_gencpp.gen_template_signature_class(m_os,type);
+ m_os<<" ";
+ /**
+ * TODO very wrong type should not have parameter except if its a private
+ * type
+ */
+ if (type->parameters() && m_gencpp.is_template(type->parameters()))
+ {
+ m_gencpp.gen_template_params(m_os,type->parameters());
+ }
+ m_os<<" &s"<<")\n{\n";
+ m_os<<"\tstd::streamsize indent = os.precision() + 2;"<<std::endl;
+ m_os<<"\tos<<std::setw(indent+10)<<\"SEQUENCE (\\n\";\n";
+
+ for (asn1::node::iterator it = type->begin(); it != type->end() ; it++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*it);
+ asn1::typenode *attr_type = f->get_type();
+ if (attr_type != NULL)
+ {
+ if (attr_type->type_id()() == asn1::type::ASN1_EXTENSIBLE)
+ {
+ m_os<<"\t// Extensible marker"<<std::endl;
+ } else
+ {
+ m_os<<"\tos<<";
+ m_gencpp.gen_composite_attribute_printf(m_os,scope,*f);
+ }
+ }
+
+ }
+ m_os<<"\tos<<std::setw(indent)<<std::setprecision(indent-2)<<\")\";\n";
+ m_os<<"\treturn os;\n";
+ m_os<<"};\n\n";
+
+ m_os<<"#endif\n";
+}
+
+/**
+ *
+ */
+void
+cgcpph_sequence::gen_codec(const std::string &scope,bool priv)
+{
+ std::string structName ;
+ structName = m_gencpp.get_module()->cpp_name();
+ structName = structName + "::" +m_seq.identifier()->cpp_name();
+
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ //m_gencpp.gen_template_signature(m_os,type);
+ hpp<<"\n// sequence type "<<scope<<"::"<<structName<<" priv="<<priv<<"\n";
+#if 0
+ hpp<<"template<>\n";
+ hpp<<"void asn1::codecBER::encode(asn1::streams::ber &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int asn1::codecBER::decode(asn1::streams::ber &c,"<<structName<<" &_t);\n";
+#endif
+ if (m_gencpp.with_jer())
+ {
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void codecJER::encode(asn1::streams::jer &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int codecJER::decode(asn1::streams::jer &c,"<<structName<<" &_t);\n";
+ }
+}
+
+/**
+ * vim: et sw=2 ts=2 list:
+ */
--- /dev/null
+#ifndef CGCPPH_SEQUENCE_H
+#define CGCPPH_SEQUENCE_H
+
+
+/**
+ *
+ */
+class cgcpph_sequence : public cgh_construct
+{
+ protected:
+ cgcpph_sequence(const cgcpph_sequence &s)
+ : cgh_construct(s.m_gencpp,s.m_os,s.m_seq)
+ , m_seq(s.m_seq)
+ {}
+ public:
+ cgcpph_sequence(generate_codec_cpp &g,std::ostream &os,asn1::sequence &s) ;
+ ~cgcpph_sequence();
+
+ // Helper functions wrong signature !!!
+ virtual void generate(const std::string &scope) ;
+ // generate codec part
+ virtual void generate_per() ;
+ //
+ virtual void generate_ber() ;
+ //
+ virtual void generate_oer() ;
+ //
+ virtual void generate_xer() ;
+ protected:
+ /**
+ * Generate ctor code
+ */
+ void gen_ctor(const std::string &scope,bool priv);
+ /**
+ * Generate printf code
+ */
+ virtual void generate_printf( );
+ /**
+ * Initialize member attributes in ctor
+ */
+ void gen_ctor_init(asn1::field *field);
+ /**
+ *
+ * Generate code for copy ctor
+ */
+ void gen_copy_ctor(const std::string &scope , bool priv);
+ /**
+ * Generate clone
+ */
+ void gen_clone(const std::string &scope , bool priv);
+ /**
+ *
+ */
+ virtual void generate_operators();
+ /**
+ *
+ */
+ virtual void generate_ctors();
+ /**
+ *
+ */
+ virtual void generate_descriptor();
+ /**
+ * Generate codec
+ */
+ void gen_codec(const std::string &scope,bool priv);
+ protected:
+ asn1::sequence &m_seq;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_codec_cpp.h"
+#include "asn1_generator_helper.h"
+#include "cgcpp_helper.h"
+#include "cgcpph_sequenceof.h"
+
+
+cgcpph_sequenceof::cgcpph_sequenceof( generate_codec_cpp &g
+ , std::ostream &os
+ , asn1::sequence_of &s)
+ : cgcpp_helper(g,os) , m_seqof(s)
+{
+}
+
+cgcpph_sequenceof::~cgcpph_sequenceof()
+{
+}
+
+void cgcpph_sequenceof::generate()
+{
+ std::string structName = m_seqof.identifier()->cpp_name();
+
+ if (m_gencpp.with_source_comment())
+ m_os<<"// cgcpph_sequenceof helper launched \n";
+
+ GEN_LOG_DEBUG("cgcpph_sequenceof::generate node=%s\n",m_seqof.identifier_cpp_name().c_str());
+
+ gen_ctors();
+
+ gen_equal();
+
+ gen_printf();
+ // Generate generators
+ cgcpp_helper::generate();
+}
+//
+void cgcpph_sequenceof::gen_ctors()
+{
+ asn1::node *ns = NULL;
+ asn1::typenode *eltype = m_seqof.get_eltype();
+ std::string structName = m_seqof.identifier_cpp_name();
+ std::string eltypeName;
+ if (m_gencpp.type_in_imports(eltype,&ns) )
+ {
+ eltypeName = ns->cpp_name() + "::" + eltype->cpp_name();
+ } else
+ eltypeName = eltype->cpp_name();
+
+ // With tag
+ m_os<<"\n"<<structName;
+ m_os<<"::"<<structName<<"(const asn1::tag &t)\n";
+ m_os<<"\t\t: Seq<"<<eltypeName<<">(t)\n{\n}\n";
+ m_os<<"\n// Copy Constructor "<<structName<<"\n//\n";
+ m_os<<structName;
+ m_os<<"::"<<structName<<"(const "<<structName<<" &c)\n";
+ m_os<<"\t\t: Seq<"<<eltypeName<<">(c)\n{\n}\n";
+ //clone
+ m_os<<structName<<" *";
+ m_os<<structName;
+ m_os<<"::clone()\n";
+ m_os<<"{\n";
+ m_os<<"\treturn new "<<structName<<"(*this);\n";
+ m_os<<"}\n";
+
+}
+//
+void cgcpph_sequenceof::gen_equal()
+{
+ asn1::typenode *type = &m_seqof;
+ std::string structName = type->identifier()->cpp_name();
+
+ // With tag
+ m_os<<"\n// comparaison "<<structName<<"\n//\n";
+ m_os<<"bool\n"<<structName;
+ m_os<<"::operator =="<<"(const "<<structName<<" &t)\n{\n";
+ m_os<<"\treturn false;\n";
+ //m_os<<"\treturn get_value() == t.get_value();\n";
+ m_os<<"}\n";
+}
+
+
+//
+void cgcpph_sequenceof::gen_printf()
+{
+ std::string structName = m_seqof.identifier_cpp_name();
+ asn1::typenode *eltype = m_seqof.get_eltype();
+ std::string eltypeName;
+ asn1::node *ns = NULL;
+ if (m_gencpp.type_in_imports(eltype,&ns) )
+ {
+ eltypeName = ns->cpp_name() + "::" + eltype->cpp_name();
+ } else
+ eltypeName = eltype->cpp_name();
+
+
+ m_os<<"\nstd::ostream & operator <<(std::ostream &os,const ";
+ m_os<<structName<<" &s)\n{\n";
+ m_os<<"\toperator <<(os,(Seq<"<<eltypeName<<"> &)s);\n";
+ //m_os<<"\tos<<\"SEQUENCE OF PERSO TODO\";\n";
+ m_os<<"\treturn os;\n";
+ m_os<<"}\n";
+}
+
+
+
+void
+cgcpph_sequenceof::generate_ber()
+{
+ std::string NameS = m_gencpp.get_module()->cpp_name();
+ std::string eltypeName;
+ std::string structName( NameS + "::" +m_seqof.identifier()->cpp_name());
+ asn1::typenode *eltype = m_seqof.get_eltype();
+ asn1::node *ns = NULL;
+
+ if (m_gencpp.type_in_imports(eltype,&ns) )
+ {
+ eltypeName = ns->cpp_name() + "::" + eltype->cpp_name();
+ } else
+ {
+ if (eltype->is_primitive())
+ {
+ eltypeName = eltype->cpp_name();
+ } else
+ eltypeName = m_gencpp.get_module()->cpp_name() +"::" + eltype->cpp_name();
+ }
+
+ if (m_gencpp.with_codec())
+ {
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void codecBER::encode(asn1::streams::ber &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int codecBER::decode(asn1::streams::ber &c,"<<structName<<" &_t);\n";
+ /* Implementation */
+ cpp<<"// type sequence of "<<std::endl;
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecBER::encode(asn1::streams::ber &c,const "<<structName<<" &_t)\n{\n";
+ if ( m_seqof.tagged()
+ && ( m_gencpp.tag_mode(&m_seqof) == asn1::node::tag_type::TM_EXPLICIT))
+ {
+ cpp<<"\tstd::cout<<\"codecBER::encode sequence of "<<structName<<" UW \"<<std::endl;\n";
+ }
+ cpp<<"\tencode(c,( const Seq<"<<eltypeName<<"> &)_t);\n";
+ cpp<<"}\n";
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecBER::decode(asn1::streams::ber &c,"<<structName<<" &_t)\n{\n";
+ if ( m_seqof.tagged()
+ && ( m_gencpp.tag_mode(&m_seqof) == asn1::node::tag_type::TM_EXPLICIT))
+ {
+ cpp<<"\tstd::cout<<\"codecBER::decode sequence of "<<structName<<" UW \"<<std::endl;\n";
+ }
+ cpp<<"\treturn decode(c,( Seq<"<<eltypeName<<"> &)_t);\n";
+ cpp<<"}\n";
+ }
+
+}
+// generate per
+//
+void
+cgcpph_sequenceof::generate_per()
+{
+ std::string NameS = m_gencpp.get_module()->cpp_name();
+ std::string eltypeName;
+ std::string structName( NameS + "::" +m_seqof.identifier()->cpp_name());
+ asn1::typenode *eltype = m_seqof.get_eltype();
+ asn1::node *ns = NULL;
+
+ if (m_gencpp.type_in_imports(eltype,&ns) )
+ {
+ eltypeName = ns->cpp_name() + "::" + eltype->cpp_name();
+ } else
+ {
+ if (eltype->is_primitive())
+ {
+ eltypeName = eltype->cpp_name();
+ } else
+ eltypeName = m_gencpp.get_module()->cpp_name() +"::" + eltype->cpp_name();
+ }
+
+
+ if (m_gencpp.with_codec())
+ {
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void codecPER::encode(asn1::streams::per &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int codecPER::decode(asn1::streams::per &c,"<<structName<<" &_t);\n";
+ /* Implementation */
+ cpp<<"// type sequence of "<<std::endl;
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecPER::encode(asn1::streams::per &c,const "<<structName<<" &_t)\n{\n";
+ cpp<<"\tc.put_char(\"[\",1);\n";
+ cpp<<"\tencode(c,( const Seq<"<<eltypeName<<"> &)_t);\n";
+ cpp<<"\tc.put_char(\"] \",2);\n";
+ cpp<<"}\n";
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecPER::decode(asn1::streams::per &c,"<<structName<<" &_t)\n{\n";
+ //cpp<<"\tstd::cout<<\"codecPER::decode sequence of "<<structName<<" UW \"<<std::endl;\n";
+ cpp<<"\treturn decode(c,( Seq<"<<eltypeName<<"> &)_t);\n";
+ cpp<<"}\n";
+ }
+
+}
+
+// Generate oer
+//
+void
+cgcpph_sequenceof::generate_oer()
+{
+ std::string NameS = m_gencpp.get_module()->cpp_name();
+ std::string eltypeName;
+ std::string structName( NameS + "::" +m_seqof.identifier()->cpp_name());
+ asn1::typenode *eltype = m_seqof.get_eltype();
+ asn1::node *ns = NULL;
+
+ if (m_gencpp.type_in_imports(eltype,&ns) )
+ {
+ eltypeName = ns->cpp_name() + "::" + eltype->cpp_name();
+ } else
+ {
+ if (eltype->is_primitive())
+ {
+ eltypeName = eltype->cpp_name();
+ } else
+ eltypeName = m_gencpp.get_module()->cpp_name() +"::" + eltype->cpp_name();
+ }
+
+
+ if (m_gencpp.with_codec())
+ {
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void codecOER::encode(asn1::streams::oer &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int codecOER::decode(asn1::streams::oer &c,"<<structName<<" &_t);\n";
+ /* Implementation */
+ cpp<<"// type sequence of "<<std::endl;
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecOER::encode(asn1::streams::oer &c,const "<<structName<<" &_t)\n{\n";
+ cpp<<"\tc.put_char(\"[\",1);\n";
+ cpp<<"\tencode(c,( const Seq<"<<eltypeName<<"> &)_t);\n";
+ cpp<<"\tc.put_char(\"] \",2);\n";
+ cpp<<"}\n";
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecOER::decode(asn1::streams::oer &c,"<<structName<<" &_t)\n{\n";
+ //cpp<<"\tstd::cout<<\"codecOER::decode sequence of "<<structName<<" UW \"<<std::endl;\n";
+ cpp<<"\treturn decode(c,( Seq<"<<eltypeName<<"> &)_t);\n";
+ cpp<<"}\n";
+ }
+
+}
+
+
+
+
+//
+void
+cgcpph_sequenceof::generate_jer()
+{
+ std::string NameS = m_gencpp.get_module()->cpp_name();
+ std::string eltypeName;
+ std::string structName( NameS + "::" +m_seqof.identifier()->cpp_name());
+ asn1::typenode *eltype = m_seqof.get_eltype();
+ asn1::node *ns = NULL;
+
+ if (m_gencpp.type_in_imports(eltype,&ns) )
+ {
+ eltypeName = ns->cpp_name() + "::" + eltype->cpp_name();
+ } else
+ {
+ if (eltype->is_primitive())
+ {
+ eltypeName = eltype->cpp_name();
+ } else
+ eltypeName = m_gencpp.get_module()->cpp_name() +"::" + eltype->cpp_name();
+ }
+
+
+ if (m_gencpp.with_codec())
+ {
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void codecJER::encode(asn1::streams::jer &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int codecJER::decode(asn1::streams::jer &c,"<<structName<<" &_t);\n";
+ /* Implementation */
+ cpp<<"// type sequence of "<<std::endl;
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecJER::encode(asn1::streams::jer &c,const "<<structName<<" &_t)\n{\n";
+ cpp<<"\tc.put_char(\"[\",1);\n";
+ cpp<<"\tencode(c,( const Seq<"<<eltypeName<<"> &)_t);\n";
+ cpp<<"\tc.put_char(\"] \",2);\n";
+ cpp<<"}\n";
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecJER::decode(asn1::streams::jer &c,"<<structName<<" &_t)\n{\n";
+ //cpp<<"\tstd::cout<<\"codecJER::decode sequence of "<<structName<<" UW \"<<std::endl;\n";
+ cpp<<"\treturn decode(c,( Seq<"<<eltypeName<<"> &)_t);\n";
+ cpp<<"}\n";
+ }
+
+}
--- /dev/null
+#ifndef CODE_GEN_CPP_HELPER_SEQOF_H
+#define CODE_GEN_CPP_HELPER_SEQOF_H
+
+/**
+ * This class defines the interface that each
+ */
+class cgcpph_sequenceof : public cgcpp_helper
+{
+ public:
+ cgcpph_sequenceof(cgcpph_sequenceof &s) : cgcpp_helper(s.m_gencpp,s.m_os)
+ , m_seqof(s.m_seqof)
+ { } ;
+ cgcpph_sequenceof(generate_codec_cpp &g
+ , std::ostream &os
+ , asn1::sequence_of &s) ;
+
+ virtual ~cgcpph_sequenceof();
+ // generate entry point
+ virtual void generate() ;
+ // generate codec part
+ virtual void generate_per() ;
+ //
+ virtual void generate_ber();
+ //
+ virtual void generate_oer() ;
+ //
+ virtual void generate_jer() ;
+ //
+ virtual void generate_xer() {};
+
+ // generate encoder
+ // generate decoder
+ // generate constructor
+ // generate
+ protected:
+ void gen_ctors();
+ void gen_equal();
+ void gen_printf();
+ protected:
+ asn1::sequence_of &m_seqof;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_codec_cpp.h"
+#include "asn1_generator_helper.h"
+#include "cgcpp_helper.h"
+#include "cgh_construct.h"
+#include "cgcpph_set.h"
+
+//#undef GEN_LOG_DEBUG
+//#define GEN_LOG_DEBUG
+
+cgcpph_set::cgcpph_set(generate_codec_cpp &g,std::ostream &os,asn1::set &s)
+ : cgh_construct(g,os,s)
+ , m_set(s)
+{
+}
+
+cgcpph_set::~cgcpph_set()
+{
+}
+
+
+/** Helper functions
+ *
+ * It seems that the choice does not always have an identifier. Examples
+ * - SEQUENCE OF CHOICE {}
+ * - Test ::= CHOICE { toto INTEGER, CHOICE { } }
+ * these sequences are anonymous definitions ...
+ */
+void cgcpph_set::generate(const std::string &scope)
+{
+ asn1::node *n = m_set.identifier();
+ asn1::node *params = NULL;
+
+ if (m_gencpp.with_source_comment())
+ m_os<<"// cgcpph_set helper launched "<<m_set.identifier_name()<<std::endl;
+#if 0
+ if (n)
+ {
+ m_os<<n->name()<<std::endl;
+ } else
+ {
+ m_os<<std::endl;
+ }
+#endif
+ //compute scope
+ // Does not work for know see CHOICE SET why path2module asserts
+ //m_gencpp.path2modulestring(type,scope);
+ GEN_LOG_DEBUG("cgcpph_set::generate node=%s\n",m_set.identifier_cpp_name().c_str());
+ // I should probably loop over all attributes as I do for sequence and choice
+ m_gencpp.gen_private(m_os,scope,&m_set);
+
+ if (m_gencpp.with_codec())
+ {
+ gen_codec();
+ }
+ cgcpp_helper::generate();
+}
+
+/**
+ *
+ */
+void
+cgcpph_set::generate_descriptor()
+{
+ cgh_construct::gen_desc_seqset();
+}
+/**
+ *
+ */
+void
+cgcpph_set::generate_ctors()
+{
+ m_os<<m_structName<<"::"<<m_structName<<"(const asn1::tag &t)\n\t";
+ m_os<<" : asn1::types::sequence_type(t)\n{\n}"<<std::endl;
+}
+
+/**
+ *
+ */
+void
+cgcpph_set::generate_operators()
+{
+ cgh_construct::gen_equal();
+}
+
+
+//
+void cgcpph_set::generate_printf()
+{
+ std::string scope("");
+ asn1::set *type = &m_set;
+ asn1::node *ident = m_set.identifier();
+ /*
+ * Try to handler sequence of sequence
+ */
+
+ m_os<<"#if 1\n";
+ //m_os<<scope<<"\tfriend ";
+ m_os<<"std::ostream &operator <<(std::ostream &os,const ";
+ m_os<<m_structName;
+ if (ident->parameters() && m_gencpp.is_template(ident->parameters()))
+ {
+ m_gencpp.gen_template_params(m_os,ident->parameters());
+ }
+ m_os<<" &s"<<")\n{\n";
+ m_os<<"\tstd::streamsize indent = os.precision() + 2;"<<std::endl;
+ m_os<<"\tos<<std::setw(indent+5)<<\"SET (\\n\";\n";
+
+ for (asn1::node::iterator it = type->begin()
+ ; it != type->end()
+ ; it++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*it);
+ asn1::typenode *attr_type = f->get_type();
+ if (attr_type != NULL)
+ {
+ m_os<<"\tos<<\"\"<<";
+ m_gencpp.gen_composite_attribute_printf(m_os,scope,*f);
+ }
+
+ }
+ m_os<<"\tos<<std::setw(indent)<<std::setprecision(indent-2)<<\")\";\n";
+ m_os<<"\treturn os;\n";
+ m_os<<"}\n";
+
+ m_os<<"#endif\n";
+
+}
+
+// generate codec part
+void cgcpph_set::generate_per()
+{
+ std::string scope;
+ //
+}
+
+//
+void cgcpph_set::generate_ber()
+{
+ std::string scope;
+ bool priv = m_set.is_private();
+ //
+ // Start generating code for this function
+ gen_nencode(scope,priv);
+ gen_ndecode(scope,priv);
+ if (m_gencpp.with_codec())
+ {
+ std::string ns ( m_gencpp.get_module()->cpp_name() ) ;
+ std::string structName ( ns + "::" +m_set.identifier_cpp_name() );
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ //m_gencpp.gen_template_signature(m_os,type);
+ hpp<<"\n// sequence type "<<structName<<" priv="<<priv<<"\n";
+ hpp<<"template<>\n";
+ hpp<<"void asn1::codecBER::encode(asn1::streams::ber &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int asn1::codecBER::decode(asn1::streams::ber &c,"<<structName<<" &_t);\n";
+ /* Generate implementation */
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecBER::encode(asn1::streams::ber &c,const "<<structName<<" &_t)\n{\n";
+ cpp<<"\tc.encode_sequence_preamble(_t);\n";
+
+ for (asn1::node::iterator it = m_c.begin(); it != m_c.end() ; it++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*it);
+ asn1::typenode *attr_type = f->get_type();
+ if (attr_type != NULL)
+ {
+ if (attr_type->type_id()() == asn1::type::ASN1_EXTENSIBLE)
+ {
+ cpp<<"\t// Extensible marker"<<std::endl;
+ } else
+ {
+ if (f->flags().is_optional() && (! f->flags().is_default()))
+ {
+ cpp<<"\tif ( ! _t."<<f->cpp_name()<<".is_nul())\n\t{\n";
+ cpp<<"\t\tencode(c,_t."<<f->cpp_name()<<".get());\n\t}\n";
+ } else
+ {
+ cpp<<"\tencode(c,_t."<<f->cpp_name()<<");\n";
+ }
+ }
+ }
+
+ } /* end for */
+ cpp<<"\tc.encode_sequence_epilogue(_t);\n";
+ cpp<<"}\n";
+ /* Implementation of decoding stream */
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecBER::decode(asn1::streams::ber &c,"<<structName<<" &_t)\n{\n";
+ cpp<<"\tif ( c.decode_sequence_preamble(_t) != asn1::ok)\n";
+ cpp<<"\t\treturn asn1::wrong_type;\n";
+ /* loop over fields */
+ for (asn1::node::iterator it = m_c.begin(); it != m_c.end() ; it++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*it);
+ asn1::typenode *attr_type = f->get_type();
+ if (attr_type != NULL)
+ {
+ if (attr_type->type_id()() == asn1::type::ASN1_EXTENSIBLE)
+ {
+ cpp<<"\t// Extensible marker"<<std::endl;
+ } else
+ {
+ if (f->flags().is_optional() && (! f->flags().is_default()))
+ {
+ cpp<<"\tdecode(c,_t."<<f->cpp_name()<<".get());\n";
+ } else
+ {
+ cpp<<"\tdecode(c,_t."<<f->cpp_name()<<");\n";
+ }
+ //cpp<<"\t}\n";
+ }
+ }
+ }
+ cpp<<"\tif ( c.decode_sequence_epilogue(_t) != asn1::ok)\n";
+ cpp<<"\t\treturn asn1::wrong_type;\n";
+ cpp<<"\treturn asn1::ok;\n";
+ cpp<<"}\n";
+
+
+ /**/
+ }
+}
+
+//
+void cgcpph_set::generate_oer()
+{
+ //
+ if (m_gencpp.with_codec())
+ {
+ std::string ns ( m_gencpp.get_module()->cpp_name() ) ;
+ std::string structName ( ns + "::" +m_set.identifier_cpp_name() );
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ //m_gencpp.gen_template_signature(m_os,type);
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void codecJER::encode(asn1::streams::jer &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int codecJER::decode(asn1::streams::jer &c,"<<structName<<" &_t);\n";
+ }
+}
+
+//
+void cgcpph_set::generate_xer()
+{
+}
+
--- /dev/null
+#ifndef CGCPPH_SET_H
+#define CGCPPH_SET_H
+
+
+/**
+ *
+ */
+class cgcpph_set : public cgh_construct
+{
+ protected:
+ cgcpph_set(const cgcpph_set &s) :
+ cgh_construct(s.m_gencpp,s.m_os,s.m_set)
+ , m_set(s.m_set)
+ {}
+ public:
+ cgcpph_set(generate_codec_cpp &g,std::ostream &os,asn1::set &s) ;
+
+ ~cgcpph_set();
+
+ // Helper functions
+ virtual void generate(const std::string &scope) ;
+
+ // generate codec part
+ virtual void generate_per() ;
+ //
+ virtual void generate_ber() ;
+ //
+ virtual void generate_oer() ;
+
+ virtual void generate_jer() { };
+
+ virtual void generate_xer() ;
+ protected:
+ virtual void generate_descriptor() ;
+ virtual void generate_ctors() ;
+ virtual void generate_operators();
+ virtual void generate_printf();
+ // loop over the attributes of SEQUENCE or CHOICE
+ // and check if there are some type of SEQUENCE or CHOICE
+ // launch generation for these types first.
+ protected:
+ asn1::set &m_set;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_codec_cpp.h"
+#include "asn1_generator_helper.h"
+#include "cgcpp_helper.h"
+#include "cgcpph_setof.h"
+
+
+cgcpph_setof::cgcpph_setof( generate_codec_cpp &g
+ , std::ostream &os
+ , asn1::set_of &s)
+ : cgcpp_helper(g,os) , m_setof(s)
+{
+}
+
+cgcpph_setof::~cgcpph_setof()
+{
+}
+
+void cgcpph_setof::generate()
+{
+ std::string structName = m_setof.identifier_cpp_name();
+ m_os<<"//cgcpph_setof::generate "<<structName<<std::endl;
+ if (m_gencpp.with_source_comment())
+ m_os<<"// cgcpph_setof helper launched \n";
+
+ GEN_LOG_DEBUG("cgcpph_setof::generate node=%s\n",m_setof.identifier_cpp_name().c_str());
+
+ gen_ctors();
+ gen_equal();
+ gen_printf();
+ // Generate codec codec
+ cgcpp_helper::generate();
+}
+
+//
+void cgcpph_setof::gen_ctors()
+{
+ asn1::node *ns = NULL;
+ asn1::typenode *eltype = m_setof.get_eltype();
+ std::string structName = m_setof.identifier_cpp_name();
+ std::string eltypeName;
+ if (m_gencpp.type_in_imports(eltype,&ns) )
+ {
+ eltypeName = ns->cpp_name() + "::" + eltype->cpp_name();
+ } else
+ eltypeName = eltype->cpp_name();
+
+ // With tag
+ m_os<<"\n"<<structName;
+ m_os<<"::"<<structName<<"(const asn1::tag &t)\n";
+ m_os<<"\t\t: Set<"<<eltypeName<<">(t)\n{\n}\n";
+
+ m_os<<"\n"<<structName;
+ m_os<<"::"<<structName<<"(const "<<eltypeName<<" &t)\n";
+ m_os<<"\t\t: Set<"<<eltypeName<<">(t)\n\t";
+ m_os<<"{\n}\n";
+#if 0
+ m_os<<" asn1::types::container<"<<eltypeName<<">(asn1::tag(asn1::types::UNIVERSAL,17)\n";
+ m_os<<"{ this->m_.push_back(t);\n}\n";
+#endif
+ m_os<<"\n// Copy Constructor "<<structName<<"\n//\n";
+ m_os<<structName;
+ m_os<<"::"<<structName<<"(const "<<structName<<" &c)\n";
+ m_os<<"\t\t: Set<"<<eltypeName<<">(c)\n{\n}\n";
+ //clone
+ m_os<<structName<<" *";
+ m_os<<structName;
+ m_os<<"::clone()\n";
+ m_os<<"{\n";
+ m_os<<"\treturn new "<<structName<<"(*this);\n";
+ m_os<<"}\n";
+
+}
+//
+void cgcpph_setof::gen_equal()
+{
+ std::string structName = m_setof.identifier_cpp_name();
+
+ // With tag
+ m_os<<"\n// comparaison "<<structName<<"\n//\n";
+ m_os<<"bool\n"<<structName;
+ m_os<<"::operator =="<<"(const "<<structName<<" &t)\n{\n";
+ m_os<<"\treturn false;\n";
+ //m_os<<"\treturn get_value() == t.get_value();\n";
+ m_os<<"}\n";
+}
+
+//
+void cgcpph_setof::gen_printf()
+{
+ asn1::node *ns = NULL;
+ std::string structName = m_setof.identifier_cpp_name();
+ asn1::typenode *eltype = m_setof.get_eltype();
+ std::string eltypeName;
+ if (m_gencpp.type_in_imports(eltype,&ns) )
+ {
+ eltypeName = ns->cpp_name() + "::" + eltype->cpp_name();
+ } else
+ eltypeName = eltype->cpp_name();
+
+
+ m_os<<"\nstd::ostream & operator <<(std::ostream &os,const ";
+ m_os<<structName<<" &s)\n{\n";
+ m_os<<"\toperator<<(os, (Set<"<<eltypeName<<"> &)s);\n";
+ m_os<<"\treturn os;\n";
+ m_os<<"}\n";
+}
+
+
+
+void
+cgcpph_setof::generate_ber()
+{
+ asn1::node *type = &m_setof;
+ std::string structName = m_setof.identifier()->cpp_name();
+ //
+ if (m_setof.tagged())
+ {
+ if ( m_gencpp.tag_mode(type) == asn1::node::tag_type::TM_EXPLICIT)
+ {
+ //
+ m_os<<"\t void "<<structName<<"::encode(asn1::context &ctx)\n{\n"<<std::endl;
+ m_os<<"\tstd::cout<<\"encode "<<structName<<" TODO in generator\"<<std::endl;\n";
+ m_os<<"}\n;";
+ m_os<<"\t int "<<structName<<"::decode(asn1::context &ctx)\n{\n"<<std::endl;
+ m_os<<"\tstd::cout<<\"decode "<<structName<<" TODO in generator\"<<std::endl;\n";
+ m_os<<"\treturn asn1::ok;\n;";
+ m_os<<"}\n;";
+ }
+ }
+ // Generate code for codec way
+ if (m_gencpp.with_codec())
+ {
+ std::string ns (m_gencpp.get_module()->cpp_name());
+ std::string structName (ns + "::" +m_setof.identifier()->cpp_name());
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ cpp<<"// type set of "<<std::endl;
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void asn1::codecBER::encode(asn1::streams::ber &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int asn1::codecBER::decode(asn1::streams::ber &c,"<<structName<<" &_t);\n";
+ // Implementation part
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecBER::encode(asn1::streams::ber &c,const "<<structName<<" &_t)\n{\n";
+ cpp<<"\tstd::cout<<\"codecBER::encode "<<structName<<" TODO\"<<std::endl;\n";
+ cpp<<"}\n";
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecBER::decode(asn1::streams::ber &c,"<<structName<<" &_t)\n{\n";
+ cpp<<"\tstd::cout<<\"codecBER::decode "<<structName<<" TODO\"<<std::endl;\n";
+ cpp<<"\treturn asn1::ok;\n";
+ cpp<<"}\n";
+ }
+
+}
+
+void
+cgcpph_setof::generate_oer()
+{
+ if (m_gencpp.with_codec())
+ {
+ std::string ns (m_gencpp.get_module()->cpp_name());
+ std::string structName (ns + "::" +m_setof.identifier()->cpp_name());
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ cpp<<"// type set of "<<std::endl;
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void asn1::codecOER::encode(asn1::streams::oer &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int asn1::codecOER::decode(asn1::streams::oer &c,"<<structName<<" &_t);\n";
+ // Implementation part
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecOER::encode(asn1::streams::oer &c,const "<<structName<<" &_t)\n{\n";
+ cpp<<"\tstd::cout<<\"codecOER::encode "<<structName<<" TODO\"<<std::endl;\n";
+ cpp<<"}\n";
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecOER::decode(asn1::streams::oer &c,"<<structName<<" &_t)\n{\n";
+ cpp<<"\tstd::cout<<\"codecOER::decode "<<structName<<" TODO\"<<std::endl;\n";
+ cpp<<"\treturn asn1::ok;\n";
+ cpp<<"}\n";
+ }
+}
+
+
+
+void
+cgcpph_setof::generate_jer()
+{
+ if (m_gencpp.with_codec())
+ {
+ std::string ns (m_gencpp.get_module()->cpp_name());
+ std::string structName (ns + "::" +m_setof.identifier()->cpp_name());
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ cpp<<"// type set of "<<std::endl;
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void asn1::codecJER::encode(asn1::streams::jer &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int asn1::codecJER::decode(asn1::streams::jer &c,"<<structName<<" &_t);\n";
+ // Implementation part
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecJER::encode(asn1::streams::jer &c,const "<<structName<<" &_t)\n{\n";
+ cpp<<"\tstd::cout<<\"codecJER::encode "<<structName<<" TODO\"<<std::endl;\n";
+ cpp<<"}\n";
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecJER::decode(asn1::streams::jer &c,"<<structName<<" &_t)\n{\n";
+ cpp<<"\tstd::cout<<\"codecJER::decode "<<structName<<" TODO\"<<std::endl;\n";
+ cpp<<"\treturn asn1::ok;\n";
+ cpp<<"}\n";
+ }
+
+}
--- /dev/null
+#ifndef CODE_GEN_CPP_HELPER_SETOF_H
+#define CODE_GEN_CPP_HELPER_SETOF_H
+
+/**
+ * This class defines the interface that each
+ */
+class cgcpph_setof : public cgcpp_helper
+{
+ public:
+ cgcpph_setof(cgcpph_setof &s) : cgcpp_helper(s.m_gencpp,s.m_os)
+ , m_setof(s.m_setof)
+ { } ;
+ cgcpph_setof(generate_codec_cpp &g
+ , std::ostream &os
+ , asn1::set_of &s) ;
+
+ virtual ~cgcpph_setof();
+ // generate entry point
+ virtual void generate() ;
+ // generate codec part
+ virtual void generate_per() {};
+ //
+ virtual void generate_ber() ;
+ //
+ virtual void generate_oer() ;
+ //
+ virtual void generate_jer() ;
+ //
+ virtual void generate_xer() {};
+
+ // generate encoder
+ // generate decoder
+ // generate constructor
+ // generate
+ protected:
+ void gen_ctors();
+ void gen_equal();
+ void gen_printf();
+ protected:
+ asn1::set_of &m_setof;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_codec_cpp.h"
+#include "asn1_generator_helper.h"
+#include "cgcpp_helper.h"
+#include "cgcpph_primitive.h"
+#include "cgcpph_string.h"
+
+
+cgcpph_string::cgcpph_string( generate_codec_cpp &g
+ , std::ostream &os
+ , asn1::primitive &s)
+ : cgcpph_primitive(g,os,s) , m_string(s)
+{
+}
+
+cgcpph_string::~cgcpph_string()
+{
+}
+
+
+
+/**
+ *
+ */
+void cgcpph_string::generate_operators()
+{
+ gen_equal();
+}
+/**
+ *
+ */
+void cgcpph_string::generate_ctors()
+{
+ asn1::node *type = &m_string;
+
+ if (m_gencpp.with_source_comment())
+ m_os<<"// cgcpph_string helper launched ";
+
+ GEN_LOG_DEBUG("cgcpph_string::generate node=%s\n",m_string.identifier_cpp_name().c_str());
+
+ // With tag
+ m_os<<"\n"<<m_structName;
+ m_os<<"::"<<m_structName<<"(const asn1::tag &t)\n";
+ m_os<<"\t\t: "<<m_string.cpp_name()<<"(t)\n{\n}\n";
+ // Two other ctors
+ m_os<<m_structName<<"::"<<m_structName<<"(const std::string &s)\n";
+ m_os<<"\t\t: "<<m_string.cpp_name()<<"(s)\n{\n}\n";
+
+ //m_os<<structName<<"::"<<structName<<"(const char *s)\n";
+ //m_os<<"\t\t: "<<type->cpp_name()<<"(t)\n{\n}\n";
+ //
+ m_os<<"\n// Copy Constructor "<<m_structName<<"\n//\n";
+ m_os<<m_structName;
+ m_os<<"::"<<m_structName<<"(const "<<m_structName<<" &c)\n";
+ m_os<<"\t\t: "<<m_string.cpp_name()<<"(c)\n{\n}\n";
+ // Copy
+ m_os<<"\n// Copy Constructor from "<<m_string.cpp_name()<<"\n//\n";
+ m_os<<m_structName;
+ m_os<<"::"<<m_structName<<"(const "<<m_string.cpp_name()<<" &c";
+ m_os<<",const asn1::tag &t)\n";
+ m_os<<"\t\t: "<<m_string.cpp_name()<<"(t)\n{\n";
+ m_os<<"\t"<<m_string.cpp_name()<<"::operator =(c);\n";
+ m_os<<"}\n\n";
+ // copy assignment
+ //
+ m_os<<m_structName<<" & ";
+ m_os<<m_structName;
+ m_os<<"::operator =(const "<<m_string.cpp_name()<<" &c)\n";
+ m_os<<"{\n";
+ m_os<<"\t"<<m_string.cpp_name()<<"::operator =(c)\n;";
+ m_os<<"\treturn *this;\n";
+ m_os<<"}\n";
+
+ m_os<<m_structName<<" & ";
+ m_os<<m_structName;
+ m_os<<"::operator =(const std::string &c)\n";
+ m_os<<"{\n";
+ m_os<<"\tm_Prim = c;\n;";
+ m_os<<"\treturn *this;\n";
+ m_os<<"}\n";
+
+ m_os<<m_structName<<" & ";
+ m_os<<m_structName;
+ m_os<<"::operator =(const char *c)\n";
+ m_os<<"{\n";
+ m_os<<"\tm_Prim = std::string(c);\n";
+ m_os<<"\treturn *this;\n";
+ m_os<<"}\n";
+
+ // clone
+ m_os<<m_structName<<" * ";
+ m_os<<m_structName;
+ m_os<<"::clone()\n";
+ m_os<<"{\n";
+ m_os<<"\treturn new "<<m_structName<<"(*this)\n;";
+ m_os<<"}\n";
+}
+
+
+//
+void cgcpph_string::gen_equal()
+{
+ // With tag
+ m_os<<"\n// comparaison "<<m_structName<<"\n//\n";
+ m_os<<"bool\n"<<m_structName;
+ m_os<<"::operator =="<<"( "<<m_structName<<" &t)\n{\n";
+ m_os<<"\treturn get_value() == t.get_value();\n";
+ m_os<<"}\n";
+}
+
+
+//
+void cgcpph_string::generate_printf()
+{
+ m_os<<"\nstd::ostream & operator <<(std::ostream &os,const ";
+ m_os<<m_structName<<" &s)\n{\n";
+ m_os<<"\tos<<("<<m_string.cpp_name()<<")s;\n";
+ m_os<<"\treturn os;\n";
+ m_os<<"}\n";
+}
+
+// generate codec part
+void cgcpph_string::generate_per()
+{
+ if (m_gencpp.with_codec())
+ {
+ std::string ns( m_gencpp.get_module()->cpp_name() );
+ std::string structName ( ns + "::" + m_string.identifier_cpp_name() );
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ // hpp content
+ //m_gencpp.gen_template_signature(m_os,type);
+ hpp<<"\n// string type "<<structName<<""<<"\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void asn1::codecPER::encode(asn1::streams::per &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int asn1::codecPER::decode(asn1::streams::per &c,"<<structName<<" &_t);\n";
+ // cpp content
+ cpp<<"// string generator todo"<<std::endl;
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecPER::encode(asn1::streams::per &c,const "<<structName<<" &_t)\n{\n";
+ cpp<<"\tc.encode_string(_t);\n";
+ cpp<<"}\n";
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecPER::decode(asn1::streams::per &c,"<<structName<<" &_t)\n{\n";
+ cpp<<"\treturn c.decode_string(_t);\n";
+ cpp<<"}\n";
+ }
+
+}
+
+//
+void cgcpph_string::generate_ber()
+{
+ std::string scope;
+ std::string structName = m_string.identifier_cpp_name();
+ //
+ if (m_string.tagged())
+ {
+ if ( m_gencpp.is_tag_explicit(m_string))
+ {
+ m_os<<scope<<"void "<<structName<<"::encode(asn1::context &ctx)\n{\n"<<std::endl;
+ m_os<<"\tunsigned long pos = ctx.bytes();\n";
+ m_os<<"\tunsigned char *b = ctx.buffer();\n";
+ m_os<<"\tASN1_BER_LOG_DEBUG(\""<<structName<<"::encode(ctx) tag=%d \",this->tag().byte());\n";
+ m_os<<"\tb[pos++] = tag().byte();\n";
+ m_os<<"\tctx.nb_bits(16);\n";
+ m_os<<"\tasn1::tag t("<<m_string.tag().m_class<<","<<m_string.tag().m_value<<",true);\n";
+ m_os<<"\tset_tag(asn1::tag(0,"<<m_string.primitive_tag()<<"));\n";
+ m_os<<"\tctx.encode_string(*this);\n";
+ m_os<<"\tset_tag(t);\n";
+ m_os<<"\tb[pos] = ctx.bytes() -pos -1;\n";
+ m_os<<"}\n\n";
+ m_os<<scope<<"int "<<structName<<"::decode(asn1::context &ctx)\n{\n"<<std::endl;
+ m_os<<"\tasn1::tag t("<<m_string.tag().m_class<<","<<m_string.tag().m_value<<",true);\n";
+ m_os<<"\tASN1_BER_LOG_DEBUG(\""<<structName<<"::decode(ctx) exp tag= %d tag=%d \",t.byte(),this->tag().byte());\n";
+ m_os<<"\tif (ctx.decode_tag(t))\n\t{\n";
+ m_os<<"\t\t"<<m_string.cpp_name()<<" tmp;\n";
+ m_os<<"\t\tint rest = tmp.decode(ctx);\n";
+ m_os<<"\t\tthis->get_value() = tmp;\n";
+ m_os<<"\t\treturn rest;\n";
+ m_os<<"\t}\n";
+ m_os<<"\treturn asn1::wrong_tag;\n";
+ m_os<<"}\n";
+ }
+ }
+ if (m_gencpp.with_codec())
+ {
+ std::string ns( m_gencpp.get_module()->cpp_name() );
+ std::string structName ( ns + "::" + m_string.identifier_cpp_name() );
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ // hpp content
+ //m_gencpp.gen_template_signature(m_os,type);
+ hpp<<"\n// string type "<<structName<<""<<"\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void asn1::codecBER::encode(asn1::streams::ber &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int asn1::codecBER::decode(asn1::streams::ber &c,"<<structName<<" &_t);\n";
+ // cpp content
+ cpp<<"// string generator todo"<<std::endl;
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecBER::encode(asn1::streams::ber &c,const "<<structName<<" &_t)\n{\n";
+ if ( m_string.tagged()
+ && (m_gencpp.is_tag_explicit(m_string) )
+ )
+ {
+ cpp<<"\tasn1::tag t("<<m_string.tag().m_class<<","<<m_string.tag().m_value<<",true);\n";
+ cpp<<"\tstd::cout<<\"codecBER::decode "<<structName<<" TODO\"<<std::endl;\n";
+ }
+ cpp<<"\tc.encode_string(_t);\n";
+ cpp<<"}\n";
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecBER::decode(asn1::streams::ber &c,"<<structName<<" &_t)\n{\n";
+ if ( m_string.tagged()
+ && (m_gencpp.is_tag_explicit(m_string) )
+ )
+ {
+ cpp<<"\tasn1::tag t("<<m_string.tag().m_class<<","<<m_string.tag().m_value<<",true);\n";
+ cpp<<"\tstd::cout<<\"codecBER::decode "<<structName<<" TODO\"<<std::endl;\n";
+ }
+ cpp<<"\treturn c.decode_string(_t);\n";
+ cpp<<"}\n";
+ }
+
+}
+
+//
+void cgcpph_string::generate_oer()
+{
+ if (m_gencpp.with_codec())
+ {
+ std::string ns( m_gencpp.get_module()->cpp_name() );
+ std::string structName ( ns + "::" + m_string.identifier_cpp_name() );
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ // hpp content
+ //m_gencpp.gen_template_signature(m_os,type);
+ hpp<<"\n// string type "<<structName<<""<<"\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void asn1::codecOER::encode(asn1::streams::oer &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int asn1::codecOER::decode(asn1::streams::oer &c,"<<structName<<" &_t);\n";
+ // cpp content
+ cpp<<"// string generator todo"<<std::endl;
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecOER::encode(asn1::streams::oer &c,const "<<structName<<" &_t)\n{\n";
+ cpp<<"\tc.encode_string(_t);\n";
+ cpp<<"}\n";
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecOER::decode(asn1::streams::oer &c,"<<structName<<" &_t)\n{\n";
+ cpp<<"\treturn c.decode_string(_t);\n";
+ cpp<<"}\n";
+ }
+
+}
+
+//
+void cgcpph_string::generate_jer()
+{
+ if (m_gencpp.with_codec())
+ {
+ std::string ns( m_gencpp.get_module()->cpp_name() );
+ std::string structName ( ns + "::" + m_string.identifier_cpp_name() );
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ // hpp content
+ //m_gencpp.gen_template_signature(m_os,type);
+ hpp<<"\n// string type "<<structName<<""<<"\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void asn1::codecJER::encode(asn1::streams::jer &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int asn1::codecJER::decode(asn1::streams::jer &c,"<<structName<<" &_t);\n";
+ // cpp content
+ cpp<<"// string generator todo"<<std::endl;
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecJER::encode(asn1::streams::jer &c,const "<<structName<<" &_t)\n{\n";
+ cpp<<"\tc.encode_string(_t);\n";
+ cpp<<"}\n";
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecJER::decode(asn1::streams::jer &c,"<<structName<<" &_t)\n{\n";
+ cpp<<"\treturn c.decode_string(_t);\n";
+ cpp<<"}\n";
+ }
+
+}
+
+//
+void cgcpph_string::generate_xer()
+{
+}
--- /dev/null
+#ifndef CGCPPH_STRING_H
+#define CGCPPH_STRING_H
+
+
+/**
+ *
+ */
+class cgcpph_string : public cgcpph_primitive
+{
+ protected:
+ cgcpph_string(const cgcpph_string &s) : cgcpph_primitive(s.m_gencpp,s.m_os,s.m_string)
+ , m_string(s.m_string)
+ {}
+ public:
+ cgcpph_string(generate_codec_cpp &g
+ , std::ostream &os
+ , asn1::primitive &s) ;
+
+ ~cgcpph_string();
+
+ // generate codec part
+ virtual void generate_per() ;
+ //
+ virtual void generate_ber() ;
+ //
+ virtual void generate_oer() ;
+ //
+ virtual void generate_jer() ;
+ //
+ virtual void generate_xer() ;
+ protected:
+ virtual void generate_printf();
+ virtual void generate_operators();
+ virtual void generate_ctors();
+ void gen_equal();
+ protected:
+ asn1::primitive &m_string;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_codec_cpp.h"
+#include "asn1_generator_helper.h"
+#include "cgcpp_helper.h"
+#include "cgcpph_typeref.h"
+
+
+/**
+ *
+ *
+ */
+cgcpph_typeref::cgcpph_typeref(generate_codec_cpp &g,std::ostream &os,asn1::typeref &s)
+ : cgcpp_helper(g,os)
+ , m_typeref(s)
+ //, m_log(g.logger())
+{
+}
+
+/**
+ *
+ *
+ */
+cgcpph_typeref::~cgcpph_typeref()
+{
+}
+
+
+/** Helper functions
+ *
+ */
+void cgcpph_typeref::generate(const std::string &scope)
+{
+ asn1::node *n = m_typeref.identifier();
+ asn1::node *type = &m_typeref;
+
+ if (m_gencpp.with_source_comment())
+ m_os<<"// cgcpph_typeref helper launched "<<n->name()<<std::endl;
+
+ if (m_typeref.is_simple())
+ {
+ cgcpp_helper::generate();
+ } else if (m_typeref.is_objectclass())
+ {
+ generate_objectclass();
+ } else
+ {
+ assert(0);
+ }
+}
+
+struct TyperefPrintTag {
+ TyperefPrintTag(generate_codec_cpp &_g,std::ostream &os,unsigned int &c)
+ : m_gencpp(_g), m_os(os), m_count(c) {}
+ void operator ()(asn1::node *_node)
+ {
+ m_os<<"\t";
+ if (m_count++)
+ m_os<<", ";
+ m_os<<"asn1::tag("<<_node->tag().m_class<<","<<_node->tag().m_value;
+ if (m_gencpp.is_tag_explicit(*_node->as_typenode()))
+ m_os<<",true";
+ m_os<<")\n";
+ }
+ std::ostream &m_os;
+ unsigned int &m_count;
+ generate_codec_cpp &m_gencpp;
+};
+
+void
+cgcpph_typeref::generate_descriptor()
+{
+ std::string cn(m_typeref.identifier_cpp_name());
+ unsigned int _count = 0;
+ std::list<asn1::node *> refs;
+ TyperefPrintTag pt(m_gencpp,m_os,_count);
+ m_gencpp.reference_chaine(&m_typeref,refs);
+
+ m_os<<"static asn1::tag TAGS_"<<m_typeref.identifier_cpp_name()<<"[] = {\n";
+ std::for_each(refs.rbegin(),refs.rend(),pt);
+ if (m_typeref.tagged())
+ {
+ if (_count)
+ m_os<<"\t, ";
+ m_os<<"asn1::tag("<<m_typeref.tag().m_class<<","<<m_typeref.tag().m_value;
+ if (m_gencpp.is_tag_explicit(m_typeref))
+ m_os<<",true";
+ m_os<<")\n";
+
+ }
+ m_os<<"};\n";
+
+ m_os<<"const asn1::types::descriptor "<<m_typeref.identifier_cpp_name()<<"::_meta = {\n";
+ m_os<<" TAGS_"<<cn<<",";
+ m_os<<"sizeof(TAGS_"<<cn<<")/sizeof(TAGS_"<<cn<<"[0]),\n"; /* Tag List */
+ m_os<<" NULL,\n"; /* MEMBER List */
+ m_os<<" 0,\n"; /* Member list count */
+ m_os<<" NULL,\n"; /*tag to element */
+ m_os<<" 0\n"; /* tag to element count*/
+ m_os<<"};\n";
+ m_os<<std::endl;
+}
+
+/**
+ *
+ */
+void
+cgcpph_typeref::generate_ctors()
+{
+ gen_simple_ctors();
+}
+/**
+ *
+ */
+void
+cgcpph_typeref::generate_operators()
+{
+ gen_simple_equal();
+}
+
+//
+void
+cgcpph_typeref::gen_simple_equal()
+{
+ std::string refName;
+ asn1::node *ns = NULL;
+ asn1::node *n = m_typeref.identifier();
+ asn1::typeref *type = &m_typeref;
+ std::string structName =n->cpp_name();
+
+
+ if (m_gencpp.type_in_imports(type,&ns) )
+ {
+ refName = ns->cpp_name()+"::"+type->cpp_name();
+ } else
+ {
+ refName = type->cpp_name();
+ }
+
+ m_os<<"bool "<<structName<<"::operator==(";
+ m_os<<structName<<" &o)\n{\n";
+ m_os<<"\tstd::cerr<<\""<<structName<<"::operator== TOBE CODED\\n\";\n";
+ m_os<<"\treturn false;\n";
+ //m_os<<"\treturn this->get_value() == o.get_value();\n";
+ m_os<<"}\n";
+}
+
+//
+void
+cgcpph_typeref::gen_simple_ctors()
+{
+ std::string refName;
+ std::list<asn1::node *> refs;
+ asn1::node *ns = NULL;
+ asn1::node *n = m_typeref.identifier();
+ asn1::typeref *type = &m_typeref;
+ std::string structName = n->cpp_name();
+
+ m_gencpp.reference_chaine(type,refs);
+
+ if (m_gencpp.type_in_imports(type,&ns) )
+ {
+ refName = ns->cpp_name()+"::"+type->cpp_name();
+ } else
+ {
+ refName = type->cpp_name();
+ }
+
+ // Basic ctor
+ m_os<<structName<<"::"<<structName;
+ m_os<<"(const asn1::tag &_t)";
+ if ( type->tagged()
+ && (type->tag().m_mode == asn1::node::tag_type::TM_IMPLICIT))
+ {
+ m_os<<"\t: "<<refName<<"(_t)\n{\n" ;
+ } else
+ m_os<<"\t: "<<refName<<"(_t)\n{\n" ;
+ m_os<<"\n}\n";
+ if (!type->tagged())
+ {
+ m_os<<structName<<"::"<<structName;
+ m_os<<"( )";
+ m_os<<"\t: "<<refName<<"()\n{\n" ;
+ m_os<<"\n}\n";
+ }
+ // Copy ctor
+ m_os<<structName<<"::"<<structName;
+ m_os<<"(const "<<structName<<" &_t)";
+ m_os<<"\t: "<<refName<<"(_t)\n{\n" ;
+ m_os<<"\n}\n";
+ // Check Type of Initial type
+#if 1
+ if ( refs.size()>0 &&
+ refs.back()->type_id()() == asn1::type::ASN1_CHOICE)
+ {
+ m_os<<structName<<"::"<<structName<<"(unsigned int i, const asn1::tag &_t) "<<std::endl;
+ m_os<<"\t: "<<refName<<"(i,_t)\n{\n" ;
+ m_os<<"\n}\n";
+ }
+#endif
+
+ // Add an operator
+ m_os<<"//\n// Operator\n"<<structName<<" &\n";
+ m_os<<""<<structName<<"::operator =(const "<<refName<<" &_v)\n";
+ m_os<<"{\n";
+ m_os<<"\tthis->get_value() = _v.get_value();\n";
+ m_os<<"\treturn *this;\n";
+ m_os<<"}\n";
+
+}
+
+
+// This method will be used to deal with
+// TYPE-IDENTIFIER and OBJECT CLASS
+void
+cgcpph_typeref::generate_objectclass()
+{
+ asn1::node *n = m_typeref.identifier();
+ m_os<<"// cgcpph_typeref::generate_objectclass helper launched "<<n->name();
+ if (n->parameters())
+ {
+ m_os<<" SHOULD ONLY GENERATE WITH ACTUAL_PARAMETERS ";
+ }
+ if (m_typeref.act_parameters())
+ {
+ m_os<<" "<<m_typeref.name()<<" has actual parameters ";
+ }
+ m_os<<std::endl;
+ ;
+}
+
+//
+void cgcpph_typeref::gen_printf(const std::string &scope)
+{
+}
+
+// generate codec part
+void cgcpph_typeref::generate_per()
+{
+ if (m_gencpp.with_codec())
+ {
+ std::string ns( m_gencpp.get_module()->cpp_name() );
+ std::string structName( ns + "::" + m_typeref.identifier_cpp_name() );
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void codecPER::encode(streams::per &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int codecPER::decode(streams::per &c,"<<structName<<" &_t);\n";
+
+ cpp<<"// typeref generator todo"<<std::endl;
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecPER::encode(asn1::streams::per &c,const "<<structName<<" &_t)\n{\n";
+ cpp<<"\tstd::cout<<\"encode typeref "<<structName<<"\"<<std::endl;\n";
+ cpp<<"\tc.encode_octetstring(_t);";
+ cpp<<"}\n";
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecPER::decode(asn1::streams::per &c,"<<structName<<" &_t)\n{\n";
+ cpp<<"\tstd::cout<<\"decode typeref "<<structName<<"\"<<std::endl;\n";
+ cpp<<"\treturn asn1::ok;\n";
+ cpp<<"}\n";
+ }
+
+}
+
+/**
+ *
+ *
+ */
+void cgcpph_typeref::generate_ber()
+{
+ std::string scope;
+ std::string refName;
+ asn1::node *ns = NULL;
+ std::list<asn1::node *> refs;
+ asn1::node *ident = m_typeref.identifier();
+ asn1::typeref *type = &m_typeref;
+ std::string structName = ident->cpp_name();
+
+ m_gencpp.reference_chaine(type,refs);
+
+ if (m_gencpp.type_in_imports(type,&ns) )
+ {
+ refName = ns->cpp_name()+"::"+type->cpp_name();
+ } else
+ {
+ refName = type->cpp_name();
+ }
+
+ //
+ if (m_typeref.tagged())
+ {
+ if ( m_gencpp.tag_mode(type) == asn1::node::tag_type::TM_EXPLICIT)
+ {
+ asn1::node *refnode = refs.front();
+ // encoder
+ m_os<<"void\n"<<scope<<structName<<"::encode(asn1::context &ctx)\n{"<<std::endl;
+ m_os<<"\tunsigned long pos = ctx.bytes();\n";
+ m_os<<"\tunsigned char *b = ctx.buffer();\n";
+ m_os<<"\tasn1::tag tg(tag());\n";
+ m_os<<"\ttg.set_constructed();\n";
+ m_os<<"\tb[pos] = tg.byte();\n";
+ m_os<<"\tctx.nb_bits(+ (2<<3) );";
+ m_os<<"\tset_tag(asn1::tag("<<refnode->tag().m_class<<","<<refnode->tag().m_value<<"));\n";
+ m_os<<"\tthis->"<<refName<<"::encode(ctx);\n";
+ m_os<<"\tint len = ctx.bytes() - pos - 2;\n";
+ m_os<<"\tassert( len < 127); // Restriction.\n";
+ m_os<<"\tb[++pos] = len ;\n";
+ m_os<<"}\n";
+ // decoder
+ m_os<<"\nint\n"<<scope<<structName<<"::decode(asn1::context &ctx)\n{"<<std::endl;
+ m_os<<"\tint len;\n";
+ m_os<<"\tasn1::tag tg(tag());\n";
+ m_os<<"\ttg.set_constructed();\n";
+ m_os<<"\tif (ctx.decode_tag(tg))\n\t{\n";
+ // Set tag to ref tag
+ m_os<<"\t\tset_tag(asn1::tag("<<refnode->tag().m_class<<","<<refnode->tag().m_value<<"));\n";
+ m_os<<"\t\tthis->"<<refName<<"::decode(ctx);\n";
+ m_os<<"\t\treturn asn1::ok;\n";
+ m_os<<"\t}\n";
+ m_os<<"\treturn asn1::wrong_tag;\n";
+ m_os<<"}\n";
+ } else
+ {
+ // IMPLICIT Case
+ // encoder
+ m_os<<"void\n"<<scope<<structName<<"::encode(asn1::context &ctx)\n{"<<std::endl;
+ m_os<<"\tthis->"<<refName<<"::encode(ctx);\n";
+ m_os<<"}\n";
+ // decoder
+ m_os<<"\nint\n"<<scope<<structName<<"::decode(asn1::context &ctx)\n{"<<std::endl;
+ m_os<<"\treturn this->"<<refName<<"::decode(ctx);\n";
+ m_os<<"}\n";
+ }
+ }
+ //m_gencpp.gen_template_signature(m_os,type);
+ if (m_gencpp.with_codec())
+ {
+ std::string ns( m_gencpp.get_module()->cpp_name() );
+ std::string structName( ns + "::" + m_typeref.identifier_cpp_name() );
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void codecBER::encode(streams::ber &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int codecBER::decode(streams::ber &c,"<<structName<<" &_t);\n";
+
+ cpp<<"// typeref generator todo"<<std::endl;
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecBER::encode(asn1::streams::ber &c,const "<<structName<<" &_t)\n{\n";
+ cpp<<"\tstd::cout<<\"encode typeref "<<structName<<"\"<<std::endl;\n";
+ if ( m_typeref.tagged()
+ && ( m_gencpp.tag_mode(type) == asn1::node::tag_type::TM_EXPLICIT)
+ )
+ {
+ cpp<<"\tstd::cout<<\"encode typeref explicit tag "<<refName<<"\"<<std::endl;\n";
+ }
+ //cpp<<"\tc.encode_octetstring(_t);";
+ cpp<<"}\n";
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecBER::decode(asn1::streams::ber &c,"<<structName<<" &_t)\n{\n";
+ cpp<<"\tstd::cout<<\"decode typeref "<<structName<<"\"<<std::endl;\n";
+ if ( m_typeref.tagged()
+ && ( m_gencpp.tag_mode(type) == asn1::node::tag_type::TM_EXPLICIT)
+ )
+ {
+ cpp<<"\tstd::cout<<\"decode typeref explicit tag "<<refName<<"\"<<std::endl;\n";
+ }
+ cpp<<"\treturn asn1::ok;\n";
+ cpp<<"}\n";
+ }
+
+}
+
+//
+void cgcpph_typeref::generate_oer()
+{
+ if (m_gencpp.with_codec())
+ {
+ std::string ns( m_gencpp.get_module()->cpp_name() );
+ std::string structName( ns + "::" + m_typeref.identifier_cpp_name() );
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void codecOER::encode(streams::oer &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int codecOER::decode(streams::oer &c,"<<structName<<" &_t);\n";
+
+ cpp<<"// typeref generator todo"<<std::endl;
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecOER::encode(asn1::streams::oer &c,const "<<structName<<" &_t)\n{\n";
+ cpp<<"\tstd::cout<<\"encode typeref "<<structName<<"\"<<std::endl;\n";
+ cpp<<"\tc.encode_octetstring(_t);";
+ cpp<<"}\n";
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecOER::decode(asn1::streams::oer &c,"<<structName<<" &_t)\n{\n";
+ cpp<<"\tstd::cout<<\"decode typeref "<<structName<<"\"<<std::endl;\n";
+ cpp<<"\treturn asn1::ok;\n";
+ cpp<<"}\n";
+ }
+
+}
+
+//
+void cgcpph_typeref::generate_jer()
+{
+ //m_gencpp.gen_template_signature(m_os,type);
+ if (m_gencpp.with_codec())
+ {
+ std::string ns( m_gencpp.get_module()->cpp_name() );
+ std::string structName( ns + "::" + m_typeref.identifier_cpp_name() );
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void codecJER::encode(streams::jer &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int codecJER::decode(streams::jer &c,"<<structName<<" &_t);\n";
+
+ cpp<<"// typeref generator todo"<<std::endl;
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecJER::encode(asn1::streams::jer &c,const "<<structName<<" &_t)\n{\n";
+ cpp<<"\tstd::cout<<\"encode typeref "<<structName<<"\"<<std::endl;\n";
+ cpp<<"\tc.encode_octetstring(_t);";
+ cpp<<"}\n";
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecJER::decode(asn1::streams::jer &c,"<<structName<<" &_t)\n{\n";
+ cpp<<"\tstd::cout<<\"decode typeref "<<structName<<"\"<<std::endl;\n";
+ cpp<<"\treturn asn1::ok;\n";
+ cpp<<"}\n";
+ }
+
+}
+
+//
+void cgcpph_typeref::generate_xer()
+{
+}
+
--- /dev/null
+#ifndef CGCPPH_TYPEREF_H
+#define CGCPPH_TYPEREF_H
+
+
+/**
+ *
+ */
+class cgcpph_typeref : public cgcpp_helper
+{
+ protected:
+ cgcpph_typeref(const cgcpph_typeref &s) : cgcpp_helper(s.m_gencpp,s.m_os)
+ , m_typeref(s.m_typeref) {}
+ public:
+ cgcpph_typeref(generate_codec_cpp &g,std::ostream &os,asn1::typeref &s) ;
+ ~cgcpph_typeref();
+
+ // Helper functions
+ virtual void generate(const std::string &scope) ;
+
+ void gen_printf(const std::string &scope);
+ // generate codec part
+ virtual void generate_per() ;
+ //
+ virtual void generate_ber() ;
+ //
+ virtual void generate_oer() ;
+ //
+ virtual void generate_jer() ;
+ //
+ virtual void generate_xer() ;
+ protected:
+ //
+ virtual void generate_descriptor() ;
+ virtual void generate_ctors() ;
+ virtual void generate_operators() ;
+ protected:
+ void gen_simple_ctors() ;
+ void gen_simple_equal() ;
+ void generate_external_type() {} ;
+ void generate_external_value() {} ;
+ // This method will be used to deal with
+ // TYPE-IDENTIFIER and OBJECT CLASS
+ void generate_objectclass() ;
+ void gen_objectclass_ctors() {} ;
+ protected:
+ asn1::typeref &m_typeref;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include <fstream>
+#include <sstream>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_hpp.h"
+#include "asn1_generator_helper.h"
+#include "asn1_gen_codec_cpp.h"
+#include "cgcpp_helper.h"
+#include "asn1_gen_codec_cpp.h"
+#include "cgh_construct.h"
+#include "asn1_recursive_visitor.h"
+
+
+cgh_construct::cgh_construct( generate_codec_cpp &g
+ , std::ostream &os
+ , asn1::constructed &cdef)
+ : cgcpp_helper(g,os) ,m_c(cdef)
+ , m_elcount(0)
+ , m_t2elcount(0)
+{
+ m_gencpp.struct_name(&m_c,m_structName);
+}
+
+cgh_construct::~cgh_construct()
+{
+}
+
+/**
+ * I'm not yet convinced about what to put in here.
+ * below construct, there are simple types like
+ * integer, enumerated, oid, bit_string
+ * and real constructed type like
+ * choice, set, sequence
+ *
+ * Let's use the implementation below for the simple types.
+ */
+void
+cgh_construct::generate_descriptor()
+{
+
+ std::string cn(m_c.identifier_cpp_name());
+ unsigned int _count = 0;
+
+ m_os<<"static asn1::tag TAGS_"<<m_c.identifier_cpp_name()<<"[] = {\n";
+ if (m_c.tagged())
+ {
+ m_os<<"asn1::tag("<<m_c.tag().m_class<<","<<m_c.tag().m_value;
+ if (m_gencpp.is_tag_explicit(m_c))
+ m_os<<",true";
+ m_os<<")\n";
+ } else {
+ m_os<<"asn1::tag("<<m_c.tag().m_class<<","<<m_c.tag().m_value;
+ m_os<<")\n";
+ }
+ m_os<<"};\n";
+
+/**/
+
+ m_os<<"const asn1::types::descriptor "<<m_structName<<"::_meta = {\n";
+ if (m_c.tagged())
+ {
+ }
+ m_os<<" TAGS_"<<cn<<",";
+ m_os<<"sizeof(TAGS_"<<cn<<")/sizeof(TAGS_"<<cn<<"[0]),\n"; /* Tag List */
+ m_os<<" NULL,\n"; /* MEMBER List */
+ m_os<<" 0,\n"; /* Member list count */
+ m_os<<" NULL,\n"; /*tag to element */
+ m_os<<" 0\n"; /* tag to element count*/
+ m_os<<"};\n";
+ m_os<<std::endl;
+}
+
+void
+cgh_construct::gen_desc_seqset()
+{
+ std::string cn(m_c.identifier_cpp_name());
+ unsigned int _count = 0;
+
+ gen_member_table();
+
+ m_os<<"static asn1::tag TAGS_"<<m_c.identifier_cpp_name()<<"[] = {\n";
+ if (m_c.tagged())
+ {
+ m_os<<"asn1::tag("<<m_c.tag().m_class<<","<<m_c.tag().m_value;
+ if (m_gencpp.is_tag_explicit(m_c))
+ m_os<<",true";
+ m_os<<")\n";
+ } else {
+ m_os<<"asn1::tag("<<m_c.tag().m_class<<","<<m_c.tag().m_value;
+ m_os<<")\n";
+ }
+ m_os<<"};\n";
+
+/**/
+
+ m_os<<"const asn1::types::descriptor "<<m_structName<<"::_meta = {\n";
+ if (m_c.tagged())
+ {
+ }
+ m_os<<" TAGS_"<<cn<<",";
+ m_os<<"sizeof(TAGS_"<<cn<<")/sizeof(TAGS_"<<cn<<"[0]),\n"; /* Tag List */
+ m_os<<" MEMBER_"<<m_structName<<",\n"; /* MEMBER List */
+ m_os<<" sizeof(MEMBER_"<<m_structName<<")/sizeof(MEMBER_"<<m_structName<<"[0]),\n"; /* Member list count */
+ m_os<<" NULL,\n"; /*tag to element */
+ m_os<<" 0\n"; /* tag to element count*/
+ m_os<<"};\n";
+ m_os<<std::endl;
+}
+
+void
+cgh_construct::gen_equal()
+{
+ std::string lscope;
+ asn1::node *type = &m_c;
+ asn1::node::iterator lit = m_c.begin();
+ //
+
+ // let s start
+ m_gencpp.gen_template_signature(m_os,&m_c);
+
+ lscope = m_structName;
+ m_os<<"bool "<<m_structName;
+ m_gencpp.gen_template_signature_class(m_os,&m_c);
+ m_os<<"::"<<"operator ==";
+ m_os<<"("<<m_structName;
+ m_gencpp.gen_template_signature_class(m_os,&m_c);
+ m_os<<" &o) \n{\n";
+ m_os<<"\tstd::cerr<<\""<<m_structName<<"::operator == NEEDS TO BE CODED\\n\";\n";
+ m_os<<"\treturn false;\n";
+ m_os<<"}\n";
+ /**/
+}
+
+void
+cgh_construct::gen_data_length()
+{
+ int _count = 0;
+
+ m_gencpp.gen_template_signature(m_os,&m_c);
+ m_os<<"size_t "<<m_structName;
+ m_gencpp.gen_template_signature_class(m_os,&m_c);
+ m_os<<"::get_data_length() const\n{\n";
+ m_os<<"\treturn ";
+ for ( asn1::node::iterator it = m_c.begin()
+ ; it != m_c.end()
+ ; ++it )
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*it);
+ asn1::typenode *type = f->get_type();
+ if (!type)
+ {
+ continue;
+ }
+ if (it != m_c.begin() )
+ m_os<<"\t\t+ ";
+ m_os<<""<<f->cpp_name()<<".get_length()\n";
+ _count++;
+ }
+ if (! _count)
+ {
+ m_os<<"0 ;\n";
+ }else
+ m_os<<"\t;\n";
+ m_os<<"};\n";
+}
+
+struct ConstructPrintTag
+{
+ ConstructPrintTag(generate_codec_cpp &_g,std::ostream &os,unsigned int &c)
+ : m_gencpp(_g), m_os(os), m_count(c) {}
+ void operator ()(asn1::node *_node)
+ {
+ if (asn1::typenode *tn = _node->as_typenode())
+ {
+ m_os<<"\t";
+ if (m_count++)
+ m_os<<", ";
+ m_os<<"asn1::tag("<<_node->tag().m_class<<","<<_node->tag().m_value;
+ if (m_gencpp.is_tag_explicit(*_node->as_typenode()))
+ m_os<<",true";
+ m_os<<")\n";
+ }
+ }
+ std::ostream &m_os;
+ unsigned int &m_count;
+ generate_codec_cpp &m_gencpp;
+};
+
+/**
+ *
+ */
+void
+cgh_construct::gen_member_tags(std::ostream &_os_tags,asn1::field &_f,asn1::typenode &_type)
+{
+ std::string cls(m_c.identifier()->cpp_name());
+ unsigned int _count = 0;
+ ConstructPrintTag pt(m_gencpp,_os_tags,_count);
+
+
+ _os_tags<<"static asn1::tag MTAGS_"<<cls<<"_"<<_f.cpp_name()<<"[] = {\n";
+ if (_type.tagged())
+ {
+ _os_tags<<"asn1::tag("<<_type.tag().m_class<<","<<_type.tag().m_value;
+ if (m_gencpp.is_tag_explicit(_type))
+ _os_tags<<",true";
+ _os_tags<<")\n";
+ } else {
+ if (asn1::typeref *tref = _type.as_typeref())
+ {
+ asn1::node::tag_type tg = tref->otag(m_gencpp.resolver());
+ std::list<asn1::node *> refs;
+ _os_tags<<"// Is private "<<_f.cpp_name()<<"\n";
+ m_gencpp.reference_chaine(tref,refs);
+ std::for_each(refs.rbegin(),refs.rend(),pt);
+ } else
+ {
+ _os_tags<<"asn1::tag("<<_type.tag().m_class<<","<<_type.tag().m_value;
+ _os_tags<<")\n";
+ }
+ }
+ _os_tags<<"};\n";
+}
+/**
+ *
+ */
+void
+cgh_construct::gen_member_desc(std::ostream &_os_desc,asn1::field &_f,asn1::typenode &_type)
+{
+ std::string cls(m_c.identifier()->cpp_name());
+ std::string cn("MTAGS_"+cls+"_"+_f.cpp_name());
+
+ _os_desc<<"static asn1::types::descriptor DESC_"<<cls<<"_"<<_f.cpp_name()<<" = {\n";
+ _os_desc<<" "<<cn<<",\n";
+ _os_desc<<" sizeof("<<cn<<")/sizeof("<<cn<<"[0]),\n"; /* Tag List */
+ _os_desc<<" NULL,\n"; /* MEMBER List */
+ _os_desc<<" 0,\n"; /* Member list count */
+ _os_desc<<" NULL,\n"; /*tag to element */
+ _os_desc<<" 0\n"; /* tag to element count*/
+ _os_desc<<"};\n";
+}
+
+void
+cgh_construct::gen_member_table()
+{
+ size_t _count = 0;
+ bool is_choice = (m_c.as_choice() == NULL)?false:true;
+ std::string cls(m_c.identifier()->cpp_name());
+ std::ostringstream _os("");
+ std::ostringstream _os_tags("");
+ std::ostringstream _os_desc("");
+ _os<<"static asn1::types::member_desc MEMBER_"<<cls<<"[] = {\n";
+
+ for ( asn1::node::iterator it = m_c.begin()
+ ; it != m_c.end()
+ ; ++it , _count++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*it);
+ asn1::typenode *type = f->get_type();
+ if (!type)
+ {
+ _os<<" /*...*/\n";
+ continue;
+ }
+ std::ostringstream mos("");
+ gen_member_tags(_os_tags,*f,*type);
+ gen_member_desc(_os_desc,*f,*type);
+ std::string desc("DESC_"+cls+"_"+f->cpp_name());
+ //mos<<"MEMBER_OFFSET("<<cls<<",m_choice)";
+ // No member offset for choice type
+ mos<<"0";
+ std::string tf("asn1::types::TF_POINTER");
+ // try to set appropriate tag
+ if (!is_choice)
+ {
+ if (f->flags().is_optional())
+ tf="asn1::types::TF_SHARED_POINTER";
+ else
+ tf="asn1::types::TF_NONE";
+ }
+ m_elcount++;
+ if ( type
+ && type->tagged()
+ )
+ {
+ std::string _mode = (m_gencpp.is_tag_explicit(*type))?" 1":"-1";
+ _os<<" { "<<tf<<",\n ";
+ _os<<_mode<<" , ("<<type->tag().m_value<<"<<2) | ";
+ _os<<type->tag().m_class<<" ,\n "<<mos.str()<<","<<_count;
+ _os<<",\n &"<<desc<<",\n \""<<f->name()<<"\"}, /* "<<f->name()<<" */\n";
+ } else
+ {
+ if (asn1::typeref *ref = type->as_typeref())
+ {
+ asn1::node::tag_type tg = ref->otag(m_gencpp.resolver());
+ if ( ref->get_canonical_typenode()
+ && dynamic_cast<asn1::choice *>(ref->get_canonical_typenode()))
+ {
+ _os<<" { "<<tf<<",0 ,\n -1 "<<" ,";
+ _os<<mos.str()<<","<<_count<<",\n ";
+ _os<<"&"<<desc<<",\n \""<<f->name()<<"\"}, /* Choice ...*/\n";
+ } else if (ref->is_complex() && (tg.m_value == -1))
+ {
+ tf = "asn1::types::TF_OPEN_TYPE";
+ _os<<" { "<<tf<<",\n 0 , -1"<<",\n ";
+ _os<<mos.str()<<","<<_count<<",\n ";
+ _os<<"&"<<desc<<",\n \""<<f->name()<<"\"}, /* Cplx ...*/\n";
+ } else
+ {
+ _os<<" { "<<tf<<",\n";
+ _os<<" -1 , ("<<tg.m_value<<"<<2) | "<<tg.m_class<<" ,\n";
+ _os<<" "<<mos.str()<<","<<_count<<",\n";
+ _os<<" &"<<desc<<",\n \""<<f->name()<<"\"},";
+ _os<<" /* cano:"<<ref->get_canonical_typenode()->name()<<"*/\n";
+ }
+ } else
+ {
+ if (f->flags().is_optional())
+ tf="asn1::types::TF_SHARED_POINTER";
+ else
+ tf="asn1::types::TF_NONE";
+#if 0
+ // 2017/07/26 Generated too many compiler warning
+ if (! is_choice)
+ {
+ mos.str("");
+ mos<<"MEMBER_OFFSET("<<cls<<","<<f->cpp_name()<<")";
+ }
+#endif
+ _os<<" { "<<tf<<",-1 , 0 ,"<<mos.str()<<","<<_count<<",NULL,\""<<f->name()<<"\"},\n";
+ }
+ }
+
+ }
+ _os<<"};\n";
+ m_os<<_os_tags.str()<<std::endl;
+ m_os<<_os_desc.str()<<std::endl;
+ m_os<<_os.str()<<std::endl;
+}
+
+
+class tag2glv : public asn1::recursive_visitor<tag2glv>
+{
+ protected:
+ std::fstream &m_log;
+ generate_cpp &m_gencpp;
+ asn1::constructed &m_c;
+ std::ostream &m_os;
+ std::string m_current_choice;
+ int &m_t2elcount;
+ int m_elcount;
+ public:
+
+ tag2glv( generate_cpp &g
+ , std::ostream &os
+ , asn1::constructed &cdef
+ , int &_t2elc)
+ : m_gencpp(g), m_os(os) ,m_c(cdef)
+ , m_log(g.logger())
+ , m_t2elcount(_t2elc)
+ , m_elcount(0)
+ {
+ }
+
+ bool visit_alternative_choice(asn1::field *f)
+ {
+ asn1::typenode *type = f->get_type();
+ if (f->get_parent()->name() == m_c.name())
+ {
+ m_current_choice = f->cpp_name();
+ m_elcount++;
+ }
+ if (f->is_extensible())
+ return false;
+ if (type && type->tagged())
+ {
+ asn1::node::tag_type tg = type->tag();
+ print_entry(tg,f);
+ m_t2elcount++;
+ return false;
+ } else if (asn1::typeref *r = type->as_typeref())
+ {
+ if (asn1::node *rt = r->get_real_type())
+ {
+ if (r->is_complex())
+ {
+ traverse_type(rt);
+ return false;
+ }
+ if (asn1::choice *c = dynamic_cast<asn1::choice *>(rt))
+ {
+ traverse_type(rt);
+ return false;
+ }
+ if (asn1::typeref *oref = rt->as_typeref())
+ {
+ asn1::node::tag_type tg = oref->otag(m_gencpp.resolver());
+ print_entry(tg,f);
+ m_t2elcount++;
+ return false;
+ }
+ asn1::node::tag_type tg = rt->tag();
+ assert( (tg.m_value != -1) && "Tag must be other than -1");
+ print_entry(tg,f);
+ m_t2elcount++;
+ return false;
+ } else {
+ asn1::node *nrt = m_gencpp.resolver().resolve(*r);
+ if (nrt && nrt->tagged())
+ {
+ asn1::node::tag_type tg = nrt->tag();
+ print_entry(tg,f);
+ m_t2elcount++;
+ return false;
+ }
+ }
+ //m_os<<"n";
+ } else if (type ) {
+ asn1::node::tag_type tg = type->tag();
+ print_entry(tg,f);
+ m_t2elcount++;
+ return false;
+ }
+ m_os<<"/*end "<<__FUNCTION__<<"*/";
+ return true;
+ }
+ //
+ bool visit_primitive(asn1::node *p)
+ {
+ return true;
+ }
+ //
+ bool visit_reference(asn1::node *type)
+ {
+ if (type->tagged())
+ return true;
+ if (asn1::typeref *r = type->as_typeref())
+ {
+ if (asn1::node *rt = r->get_real_type())
+ {
+ if (asn1::choice *c = dynamic_cast<asn1::choice *>(rt))
+ return traverse_type(rt);
+ if (r->is_complex())
+ return traverse_type(rt);
+ m_os<<".";
+ }
+ }
+ m_os<<"/* "<<__FUNCTION__<<" : "<<type->cpp_name();
+ m_os<<"*/"<<std::endl;
+ return true;
+ }
+ /* I'm somewhere else */
+ bool visit_component_type(asn1::field *f)
+ {
+ return true;
+ }
+ /* */
+ void print_entry(asn1::node::tag_type &tg,asn1::field *f)
+ {
+ m_os<<" {"<<"( ("<<tg.m_value<<"<<2) | "<<tg.m_class<<"),";
+ m_os<<m_c.identifier()->cpp_name()<<"::"<<"typeof_"<<m_current_choice;
+ m_os<<","<<(m_elcount-1)<<" }, /*"<<f->name()<<" */"<<std::endl;
+ }
+};
+
+
+void
+cgh_construct::gen_tag2el_table()
+{
+ size_t _count = 0;
+ tag2glv glv(m_gencpp,m_os,m_c,m_t2elcount);
+
+ m_os<<"static asn1::types::tag2member_desc MAP_"<<m_c.identifier()->cpp_name()<<"_tag2el[] = {\n";
+ bool r= glv.traverse_type(&m_c);
+ m_os<<"};\n";
+}
+
+
+/**
+ *
+ */
+void
+cgh_construct::gen_codec_ber_encode()
+{
+ std::string ns ( m_gencpp.get_module()->cpp_name() ) ;
+ std::string structName ( ns + "::" +m_c.identifier_cpp_name() );
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+#if 0
+ //m_gencpp.gen_template_signature(m_os,type);
+ hpp<<"\n// sequence type "<<structName<<" priv="<<priv<<"\n";
+ hpp<<"template<>\n";
+ hpp<<"void asn1::codecBER::encode(asn1::streams::ber &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int asn1::codecBER::decode(asn1::streams::ber &c,"<<structName<<" &_t);\n";
+#endif
+ /* Generate implementation */
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecBER::encode(asn1::streams::ber &c,const "<<structName<<" &_t)\n{\n";
+ cpp<<"\tc.encode_sequence_preamble(_t);\n";
+
+ for (asn1::node::iterator it = m_c.begin(); it != m_c.end() ; it++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*it);
+ asn1::typenode *attr_type = f->get_type();
+ if (attr_type != NULL)
+ {
+ if (attr_type->type_id()() == asn1::type::ASN1_EXTENSIBLE)
+ {
+ cpp<<"\t// Extensible marker"<<std::endl;
+ continue;
+ }
+ /* */
+ if (attr_type->tagged()
+ && (m_gencpp.is_tag_explicit(*attr_type)))
+ {
+ asn1::node::tag_type lt = attr_type->tag();
+ cpp<<"\t{\n";
+ cpp<<"\t\t"<<"asn1::tag t("<<lt.m_class<<","<<lt.m_value<<",true); "<<std::endl;
+ cpp<<"\t\t"<<"encode_tag(c,t,_t."<<f->cpp_name()<<".get_length());\n";
+ }
+
+ if (f->flags().is_optional() && (! f->flags().is_default()))
+ {
+ cpp<<"\tif ( ! _t."<<f->cpp_name()<<".is_nul())\n\t{\n";
+ cpp<<"\t\tencode(c,_t."<<f->cpp_name()<<".get());\n\t}\n";
+ } else
+ {
+ cpp<<"\tencode(c,_t."<<f->cpp_name()<<");\n";
+ }
+ /* end explicit */
+ if (attr_type->tagged()
+ && (m_gencpp.is_tag_explicit(*attr_type)))
+ cpp<<"\t}\n";
+ }
+
+ } /* end for */
+ cpp<<"\tc.encode_sequence_epilogue(_t);\n";
+ cpp<<"}\n";
+}
+/**
+ *
+ */
+void
+cgh_construct::gen_codec_ber_decode()
+{
+ std::string ns ( m_gencpp.get_module()->cpp_name() ) ;
+ std::string structName ( ns + "::" +m_c.identifier_cpp_name() );
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecBER::decode(asn1::streams::ber &c,"<<structName<<" &_t)\n{\n";
+ //cpp<<"\tint len = 0;"<<""<<std::endl;
+ cpp<<"\tif ( c.decode_sequence_preamble(_t) != asn1::ok)\n";
+ cpp<<"\t\treturn asn1::wrong_type;\n";
+ /* loop over fields */
+ for (asn1::node::iterator it = m_c.begin(); it != m_c.end() ; it++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*it);
+ asn1::typenode *attr_type = f->get_type();
+ if (attr_type != NULL)
+ {
+ if (attr_type->type_id()() == asn1::type::ASN1_EXTENSIBLE)
+ {
+ cpp<<"\t// Extensible marker"<<std::endl;
+ continue;
+ }
+
+ /* */
+ if (attr_type->tagged()
+ && (m_gencpp.is_tag_explicit(*attr_type)))
+ {
+ asn1::node::tag_type lt = attr_type->tag();
+ cpp<<"\t{\n";
+ cpp<<"\t\tasn1::tag t("<<lt.m_class<<","<<lt.m_value<<",true);\n";
+ cpp<<"\t\t"<<"if (c.decode_tag(t))\n\t\t{\n\t\t";
+ }
+
+ if (f->flags().is_optional() && (! f->flags().is_default()))
+ {
+ cpp<<"\tdecode(c,_t."<<f->cpp_name()<<".get());\n";
+ } else
+ {
+ cpp<<"\tdecode(c,_t."<<f->cpp_name()<<");\n";
+ }
+ if (attr_type->tagged()
+ && (m_gencpp.is_tag_explicit(*attr_type)))
+ {
+ cpp<<"\t\t}\n";
+ cpp<<"\t}\n";
+ }
+ }
+ }
+ cpp<<"\tif ( c.decode_sequence_epilogue(_t) != asn1::ok)\n";
+ cpp<<"\t\treturn asn1::wrong_type;\n";
+ cpp<<"\treturn asn1::ok;\n";
+ cpp<<"}\n";
+
+}
+
+/**
+ *
+ */
+void
+cgh_construct::gen_ndecode(const std::string &scope,bool priv)
+{
+ asn1::constructed *type = &m_c;
+ asn1::node::iterator lit = type->begin();
+ asn1::node::iterator end = type->end();
+ std::string lscope;
+
+ gen_ndecode_preamble(scope,priv);
+ gen_ndecode_epilogue(scope,priv);
+ m_gencpp.gen_template_signature(m_os,type);
+
+ if (!priv)
+ {
+ lscope = type->identifier_cpp_name();
+ m_os<<"int "<<type->identifier_cpp_name();
+ } else
+ {
+ lscope = scope + type->cpp_name();
+ m_os<<"int "<<scope<<type->cpp_name();
+ }
+
+ m_gencpp.gen_template_signature_class(m_os,type);
+ m_os<<"::decode(asn1::context &ctx)"<<std::endl<<"{"<<std::endl;
+ if (m_gencpp.with_source_debug())
+ m_os<<"\tASN1_BER_LOG_DEBUG(\""<<lscope<<"::decode SEQ \");"<<std::endl;
+ // Core of the function
+ m_os<<"\tif (decode_preamble(ctx) != asn1::ok)\n\t{\n"<<std::endl;
+ if (m_gencpp.with_source_debug())
+ m_os<<"\t\tASN1_BER_LOG_DEBUG(\""<<lscope<<"::decode SEQ FAILED decode preamble\");"<<std::endl;
+ m_os<<"\t\treturn asn1::unknown;"<<std::endl;
+ m_os<<"\t}\n";
+ //
+ for (; lit != end ; lit++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*lit);
+ if (f->get_type() != NULL)
+ {
+ asn1::typenode *attribute_type = f->get_type();
+
+ if (f->flags().m_flags == asn1::node::marker_type::FL_OPTIONAL)
+ {
+ m_os<<"\t// DEF OPTIONAL ATTRIBUTE"<<std::endl;
+ }
+ if ( attribute_type->tagged())
+ { // Ok tagged value
+ asn1::node::tag_type lt = attribute_type->tag();
+ if(attribute_type->tag().m_mode == asn1::node::tag_type::TM_IMPLICIT)
+ {
+ m_os<<"\t"<<f->cpp_name()<<".decode(ctx);";
+ m_os<<"// IMPLICIT DEF="<<attribute_type->type_id()()<<std::endl;
+ } else
+ {
+ m_os<<"\t{\n";
+ m_os<<"\t\t"<<"asn1::tag t("<<lt.m_class<<","<<lt.m_value<<",true); "<<std::endl;
+ m_os<<"\t\t"<<"if ( ctx.decode_tag(t))\n";
+ m_os<<"\t\t{"<<std::endl;
+ if (attribute_type->has_constraints() )
+ {
+ std::string indent("\t\t");
+ m_gencpp.gen_attribute_constrained_ndecode(m_os,scope,indent ,f);
+ } else if (f->flags().is_default() )
+ {
+ m_os<<"\t"<<f->cpp_name()<<".decode(ctx);";
+ m_os<<"// EXPLICIT DEF D ="<<attribute_type->type_id()()<<std::endl;
+ } else
+ {
+ m_os<<"\t\t\t";
+ if (f->flags().is_optional())
+ m_os<<"ASN1_ATTRIBUTE_OPTIONAL_DECODE(";
+ m_os<<f->cpp_name();
+ if (! f->flags().is_optional())
+ m_os<<".decode(ctx";
+ m_os<<");// EXPLICIT DEF O ="<<attribute_type->type_id()()<<std::endl;
+ }
+ m_os<<"\t\t}\n";
+ m_os<<"\t}"<<std::endl;
+ }
+ } else
+ {
+ std::string indent("");
+ if (attribute_type->has_constraints() )
+ {
+ m_gencpp.gen_attribute_constrained_ndecode(m_os,scope,indent ,f);
+ } else if (f->flags().is_default() )
+ {
+ // gen_attribute_default_encode(os,scope,indent ,(*lit));
+ m_os<<"\t"<<""<<f->cpp_name()<<".decode(ctx);//DEF D =";
+ m_os<<attribute_type->type_id()()<<" - "<<std::endl;
+ } else if (f->flags().is_optional() )
+ {
+ // gen_attribute_optional_encode(os,scope,indent ,(*lit));
+ m_os<<"\t"<<"ASN1_ATTRIBUTE_OPTIONAL_DECODE(";
+ m_os<<f->cpp_name()<<");//DEF O =";
+ m_os<<attribute_type->type_id()()<<" - "<<std::endl;
+ }
+ else
+ {
+ m_os<<"\t"<<""<<f->cpp_name()<<".decode(ctx);//DEF=";
+ m_os<<attribute_type->type_id()()<<" - "<<std::endl;
+ }
+ }
+ }
+ }
+ m_os<<"\tdecode_epilogue(ctx);"<<std::endl;
+
+ m_os<<"\treturn asn1::ok;"<<std::endl;
+ m_os<<"\n}"<<std::endl;
+}
+
+/**
+ *
+ */
+void
+cgh_construct::gen_ndecode_preamble(const std::string &scope,bool priv)
+{
+ asn1::constructed *type = &m_c;
+
+ //
+ if (type->tagged())
+ {
+ if ( m_gencpp.is_tag_explicit(m_c) )
+ {
+ if (!priv)
+ {
+ m_os<<"int "<<type->identifier_cpp_name();
+ m_gencpp.gen_template_signature_class(m_os,type);
+ m_os<<"::decode_preamble_ber(asn1::streams::ber &ctx)"<<std::endl<<"{"<<std::endl;
+ if (m_gencpp.with_source_debug())
+ m_os<<"\tASN1_BER_LOG_DEBUG(\""<<type->identifier_name()<<"::decode_preamble_ber EXPLICIT tag:%d\",this->tag().byte());\n";
+ } else
+ {
+ m_os<<"int "<<scope<<type->cpp_name();
+ m_gencpp.gen_template_signature_class(m_os,type);
+ m_os<<"::decode_preamble_ber(asn1::streams::ber &ctx)"<<std::endl<<"{"<<std::endl;
+ if (m_gencpp.with_source_debug())
+ m_os<<"\tASN1_BER_LOG_DEBUG(\""<<type->cpp_name()<<"::decode_preamble_ber EXPLICIT tag:%d\",this->tag().byte());\n";
+ }
+ //
+ m_os<<"\tctx.nb_bits((1)<<3);"<<std::endl;
+ m_os<<"\tlong len = 0;"<<std::endl;
+ m_os<<"\tunsigned char *b = ctx.buffer();"<<std::endl;
+ m_os<<"\tm_pos = ctx.bytes();"<<std::endl;
+ m_os<<"\tctx.decode_length(&b[m_pos],&len);"<<std::endl;
+ m_os<<"\tctx.nb_bits((len)<<3);"<<std::endl;
+ m_os<<"\treturn asn1::ok;"<<std::endl;
+ m_os<<"}"<<std::endl;
+ }
+ }
+}
+
+/**
+ *
+ */
+void
+cgh_construct::gen_ndecode_epilogue(const std::string &scope,bool priv)
+{
+ asn1::constructed *type = &m_c;
+ //
+ if (type->tagged())
+ {
+ if ( m_gencpp.is_tag_explicit(m_c) )
+ {
+ if (!priv)
+ {
+ m_os<<"int "<<type->identifier_cpp_name();
+ m_gencpp.gen_template_signature_class(m_os,type);
+ m_os<<"::decode_epilogue_ber(asn1::streams::ber &ctx)"<<std::endl<<"{"<<std::endl;
+ if (m_gencpp.with_source_debug())
+ {
+ m_os<<"\tASN1_BER_LOG_DEBUG(\""<<type->identifier_name();
+ m_os<<"::decode_epilogue_ber EXPLICIT SEQUENCE tag:%d\",this->tag().byte());\n";
+ }
+ } else
+ {
+ m_os<<"int "<<scope<<type->cpp_name();
+ m_gencpp.gen_template_signature_class(m_os,type);
+ m_os<<"::decode_epilogue_ber(asn1::streams::ber &ctx)"<<std::endl<<"{"<<std::endl;
+ if (m_gencpp.with_source_debug())
+ {
+ m_os<<"\tASN1_BER_LOG_DEBUG(\""<<type->cpp_name();
+ m_os<<"::decode_epilogue_ber EXPLICIT SEQUENCE tag:%d\",this->tag().byte());\n";
+ }
+ }
+ //
+ m_os<<"\tunsigned long pos = ctx.bytes();"<<std::endl;
+ m_os<<"\tunsigned char *b = ctx.buffer();"<<std::endl;
+ m_os<<"\treturn asn1::ok;"<<std::endl;
+ m_os<<"}"<<std::endl;
+ }
+ }
+}
+
+/**
+ *
+ */
+void
+cgh_construct::gen_nencode(const std::string &scope,bool priv)
+{
+ asn1::constructed *type = &m_c;
+ asn1::node::iterator lit = (type)->begin();
+ asn1::node::iterator end = (type)->end();
+
+ gen_nencode_preamble(scope,priv);
+ gen_nencode_epilogue(scope,priv);
+
+ m_gencpp.gen_template_signature(m_os,type);
+ if (!priv)
+ {
+ m_os<<"void "<<type->identifier_cpp_name();
+ m_gencpp.gen_template_signature_class(m_os,type);
+ m_os<<"::encode(asn1::context &ctx)"<<std::endl<<"{"<<std::endl;
+ if (m_gencpp.with_source_debug())
+ m_os<<"\tASN1_BER_LOG_DEBUG(\""<<type->identifier_name()<<"::encode SEQUENCE \");\n";
+ } else
+ {
+ m_os<<"void "<<scope<<type->cpp_name();
+ m_gencpp.gen_template_signature_class(m_os,type);
+ m_os<<"::encode(asn1::context &ctx)"<<std::endl<<"{"<<std::endl;
+ if (m_gencpp.with_source_debug())
+ m_os<<"\tASN1_BER_LOG_DEBUG(\""<<type->cpp_name()<<"::encode SEQUENCE\");\n";
+ }
+ //
+ m_os<<"\tencode_preamble(ctx);"<<std::endl;
+ for (; lit != end ; lit++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*lit);
+ if (f->get_type() != NULL)
+ {
+ asn1::typenode *attribute_type = f->get_type();
+
+ if ((*lit)->flags().m_flags == asn1::node::marker_type::FL_OPTIONAL)
+ {
+ m_os<<"\t\t// DEF OPTIONAL ATTRIBUTE"<<std::endl;
+ }
+ if ( attribute_type->tagged())
+ { // Ok tagged value
+ if(attribute_type->tag().m_mode == asn1::node::tag_type::TM_IMPLICIT)
+ {
+ asn1::node::tag_type lt = attribute_type->tag();
+ m_os<<"\t\t"<<f->cpp_name()<<".encode(ctx);// IMPLICIT DEF="<<attribute_type->type_id()()<<std::endl;
+ } else {
+ asn1::node::tag_type lt = attribute_type->tag();
+ m_os<<"\t\t"<<f->cpp_name()<<".encode(ctx);// EXPLICIT DEF="<<attribute_type->type_id()()<<std::endl;
+ }
+ } else
+ {
+ std::string indent("\t");
+ if (attribute_type->has_constraints() )
+ {
+ // gen_attribute_constrained_encode(os,scope,indent ,(*lit));
+ std::string indent("\t\t");
+ m_gencpp.gen_attribute_constrained_nencode(m_os,scope,indent ,f);
+ } else if (f->flags().is_default() )
+ {
+ // gen_attribute_default_encode(os,scope,indent ,(*lit));
+ m_os<<"\tif (bit_mask.test("<<m_c.identifier()->cpp_name()<<"::";
+ m_os<<f->cpp_name()<<"_present))\n";
+ m_os<<"\t\t"<<""<<f->cpp_name()<<".encode(ctx);//DEF D =";
+ m_os<<f->get_type()->type_id()()<<" - "<<std::endl;
+ } else if (f->flags().is_optional() )
+ {
+ // gen_attribute_optional_encode(os,scope,indent ,(*lit));
+ m_os<<"\t\t"<<"ASN1_ATTRIBUTE_OPTIONAL_ENCODE(";
+ m_os<<f->cpp_name()<<");//DEF O =";
+ m_os<<attribute_type->type_id()()<<" - "<<std::endl;
+ }
+ else
+ {
+ m_os<<"\t\t"<<""<<f->cpp_name()<<".encode(ctx);//DEF=";
+ m_os<<attribute_type->type_id()()<<" - "<<std::endl;
+ }
+ }
+ }
+ }
+ m_os<<"\tencode_epilogue(ctx);"<<std::endl;
+
+ m_os<<"\n}"<<std::endl;
+}
+
+/**
+ *
+ */
+void
+cgh_construct::gen_nencode_preamble(const std::string &scope,bool priv)
+{
+ asn1::node *type = &m_c;
+ //
+ if (type->tagged())
+ {
+ if ( m_gencpp.is_tag_explicit(m_c) )
+ {
+ if (!priv)
+ {
+ m_os<<"void "<<type->identifier_cpp_name()<<"::encode_preamble_ber(asn1::context &ctx)"<<std::endl<<"{"<<std::endl;
+ if (m_gencpp.with_source_debug())
+ m_os<<"\tASN1_BER_LOG_DEBUG(\""<<type->identifier_name()<<"::encode_preamble_ber EXPLICIT tag:%d\",this->tag().byte());\n";
+ } else
+ {
+ m_os<<"void "<<scope<<type->cpp_name()<<"::encode_preamble_ber(asn1::context &ctx)"<<std::endl<<"{"<<std::endl;
+ if (m_gencpp.with_source_debug())
+ m_os<<"\tASN1_BER_LOG_DEBUG(\""<<type->cpp_name()<<"::encode_preamble_ber EXPLICIT tag:%d\",this->tag().byte());\n";
+ }
+ //
+ m_os<<"\tunsigned char *b = ctx.buffer();"<<std::endl;
+ m_os<<"\tm_pos = ctx.bytes();"<<std::endl;
+ m_os<<"\tasn1::tag t("<<type->tag().m_class<<","<<type->tag().m_value<<",true);"<<std::endl;
+ m_os<<"\tb[m_pos] = t.byte() | 0x20; //encode tag constructed "<<std::endl;
+ if (type->type_id()() == asn1::type::ASN1_SET)
+ {
+ m_os<<"\tb[m_pos+2] = MAKE_TAG(0,1,17);\n";
+ } else
+ m_os<<"\tb[m_pos+2] = MAKE_TAG(0,1,16);\n";
+
+ m_os<<"\tctx.nb_bits((4)<<3);"<<std::endl;
+ m_os<<"}"<<std::endl;
+ }
+ }
+}
+
+/**
+ *
+ */
+void
+cgh_construct::gen_nencode_epilogue(const std::string &scope,bool priv)
+{
+ //
+ if (m_c.tagged())
+ {
+ if ( m_gencpp.is_tag_explicit(m_c) )
+ {
+ if (!priv)
+ {
+ m_os<<"void "<<m_c.identifier_cpp_name()<<"::encode_epilogue_ber(asn1::context &ctx)"<<std::endl<<"{"<<std::endl;
+ if (m_gencpp.with_source_debug())
+ m_os<<"\tASN1_BER_LOG_DEBUG(\""<<m_c.identifier_name()<<"::encode_epilogue_ber EXPLICIT tag:%d\",this->tag().byte());\n";
+ } else
+ {
+ m_os<<"void "<<scope<<m_c.cpp_name()<<"::encode_epilogue_ber(asn1::context &ctx)"<<std::endl<<"{"<<std::endl;
+ if (m_gencpp.with_source_debug())
+ m_os<<"\tASN1_BER_LOG_DEBUG(\""<<m_c.cpp_name()<<"::encode_epilogue_ber EXPLICIT tag:%d\",this->tag().byte());\n";
+ }
+ //
+ m_os<<"\tunsigned long pos = ctx.bytes();"<<std::endl;
+ m_os<<"\tunsigned char *b = ctx.buffer();"<<std::endl;
+ m_os<<"\tb[m_pos+1] = pos - m_pos - 2;"<<std::endl;
+ m_os<<"\tb[m_pos+3] = pos - m_pos - 4;\n";
+ m_os<<"}"<<std::endl;
+ }
+ }
+}
+
+void cgh_construct::gen_codec()
+{
+
+ std::string structName = m_gencpp.get_module()->cpp_name();
+ structName = structName + "::" +m_c.identifier()->cpp_name();
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ //m_Gen.gen_template_signature(m_os,type);
+ hpp<<"\n// construct type "<<structName<<""<<"\n";
+#if 0
+ hpp<<"template<>\n";
+ hpp<<"void asn1::codecBER::encode(asn1::codec::ber &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int asn1::codecBER::decode(asn1::codec::ber &c,"<<structName<<" &_t);\n";
+#endif
+ if (m_gencpp.with_jer())
+ {
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void codecJER::encode(streams::jer &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int codecJER::decode(streams::jer &c,"<<structName<<" &_t);\n";
+ }
+}
+
+
+/**
+ * @brief same code for set and sequence for JER
+ * encoding and decoding
+ *
+ */
+void cgh_construct::generate_jer()
+{
+
+
+ if (m_gencpp.with_codec())
+ {
+ std::string MName = m_gencpp.get_module()->cpp_name();
+ std::string structName ( MName + "::" + m_c.identifier_cpp_name() );
+ std::fstream &hpp(m_gencpp.get_streams().m_os_codec_hpp);
+ std::fstream &cpp(m_gencpp.get_streams().m_os_codec_cpp);
+
+
+ hpp<<"\n// cgh_construct sequence or set type "<<structName<<"\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"void codecJER::encode(asn1::streams::jer &c,const "<<structName<<" &_t);\n";
+ hpp<<"\ntemplate<>\n";
+ hpp<<"int codecJER::decode(asn1::streams::jer &c,"<<structName<<" &_t);\n";
+
+ /* Implementation part */
+ cpp<<"\ntemplate<>\n";
+ cpp<<"void codecJER::encode(asn1::streams::jer &c,const "<<structName<<" &_t)\n{\n";
+
+ cpp<<"\tc.put_char(\"{\",1);\n";
+ for (asn1::node::iterator it = m_c.begin(); it != m_c.end() ; it++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*it);
+ asn1::typenode *attr_type = f->get_type();
+ if (attr_type != NULL)
+ {
+ if (attr_type->type_id()() == asn1::type::ASN1_EXTENSIBLE)
+ {
+ cpp<<"\t// Extensible marker"<<std::endl;
+ } else
+ {
+ if (it != m_c.begin())
+ {
+ if (f->flags().is_optional() )
+ {
+ cpp<<"\tif ( ! _t."<<f->cpp_name()<<".is_nul())\n\t";
+ }
+ cpp<<"\tc.put_char(\", \",2);\n";
+ }
+ if (f->flags().is_optional() )
+ {
+ cpp<<"\tif ( ! _t."<<f->cpp_name()<<".is_nul())\n\t{\n";
+ cpp<<"\t\tc.put_field(\"";
+ cpp<<f->cpp_name()<<"\","<<f->cpp_name().size()<<");\n";
+ cpp<<"\t\tc.put_char(\": \",2);\n";
+ cpp<<"\t\tencode(c,_t."<<f->cpp_name()<<".get());\n\t}\n";
+ } else
+ {
+ cpp<<"\tc.put_field(\"";
+ cpp<<f->cpp_name()<<"\","<<f->cpp_name().size()<<");\n";
+ cpp<<"\tc.put_char(\": \",2);\n";
+ cpp<<"\tencode(c,_t."<<f->cpp_name()<<");\n";
+ }
+ }
+ }
+
+ }
+ cpp<<"\tc.put_char(\"}\",1);\n";
+
+ cpp<<"}\n";
+ /* Implementation of decoding stream */
+ cpp<<"\ntemplate<>\n";
+ cpp<<"int codecJER::decode(asn1::streams::jer &c,"<<structName<<" &_t)\n{\n";
+ cpp<<"\tif ( c.decode_sequence_preamble(_t) != asn1::ok)\n";
+ cpp<<"\t\treturn asn1::wrong_type;\n";
+ /* loop over fields */
+ for (asn1::node::iterator it = m_c.begin(); it != m_c.end() ; it++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*it);
+ asn1::typenode *attr_type = f->get_type();
+ if (attr_type != NULL)
+ {
+ if (attr_type->type_id()() == asn1::type::ASN1_EXTENSIBLE)
+ {
+ cpp<<"\t// Extensible marker"<<std::endl;
+ } else
+ {
+ if (it != m_c.begin())
+ cpp<<"\tc.get_token(asn1::streams::jer::jer_tok_comma);\n";
+ cpp<<"\tif (c.get_token(\"";
+ cpp<<f->cpp_name()<<"\"))\n\t{\n";
+ cpp<<"\t\tc.get_token(asn1::streams::jer::jer_tok_colon);\n";
+ if (f->flags().is_optional())
+ {
+ cpp<<"\t\tdecode(c,_t."<<f->cpp_name()<<".get());\n";
+ } else
+ {
+ cpp<<"\t\tdecode(c,_t."<<f->cpp_name()<<");\n";
+ }
+ cpp<<"\t}\n";
+ }
+ }
+ }
+ cpp<<"\tif ( c.decode_sequence_epilogue(_t) != asn1::ok)\n";
+ cpp<<"\t\treturn asn1::wrong_type;\n";
+ cpp<<"\treturn asn1::ok;\n";
+ cpp<<"}\n";
+ }
+}
+
+
+
+/**
+ * vim: et sw=2 ts=2 list:
+ */
--- /dev/null
+#ifndef CGH_CONSTRUCT_H
+#define CGH_CONSTRUCT_H
+
+
+/**
+ *
+ */
+class cgh_construct : public cgcpp_helper
+{
+ protected:
+ int m_elcount;
+ int m_t2elcount;
+ cgh_construct(const cgh_construct &s )
+ : cgcpp_helper(s.m_gencpp,s.m_os)
+ , m_c(s.m_c)
+ {}
+ public:
+ cgh_construct( generate_codec_cpp &g
+ , std::ostream &os
+ , asn1::constructed &cdef) ;
+
+ ~cgh_construct();
+
+ // generate codec part
+ virtual void generate_per() {};
+ //
+ virtual void generate_ber() {};
+ //
+ virtual void generate_oer() {};
+ //
+ virtual void generate_jer() ;
+ //
+ virtual void generate_xer() {} ;
+
+ protected:
+ //
+ virtual void generate_descriptor() ;
+ /**
+ * Generate descriptor for set and sequence
+ */
+ void gen_desc_seqset();
+ void gen_codec();
+ void gen_equal();
+ void gen_data_length();
+ void gen_codec_ber_encode();
+ void gen_codec_ber_decode();
+ protected:
+ void gen_member_tags(std::ostream &os,asn1::field &_f,asn1::typenode &_type);
+ void gen_member_desc(std::ostream &os,asn1::field &_f,asn1::typenode &_type);
+ // Usefull
+ void gen_member_table();
+ // Generate a table for choice to be able to compute
+ // the appropriate m_kind from the tag
+ void gen_tag2el_table();
+ // 2017/06/06 Lets say I'm going to use same way for
+ // sequence and set even if it's not the same
+ void gen_ndecode(const std::string &scope,bool priv);
+ void gen_ndecode_preamble(const std::string &scope,bool priv);
+ void gen_ndecode_epilogue(const std::string &scope,bool priv);
+ void gen_nencode(const std::string &scope,bool priv);
+ void gen_nencode_preamble(const std::string &scope,bool priv);
+ void gen_nencode_epilogue(const std::string &scope,bool priv);
+ protected:
+ asn1::constructed &m_c;
+ std::string m_structName;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include <fstream>
+#include <sstream>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_hpp.h"
+#include "asn1_generator_helper.h"
+#include "asn1_gen_codec_cpp.h"
+#include "cghpp_helper.h"
+#include "asn1_gen_codec_cpp.h"
+#include "cgh_hconstruct.h"
+#include "asn1_recursive_visitor.h"
+
+
+cgh_hconstruct::cgh_hconstruct( generate_header &g
+ , std::ostream &os
+ , asn1::constructed &cdef)
+ : cghpp_helper(g,os) ,m_c(cdef)
+{
+ m_gencpp.struct_name(&m_c,m_structName);
+}
+
+cgh_hconstruct::~cgh_hconstruct()
+{
+}
+
+void
+cgh_hconstruct::generate()
+{
+#if 1
+ cghpp_helper::generate();
+#else
+ generate_prolog( );
+
+ // Missing constructors
+ generate_descriptor( );
+ // Initial ctor
+ generate_ctors( );
+
+ generate_operators( );
+
+ generate_members( );
+ //
+ generate_ber();
+ //
+ generate_printf( );
+
+ m_os<<"};\n";
+#endif
+}
+
+void
+cgh_hconstruct::generate_descriptor()
+{
+ cghpp_helper::generate_descriptor( );
+}
+
+
+/**
+ * vim: et sw=2 ts=2 list:
+ */
--- /dev/null
+#ifndef CGH_HCONSTRUCT_H
+#define CGH_HCONSTRUCT_H
+
+
+/**
+ *
+ */
+class cgh_hconstruct : public cghpp_helper
+{
+ protected:
+ cgh_hconstruct(const cgh_hconstruct &s )
+ : cghpp_helper(s.m_gencpp,s.m_os)
+ , m_c(s.m_c) , m_structName(s.m_structName)
+ {}
+ public:
+ cgh_hconstruct( generate_header &g
+ , std::ostream &os
+ , asn1::constructed &cdef) ;
+
+ ~cgh_hconstruct();
+
+ // Helper functions
+ virtual void generate() ;
+
+ // generate codec part
+ virtual void generate_per() {};
+ //
+ virtual void generate_ber() {};
+ //
+ virtual void generate_oer() {};
+ //
+ virtual void generate_jer() {};
+ //
+ virtual void generate_xer() {} ;
+
+ protected:
+ // Usefull
+ /**
+ * @brief implement the code that generated
+ * the begin of the structure. example:
+ * struct type : public primary type \n {\n
+ */
+ virtual void generate_prolog( ) { } ;
+ /**
+ * @ brief add a static descriptor attribute to each datatype
+ * this static variable contains the asn1 type meta data
+ * static const types::descriptor _meta;
+ */
+ void generate_descriptor();
+ /**
+ * @brief generate constructors for the type
+ *
+ */
+ virtual void generate_ctors() { };
+ /**
+ * @brief generique function to generate printf
+ */
+ virtual void generate_printf() { };
+ /**
+ * @brief for choice, sequence and set this
+ * can be useful
+ */
+ virtual void generate_members() { };
+ /**
+ * @brief use this function to generate code related to
+ * c++ operator like equal, + - * / etc...
+ */
+ virtual void generate_operators() { };
+
+ protected:
+ asn1::constructed &m_c;
+ std::string m_structName;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include <fstream>
+#include <sstream>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_hpp.h"
+#include "asn1_gen_codec_cpp.h"
+#include "asn1_generator_helper.h"
+#include "cgcpp_helper.h"
+#include "cgh_object.h"
+#include "asn1_visitor.h"
+
+
+cgh_object::cgh_object( generate_cpp &g
+ , std::ostream &os
+ , asn1::object &s
+ , asn1::classdef &cdef)
+ : m_Gencpp(g), generator_helper(os) , m_object(s) ,m_classdef(cdef)
+ , m_log(g.logger())
+{
+}
+
+cgh_object::~cgh_object()
+{
+}
+
+
+/**
+ * Helper functions
+ *
+ */
+void cgh_object::generate()
+{
+}
+
+// generate codec part
+void cgh_object::generate_per()
+{
+}
+
+//
+void cgh_object::generate_ber()
+{
+}
+
+//
+void cgh_object::generate_oer()
+{
+}
+
+//
+void cgh_object::generate_jer()
+{
+}
+
+//
+void cgh_object::generate_xer()
+{
+}
+
+/**
+ *
+ */
+class cgho_gtplt_args : public node_visitor<cgho_gtplt_args>
+{
+ protected:
+ asn1::classdef &m_classdef;
+ asn1::object &m_object;
+ generate_cpp &m_gen;
+ std::stringstream m_os;
+ std::fstream &m_log;
+ long m_count;
+ bool m_with_scope;
+ public:
+ cgho_gtplt_args(generate_cpp &_gen,asn1::object &_obj,asn1::classdef &_cdef,bool with_scope)
+ : m_count(0), m_classdef(_cdef),m_object(_obj),m_gen(_gen)
+ , m_log(_gen.logger()) , m_with_scope(with_scope)
+ { m_os.str(""); } ;
+
+ std::string result() { return m_os.str() ; }
+
+#define ASN1_CLASSFIELD_TYPE(cf,code) \
+ void visit_##cf(asn1::cf *field) code
+
+ASN1_CLASSFIELD_TYPE(classfield_tf,{
+ asn1::node *type = NULL;
+ if ( (type = m_object.get_field(field->name()) ) != NULL)
+ {
+ if (m_count++)
+ m_os<<" ,";
+ if (m_with_scope)
+ {
+ asn1::typeref *ref = dynamic_cast<asn1::typeref *>(type);
+ asn1::node *rtype = (ref)?ref->get_real_type():NULL;
+ if(ref && !rtype)
+ {
+ ref->resolve(m_gen.resolver());
+ rtype = ref->get_real_type();
+ } else
+ {
+ std::cerr<<"gen_template_args type= ";
+ std::cerr<<type->name()<<" NOT TYPEREF\n";
+ }
+ if (rtype)
+ {
+ m_os<<" "<<rtype->get_parent()->cpp_name()<<"::";
+ }
+ } else
+ m_os<<" ";
+ switch (type->type_id()())
+ {
+ case asn1::type::ASN1_SET_OF:
+ {
+ asn1::node *seqof_type = type->as_typenode()->get_eltype();
+ std::string strtype;
+ if (m_gen.type2cppstring(type->as_typenode(),strtype))
+ {
+ m_os<<type->cpp_name()<<"<";
+ m_os<<strtype;
+ m_os<<"/*s */ > ";
+ } else
+ {
+ m_os<<type->cpp_name()<<"<";
+ m_os<<seqof_type->cpp_name();
+ m_os<<"> ";
+ }
+ }
+ break;
+ default:
+ GEN_LOG_ERROR( "gen_template_args TFT %s %s\n"
+ , field->name().c_str()
+ , type->cpp_name().c_str());
+ m_os<<type->cpp_name();
+ }
+ } else
+ { // Undefined type. replace with asn1::type
+ if (m_count++)
+ m_os<<" ,";
+ m_os<<" asn1::types::type";
+ }
+
+})
+ASN1_CLASSFIELD_TYPE(classfield_ftvf,{
+ asn1::valuetype *type = NULL;
+ if ( (type = m_object.get_ftvf(field->name()) ) != NULL )
+ {
+ std::string s = field->name();
+ s[0] = '_';
+ switch (type->type_id()())
+ {
+ case asn1::type::ASN1_INTEGER:
+ {
+ GEN_LOG_DEBUG( "gen_template_args INT %s %s\n"
+ , field->name().c_str()
+ , type->cpp_name().c_str());
+ if (m_count++)
+ m_os<<" ,";
+ m_os<<" "<<type->cpp_name();
+ }
+ break;
+ case asn1::type::ASN1_OBJECT_IDENTIFIER:
+ {
+ GEN_LOG_DEBUG( "gen_template_args OID %s %s\n"
+ ,field->name().c_str(),type->cpp_name().c_str());
+ asn1::object_identifier *oid = type->as_object_identifier();
+ long size = oid->hash();
+ if (m_count++)
+ m_os<<" ,";
+ m_os<<" "<<size;
+ }
+ break;
+ case asn1::type::ASN1_CHOICE:
+ {
+ asn1::value *v = type->value();
+ GEN_LOG_DEBUG( "gen_template_args CHOICE %s %s\n"
+ , field->name().c_str(),type->cpp_name().c_str());
+ if (m_count++)
+ m_os<<" ,";
+ m_os<<" "<<v->cpp_name();
+ }
+ default:
+ GEN_LOG_ERROR( "gen_template_args %s id %s\n"
+ , field->name().c_str()
+ , type->type_id().name());
+ }
+ }
+
+})
+ASN1_CLASSFIELD_TYPE(classfield_vtvf,{})
+ASN1_CLASSFIELD_TYPE(classfield_ftvsf,{})
+ASN1_CLASSFIELD_TYPE(classfield_vtvsf,{})
+ASN1_CLASSFIELD_TYPE(classfield_of,{})
+ASN1_CLASSFIELD_TYPE(classfield_osf,{})
+#undef ASN1_CLASSFIELD_TYPE
+};
+
+/**
+ * Needs some reworking for SET_OF type in CMIP
+ */
+void
+cgh_object::gen_template_args(bool with_scope)
+{
+ asn1::node::iterator fit = m_classdef.begin();
+ int count = 0;
+
+ cgho_gtplt_args cgho(m_Gencpp,m_object,m_classdef,with_scope);
+ //std::cout<<"\n\nBEGIN FUNCTION get_template_args with_scope="<<with_scope<<"\n\n";
+ GEN_LOG_DEBUG("gen_template_args start with_scope = %d\n",with_scope);
+ for ( ; fit != m_classdef.end()
+ ; ++fit)
+ {
+ cgho.visit(*fit);
+ }
+ m_os<<cgho.result();
+ GEN_LOG_DEBUG("gen_template_args end count = %d\n",count);
+}
--- /dev/null
+#ifndef CGH_OBJECT_H
+#define CGH_OBJECT_H
+
+
+/**
+ *
+ */
+class cgh_object : public generator_helper
+{
+ protected:
+ cgh_object(const cgh_object &s )
+ : generator_helper(s.m_os)
+ , m_Gencpp(s.m_Gencpp)
+ , m_object(s.m_object)
+ , m_classdef(s.m_classdef)
+ , m_log(s.m_log)
+ {}
+ public:
+ cgh_object( generate_cpp &g
+ , std::ostream &os
+ , asn1::object &s
+ , asn1::classdef &cdef) ;
+
+ ~cgh_object();
+
+ // Helper functions
+ virtual void generate() ;
+
+ // generate codec part
+ virtual void generate_per() ;
+ //
+ virtual void generate_ber() ;
+ //
+ virtual void generate_oer() ;
+ //
+ virtual void generate_jer() ;
+ //
+ virtual void generate_xer() ;
+
+ asn1::object &get_object() { return m_object;}
+
+ asn1::classdef &get_classdef() { return m_classdef;}
+ protected:
+ // Generate template arguments for object
+ void gen_template_args(bool with_scope=false);
+ protected:
+ std::fstream &m_log;
+ generate_cpp &m_Gencpp;
+ asn1::object &m_object;
+ asn1::classdef &m_classdef;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_hpp.h"
+#include "asn1_generator_helper.h"
+#include "cgcpp_helper.h"
+#include "cgh_value.h"
+
+
+cgh_value::cgh_value( generate_header &g
+ , std::ostream &os
+ , asn1::value &s)
+ : m_Gen(g)
+ , generator_helper(os)
+ , m_value(s)
+ , m_log(g.logger())
+{
+}
+
+cgh_value::~cgh_value()
+{
+}
+
+
+/** Helper functions
+ *
+ * It seems that the choice does not always have an identifier. Examples
+ * - SEQUENCE OF CHOICE {}
+ * - Test ::= CHOICE { toto INTEGER, CHOICE { } }
+ * these sequences are anonymous definitions ...
+ */
+void cgh_value::generate()
+{
+ asn1::node *n = m_value.identifier();
+ asn1::node *type = &m_value;
+ asn1::node *params = NULL;
+ std::string structName;
+ std::string scope("");
+
+ if (m_Gen.with_source_comment())
+ m_os<<"// cgh_value helper launched "<<std::endl;
+
+}
+
+//
+void cgh_value::gen_printf()
+{
+}
+
+// generate codec part
+void cgh_value::generate_per()
+{
+}
+
+//
+void cgh_value::generate_ber()
+{
+}
+
+//
+void cgh_value::generate_oer()
+{
+}
+
+//
+void cgh_value::generate_jer()
+{
+}
+
+//
+void cgh_value::generate_xer()
+{
+}
--- /dev/null
+#ifndef CGH_VALUE_H
+#define CGH_VALUE_H
+
+
+/**
+ *
+ */
+class cgh_value : public generator_helper
+{
+ protected:
+ cgh_value(const cgh_value &s) : generator_helper(s.m_os)
+ , m_Gen(s.m_Gen)
+ , m_log(s.m_log)
+ , m_value(s.m_value) {}
+ public:
+ cgh_value(generate_header &g,std::ostream &os,asn1::value &s) ;
+ ~cgh_value();
+
+ // Helper functions
+ virtual void generate() ;
+
+ // generate codec part
+ virtual void generate_per() ;
+ //
+ virtual void generate_ber() ;
+ //
+ virtual void generate_oer() ;
+ //
+ virtual void generate_jer() ;
+ //
+ virtual void generate_xer() ;
+ protected:
+ void gen_printf();
+ protected:
+ std::fstream &m_log;
+ generate_header &m_Gen;
+ asn1::value &m_value;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_codec_cpp.h"
+#include "asn1_generator_helper.h"
+#include "asn1_gen_hpp.h"
+#include "cghpp_helper.h"
+
+
+/**
+ * constructor
+ */
+cghpp_helper::cghpp_helper( generate_header &g
+ , std::ostream &os
+ )
+ : m_gencpp(g), generator_helper(os),m_log(g.logger())
+{
+}
+
+/**
+ *
+ * @brief common way to generate the required code depending
+ * on the global settings given to the asn1 parser.
+ */
+void
+cghpp_helper::generate()
+{
+ // generate class begin
+ generate_prolog();
+ // descriptor is a static attribute named _meta
+ generate_descriptor();
+ // generate ctors
+ generate_ctors();
+ // generate members
+ generate_members();
+ // generate ber
+ generate_ber();
+ // generate jer
+ // generate oer
+ // generate per
+ generate_operators();
+ //
+ generate_printf();
+ // generate class end
+ m_os<<"};\n";
+}
+
+void
+cghpp_helper::generate_descriptor()
+{
+ m_os<<"\tstatic const asn1::types::descriptor _meta;\n";
+}
+
+void
+cghpp_helper::generate_prolog()
+{
+}
+
+void
+cghpp_helper::generate_ctors()
+{
+}
+
+/* Only valid for choice, set ,and sequence */
+void
+cghpp_helper::generate_members()
+{
+}
+
+void
+cghpp_helper::generate_printf()
+{
+}
--- /dev/null
+#ifndef CODE_GEN_HPP_HELPER_H
+#define CODE_GEN_HPP_HELPER_H
+
+/**
+ * This class defines the interface that each
+ * asn1 type generation should implement ....
+ * Unlike generator_helper, this class provides a first
+ * level of functions dedicated to c++ code generation. The goal is
+ * to move the generation from one unique file to one file per type.
+ * -> provide streams for cpp,h and hpp.
+ * -> provide generic preamble et epilog
+ * -> open /close stream
+ */
+class cghpp_helper : public generator_helper
+{
+ public:
+ cghpp_helper( generate_header &g
+ , std::ostream &os
+ );
+
+ /**
+ * @brief entry point to generate the structure. Should
+ * follow the same pattern for all asn1 types.
+ * @TODO This function should not be virtual when you think
+ * of it.
+ */
+ virtual void generate() ;
+ // generate codec part
+ virtual void generate_per() {};
+ //
+ virtual void generate_ber() {};
+ //
+ virtual void generate_oer() {};
+ //
+ virtual void generate_jer() {};
+ //
+ virtual void generate_xer() {};
+
+ // generate encoder
+ // generate decoder
+ // generate constructor
+ // generate
+ protected:
+ /**
+ * @brief implement the code that generated
+ * the begin of the structure. example:
+ * struct type : public primary type \n {\n
+ */
+ virtual void generate_prolog();
+ /**
+ * @ brief add a static descriptor attribute to each datatype
+ * this static variable contains the asn1 type meta data
+ * static const types::descriptor _meta;
+ */
+ void generate_descriptor();
+ /**
+ * @brief generate constructors for the type
+ *
+ */
+ virtual void generate_ctors();
+ /**
+ * @brief generique function to generate printf
+ */
+ virtual void generate_printf();
+ /**
+ * @brief for choice, sequence and set this
+ * can be useful
+ */
+ virtual void generate_members();
+ /**
+ * @brief use this function to generate code related to
+ * c++ operator like equal, + - * / etc...
+ */
+ virtual void generate_operators() {};
+ protected:
+ std::fstream &m_log;
+ generate_header &m_gencpp;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_hpp.h"
+#include "asn1_gen_codec_cpp.h"
+#include "asn1_generator_helper.h"
+#include "cghpp_helper.h"
+#include "cgh_hconstruct.h"
+#include "cghpph_bitstring.h"
+
+
+cghpph_bit_string::cghpph_bit_string(generate_header &g,std::ostream &os,asn1::bit_string &s)
+ : cgh_hconstruct(g,os,s) , m_bit_string(s)
+{
+}
+
+cghpph_bit_string::~cghpph_bit_string()
+{
+}
+
+
+/** Helper functions
+ *
+ * It seems that the choice does not always have an identifier. Examples
+ * - SEQUENCE OF CHOICE {}
+ * - Test ::= CHOICE { toto INTEGER, CHOICE { } }
+ * these sequences are anonymous definitions ...
+ */
+void cghpph_bit_string::generate()
+{
+ cgh_hconstruct::generate( );
+}
+
+/**
+ *
+ */
+void cghpph_bit_string::generate_prolog()
+{
+ if (m_gencpp.with_source_comment())
+ m_os<<"// cghpph_bit_string helper launched "<<std::endl;
+
+ m_os<<"struct "<<m_bit_string.identifier_cpp_name()<<" : public BIT_STRING\n{\n";
+}
+
+/**
+ *
+ */
+void cghpph_bit_string::generate_ctors()
+{
+ // Initial ctor
+ m_os<<"\t"<<m_c.identifier_cpp_name()<<"(const asn1::tag &t = asn1::tag(";
+ if (m_bit_string.tagged())
+ {
+ if ( m_gencpp.is_tag_explicit(m_bit_string) )
+ {
+ m_os<<m_bit_string.tag().m_class<<","<<m_bit_string.tag().m_value<<",true));\n";
+ } else
+ {
+ m_os<<m_bit_string.tag().m_class<<","<<m_bit_string.tag().m_value<<",false));\n";
+ }
+ }else
+ m_os<<"0,3)) ;\n";
+ // copy
+ m_os<<"\t"<<m_c.identifier_cpp_name()<<"(const "<<m_c.identifier_cpp_name()<<" &t"<<") ;\n";
+
+}
+
+/**
+ *
+ */
+void cghpph_bit_string::generate_members()
+{
+ for (asn1::node::iterator it = m_c.begin(); it != m_c.end() ; it++)
+ {
+ asn1::valuetype *tv = dynamic_cast<asn1::valuetype *>(*it);
+ if ((*it)->type_id()()== asn1::type::ASN1_INTEGER /*&& (*it)->value_long()<31*/)
+ {
+ m_os<<"\tstatic unsigned long const "<<(*it)->cpp_name();
+ long dest= tv->value_long();
+ m_os<<"\t= "<<dest<<";";
+ } else {
+ m_os<<"\t//static unsigned long const "<<(*it)->cpp_name();
+ long dest= tv->value_long();
+ m_os<<"\t= "<<dest<<";";
+ }
+ if (it != m_c.end())
+ {
+ m_os<<"\n";
+ } else
+ {
+ m_os<<"\n";
+ }
+ }
+}
+
+/**
+ *
+ */
+void cghpph_bit_string::generate_printf()
+{
+ m_os<<"\tfriend std::ostream &operator <<(std::ostream &os,const ";
+ m_os<<m_bit_string.identifier_cpp_name()<<" &s);\n";
+}
+
+//
+void cghpph_bit_string::generate_ber()
+{
+ //
+ if (m_bit_string.tagged()
+ && m_gencpp.is_tag_explicit(m_bit_string) )
+ {
+ {
+ m_os<<"\tvirtual void encode(asn1::context &ctx);"<<std::endl;
+ m_os<<"\tvirtual int decode(asn1::context &ctx);"<<std::endl;
+ }
+ }
+}
+
--- /dev/null
+#ifndef CGHPPH_BITSTRING_H
+#define CGHPPH_BITSTRING_H
+
+
+/**
+ *
+ */
+class cghpph_bit_string : public cgh_hconstruct
+{
+ protected:
+ cghpph_bit_string(const cghpph_bit_string &s) : cgh_hconstruct(s.m_gencpp,s.m_os,s.m_c)
+ , m_bit_string(s.m_bit_string) {}
+ public:
+ cghpph_bit_string(generate_header &g,std::ostream &os,asn1::bit_string &s) ;
+ ~cghpph_bit_string();
+
+ // Helper functions
+ virtual void generate() ;
+
+ virtual void generate_prolog();
+
+ virtual void generate_printf();
+
+ virtual void generate_ctors();
+
+ virtual void generate_members();
+ // generate codec part
+ virtual void generate_per() {};
+ //
+ virtual void generate_ber() ;
+ //
+ virtual void generate_oer() {};
+ //
+ virtual void generate_jer() {};
+ //
+ virtual void generate_xer() {};
+
+ protected:
+ asn1::bit_string &m_bit_string;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_hpp.h"
+#include "asn1_generator_helper.h"
+#include "asn1_gen_codec_cpp.h"
+#include "cghpp_helper.h"
+#include "cghpph_primitive.h"
+#include "cghpph_boolean.h"
+
+
+cghpph_boolean::cghpph_boolean(generate_header &g,std::ostream &os,asn1::boolean &s)
+ : cghpph_primitive(g,os,s)
+ , m_boolean(s)
+{
+}
+
+cghpph_boolean::~cghpph_boolean()
+{
+}
+
+/**
+ *
+ */
+void cghpph_boolean::generate_prolog()
+{
+ if (m_gencpp.with_source_comment())
+ m_os<<"// cghpph_boolean helper launched "<<std::endl;
+
+ assert(m_boolean.type_id()() == asn1::type::ASN1_BOOLEAN);
+
+ if (m_gencpp.with_source_comment())
+ m_os<<"\n//\n// struct "<<m_structName<<"\n//\n";
+ m_os<<"struct "<<m_structName<<" : public BOOLEAN\n{\n";
+}
+
+/**
+ *
+ */
+void cghpph_boolean::generate_ctors()
+{
+ // Initial ctor
+ m_os<<"\t"<<m_structName<<"(const asn1::tag &t = asn1::tag(";
+ if (m_boolean.tagged())
+ {
+ if ( m_gencpp.is_tag_explicit(m_boolean) )
+ {
+ m_os<<m_boolean.tag().m_class<<","<<m_boolean.tag().m_value<<",true));\n";
+ } else
+ {
+ m_os<<m_boolean.tag().m_class<<","<<m_boolean.tag().m_value<<",false));\n";
+ }
+ }else
+ m_os<<"0,1)) ;\n";
+ // copy
+ m_os<<"\t"<<m_structName<<"(const "<<m_structName<<" &t"<<") ;\n";
+}
+
+/**
+ *
+ */
+void cghpph_boolean::generate_operators()
+{
+ // equal operator
+ m_os<<"\tbool operator ==("<<m_structName<<" &_c);\n";
+}
+
+/**
+ *
+ */
+void cghpph_boolean::generate_printf()
+{
+ asn1::node *ident = m_boolean.identifier();
+ asn1::node *params = ident->parameters();
+
+ m_os<<"\tfriend std::ostream &operator <<(std::ostream &os,const "<<m_structName;
+ if (ident->parameters() && m_gencpp.is_template(ident->parameters()))
+ {
+ m_gencpp.gen_template_params(m_os,ident->parameters());
+ }
+ m_os<<" &s"<<");";
+ m_os<<"\n";
+}
+
+/**
+ *
+ */
+void cghpph_boolean::generate_ber()
+{
+ //
+ if (m_boolean.tagged())
+ {
+ if ( m_gencpp.is_tag_explicit(m_boolean) )
+ {
+ //
+ m_os<<"\tvirtual void encode(asn1::context &ctx);"<<std::endl;
+ m_os<<"\tvirtual int decode(asn1::context &ctx);"<<std::endl;
+ }
+ }
+}
+
--- /dev/null
+#ifndef CGHPPH_BOOLEAN_H
+#define CGHPPH_BOOLEAN_H
+
+
+/**
+ *
+ */
+class cghpph_boolean : public cghpph_primitive
+{
+ protected:
+ cghpph_boolean(const cghpph_boolean &s) : cghpph_primitive(s.m_gencpp,s.m_os,s.m_boolean)
+ , m_boolean(s.m_boolean) {}
+ public:
+ cghpph_boolean(generate_header &g,std::ostream &os,asn1::boolean &s) ;
+ ~cghpph_boolean();
+
+ // Helper functions
+
+ // generate codec part
+ virtual void generate_per() {};
+ //
+ virtual void generate_ber() ;
+ //
+ virtual void generate_oer() {};
+ //
+ virtual void generate_jer() {};
+ //
+ virtual void generate_xer() {};
+
+ // loop over the attributes of SEQUENCE or CHOICE
+ // and check if there are some type of SEQUENCE or CHOICE
+ // launch generation for these types first.
+ protected:
+ virtual void generate_prolog();
+ virtual void generate_ctors();
+ virtual void generate_printf();
+ virtual void generate_operators();
+ protected:
+ asn1::boolean &m_boolean;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_hpp.h"
+#include "asn1_generator_helper.h"
+#include "asn1_gen_codec_cpp.h"
+#include "cghpp_helper.h"
+#include "cgh_hconstruct.h"
+#include "cghpph_choice.h"
+
+#undef GEN_LOG_DEBUG
+#define GEN_LOG_DEBUG
+
+cghpph_choice::cghpph_choice(generate_header &g,std::ostream &os,asn1::choice &s)
+ : cgh_hconstruct(g,os,s) , m_choice(s)
+{
+}
+
+cghpph_choice::~cghpph_choice()
+{
+}
+
+
+/** Helper functions
+ *
+ * It seems that the choice does not always have an identifier. Examples
+ * - SEQUENCE OF CHOICE {}
+ * - Test ::= CHOICE { toto INTEGER, CHOICE { } }
+ * these sequences are anonymous definitions ...
+ */
+void cghpph_choice::generate()
+{
+ asn1::node *ident = m_choice.identifier();
+ asn1::constructed *params = (ident) ? ident->parameters() : NULL;
+
+ if (m_gencpp.with_source_comment())
+ {
+ m_os<<"\n//\n// cghpph_choice helper launched ";
+ m_os<<m_structName<<"\n//"<<std::endl;
+ }
+ // Rework Old code ...
+ //
+ if ( ! m_gencpp.add_symbol(m_structName,&m_choice) )
+ {
+ m_os<<"//cghpph_choice Structure already in map, skip\n";
+ return;
+ }
+
+ cgh_hconstruct::generate();
+}
+
+
+void
+cghpph_choice::generate_prolog( )
+{
+ asn1::node *ident = m_choice.identifier();
+ asn1::constructed *params = (ident) ? ident->parameters() : NULL;
+
+ // Handle parameter stuff
+ if (ident->parameters() && m_gencpp.is_template(ident->parameters()))
+ {
+ m_os<<"//"<<__FUNCTION__<<" parameterized\n";
+ // Forward declaration for ostream function
+ m_os<<"template ";
+ m_gencpp.gen_template_signature(m_os,params);
+ m_os<<" struct "<<m_structName<<" /* : public asn1::types::type */ ;\n";
+ m_os<<"template ";
+ m_gencpp.gen_template_signature(m_os,params);
+ m_os<<"\nstd::ostream & operator<<(std::ostream &m_os,const "<<m_structName;
+ m_gencpp.gen_template_params(m_os,params);
+ m_os<<" &s) ;\n";
+
+ // Real declaration
+ m_os<<"template ";
+ m_gencpp.gen_template_signature(m_os,params);
+ }
+ m_os<<"struct "<<m_structName<<" : public asn1::types::choice_type\n";
+ m_os<<"{\n";
+}
+
+/**
+ *
+ */
+void
+cghpph_choice::generate_operators( )
+{
+ // == operator
+ m_os<<"\tbool operator ==("<<m_structName<<" &_c);\n";
+}
+/**
+ *
+ */
+void
+cghpph_choice::generate_ctors( )
+{
+ asn1::node::iterator it;
+ asn1::node *ident = m_choice.identifier();
+ asn1::constructed *params = (ident) ? ident->parameters() : NULL;
+
+ // Constructor
+ // Initialize tag , with first aleternative choice
+ // First alternative choice
+ it = m_choice.begin();
+ asn1::field *first = dynamic_cast<asn1::field *>(*it);
+
+ if (first->get_type()->tagged())
+ {
+ asn1::node::tag_type lt = first->get_type()->tag();
+
+ m_os<<"\t"<<m_structName<<"(unsigned int _kind ,const asn1::tag t = asn1::tag("<<lt.m_class<<","<<lt.m_value<<"));\n";
+ m_os<<"\t"<<m_structName<<"(const asn1::tag &t = asn1::tag("<<lt.m_class<<","<<lt.m_value<<"));\n";
+ } else if (asn1::typeref *tref = first->get_type()->as_typeref())
+ {
+ // get outer most tag
+ //asn1::node::tag_type o_tag = tref->otag();
+ asn1::node::tag_type o_tag = m_choice.get_tag(m_gencpp.resolver());
+ m_os<<"\t"<<m_structName<<"(unsigned int _kind ,const asn1::tag t = asn1::tag(";
+ m_os<<o_tag.m_class<<","<<o_tag.m_value<<"/*ref*/));\n";
+ m_os<<"\t"<<m_structName<<"(const asn1::tag &t = asn1::tag(";
+ m_os<<o_tag.m_class<<","<<o_tag.m_value<<"/*ref*/));\n";
+
+ } else {
+ m_os<<"\t"<<m_structName<<"(unsigned int _kind ,const asn1::tag t = asn1::tag(0,";
+ m_os<<""<<first->get_type()->tag().m_value<<"));\n";
+ // Why ...
+ m_os<<"\t"<<m_structName<<"(const asn1::tag &t = asn1::tag(0,";
+ m_os<<""<<first->get_type()->tag().m_value<<"));\n";
+ }
+
+ // Missing Copy constructor
+ m_os<<"\t"<<m_structName<<"(const "<<m_structName;
+ if (ident->parameters() && m_gencpp.is_template(ident->parameters()))
+ {
+ m_gencpp.gen_template_params(m_os,ident->parameters());
+ }
+ m_os<<" &s) ;\n";
+ // Clone
+ m_os<<"\tvirtual "<<m_structName;;
+ if (params && m_gencpp.is_template(params))
+ {
+ m_gencpp.gen_template_params(m_os,params);
+ }
+ m_os<<" *clone() ;\n";
+
+ // Missing Destructor
+ // m_choice is deleted by choice_type.
+ //m_os<<"\t//virtual ~"<<m_structName<<"();\n";
+ // Create object
+ m_os<<"\tvirtual bool create_object();\n";
+
+}
+
+/**
+ *
+ *
+ */
+void
+cghpph_choice::generate_members()
+{
+ std::string scope("");
+ asn1::node *ident = m_choice.identifier();
+ asn1::parameters *params = dynamic_cast<asn1::parameters *>(ident->parameters());
+
+ // Ok, loop over attributes
+ // to generate setter and getter
+ for ( asn1::node::iterator it = m_choice.begin()
+ ; it != m_choice.end() ; ++it)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*it);
+ m_gencpp.gen_composite_attribute(m_os,scope,*f,ident->parameters(),false);
+ // Setter
+ gen_setter(f);
+ }
+ // Now add an enum to identifie type
+ gen_enum_type();
+ // Gen attribute parameters (OPERATION ....)
+
+
+ if (params)
+ {
+ for (asn1::node::iterator it = params->begin();
+ it != params->end();
+ ++it)
+ {
+ asn1::parameter *p = dynamic_cast<asn1::parameter *>(*it);
+ if (asn1::node *g = p->get_governor())
+ {
+ asn1::typeref *objr = dynamic_cast<asn1::typeref *>(g);
+ asn1::node *obj = m_gencpp.resolver().resolve(*objr);
+ asn1::module *m = dynamic_cast<asn1::module *>(obj->get_parent());
+ m_os<<"\t// "<<g->name()<<" "<<p->name()<<std::endl;
+ if (!objr->is_simple())
+ {
+ m_os<<"\t"<<m->cpp_name()<<"::I"<<g->name()<<" **"<<p->name()<<";"<<std::endl;
+ }
+ }
+ }
+ }
+}
+
+/**
+* generate setter and getter
+* - attribute an attribute of choice
+* - params the potential parameters stored in choice ident
+*/
+void cghpph_choice::gen_setter(asn1::field *attribute )
+{
+ std::string scope; // TODO make this deprecated
+ asn1::node *ident = m_choice.identifier();
+ asn1::node *params = ident->parameters();
+ asn1::typenode *attr_type = attribute->get_type();
+ m_os<<"\n";
+ //
+ if (attr_type != NULL)
+ {
+ switch (attr_type->type_id()())
+ {
+ case asn1::type::ASN1_ENUMERATED:
+ case asn1::type::ASN1_CHOICE:
+ {
+ assert( 0 && "cghpph_choice::gen_setter ENUM OR CHOICE should not happend");
+ }
+ break;
+ case asn1::type::ASN1_REFERENCE:
+ {
+ asn1::typeref *tref = dynamic_cast<asn1::typeref *>(attr_type);
+ asn1::node *rt = m_gencpp.resolver().resolve(*tref);
+ if ( tref->is_simple()
+ || (rt && rt->type_node())
+ )
+ {
+ m_os<<"\tvoid set_"<<attribute->cpp_name()<<"(const ";
+ m_gencpp.gen_composite_attribute_ref(m_os,scope,attribute,params);
+ m_os<<" &s);\n";
+ m_os<<"\t";
+ m_gencpp.gen_composite_attribute_ref(m_os,scope,attribute,params);
+ m_os<<"& get_"<<attribute->cpp_name()<<"();\n";
+
+ m_os<<"\tconst ";
+ m_gencpp.gen_composite_attribute_ref(m_os,scope,attribute,params);
+ m_os<<" &get_"<<attribute->cpp_name()<<" () const ; \n";
+ }else
+ {
+ m_os<<"// Complex reference "<<attribute->name()<<std::endl;
+ m_os<<"\tvoid set_"<<attribute->cpp_name()<<"(const ";
+ m_gencpp.gen_composite_attribute_ref(m_os,scope,attribute,params);
+ m_os<<" *s);\n";
+ m_os<<"\t";
+ m_gencpp.gen_composite_attribute_ref(m_os,scope,attribute,params);
+ m_os<<"* get_"<<attribute->cpp_name()<<"();\n";
+
+ }
+ }
+ break;
+ default:
+ {
+ std::string strtype;
+ if (m_gencpp.type2cppstring(attr_type,strtype) )
+ {
+ m_os<<"\tvoid set_"<<attribute->cpp_name()<<"(const ";
+ m_os<<strtype;
+ m_os<<" &s);\n";
+ m_os<<"\t"<<strtype<<" &get_"<<attribute->cpp_name()<<" () ;\n";
+ m_os<<"\tconst "<<strtype<<" &get_"<<attribute->cpp_name()<<" () const;\n";
+ } else
+ {
+ assert(0);
+ }
+ }
+ break;
+ }
+ } else
+ {
+ GEN_LOG_ERROR("attr_type is NULL\n");
+ }
+}
+
+/**
+ *
+ */
+void cghpph_choice::gen_enum_type()
+{
+ asn1::choice *type = &m_choice;
+ // Now add an enum to identifie type
+
+ m_os<<"\tenum { "<<std::endl;
+ asn1::node::iterator lit = type->begin();
+
+ for (; lit != (type)->end() ; lit++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*lit);
+ asn1::typenode *attribute_type = f->get_type();
+ if (f->is_extensible())
+ continue;
+ if (attribute_type && attribute_type->tagged())
+ {
+ /* tagged */
+ m_os<<"\t\ttypeof_"<<(*lit)->cpp_name();
+ if (m_gencpp.is_tag_explicit(*attribute_type) )
+ {
+ m_os<<"\t="<<attribute_type->tag().get_tag()<<", ";
+ m_os<<" // Explicit + "<<(int)attribute_type->tag().byte();
+ } else
+ {
+ m_os<<"\t="<<attribute_type->tag().get_tag()<<", ";
+ m_os<<" // Implicit + "<<(int)attribute_type->tag().byte();
+ }
+ m_os<<std::endl;
+ } else if (attribute_type && attribute_type->type_id()() == asn1::type::ASN1_REFERENCE)
+ {
+ /* reference type */
+ std::list<asn1::node *>lst;
+ m_gencpp.reference_chaine(attribute_type->as_typeref(),lst);
+
+ if ((lst.size() > 0) && lst.back() != NULL)
+ {
+ if (lst.back()->tag().m_value >= 0)
+ {
+ m_os<<"\t\ttypeof_"<<(*lit)->cpp_name();
+ if (m_gencpp.is_tag_explicit(* dynamic_cast<asn1::typenode *>(lst.back())) )
+ {
+ m_os<<"\t="<<lst.back()->tag().get_tag()<<", ";
+ m_os<<" // Explicit "<<(int)lst.back()->tag().byte();
+ } else
+ {
+ m_os<<"\t="<<lst.back()->tag().get_tag()<<", ";
+ m_os<<" // Implicit "<<(int)lst.back()->tag().byte();
+ }
+ m_os<<", /*ref tag*/"<<std::endl;
+ } else {
+ m_os<<"\t\ttypeof_"<<(*lit)->cpp_name()<<", ";
+ m_os<<"// ref type no tag "<<lst.back()->name()<<std::endl;
+ }
+ } else
+ {
+ m_os<<"\t\ttypeof_"<<(*lit)->cpp_name()<<",/*ext ref missing*/ "<<std::endl;
+ }
+ } else if (attribute_type )
+ {
+ /* untagged type */
+ if (attribute_type->tag().m_value > 0)
+ {
+ m_os<<"\t\ttypeof_"<<(*lit)->cpp_name()<<"\t="<<attribute_type->tag().get_tag()<<" ,";
+ m_os<<"// m_value > 0";
+ m_os<<std::endl;
+ } else
+ m_os<<"\t\ttypeof_"<<(*lit)->cpp_name()<<",/*no tag */ "<<std::endl;
+ } else
+ {
+ m_os<<"\t\ttypeof_"<<(*lit)->cpp_name()<<", "<<std::endl;
+ }
+ }
+
+ m_os<<"\t\ttypeof_end\n\t};"<<std::endl;
+
+}
+
+//
+void cghpph_choice::generate_printf( )
+{
+ asn1::node *ident = m_choice.identifier();
+
+ m_os<<"\tfriend std::ostream & operator<< ";
+ if (ident && ident->parameters() && m_gencpp.is_template(ident->parameters()))
+ {
+ m_os<<"<>";
+ }
+ m_os<<"(std::ostream &os,const ";
+ m_os<<""<<m_structName;
+ // Parameter stuff here
+ if (ident && ident->parameters() && m_gencpp.is_template(ident->parameters()))
+ {
+ m_gencpp.gen_template_params(m_os,ident->parameters());
+ }
+ m_os<<" &s"<<")";
+ m_os<<";\n";
+}
+
+// generate codec part
+void cghpph_choice::generate_per()
+{
+}
+
+//
+void cghpph_choice::generate_ber()
+{
+ std::string scope;
+ asn1::node *type = &m_choice;
+
+ if ( m_gencpp.with_ber()
+ && m_choice.tagged()
+ && m_gencpp.is_tag_explicit(m_choice) )
+ {
+ m_os<<"\tvirtual void encode_ber(asn1::streams::ber &ctx);"<<std::endl;
+ m_os<<"\tvirtual int decode_ber(asn1::streams::ber &ctx);"<<std::endl;
+ }
+}
+
+//
+void cghpph_choice::generate_oer()
+{
+}
+
+//
+void cghpph_choice::generate_jer()
+{
+}
+
+//
+void cghpph_choice::generate_xer()
+{
+}
+
--- /dev/null
+#ifndef CGHPPH_CHOICE_H
+#define CGHPPH_CHOICE_H
+
+
+/**
+ *
+ */
+class cghpph_choice : public cgh_hconstruct
+{
+ protected:
+ cghpph_choice(const cghpph_choice &s) : cgh_hconstruct(s.m_gencpp,s.m_os,s.m_choice)
+ , m_choice(s.m_choice)
+ {}
+ public:
+ cghpph_choice(generate_header &g,std::ostream &os,asn1::choice &s) ;
+ ~cghpph_choice();
+
+ // Helper functions
+ virtual void generate() ;
+
+ // generate codec part
+ virtual void generate_per() ;
+ //
+ virtual void generate_ber() ;
+ //
+ virtual void generate_oer() ;
+ //
+ virtual void generate_jer() ;
+ //
+ virtual void generate_xer() ;
+
+ protected:
+ /**
+ * generate setter and getter
+ */
+ void gen_setter(asn1::field *attribute);
+
+ virtual void generate_prolog();
+ virtual void generate_ctors();
+ virtual void generate_printf();
+ virtual void generate_operators();
+ /**
+ * @brief Generate member attributes for
+ * Parameterized types
+ */
+ virtual void generate_members();
+ /**
+ * enum in choice of all type for selection purpose
+ */
+ void gen_enum_type();
+ protected:
+ asn1::choice &m_choice;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_hpp.h"
+#include "asn1_generator_helper.h"
+#include "asn1_gen_codec_cpp.h"
+#include "cgcpp_helper.h"
+#include "cghpph_classdef.h"
+#include "asn1_visitor.h"
+
+
+cghpph_classdef::cghpph_classdef(generate_header &g,std::ostream &os,asn1::classdef &s)
+ : m_Gen(g)
+ , generator_helper(os)
+ , m_classdef(s)
+ , m_log(g.logger())
+{
+}
+
+cghpph_classdef::~cghpph_classdef()
+{
+}
+
+
+struct gen_iattr : public node_visitor<gen_iattr>
+{
+ std::string fieldname;
+ bool m_istemplate; // Use same generator for template
+ gen_iattr( std::ostream &os,generate_header &h,bool _istplt=false)
+ : m_os(os) , m_Gen(h),m_istemplate(_istplt)
+ {
+ }
+ void operator ()(asn1::node *n)
+ {
+ fieldname = n->cpp_name();
+ fieldname[0] = '_';
+ visit(n);
+ }
+#define ASN1_CLASSFIELD_TYPE(cls,code) \
+ void visit_##cls(asn1::cls *f) code
+
+ASN1_CLASSFIELD_TYPE(classfield_tf,{
+ if (!m_istemplate)
+ return ;
+ //m_os<<" type "<<f->cpp_name()<<std::endl;
+ m_os<<"\t\t"<<fieldname<<" m"<<fieldname<<";\n";
+})
+ASN1_CLASSFIELD_TYPE(classfield_ftvf,{
+ std::string strtype;
+ // For templates ftvf are interface attributes
+ if (m_istemplate)
+ return;
+ m_Gen.type2cppstring(f->get_type(),strtype);
+ m_os<<"\t\t"<<strtype<<"\t"<<fieldname<<";\n";
+})
+ASN1_CLASSFIELD_TYPE(classfield_vtvf,{})
+ASN1_CLASSFIELD_TYPE(classfield_ftvsf,{
+ m_os<<"\t\tSet<"<<f->get_type()->cpp_name()<<">\t"<<fieldname<<";\n";
+})
+ASN1_CLASSFIELD_TYPE(classfield_vtvsf,{})
+ASN1_CLASSFIELD_TYPE(classfield_of,{})
+ASN1_CLASSFIELD_TYPE(classfield_osf,{
+ m_os<<"\t\tasn1::ObjectSetEntry\t*"<<fieldname<<";\n";
+})
+
+ std::ostream &m_os;
+ generate_header &m_Gen;
+};
+
+/**
+ * Helper functions
+ *
+ */
+void cghpph_classdef::generate()
+{
+ asn1::node::iterator it = m_classdef.begin();
+ asn1::node *n = m_classdef.identifier();
+ asn1::classdef *type = &m_classdef;
+ asn1::node *params = NULL;
+ std::string structName;
+ std::string scope("");
+
+ m_os<<"// cghpph_classdef helper launched "<<std::endl;
+ if (! should_generate())
+ {
+ m_os<<"// Don't generare class "<<n->identifier()<<std::endl;
+ return;
+ }
+ assert(m_classdef.type_id()() == asn1::type::ASN1_CLASSDEF);
+ structName = n->cpp_name();
+
+ /**
+ *
+ */
+ m_Gen.gen_object_class_missing(m_os,type);
+ //
+ //
+ gen_interface();
+
+ gen_objectset();
+
+ if (std::string("ERROR").compare(n->cpp_name()) == 0)
+ {
+ m_os<<"#ifdef ERROR\n";
+ m_os<<"#undef ERROR\n";
+ m_os<<"#endif\n";
+ }
+ //
+ //
+ gen_template();
+}
+
+
+/**
+ * Helper to travers class fields in template ...
+ */
+class cghcdtplt : public node_visitor<cghcdtplt>
+{
+ protected:
+ std::ostream &m_os;
+ generate_header &m_gen;
+ std::string fieldname;
+ std::fstream &m_log;
+ public:
+ cghcdtplt(std::ostream &_os,generate_header &h)
+ : m_os(_os),m_gen(h),m_log(h.logger())
+ {}
+
+ // used by foreach
+ void operator ()(asn1::node *n)
+ {
+ fieldname = n->cpp_name();
+ fieldname[0] = '_';
+ m_os<<"\t// "<<n->cpp_name()<<" type_id="<<n->type_id()();
+ visit(n);
+ }
+#define ASN1_CLASSFIELD_TYPE(cls,code) \
+ void visit_##cls(asn1::cls *f) code
+
+ASN1_CLASSFIELD_TYPE(classfield_tf,{
+
+ m_os<<"\n\t//getter \n";
+ m_os<<"\tint get"<<fieldname<<"("<<fieldname<<" &v)\n\t{\n";
+ m_os<<"\t\tv = m"<<fieldname<<";\n";
+ if ( f->flags().is_optional() )
+ {
+ m_os<<"\t\treturn m.present"<<fieldname<<";\n";
+ } else
+ {
+ m_os<<"\t\treturn 1;\n";
+ }
+ m_os<<"\t};\n";
+ // Fast Access
+ m_os<<"\t"<<fieldname<<"\t&get"<<fieldname<<"()\n\t{\n";
+ m_os<<"\t\treturn m"<<fieldname<<";\n";
+ m_os<<"\t};\n";
+
+ // Setter
+ m_os<<"\t//setter \n";
+ m_os<<"\tvoid set"<<fieldname<<"(const "<<fieldname<<" &v)\n\t{\n";
+ m_os<<"\t\tm"<<fieldname<<"= v;\n";
+ if ( f->flags().is_optional() )
+ {
+ m_os<<"\t\tmemset(&m,0x00,sizeof(struct _present)); \n";
+ m_os<<"\t\tm.present"<<fieldname<<"= 1;\n";
+ }
+ m_os<<"\t};\n\n";
+ // New decode function
+ m_os<<"\tint decode"<<fieldname<<"(asn1::context &ctx)\n\t{"<<std::endl;
+ if (m_gen.with_source_debug())
+ {
+ m_os<<"\t\tASN1_BER_LOG_DEBUG(\""<<f->cpp_name()<<"::decode"<<fieldname;
+ m_os<<"(ctx &c) \");"<<std::endl;
+ }
+ if ( f->flags().is_optional() )
+ m_os<<"\t\tm.present"<<fieldname<<"= 1;\n";
+ m_os<<"\t\treturn m"<<fieldname<<".decode(ctx);"<<std::endl;
+ m_os<<"\t};\n";
+ // encode
+ m_os<<"\tvoid encode"<<fieldname<<"(asn1::context &ctx)\n\t{"<<std::endl;
+ if (m_gen.with_source_debug())
+ {
+ m_os<<"\t\tASN1_BER_LOG_DEBUG(\""<<f->cpp_name();
+ m_os<<"::decode"<<fieldname<<"(ctx &c) \");"<<std::endl;
+ }
+ if ( f->flags().is_optional() )
+ m_os<<"\t\tif (m.present"<<fieldname<<")\n";
+ m_os<<"\t\t\tm"<<fieldname<<".encode(ctx);"<<std::endl;
+ m_os<<"\t};\n";
+})
+
+ASN1_CLASSFIELD_TYPE(classfield_ftvf,{
+ m_os<<std::endl;
+ return ;
+})
+ASN1_CLASSFIELD_TYPE(classfield_vtvf,{
+ m_os<<std::endl;
+})
+ASN1_CLASSFIELD_TYPE(classfield_ftvsf,{
+ m_os<<std::endl;
+})
+ASN1_CLASSFIELD_TYPE(classfield_vtvsf,{
+ m_os<<std::endl;
+})
+ASN1_CLASSFIELD_TYPE(classfield_of,{
+ m_os<<std::endl;
+})
+ASN1_CLASSFIELD_TYPE(classfield_osf,{
+ m_os<<std::endl;
+})
+
+
+ protected:
+};
+
+void cghpph_classdef::gen_template()
+{
+ asn1::node::iterator it = m_classdef.begin();
+ asn1::node *n = m_classdef.identifier();
+ asn1::classdef *type = &m_classdef;
+ asn1::node *params = NULL;
+ std::string structName;
+ std::string scope("");
+
+ if (! should_generate())
+ {
+ m_os<<"// Don't generare class "<<n->identifier()<<std::endl;
+ return;
+ }
+
+ structName = n->cpp_name();
+
+ m_Gen.gen_object_class_tplt(m_os,type);
+ m_os<<"struct "<<n->cpp_name()<<" : public I"<<n->cpp_name()<<"\n{\n"<<std::endl;;
+ m_os<<"\tenum {uuid = _uuid};"<<std::endl;
+ //typedef asn1::intrusive_ptr<Object> ptr;
+ m_os<<"\ttypedef asn1::intrusive_ptr<"<<n->cpp_name();
+ m_Gen.gen_object_class_tplt_params(m_os,type);
+ m_os<<" > ptr;\n";
+ m_os<<"\ttypedef "<<n->cpp_name();
+ m_Gen.gen_object_class_tplt_params(m_os,type);
+ m_os<<" otype;\n";
+ m_os<<"\ttypedef "<<n->cpp_name();
+ m_Gen.gen_object_class_tplt_params(m_os,type);
+ m_os<<" & otype_reference;\n";
+ // constructors
+ m_os<<"\t"<<n->cpp_name()<<"()\n\t{\n\t\t/*never called */\n";
+ m_os<<"\t};\n";
+ // Missing copy constructor
+ //m_os<<"\t"<<n->cpp_name()<<"";
+ m_os<<"\t"<<n->cpp_name()<<"(const "<<n->cpp_name()<<"";
+ m_Gen.gen_object_class_tplt_params(m_os,type);
+ m_os<<" &o);"<<std::endl;
+ // Destructor
+ m_os<<"\t~"<<n->cpp_name()<<"()\n\t{};\n";
+
+ //m_os<<"\tvirtual I"<<n->cpp_name()<<" *Create()\n\t{\n";
+ m_os<<"\tstatic otype *Create()\n\t{\n";
+ if (m_Gen.with_source_debug())
+ {
+ m_os<<"\t\tASN1_BER_LOG_DEBUG(\"Create ";
+ m_os<<n->cpp_name()<<" %s\",typeid(this).name());\n";
+ }
+ m_os<<"\t\totype *o = new otype";
+ m_os<<"();\n";
+ if (has_optional())
+ m_os<<"\t\tmemset(&o->m,0x00,sizeof(struct _present)) ;\n";
+ m_os<<"\t\treturn o;\n\t};\n";
+
+ m_os<<"\totype_reference";
+ m_os<<"\toperator =(asn1::Object &_c)\n\t{\n";
+
+ if (m_Gen.with_source_debug())
+ {
+ m_os<<"\t\tASN1_BER_LOG_DEBUG(\" "<<n->cpp_name()<<" operator %s = %s\"\n";
+ m_os<<"\t\t\t\t\t,typeid(this).name()\n";
+ m_os<<"\t\t\t\t\t,typeid(_c).name());\n";
+ }
+ m_os<<"\t\treturn *this;\n";
+ m_os<<"\t};\n";
+
+ m_os<<"\tvirtual otype *clone() const\n\t{\n";
+ if (m_Gen.with_source_debug())
+ m_os<<"\t\tASN1_BER_LOG_DEBUG(\"Clone "<<n->cpp_name()<<"\");\n";
+ m_os<<"\t\treturn new otype(*this);\n\t}\n";
+ // generate optionnals
+ gen_printf();
+ //
+ cghcdtplt cga(m_os,m_Gen);
+ for_each( m_classdef.begin()
+ , m_classdef.end()
+ , cga);
+
+ m_os<<"\tprotected:\n";
+
+ for_each( m_classdef.begin()
+ , m_classdef.end()
+ , gen_iattr(m_os,m_Gen,true));
+ m_os<<"};\n"<<std::endl;
+
+}
+
+//
+void cghpph_classdef::gen_printf()
+{
+ std::string structName;
+ asn1::node::iterator it;
+ asn1::classdef *type = &m_classdef;
+ asn1::node *ident = m_classdef.identifier();
+ asn1::constructed *params = ident->parameters();
+ /*
+ * Try to handler sequence of sequence
+ */
+ it = type->begin();
+
+ structName = ident->cpp_name();
+ if (m_Gen.with_source_comment())
+ m_os<<"\t// display function\n";
+ m_os<<"\tvirtual void printf(std::ostream &os) const\n\t{\n";
+ for ( ; it != type->end(); ++it)
+ {
+ asn1::node *ltype = (*it);
+ std::string fieldname = (*it)->cpp_name();
+ fieldname[0] = '_';
+
+ switch(ltype->type_id()())
+ {
+ case asn1::type::ASN1_CLASSFIELD_TF: /* Type Field */
+ if ( (ltype->flags().m_flags & asn1::node::marker_type::FL_OPTIONAL) )
+ {
+ m_os<<"\t\tif (m.present"<<fieldname<<")"<<std::endl;
+ }
+ m_os<<"\t\t\tos<<\""<<ltype->cpp_name();
+ m_os<<" : \"<<m"<<fieldname<<"<<std::endl;\n";
+ break;
+ default:
+ ;
+ }
+
+ }
+ m_os<<"\t};\n\n";
+}
+
+// generate codec part
+void cghpph_classdef::generate_per()
+{
+ std::string scope;
+ //
+ m_os<<scope<<"\tvirtual void encode_per(asn1::context &ctx);"<<std::endl;
+ m_os<<scope<<"\tvirtual int decode_per(asn1::context &ctx);"<<std::endl;
+}
+
+//
+void cghpph_classdef::generate_ber()
+{
+ std::string scope;
+ asn1::node *type = &m_classdef;
+ //
+ m_os<<scope<<"\tvirtual void encode(asn1::context &ctx);"<<std::endl;
+ m_os<<scope<<"\tvirtual int decode(asn1::context &ctx);"<<std::endl;
+ //
+ if (m_classdef.tagged()) {
+ if ( m_Gen.tag_mode(type) == asn1::node::tag_type::TM_EXPLICIT)
+ {
+ m_os<<scope<<"\tvirtual void encode_preamble_ber(asn1::context &ctx);"<<std::endl;
+ m_os<<scope<<"\tvirtual void encode_epilogue_ber(asn1::context &ctx);"<<std::endl;
+ m_os<<scope<<"\tvirtual int decode_preamble_ber(asn1::streams::ber &ctx);"<<std::endl;
+ m_os<<scope<<"\tvirtual int decode_epilogue_ber(asn1::streams::ber &ctx);"<<std::endl;
+ }
+ }
+}
+
+//
+void cghpph_classdef::generate_oer()
+{
+ //
+ std::string scope;
+ m_os<<scope<<"\tvirtual void encode_oer(asn1::context &ctx);"<<std::endl;
+ m_os<<scope<<"\tvirtual int decode_oer(asn1::context &ctx);"<<std::endl;
+}
+
+//
+void cghpph_classdef::generate_jer()
+{
+}
+
+//
+void cghpph_classdef::generate_xer()
+{
+}
+
+
+/**
+ *
+ */
+void cghpph_classdef::gen_objectset()
+{
+ asn1::node *ident = m_classdef.identifier();
+ asn1::classdef *type = &m_classdef;
+ asn1::node::iterator it = (type)->begin();
+ std::string structName = ident->cpp_name();
+
+ m_os<<"\n//\n// Objectset struct\n//\n";
+ m_os<<"struct "<<structName<<"Set\n";
+ m_os<<"{\n";
+ m_os<<"\t"<<structName<<"Set *m_next;\n";
+ m_os<<"\tI"<<structName<<" *m_object;\n";
+ m_os<<"};\n";
+}
+
+
+
+/**
+ * Helper to travers class fields in template ...
+ */
+class cghcditf : public node_visitor<cghcditf>
+{
+ protected:
+ std::ostream &m_os;
+ std::string fieldname;
+ generate_header &m_gen;
+ public:
+ cghcditf(std::ostream &_os,generate_header &h)
+ : m_os(_os),m_gen(h)
+ {}
+ // used by foreach
+ void operator ()(asn1::node *n)
+ {
+ std::string fieldname = n->cpp_name();
+ fieldname[0] = '_';
+ visit(n);
+ }
+#define ASN1_CLASSFIELD_TYPE(cls,code) \
+ void visit_##cls(asn1::cls *f) code
+
+ASN1_CLASSFIELD_TYPE(classfield_tf,{
+ fieldname = f->cpp_name();
+ fieldname[0] = '_';
+ m_os<<"\t// "<<f->cpp_name()<<" type_id="<<f->type_id()();
+ m_os<<" type "<<f->cpp_name()<<std::endl;
+ // new encode / decode
+ m_os<<"\tvirtual void encode"<<fieldname<<"(asn1::context &ctx)\n\t{\n";
+ if (m_gen.with_source_debug())
+ m_os<<"\t\tstd::cout<<\"encode_"<<fieldname<<"\"<<std::endl;\n";
+ m_os<<"\t};\n";
+
+ m_os<<"\tvirtual int decode"<<fieldname<<"(asn1::context &ctx)\n\t{\n";
+ if (m_gen.with_source_debug())
+ {
+ m_os<<"\t\tstd::cout<<\"decode_"<<fieldname;
+ m_os<<"\"<<std::endl;\n";
+ }
+ m_os<<"\t\treturn 0;\n\t};\n\n";
+})
+ASN1_CLASSFIELD_TYPE(classfield_ftvf,{
+ fieldname = f->cpp_name();
+ fieldname[0] = '_';
+ asn1::typenode *ftvf_type = f->get_type();
+ std::string strtype;
+ m_gen.type2cppstring(ftvf_type,strtype);
+ m_os<<std::endl;
+ m_os<<"\tbool "<<fieldname.substr(1)<<"Equals(";
+ m_os<<strtype<<" &_v)\n\t{\n";
+ m_os<<"\t\treturn _v == "<<fieldname<<";\n";
+ m_os<<"\t};\n";
+ // Add getter
+ m_os<<std::endl;
+ m_os<<"\t"<<strtype<<" &get_"<<fieldname.substr(1)<<"(";
+ m_os<<")\n\t{\n";
+ m_os<<"\t\treturn "<<fieldname<<";\n";
+ m_os<<"\t};\n";
+})
+ASN1_CLASSFIELD_TYPE(classfield_vtvf,{})
+ASN1_CLASSFIELD_TYPE(classfield_ftvsf,{
+ fieldname = f->cpp_name();
+ fieldname[0] = '_';
+ m_os<<std::endl;
+ m_os<<"\tSet<"<<f->get_type()->cpp_name()<<"> &get";
+ m_os<<fieldname;
+ m_os<<"()\n\t{\n";
+ m_os<<"\t\treturn "<<fieldname;
+ m_os<<";\n\t};\n\n";
+})
+ASN1_CLASSFIELD_TYPE(classfield_vtvsf,{})
+ASN1_CLASSFIELD_TYPE(classfield_of,{})
+ASN1_CLASSFIELD_TYPE(classfield_osf,{})
+
+
+protected:
+};
+
+
+/**
+*
+*/
+void cghpph_classdef::gen_interface()
+{
+asn1::node *ident = m_classdef.identifier();
+asn1::classdef *type = &m_classdef;
+asn1::node::iterator it = (type)->begin();
+std::string structName = ident->cpp_name();
+
+m_os<<"\n//\n// Interface I"<<structName;
+m_os<<"\n//\n";
+m_os<<"class I"<<structName<<" : public asn1::Object\n{\n"<<std::endl;;
+
+// constructors
+m_os<<"\tpublic:\n";
+m_os<<"\ttypedef asn1::intrusive_ptr<I"<<structName<<"> ptr;\n";
+m_os<<"\tI"<<structName<<"() {};\n";
+m_os<<"\t~I"<<structName<<"() {};\n\n";
+//m_os<<"\tvirtual I"<<structName<<" *Create() =0;\n";
+m_os<<"\tvirtual I"<<structName<<" *clone() const = 0;\n";
+m_os<<"\n";
+gen_optional();
+m_os<<"\tvirtual size_t get_data_length() const { return 0 ; };";
+m_os<<"\tvirtual size_t get_length() const { return 0 ; };";
+m_os<<"\tvirtual const asn1::tag &tag() const\n\t{\n";
+m_os<<"\t\tstatic asn1::tag t = asn1::tag(0,0);\n";
+m_os<<"\t\treturn t;\n\t};\n"<<std::endl;
+// generate optionnals
+
+
+ cghcditf iav(m_os,m_Gen);
+ for_each( m_classdef.begin()
+ , m_classdef.end()
+ , iav);
+ // Add protected members
+ m_os<<"\tprotected:\n";
+ for_each( m_classdef.begin()
+ , m_classdef.end()
+ , gen_iattr(m_os,m_Gen));
+ m_os<<"};\n"<<std::endl;
+ m_os<<"\ntypedef asn1::intrusive_ptr<I"<<structName<<">";
+ m_os<<" I"<<structName<<"_ptr;\n\n";
+}
+
+/**
+ *
+ */
+bool cghpph_classdef::should_generate()
+{
+ asn1::node::iterator it = m_classdef.begin();
+ bool should = false;
+
+ for ( ; it != m_classdef.end()
+ ; ++it)
+ {
+ asn1::node *field = (*it);
+ if (field->type_id()() == asn1::type::ASN1_CLASSFIELD_TF)
+ {
+ should = true;
+ break;
+ }
+ }
+ return should;
+}
+
+
+/**
+ *
+ */
+bool cghpph_classdef::has_optional()
+{
+ return m_classdef.opt_size() > 0;
+}
+
+/**
+ *
+ */
+void cghpph_classdef::gen_optional()
+{
+ asn1::node *ident = m_classdef.identifier();
+ asn1::classdef *type = &m_classdef;
+ asn1::node::iterator it = (type)->begin();
+ bool opt = false;
+ std::list<std::string> l;
+
+ for ( ; it != type->end(); ++it)
+ {
+ std::string fieldname = (*it)->cpp_name();
+ fieldname[0] = '_';
+ if ( ((*it)->flags().m_flags & asn1::node::marker_type::FL_OPTIONAL) )
+ {
+ l.push_back(fieldname);
+ }
+ }
+
+ if ( l.size() > 0 )
+ {
+ m_os<<"\tstruct _present\n\t{\n";
+ for (std::list<std::string>::const_iterator it = l.begin()
+ ; it != l.end()
+ ; ++it)
+ {
+ m_os<<"\t\tunsigned present"<<(*it)<<" : 1;\n";
+ }
+ m_os<<"\t} m;\n";
+ }
+}
+
+/**
+ * vim: et sw=2 ts=2 list:
+ */
--- /dev/null
+#ifndef CGHPPH_CLASSDEF_H
+#define CGHPPH_CLASSDEF_H
+
+
+/**
+ *
+ */
+class cghpph_classdef : public generator_helper
+{
+ protected:
+ cghpph_classdef(const cghpph_classdef &s) : generator_helper(s.m_os)
+ , m_log(s.m_log)
+ , m_Gen(s.m_Gen)
+ , m_classdef(s.m_classdef) {}
+ public:
+ cghpph_classdef(generate_header &g,std::ostream &os,asn1::classdef &s) ;
+ ~cghpph_classdef();
+
+ // Helper functions
+ virtual void generate() ;
+
+ // generate codec part
+ virtual void generate_per() ;
+ //
+ virtual void generate_ber() ;
+ //
+ virtual void generate_oer() ;
+ //
+ virtual void generate_jer() ;
+ //
+ virtual void generate_xer() ;
+ protected:
+ void gen_printf();
+ // loop over the attributes of SEQUENCE or CHOICE
+ // and check if there are some type of SEQUENCE or CHOICE
+ // launch generation for these types first.
+ void gen_interface();
+
+ void gen_template();
+ //
+ // Gen Optional structure
+ void gen_optional();
+ // Are there optional attributes ?
+ bool has_optional();
+ // Generate structure for ObjectSet of this class type
+ void gen_objectset();
+ // Test If need to generate code for this class
+ // If there are no FT, probably not
+ bool should_generate();
+ protected:
+ std::fstream &m_log;
+ generate_header &m_Gen;
+ asn1::classdef &m_classdef;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_hpp.h"
+#include "asn1_gen_codec_cpp.h"
+#include "asn1_generator_helper.h"
+#include "cghpp_helper.h"
+#include "cgh_hconstruct.h"
+#include "cghpph_enumerated.h"
+
+#undef GEN_LOG_DEBUG
+#define GEN_LOG_DEBUG
+
+cghpph_enumerated::cghpph_enumerated(generate_header &g,std::ostream &os,asn1::enumerated &s)
+ : cgh_hconstruct(g,os,s) , m_enumerated(s)
+{
+}
+
+cghpph_enumerated::~cghpph_enumerated()
+{
+}
+
+
+/** Helper functions
+ *
+ * It seems that the choice does not always have an identifier. Examples
+ * - SEQUENCE OF CHOICE {}
+ * - Test ::= CHOICE { toto INTEGER, CHOICE { } }
+ * these sequences are anonymous definitions ...
+ */
+void cghpph_enumerated::generate()
+{
+ cgh_hconstruct::generate( );
+}
+
+/**
+ *
+ */
+void cghpph_enumerated::generate_prolog( )
+{
+ if (m_gencpp.with_source_comment())
+ m_os<<"// cghpph_enumerated helper launched private "<<m_enumerated.name()<<std::endl;
+ m_os<<"struct "<<m_structName<<" : public asn1::ENUMERATED\n{\n";
+}
+
+/**
+ *
+ */
+void cghpph_enumerated::generate_ctors( )
+{
+ if (m_enumerated.tagged() )
+ {
+ if ( ! m_gencpp.is_tag_explicit(m_enumerated) )
+ {
+ asn1::node::tag_type tg = m_enumerated.tag();
+ m_os<<"\t"<<m_structName<<"(const asn1::tag &t= asn1::tag("<<tg.m_class<<","<<tg.m_value<<")) ;\n";
+ } else
+ {
+ m_os<<"\t"<<m_structName<<"(const asn1::tag &t= asn1::tag(0,10)) ;\n";
+ }
+ } else
+ {
+ m_os<<"\t"<<m_structName<<"(const asn1::tag &t= asn1::tag(0,10)) ;\n";
+ }
+ // copy constructor
+ m_os<<"\t"<<m_structName<<"(const "<<m_structName<<" &t) ;"<<std::endl;
+ // clone
+ m_os<<"\t"<<m_structName<<"* clone();"<<std::endl;
+}
+
+/**
+ *
+ */
+void cghpph_enumerated::generate_members( )
+{
+ asn1::node::iterator it = m_enumerated.begin();
+ m_os<<"\tenum e"<< m_structName<<" {\n";
+ for (; it != m_enumerated.end();++it)
+ {
+ asn1::value *num = (*it)->value();
+ if (it != m_enumerated.begin() )
+ m_os<<",\n";
+ m_os<<"\t\t"<<(*it)->cpp_name()<<" ";
+
+ if ( num != NULL)
+ {
+ m_os<<" = "<<(num)->m_integer;
+ }
+ }
+ m_os<<"\n"<<"\t};\n";
+}
+
+/**
+ *
+ */
+void cghpph_enumerated::generate_operators( )
+{
+ m_os<<"\t"<<m_structName<<"& operator = (unsigned int v ) ; "<<std::endl;
+ m_os<<"\tbool operator ==(const "<<m_structName<<" &v) const ;\n";
+ m_os<<"\tbool operator ==(const e"<<m_structName<<" v) const ;\n";
+ m_os<<"\tbool operator !=(const e"<<m_structName<<" v) const ;\n";
+}
+/**
+ *
+ */
+void cghpph_enumerated::generate_printf( )
+{
+
+ m_os<<"\tvirtual void printf(std::ostream &os) const;"<<std::endl;
+ m_os<<"\tfriend std::ostream &operator <<(std::ostream &os,const "<<m_structName;
+ m_os<<" &s"<<");"<<std::endl;
+}
+
+// generate codec part
+
+//
+void cghpph_enumerated::generate_ber()
+{
+}
+
--- /dev/null
+#ifndef CGHPPH_ENUMERATED_H
+#define CGHPPH_ENUMERATED_H
+
+
+/**
+ *
+ */
+class cghpph_enumerated : public cgh_hconstruct
+{
+ protected:
+ cghpph_enumerated(const cghpph_enumerated &s) : cgh_hconstruct(s.m_gencpp,s.m_os,s.m_c)
+ , m_enumerated(s.m_enumerated) {}
+ public:
+ cghpph_enumerated(generate_header &g,std::ostream &os,asn1::enumerated &s) ;
+ ~cghpph_enumerated();
+
+ // Helper functions
+ virtual void generate() ;
+
+ // generate codec part
+ virtual void generate_per() { };
+ //
+ virtual void generate_ber() ;
+ //
+ virtual void generate_oer() { };
+ //
+ virtual void generate_jer() { };
+ //
+ virtual void generate_xer() { };
+
+ protected:
+ virtual void generate_prolog( );
+ virtual void generate_ctors( );
+ virtual void generate_members( );
+ virtual void generate_operators( );
+ virtual void generate_printf( );
+ protected:
+ asn1::enumerated &m_enumerated;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_hpp.h"
+#include "asn1_generator_helper.h"
+#include "asn1_gen_codec_cpp.h"
+#include "cgcpp_helper.h"
+#include "cghpph_import.h"
+
+
+cghpph_import::cghpph_import(generate_header &g,std::ostream &os,asn1::import &s)
+ : m_Gen(g)
+ , generator_helper(os)
+ , m_import(s)
+ , m_log(g.logger())
+{
+}
+
+cghpph_import::~cghpph_import()
+{
+}
+
+
+/** Helper functions
+ *
+ * It seems that the choice does not always have an identifier. Examples
+ * - SEQUENCE OF CHOICE {}
+ * - Test ::= CHOICE { toto INTEGER, CHOICE { } }
+ * these sequences are anonymous definitions ...
+ */
+void cghpph_import::generate()
+{
+ asn1::node::iterator items,end;
+
+ m_os<<"// cghpph_import helper launched "<<std::endl;
+ asn1::node::iterator it = m_import.begin();
+
+ items = m_import.begin();
+ end = m_import.end();
+ // Loop over items and check if OPERATION is imported
+ for ( items = m_import.begin()
+ ; items != end
+ ; ++items)
+ {
+ //os <<"//#include \""<<(*it)->identifier_cpp_name()<<"/"<<(*items)->cpp_name()<<".h\" /*item "<<(*items)->name()<<"*/\n";
+ if (std::string("OPERATION").compare((*items)->name()) == 0 )
+ {
+ m_os<<"#include \"rtasn1/asn1_rose.h\"\n";
+ }
+ }
+ if (std::string("Remote-Operations-Useful-Definitions")
+ .compare(m_import.identifier()->name()))
+ m_os<<"#include \""<<m_import.identifier()->cpp_name()<<".h\"\n";
+
+ gen_forward_decl();
+}
+
+//
+void cghpph_import::gen_printf(const std::string &_scope)
+{
+ std::string structName;
+ std::string scope("");
+ asn1::node::iterator lit;
+ asn1::node *type = &m_import;
+
+
+}
+
+// generate codec part
+void cghpph_import::generate_per()
+{
+ std::string scope;
+ //
+}
+
+//
+void cghpph_import::generate_ber()
+{
+ std::string scope;
+ asn1::node *type = &m_import;
+ //
+}
+
+//
+void cghpph_import::generate_oer()
+{
+ //
+ std::string scope;
+}
+
+//
+void cghpph_import::generate_jer()
+{
+}
+
+//
+void cghpph_import::generate_xer()
+{
+}
+
+/**
+ * private structures are generated before the current on.
+ * outside the scope of the current type.
+ * This code could be factorized and generator level
+ */
+void cghpph_import::gen_private()
+{
+ asn1::node *type = &m_import;
+}
+/**
+ *
+ */
+void cghpph_import::gen_forward_decl()
+{
+ asn1::node::iterator items,end;
+
+ items = m_import.begin();
+ end = m_import.end();
+ m_os<<"namespace "<<m_import.identifier()->cpp_name()<<" {\n";
+ // Loop over items and check if OPERATION is imported
+ for ( items = m_import.begin()
+ ; items != end
+ ; ++items)
+ {
+ asn1::node *type = NULL;
+ asn1::typeref *ref = dynamic_cast<asn1::typeref *>(*items);
+ if (ref)
+ {
+ type = m_Gen.resolver().resolve(*ref);
+ if (type)
+ {
+ switch(type->type_id()())
+ {
+ case asn1::type::ASN1_BIT_STRING :
+ case asn1::type::ASN1_SET :
+ case asn1::type::ASN1_SEQUENCE :
+ if (type->identifier()->parameters())
+ {
+ m_os<<"// type "<<type->type_id()()<<" with param\n";
+ } else
+ m_os<<"class "<<ref->cpp_name()<<";// type "<<type->type_id()()<<"\n";
+ break;
+ case asn1::type::ASN1_OBJECTSET:
+ {
+ asn1::objectset *objs = dynamic_cast<asn1::objectset *>(type);
+ asn1::typeref *cref = objs->get_classref();
+ m_os<<"// object set "<<objs->name()<<" cref="<<cref->name()<<std::endl;
+ m_os<<"I"<<cref->cpp_name()<<" **"<<objs->name()<<";"<<std::endl;
+ }
+ break;
+ case asn1::type::ASN1_VALUESET:
+ {
+ asn1::objectset *objs = dynamic_cast<asn1::objectset *>(type);
+ asn1::typeref *cref = objs->get_classref();
+ m_os<<"// WRONG value set "<<objs->name()<<" its objs cref=";
+ m_os<<cref->name()<<std::endl;
+ m_os<<"extern I"<<cref->cpp_name()<<" **"<<objs->name()<<";"<<std::endl;
+
+ }
+ break;
+ case asn1::type::ASN1_REFERENCE :
+ {
+ asn1::typeref *real_ref = dynamic_cast<asn1::typeref *>(type);
+ if (type->type_node())
+ {
+ std::cerr<<"// IMPORT TODO type "<<type->name()<<" "<<type->type_node()->cpp_name()<<std::endl;
+ //assert(0 && "??? how can that be ?");
+ //m_os<<"class "<<ref->name()<<";";
+ m_os<<"// type "<<type->type_id()()<<"\n";
+ } else if (type->identifier() && type->identifier()->parameters())
+ {
+ m_os<<"// type "<<type->type_id()()<<" with param\n";
+ } else if (real_ref && real_ref->is_objectclass())
+ {
+ m_os<<"// type "<<type->type_id()()<<" object class\n";
+ } else
+ m_os<<"class "<<ref->cpp_name()<<";// type "<<type->type_id()()<<"\n";
+ }
+ break;
+ case asn1::type::ASN1_INTEGER :
+ if (type->meta_id()() != asn1::meta::TYPE)
+ {
+ break;
+ }
+ case asn1::type::ASN1_CHOICE :
+ case asn1::type::ASN1_OCTET_STRING :
+ case asn1::type::ASN1_ENUMERATED:
+ m_os<<"struct "<<ref->cpp_name()<<";\n";
+ break;
+ case asn1::type::ASN1_CLASSDEF :
+ {
+ std::string cls = type->identifier()->cpp_name();
+ m_os<<"#ifndef TEMPLATE_CLASS_"<<cls<<"\n";
+ m_os<<"#define TEMPLATE_CLASS_"<<cls<<"\n";
+ if (std::string("ERROR").compare(type->identifier()->cpp_name()) == 0)
+ {
+ m_os<<"#ifdef ERROR\n";
+ m_os<<"#undef ERROR\n";
+ m_os<<"#endif\n";
+ }
+ m_os<<"class I"<<type->identifier()->cpp_name()<<";// id="<<type->type_id()()<<"\n";
+ m_os<<"\n";
+#if 0
+ m_Gen.gen_object_class_tplt(m_os,type->identifier());
+ m_os<<"class "<<type->identifier()->cpp_name()<<";\n";
+#endif
+ m_os<<"#endif\n";
+ }
+ break;
+ default:
+ //m_os<<"class "<<type->identifier_cpp_name()<<";";
+ m_os<<"//default FOUND "<<type->name()<<" id="<<type->type_id()()<<"\n";
+ ;
+ }
+ } else
+ {
+ m_os<<"//NOT FOUND "<<ref->name()<<"\n";
+ }
+ } else
+ {
+ m_os<<"//NOT FOUND not typeref "<<(*items)->name()<<"\n";
+ }
+
+ // Resolve symbol to figure out the kind.
+ if (std::string("OPERATION").compare((*items)->name()) == 0 )
+ {
+ }
+ }
+ m_os<<"}\n";
+}
--- /dev/null
+#ifndef CGHPPH_IMPORT_H
+#define CGHPPH_IMPORT_H
+
+
+/**
+ *
+ */
+class cghpph_import : public generator_helper
+{
+ protected:
+ cghpph_import(const cghpph_import &s) : generator_helper(s.m_os)
+ , m_Gen(s.m_Gen)
+ , m_log(s.m_log)
+ , m_import(s.m_import) {}
+ public:
+ cghpph_import(generate_header &g,std::ostream &os,asn1::import &s) ;
+ ~cghpph_import();
+
+ // Helper functions
+ virtual void generate() ;
+
+ void gen_printf(const std::string &scope);
+ // generate codec part
+ virtual void generate_per() ;
+ //
+ virtual void generate_ber() ;
+ //
+ virtual void generate_oer() ;
+ //
+ virtual void generate_jer() ;
+ //
+ virtual void generate_xer() ;
+ protected:
+ void gen_private();
+ //
+ void gen_forward_decl();
+ protected:
+ std::fstream &m_log;
+ generate_header &m_Gen;
+ asn1::import &m_import;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_hpp.h"
+#include "asn1_generator_helper.h"
+#include "asn1_gen_codec_cpp.h"
+#include "cghpp_helper.h"
+#include "cgh_hconstruct.h"
+#include "cghpph_integer.h"
+
+
+cghpph_integer::cghpph_integer(generate_header &g,std::ostream &os,asn1::integer &s)
+ : cgh_hconstruct(g,os,s) , m_integer(s)
+{
+}
+
+cghpph_integer::~cghpph_integer()
+{
+}
+
+
+/** Helper functions
+ *
+ * It seems that the choice does not always have an identifier. Examples
+ * - SEQUENCE OF CHOICE {}
+ * - Test ::= CHOICE { toto INTEGER, CHOICE { } }
+ * these sequences are anonymous definitions ...
+ */
+void cghpph_integer::generate()
+{
+ GEN_LOG_DEBUG("INTEGER type %s ident=%s size=%ld\n"
+ , m_integer.name().c_str()
+ , m_integer.identifier_name().c_str()
+ , m_integer.size());
+ cgh_hconstruct::generate();
+}
+
+/**
+ *
+ */
+void cghpph_integer::generate_prolog( )
+{
+ if (m_gencpp.with_source_comment())
+ m_os<<"// cghpph_integer helper launched "<<std::endl;
+ m_os<<"//\n// "<<m_integer.identifier_name()<<"\n//\n";
+
+ m_os<<"struct "<<m_integer.identifier_cpp_name()<<" : public ";
+ if (m_integer.is_unsigned())
+ {
+ m_os<<"UInt64\n{\n";
+ } else
+ m_os<<"INTEGER\n{\n";
+
+}
+
+/**
+ *
+ */
+void cghpph_integer::generate_ctors( )
+{
+ m_os<<"\t"<<m_integer.identifier_cpp_name()<<"(const asn1::tag &t = asn1::tag(";
+ if (m_integer.tagged())
+ {
+ m_os<<m_integer.tag().m_class<<","<<m_integer.tag().m_value<<",";
+ if ( m_gencpp.is_tag_explicit(m_integer) )
+ {
+ m_os<<"true";
+ }else
+ m_os<<"false";
+ } else
+ {
+ m_os<<"0,2";
+ }
+ m_os<<")) ;"<<std::endl;
+
+}
+
+/**
+ *
+ */
+void cghpph_integer::generate_operators( )
+{
+ if (m_integer.is_unsigned())
+ {
+ m_os<<"\tvoid operator =(const unsigned long v) ;\n";
+ m_os<<"\tvoid operator =(const asn1::prim::types::UInt64 &v) ;\n";
+ } else
+ {
+ m_os<<"\tvoid operator =(const long v) ;\n";
+ m_os<<"\tvoid operator =(const asn1::prim::types::Integer &v) ;\n";
+ }
+
+ m_os<<"\tbool operator ==(const "<<m_integer.identifier_cpp_name()<<" &v) const ;\n";
+}
+
+/**
+ *
+ */
+void cghpph_integer::generate_members( )
+{
+ if (m_integer.size() > 0)
+ {
+ asn1::node::iterator it = m_integer.begin();
+ m_os<<"\tenum e"<<m_integer.identifier_cpp_name()<<" {\n";
+ for (; it != m_integer.end() ; ++it)
+ {
+ asn1::valuetype *tv = dynamic_cast<asn1::valuetype *>(*it);
+ assert (tv != NULL);
+ if (it != m_integer.begin() )
+ {
+ m_os<<"\t\t,";
+ } else
+ m_os<<"\t\t";
+
+ m_os<<(*it)->cpp_name()<<" = "<<tv->value_long()<<"\n";
+ }
+ m_os<<"\t};\n"; // end of enum
+ m_os<<"\tbool operator ==(const e"<<m_integer.identifier_cpp_name()<<" v) const ;\n";
+ m_os<<"\tvoid operator =(const e"<<m_integer.identifier_cpp_name()<<" v) ;\n";
+ }
+
+
+}
+
+/**
+ *
+ */
+void cghpph_integer::generate_ber()
+{
+ std::string scope;
+ asn1::node *type = &m_integer;
+ //
+ //
+ if ( m_integer.tagged()
+ && m_gencpp.is_tag_explicit(m_c))
+ {
+ m_os<<scope<<"\tvirtual void encode(asn1::context &ctx);"<<std::endl;
+ m_os<<scope<<"\tvirtual int decode(asn1::context &ctx);"<<std::endl;
+ }
+}
+
--- /dev/null
+#ifndef CGHPPH_INTEGER_H__
+#define CGHPPH_INTEGER_H__
+
+
+/**
+ *
+ */
+class cghpph_integer : public cgh_hconstruct
+{
+ protected:
+ cghpph_integer(const cghpph_integer &s) : cgh_hconstruct(s.m_gencpp,s.m_os,s.m_c)
+ , m_integer(s.m_integer) {}
+ public:
+ cghpph_integer(generate_header &g,std::ostream &os,asn1::integer &s) ;
+ ~cghpph_integer();
+
+ // Helper functions
+ virtual void generate() ;
+ //
+ virtual void generate_ber() ;
+ // generate codec part
+ virtual void generate_per() { };
+ //
+ virtual void generate_oer() { };
+ //
+ virtual void generate_jer() { };
+ //
+ virtual void generate_xer() { };
+ protected:
+ virtual void generate_prolog( );
+ virtual void generate_ctors( );
+ virtual void generate_members( );
+ virtual void generate_operators( );
+ // loop over the attributes of SEQUENCE or CHOICE
+ // and check if there are some type of SEQUENCE or CHOICE
+ // launch generation for these types first.
+ protected:
+ asn1::integer &m_integer;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_hpp.h"
+#include "asn1_generator_helper.h"
+#include "asn1_gen_codec_cpp.h"
+#include "cgcpp_helper.h"
+#include "cgh_object.h"
+#include "cghpph_object.h"
+
+#undef GEN_LOG_DEBUG
+#define GEN_LOG_DEBUG
+
+cghpph_object::cghpph_object( generate_header &g
+ , std::ostream &os
+ , asn1::object &s
+ , asn1::classdef &cdef)
+ : m_Gen(g)
+ , cgh_object(g,os,s,cdef)
+ //, m_object(s)
+ //,m_classdef(cdef)
+{
+}
+
+cghpph_object::~cghpph_object()
+{
+}
+
+
+/**
+ * Helper functions
+ *
+ */
+void cghpph_object::generate()
+{
+ asn1::node *n = m_object.identifier();
+ asn1::node *type = &m_object;
+ asn1::node *params = NULL;
+ std::string structName;
+
+ //m_os<<"\n//\n// cghpph_object helper launched "<<n->name()<<std::endl;
+ gen_private();
+ // m_os<<"\n// chpph_object helper after missing "<<n->name()<<std::endl;
+ // gen_forward();
+#if 0
+ // c++11 feature forward decl
+ m_os<<"extern template class "<<m_classdef.identifier()->cpp_name();
+ m_os<<"<";
+ gen_template_args(true);
+ m_os<<">;\n";
+#endif
+}
+
+/**
+ * Helper functions
+ *
+ */
+void cghpph_object::generate_hpp()
+{
+ asn1::node *n = m_object.identifier();
+ asn1::node *type = &m_object;
+ asn1::node *params = NULL;
+ std::string structName;
+
+ m_os<<"\n//\n// cghpph_object helper launched "<<n->name()<<std::endl;
+
+ // Generate template_specialisation
+ if (m_classdef.get_parent() == m_Gen.get_module())
+ {
+ // open current namespace
+ m_os<<"namespace "<<m_Gen.get_module()->cpp_name()<<" {\n";
+ m_os<<"template <>\n";
+ m_os<<m_classdef.cpp_name();
+ m_os<<"<";
+ gen_template_args(true);
+ m_os<<">::"<<m_classdef.cpp_name()<<"();\n";
+ m_os<<"}\n"; // Close current namespace
+ } else
+ {
+
+ // Open template namespace
+ m_os<<"namespace "<<m_classdef.get_parent()->cpp_name()<<"\n{\n";
+
+ m_os<<"template <>\n";
+ m_os<<m_classdef.identifier()->cpp_name();
+ m_os<<"<";
+ gen_template_args(true);
+ m_os<<">::"<<m_classdef.identifier()->cpp_name()<<"();\n";
+ // Instanciate copy ctor
+ m_os<<"template <>\n";
+ m_os<<m_classdef.identifier()->cpp_name();
+ m_os<<"<";
+ gen_template_args(true);
+ m_os<<">::"<<m_classdef.identifier()->cpp_name()<<"(const ";
+ m_os<<m_classdef.identifier()->cpp_name();
+ m_os<<"<";
+ gen_template_args(true);
+ m_os<<"> &o);\n";
+
+ m_os<<"}\n"; // Close template namespace
+ }
+
+ // typedef instantiates the template
+ m_os<<"namespace "<<m_Gen.get_module()->cpp_name()<<"\n{\n";
+ m_os<<"typedef ";
+ if (m_classdef.get_parent() == m_Gen.get_module() )
+ {
+ m_os<<m_classdef.cpp_name()<<"<";
+ } else
+ {
+ asn1::module *cdef_ns = dynamic_cast<asn1::module *>(m_classdef.get_parent());
+ m_os<<cdef_ns->cpp_name();
+ m_os<<"::"<<m_classdef.identifier()->cpp_name()<<"<";
+ }
+ // To check for CMIP
+ gen_template_args(true);
+ m_os<<"> "<<n->cpp_name()<<";"<<std::endl;
+ m_os<<"}\n"; // Close current namespace
+
+ //m_os<<"\n//\n// cghpph_object helper end "<<n->name()<<std::endl;
+}
+
+
+//
+void cghpph_object::gen_printf(const std::string &scope)
+{
+}
+
+// generate codec part
+void cghpph_object::generate_per()
+{
+ std::string scope;
+ //
+ m_os<<scope<<"\tvirtual void encode_per(asn1::context &ctx);"<<std::endl;
+ m_os<<scope<<"\tvirtual int decode_per(asn1::context &ctx);"<<std::endl;
+}
+
+//
+void cghpph_object::generate_ber()
+{
+ std::string scope;
+ asn1::node *type = &m_object;
+ //
+ //
+ if (m_object.tagged())
+ {
+ if ( m_Gen.tag_mode(type) == asn1::node::tag_type::TM_EXPLICIT)
+ {
+ m_os<<scope<<"\tvirtual void encode(asn1::context &ctx);"<<std::endl;
+ m_os<<scope<<"\tvirtual int decode(asn1::context &ctx);"<<std::endl;
+ }
+ }
+}
+
+//
+void cghpph_object::generate_oer()
+{
+ //
+ std::string scope;
+ m_os<<scope<<"\tvirtual void encode_oer(asn1::context &ctx);"<<std::endl;
+ m_os<<scope<<"\tvirtual int decode_oer(asn1::context &ctx);"<<std::endl;
+}
+
+//
+void cghpph_object::generate_jer()
+{
+}
+
+//
+void cghpph_object::generate_xer()
+{
+}
+
+void cghpph_object::gen_forward()
+{
+ asn1::node::iterator fit = m_classdef.begin();
+
+ for ( ; fit != m_classdef.end()
+ ; ++fit)
+ {
+ if ( (*fit)->type_id()() == asn1::type::ASN1_CLASSFIELD_TF )
+ {
+ asn1::node *type = NULL;
+ if ( (type = m_object.get_field((*fit)->name()) ) != NULL)
+ {
+ if (type->get_parent() == m_Gen.get_module())
+ m_os<<"struct "<<type->cpp_name()<<";"<<std::endl;
+ }
+ }
+ }
+}
+
+/**
+ * private structures are generated before the current on.
+ * outside the scope of the current type.
+ * This code could be factorized and generator level
+ */
+void cghpph_object::gen_private()
+{
+ asn1::node::iterator fit = m_classdef.begin();
+
+ for ( ; fit != m_classdef.end()
+ ; ++fit)
+ {
+ if ( (*fit)->type_id()() == asn1::type::ASN1_CLASSFIELD_TF )
+ {
+ asn1::node *type = NULL;
+ if ( (type = m_object.get_field((*fit)->name()) ) != NULL)
+ {
+ asn1::typeref *ref = dynamic_cast<asn1::typeref *>(type);
+ asn1::node *rtype = NULL;
+ if(ref)
+ {
+ rtype = m_Gen.resolver().resolve(*ref);
+ } else
+ {
+ std::cerr<<"cghpph_object::gen_private type= ";
+ std::cerr<<type->name()<<" NOT TYPEREF\n";
+ }
+ if (rtype && rtype->get_parent() == m_Gen.get_module())
+ m_Gen.gen_missing(m_os,rtype->identifier());
+ }
+ }
+ }
+}
--- /dev/null
+#ifndef CGHPPH_OBJECT_H
+#define CGHPPH_OBJECT_H
+
+
+/**
+ *
+ */
+class cghpph_object : public cgh_object
+{
+ protected:
+ cghpph_object(const cghpph_object &s )
+ : cgh_object(s.m_Gencpp,s.m_os,s.m_object,s.m_classdef)
+ , m_Gen(s.m_Gen)
+ //, m_object(s.m_object)
+ //, m_classdef(s.m_classdef)
+ {}
+ public:
+ cghpph_object(generate_header &g,std::ostream &os,asn1::object &s,asn1::classdef &cdef) ;
+
+ ~cghpph_object();
+
+ // Helper functions
+ virtual void generate() ;
+
+ void generate_hpp() ;
+
+ void gen_printf(const std::string &scope);
+ // generate codec part
+ virtual void generate_per() ;
+ //
+ virtual void generate_ber() ;
+ //
+ virtual void generate_oer() ;
+ //
+ virtual void generate_jer() ;
+ //
+ virtual void generate_xer() ;
+
+ // loop over the attributes of SEQUENCE or CHOICE
+ // and check if there are some type of SEQUENCE or CHOICE
+ // launch generation for these types first.
+ void gen_private();
+ protected:
+ void gen_forward();
+ // Generate template arguments for object
+ //void gen_template_args(bool with_scope=false);
+ protected:
+ generate_header &m_Gen;
+ //asn1::object &m_object;
+ //asn1::classdef &m_classdef;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_hpp.h"
+#include "asn1_generator_helper.h"
+#include "asn1_gen_codec_cpp.h"
+#include "cghpp_helper.h"
+#include "cghpph_primitive.h"
+#include "cghpph_octetstring.h"
+
+
+cghpph_octet_string::cghpph_octet_string(generate_header &g,std::ostream &os,asn1::octet_string &s)
+ : cghpph_primitive(g,os,s) , m_octet_string(s)
+{
+}
+
+cghpph_octet_string::~cghpph_octet_string()
+{
+}
+
+
+/**
+ *
+ */
+void cghpph_octet_string::generate_prolog()
+{
+ if (m_gencpp.with_source_comment())
+ m_os<<"// cghpph_octet_string helper launched "<<m_octet_string.cpp_name()<<std::endl;
+
+ m_os<<"struct "<<m_structName<<" : public OCTET_STRING\n{\n";
+ m_os<<"\tpublic:\n";
+}
+/**
+ *
+ */
+void cghpph_octet_string::generate_ctors()
+{
+ if (m_octet_string.tagged())
+ {
+ m_os<<"\t\t"<<m_structName<<"(const asn1::tag &t = asn1::tag(";
+ m_os<<m_octet_string.tag().m_class<<","<<m_octet_string.tag().m_value<<",";
+
+ if ( m_gencpp.is_tag_explicit(m_octet_string))
+ {
+ m_os<<"true)";
+ }else
+ m_os<<"false)";
+ m_os<<");\n";
+ } else
+ {
+ m_os<<"\t\t"<<m_structName<<"(const asn1::tag &t = asn1::tag(0,4));\n";
+ }
+ m_os<<"\t\t~"<<m_structName<<"();\n";
+ // copy
+ m_os<<"\t"<<m_structName<<"(const "<<m_structName<<" &t"<<") ;\n";
+}
+/**
+ *
+ */
+void cghpph_octet_string::generate_operators()
+{
+ // Assignment
+ m_os<<"\t"<<m_structName<<" & operator =(const "<<m_structName<<" &t"<<") ;\n";
+
+ m_os<<"\t"<<m_structName<<" & operator =(const asn1::prim::types::String &t"<<") ;\n";
+
+}
+
+/**
+ *
+ */
+void cghpph_octet_string::generate_printf()
+{
+ m_os<<"\tfriend std::ostream &operator <<(std::ostream &os,const ";
+ m_os<<m_octet_string.identifier_cpp_name()<<" &s);\n";
+}
+
+// generate codec part
+void cghpph_octet_string::generate_per()
+{
+ std::string scope;
+ //
+ m_os<<scope<<"\tvirtual void encode_per(asn1::context &ctx);"<<std::endl;
+ m_os<<scope<<"\tvirtual int decode_per(asn1::context &ctx);"<<std::endl;
+}
+
+//
+void cghpph_octet_string::generate_ber()
+{
+ std::string scope;
+ asn1::node *type = &m_octet_string;
+ //
+ //
+ if (m_octet_string.tagged())
+ {
+ if ( m_gencpp.is_tag_explicit(m_octet_string) )
+ {
+ m_os<<scope<<"\t\tvirtual void encode(asn1::context &ctx);"<<std::endl;
+ m_os<<scope<<"\t\tvirtual int decode(asn1::context &ctx);"<<std::endl;
+ }
+ }
+}
+
+//
+void cghpph_octet_string::generate_oer()
+{
+ //
+ std::string scope;
+ m_os<<scope<<"\tvirtual void encode_oer(asn1::context &ctx);"<<std::endl;
+ m_os<<scope<<"\tvirtual int decode_oer(asn1::context &ctx);"<<std::endl;
+}
+
+//
+void cghpph_octet_string::generate_jer()
+{
+}
+
+//
+void cghpph_octet_string::generate_xer()
+{
+}
+
--- /dev/null
+#ifndef CGHPPH_OCTETSTRING_H
+#define CGHPPH_OCTETSTRING_H
+
+
+/**
+ *
+ */
+class cghpph_octet_string : public cghpph_primitive
+{
+ protected:
+ cghpph_octet_string(const cghpph_octet_string &s) : cghpph_primitive(s.m_gencpp,s.m_os,s.m_octet_string)
+ , m_octet_string(s.m_octet_string) {}
+ public:
+ cghpph_octet_string(generate_header &g,std::ostream &os,asn1::octet_string &s) ;
+ ~cghpph_octet_string();
+
+ // Helper functions
+
+ // generate codec part
+ virtual void generate_per() ;
+ //
+ virtual void generate_ber() ;
+ //
+ virtual void generate_oer() ;
+ //
+ virtual void generate_jer() ;
+ //
+ virtual void generate_xer() ;
+ protected:
+ virtual void generate_prolog();
+ virtual void generate_ctors();
+ virtual void generate_operators();
+ virtual void generate_printf();
+ protected:
+ asn1::octet_string &m_octet_string;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_hpp.h"
+#include "asn1_generator_helper.h"
+#include "asn1_gen_codec_cpp.h"
+#include "cghpp_helper.h"
+#include "cgh_hconstruct.h"
+#include "cghpph_oid.h"
+
+
+cghpph_oid::cghpph_oid(generate_header &g,std::ostream &os,asn1::object_identifier &s)
+ : cgh_hconstruct(g,os,s)
+ , m_oid(s)
+{
+}
+
+cghpph_oid::~cghpph_oid()
+{
+}
+
+
+/** Helper functions
+ *
+ * It seems that the choice does not always have an identifier. Examples
+ */
+void cghpph_oid::generate()
+{
+ cgh_hconstruct::generate( );
+}
+
+/**
+ *
+ */
+void cghpph_oid::generate_prolog()
+{
+ if (m_gencpp.with_source_comment())
+ m_os<<"// cghpph_oid helper launched "<<std::endl;
+ m_os<<"struct "<<m_structName<<" : public asn1::OBJECT_IDENTIFIER\n{\n";
+}
+
+/**
+ *
+ */
+void cghpph_oid::generate_ctors()
+{
+ m_os<<"\t"<<m_structName<<"(const asn1::tag &t = asn1::tag(";
+ if (m_oid.tagged())
+ {
+ if ( m_gencpp.is_tag_explicit(m_oid) )
+ {
+ m_os<<m_oid.tag().m_class<<","<<m_oid.tag().m_value<<",true));\n";
+ } else
+ {
+ m_os<<m_oid.tag().m_class<<","<<m_oid.tag().m_value<<",false));\n";
+ }
+ }else
+ m_os<<"0,"<<m_oid.primitive_tag()<<")) ;\n";
+
+
+ // copy
+ m_os<<"\t"<<m_structName<<"(const "<<m_structName<<" &t"<<") ;\n";
+ // copy assignment
+ m_os<<"\t"<<m_structName<<" & operator =(const "<<m_structName<<" &t"<<") ;\n";
+
+ m_os<<"\t"<<m_structName<<" & operator =(const "<<m_oid.cpp_name()<<" &t"<<") ;\n";
+
+}
+
+/**
+ *
+ */
+void cghpph_oid::generate_operators()
+{
+ // equal operator
+ m_os<<"\tbool operator ==("<<m_structName<<" &_c);\n";
+}
+//
+void cghpph_oid::generate_printf()
+{
+ std::string structName;
+ asn1::object_identifier *type = &m_oid;
+ asn1::node *ident = m_oid.identifier();
+ asn1::node *params = ident->parameters();
+ /*
+ * Try to handler sequence of sequence
+ */
+
+ if (m_oid.is_private())
+ {
+ structName = type->cpp_name();
+ } else
+ structName = ident->cpp_name();
+
+ m_os<<"\tfriend std::ostream &operator <<(std::ostream &os,const "<<structName;
+ if (ident->parameters() && m_gencpp.is_template(ident->parameters()))
+ {
+ m_gencpp.gen_template_params(m_os,ident->parameters());
+ }
+ m_os<<" &s"<<") ;\n";
+}
+
+// generate codec part
+void cghpph_oid::generate_per()
+{
+}
+
+//
+void cghpph_oid::generate_ber()
+{
+ std::string scope;
+ asn1::node *type = &m_oid;
+ //
+ if ( m_oid.tagged()
+ && m_gencpp.is_tag_explicit(m_oid) )
+ {
+ m_os<<scope<<"\tvirtual void encode(asn1::context &ctx);"<<std::endl;
+ m_os<<scope<<"\tvirtual int decode(asn1::context &ctx);"<<std::endl;
+ }
+}
+
+//
+void cghpph_oid::generate_oer()
+{
+}
+
+//
+void cghpph_oid::generate_jer()
+{
+}
+
+//
+void cghpph_oid::generate_xer()
+{
+}
+
--- /dev/null
+#ifndef CGHPPH_OBJECT_IDENTIFIER_H
+#define CGHPPH_OBJECT_IDENTIFIER_H
+
+
+/**
+ *
+ */
+class cghpph_oid : public cgh_hconstruct
+{
+ protected:
+ cghpph_oid(const cghpph_oid &s) : cgh_hconstruct(s.m_gencpp,s.m_os,s.m_oid)
+ , m_oid(s.m_oid) {}
+ public:
+ cghpph_oid(generate_header &g
+ ,std::ostream &os
+ ,asn1::object_identifier &s) ;
+ ~cghpph_oid();
+
+ // Helper functions
+ virtual void generate() ;
+
+ // generate codec part
+ virtual void generate_per() ;
+ //
+ virtual void generate_ber() ;
+ //
+ virtual void generate_oer() ;
+ //
+ virtual void generate_jer() ;
+ //
+ virtual void generate_xer() ;
+ protected:
+ virtual void generate_prolog();
+
+ virtual void generate_printf();
+
+ virtual void generate_ctors();
+
+ virtual void generate_operators();
+ protected:
+ asn1::object_identifier &m_oid;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_hpp.h"
+#include "asn1_generator_helper.h"
+#include "asn1_gen_codec_cpp.h"
+#include "cghpp_helper.h"
+#include "cghpph_primitive.h"
+
+
+cghpph_primitive::cghpph_primitive( generate_header &g
+ , std::ostream &os
+ , asn1::primitive &s)
+ : cghpp_helper(g,os)
+ , m_primitive(s)
+ , m_structName("")
+{
+
+ assert(m_primitive.type_id()() >= asn1::type::ASN1_ANY
+ && m_primitive.type_id()() < asn1::type::ASN1_STRING_ObjectDescriptor );
+ if (m_primitive.is_private())
+ {
+ m_structName = s.cpp_name();
+ } else
+ m_structName = s.identifier_cpp_name();
+
+}
+
+cghpph_primitive::~cghpph_primitive()
+{
+}
+
+void cghpph_primitive::generate_prolog()
+{
+ assert(m_primitive.type_id()() >= asn1::type::ASN1_ANY
+ && m_primitive.type_id()() < asn1::type::ASN1_STRING_ObjectDescriptor );
+
+ if (m_gencpp.with_source_comment())
+ m_os<<"// cghpph_primitive helper launched "<<std::endl;
+ m_os<<"struct "<<m_structName<<" : public "<<m_primitive.cpp_name()<<"\n{\n";
+}
+
+void cghpph_primitive::generate_ctors()
+{
+ m_os<<"\t"<<m_structName<<"(const asn1::tag &t = asn1::tag(";
+ if (m_primitive.tagged())
+ {
+ if ( m_gencpp.is_tag_explicit(m_primitive))
+ {
+ m_os<<m_primitive.tag().m_class<<","<<m_primitive.tag().m_value<<",true)) ;\n";
+ } else
+ {
+ m_os<<m_primitive.tag().m_class<<","<<m_primitive.tag().m_value<<",false)) ;\n";
+ }
+ }else
+ m_os<<"0,"<<m_primitive.primitive_tag()<<")) ;\n";
+
+
+ // copy
+ m_os<<"\t"<<m_structName<<"(const "<<m_structName<<" &t"<<") ;\n";
+ // clone
+ m_os<<"\tvirtual "<<m_structName<<" *clone() ;\n";
+
+ //
+}
+/** Helper functions
+ *
+ * It seems that the choice does not always have an identifier. Examples
+ * - SEQUENCE OF CHOICE {}
+ * - Test ::= CHOICE { toto INTEGER, CHOICE { } }
+ * these sequences are anonymous definitions ...
+ */
+void cghpph_primitive::generate()
+{
+ generate_prolog();
+ generate_descriptor();
+
+ generate_ctors();
+ //
+ generate_ber();
+
+ generate_operators();
+
+ generate_printf();
+ m_os<<"};\n";
+
+}
+
+/**
+ *
+ */
+void cghpph_primitive::generate_operators()
+{
+ // equal operator
+ m_os<<"\tbool operator ==("<<m_structName<<" &_c);\n";
+}
+
+/**
+ *
+ */
+void cghpph_primitive::generate_printf()
+{
+ asn1::node *ident = m_primitive.identifier();
+ asn1::node *params = ident->parameters();
+ /*
+ * Try to handler sequence of sequence
+ */
+ m_os<<"\tfriend std::ostream &operator <<(std::ostream &os,const "<<m_structName;
+ if (ident->parameters() && m_gencpp.is_template(ident->parameters()))
+ {
+ m_gencpp.gen_template_params(m_os,ident->parameters());
+ }
+ m_os<<" &s"<<") ;\n";
+
+
+}
+
+// generate codec part
+void cghpph_primitive::generate_per()
+{
+}
+
+//
+void cghpph_primitive::generate_ber()
+{
+ //
+ if (m_primitive.tagged())
+ {
+ if ( m_gencpp.is_tag_explicit(m_primitive))
+ {
+ //
+ m_os<<"\tvirtual void encode(asn1::context &ctx);"<<std::endl;
+ m_os<<"\tvirtual int decode(asn1::context &ctx);"<<std::endl;
+ }
+ }
+}
+
+//
+void cghpph_primitive::generate_oer()
+{
+}
+
+//
+void cghpph_primitive::generate_jer()
+{
+}
+
+//
+void cghpph_primitive::generate_xer()
+{
+}
--- /dev/null
+#ifndef CGHPPH_PRIMITIVE_H
+#define CGHPPH_PRIMITIVE_H
+
+
+/**
+ *
+ */
+class cghpph_primitive : public cghpp_helper
+{
+ protected:
+ cghpph_primitive(const cghpph_primitive &s) : cghpp_helper(s.m_gencpp,s.m_os)
+ , m_structName(s.m_structName)
+ , m_primitive(s.m_primitive) {}
+ public:
+ cghpph_primitive(generate_header &g,std::ostream &os,asn1::primitive &s) ;
+ ~cghpph_primitive();
+
+ // Helper functions
+ virtual void generate() ;
+
+ // generate codec part
+ virtual void generate_per() ;
+ //
+ virtual void generate_ber() ;
+ //
+ virtual void generate_oer() ;
+ //
+ virtual void generate_jer() ;
+ //
+ virtual void generate_xer() ;
+ protected:
+ virtual void generate_prolog();
+ virtual void generate_ctors();
+ virtual void generate_operators();
+ virtual void generate_printf();
+ protected:
+ asn1::primitive &m_primitive;
+ std::string m_structName;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_hpp.h"
+#include "asn1_generator_helper.h"
+#include "asn1_gen_codec_cpp.h"
+#include "cghpp_helper.h"
+#include "cghpph_primitive.h"
+#include "cghpph_real.h"
+
+
+cghpph_real::cghpph_real(generate_header &g,std::ostream &os,asn1::real &s)
+ : cghpph_primitive(g,os,s)
+ , m_real(s)
+{
+}
+
+cghpph_real::~cghpph_real()
+{
+}
+
+
+/**
+ *
+ */
+void cghpph_real::generate_prolog()
+{
+ if (m_gencpp.with_source_comment())
+ m_os<<"// cghpph_real helper launched "<<std::endl;
+
+ assert(m_real.type_id()() == asn1::type::ASN1_REAL);
+
+ m_os<<"\n//\n// struct "<<m_structName<<"\n//\n";
+ m_os<<"struct "<<m_structName<<" : public "<<m_real.cpp_name()<<"\n{\n";
+}
+/**
+ *
+ */
+void cghpph_real::generate_ctors()
+{
+ // Initial ctor
+ m_os<<"\t"<<m_structName<<"(const asn1::tag &t = asn1::tag(";
+ if (m_real.tagged())
+ {
+ if ( m_gencpp.is_tag_explicit(m_real) )
+ {
+ m_os<<m_real.tag().m_class<<","<<m_real.tag().m_value<<",true));\n";
+ } else
+ {
+ m_os<<m_real.tag().m_class<<","<<m_real.tag().m_value<<",false));\n";
+ }
+ }else
+ m_os<<"0,1)) ;\n";
+
+ // copy
+ m_os<<"\t"<<m_structName<<"(const "<<m_structName<<" &t"<<") ;\n";
+
+}
+/**
+ *
+ */
+void cghpph_real::generate_printf()
+{
+ asn1::node *ident = m_real.identifier();
+ asn1::node *params = ident->parameters();
+ /*
+ * Try to handler sequence of sequence
+ */
+
+ m_os<<"\tfriend std::ostream &operator <<(std::ostream &os,const "<<m_structName;
+ if (ident->parameters() && m_gencpp.is_template(ident->parameters()))
+ {
+ m_gencpp.gen_template_params(m_os,ident->parameters());
+ }
+ m_os<<" &s"<<");";
+ m_os<<"\n";
+}
+
+// generate codec part
+void cghpph_real::generate_per()
+{
+}
+
+//
+void cghpph_real::generate_ber()
+{
+ //
+ if (m_real.tagged())
+ {
+ if ( m_gencpp.is_tag_explicit(m_real))
+ {
+ //
+ m_os<<"\tvirtual void encode(asn1::context &ctx);"<<std::endl;
+ m_os<<"\tvirtual int decode(asn1::context &ctx);"<<std::endl;
+ }
+ }
+}
+
+//
+void cghpph_real::generate_oer()
+{
+ //
+}
+
+//
+void cghpph_real::generate_jer()
+{
+}
+
+//
+void cghpph_real::generate_xer()
+{
+}
+
--- /dev/null
+#ifndef CGHPPH_REAL_H
+#define CGHPPH_REAL_H
+
+
+/**
+ *
+ */
+class cghpph_real : public cghpph_primitive
+{
+ protected:
+ cghpph_real(const cghpph_real &s) : cghpph_primitive(s)
+ , m_real(s.m_real) {}
+ public:
+ cghpph_real(generate_header &g,std::ostream &os,asn1::real &s) ;
+ ~cghpph_real();
+
+ // Helper functions
+
+ // generate codec part
+ virtual void generate_per() ;
+ //
+ virtual void generate_ber() ;
+ //
+ virtual void generate_oer() ;
+ //
+ virtual void generate_jer() ;
+ //
+ virtual void generate_xer() ;
+
+ // loop over the attributes of SEQUENCE or CHOICE
+ // and check if there are some type of SEQUENCE or CHOICE
+ // launch generation for these types first.
+ protected:
+ void generate_prolog();
+ void generate_printf();
+ void generate_ctors();
+ protected:
+ asn1::real &m_real;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_hpp.h"
+#include "asn1_generator_helper.h"
+#include "asn1_gen_codec_cpp.h"
+#include "cghpp_helper.h"
+#include "cgh_hconstruct.h"
+#include "cghpph_sequence.h"
+
+
+cghpph_sequence::cghpph_sequence(generate_header &g,std::ostream &os,asn1::sequence &s)
+ : cgh_hconstruct(g,os,s)
+ , m_seq(s)
+{
+}
+
+cghpph_sequence::~cghpph_sequence()
+{
+}
+
+
+/** Helper functions
+ *
+ * It seems that the sequence does not always have an identifier. Examples
+ * - SEQUENCE OF SEQUENCE {}
+ * - Test ::= CHOICE { toto INTEGER, SEQUENCE { } }
+ * these sequences are anonymous definitions ...
+ */
+void cghpph_sequence::generate()
+{
+ if ( ! m_gencpp.add_symbol(m_structName,&m_seq) )
+ {
+ m_os<<"// Structure already in map, skip\n";
+ return;
+ }
+
+ cgh_hconstruct::generate();
+
+ if (m_gencpp.with_source_comment())
+ m_os<<"/* end cghpph_sequence "<<m_structName<<"*/"<<std::endl;
+
+}
+
+/**
+ *
+ */
+void
+cghpph_sequence::generate_prolog( )
+{
+ asn1::node *n = m_seq.identifier();
+ asn1::constructed *params = (n) ? n->parameters() : NULL;
+
+ if (m_gencpp.with_source_comment())
+ {
+ m_os<<"\n//\n// cghpph_sequence helper launched ";
+ m_os<<m_structName<<"\n//"<<std::endl;
+ }
+
+ if ( n
+ && n->parameters()
+ && m_gencpp.is_template(n->parameters()) )
+ {
+ // forward declaration
+ m_os<<"template ";
+ m_gencpp.gen_template_signature(m_os,params);
+ m_os<<" struct "<<m_structName<<" ;\n";
+ m_os<<"template ";
+ m_gencpp.gen_template_signature(m_os,params);
+ m_os<<"\nstd::ostream & operator<<(std::ostream &os,const "<<m_structName;
+ m_gencpp.gen_template_params(m_os,params);
+ m_os<<" &s) ;\n";
+
+ m_os<<"//"<<__FUNCTION__<<" parameterized\n";
+ m_os<<"template<";
+ for(asn1::node::iterator p = params->begin(); p != params->end() ;++p)
+ {
+ if (p != params->begin())
+ m_os<<",";
+ m_os<<"typename "<<(*p)->cpp_name();
+ }
+ m_os<<"> "<<std::endl;
+ }
+ m_os<<"struct "<<m_structName<<" : public asn1::types::sequence_type\n";
+ m_os<<"{\n";
+}
+
+/**
+ *
+ */
+void
+cghpph_sequence::generate_ctors( )
+{
+ asn1::node *n = m_seq.identifier();
+ asn1::constructed *params = (n) ? n->parameters() : NULL;
+
+ // Constructor
+ if (m_seq.tagged() )
+ {
+ if ( ! m_gencpp.is_tag_explicit(m_seq) )
+ {
+ asn1::node::tag_type tg = m_seq.tag();
+ m_os<<"\t"<<m_structName<<"(const asn1::tag &t = asn1::tag("<<tg.m_class<<","<<tg.m_value<<",true))";
+ } else
+ {
+ asn1::node::tag_type tg = m_seq.tag();
+ m_os<<"\t"<<m_structName<<"(const asn1::tag &t = asn1::tag("<<tg.m_class<<","<<tg.m_value<<",true))";
+ }
+ } else
+ m_os<<"\t"<<m_structName<<"(const asn1::tag &t = asn1::tag(0,16,true))";
+
+ m_os<<" ;\n";
+ // Copy constructor
+ m_os<<"\t"<<m_structName<<"(const "<<m_structName;
+
+ // parameterized constructor
+ if (params && m_gencpp.is_template(params))
+ {
+ m_gencpp.gen_template_params(m_os,params);
+ }
+ m_os<<" &t) ;\n";
+
+ // Destructor
+ //m_os<<scope<<"\t//virtual ~"<<structName<<"();\n";
+
+ // Clone
+ m_os<<"\tvirtual "<<m_structName;;
+ if (params && m_gencpp.is_template(params))
+ {
+ m_gencpp.gen_template_params(m_os,params);
+ }
+ m_os<<" *clone();\n";
+
+}
+
+/**
+ *
+ */
+void
+cghpph_sequence::generate_operators( )
+{
+ if (m_gencpp.with_ber())
+ {
+ m_os<<"\tvirtual size_t get_data_length() const;\n";
+ }
+
+ // == operator
+ m_os<<"\tbool operator ==("<<m_structName<<" &_c);\n";
+}
+
+/**
+ *
+ */
+void
+cghpph_sequence::generate_members( )
+{
+ std::string scope("");
+ asn1::node *n = m_seq.identifier();
+ asn1::constructed *params = (n) ? n->parameters() : NULL;
+ // Attribute Members
+ if (m_gencpp.with_source_comment())
+ {
+ m_os<<"\t//Member attributes\n";
+ }
+ for ( asn1::node::iterator lit = m_seq.begin()
+ ; lit != m_seq.end() ; lit++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*lit);
+ m_gencpp.gen_composite_attribute( m_os,scope,*f
+ , (n != NULL)?n->parameters():NULL);
+ }
+
+ m_os<<"\n";
+ // For PARAMETERS ObjectSet CLASSES generates
+ gen_members( );
+ //
+ gen_optionals();
+}
+
+
+/**
+ * See If there is a way to have a common class
+ * for this
+ * If I'm private, I also need to get parameters from parent classes example
+ * ReturnResult {OPERATION:Operations} ::= {
+ * result ::= sequence {
+ *
+ * }
+ * }
+ */
+void
+cghpph_sequence::gen_members()
+{
+ std::set<asn1::node *> parameterset;
+ asn1::node *ident = m_seq.identifier();
+ asn1::parameters *params = dynamic_cast<asn1::parameters *>(ident->parameters());
+ /* Collect all parameters */
+ asn1::node::node_list lst;
+ m_seq.path2module(lst);
+ for (asn1::node::iterator lit = lst.begin()
+ ; lit != lst.end()
+ ; ++lit)
+ {
+ if ( (*lit)->identifier() && (*lit)->identifier()->parameters())
+ {
+ asn1::parameters *_p = dynamic_cast<asn1::parameters *>( (*lit)->identifier()->parameters());
+ parameterset.insert(_p->begin(),_p->end());
+ }
+ }
+ if (params)
+ {
+ parameterset.insert(params->begin(),params->end());
+ }
+ /**/
+ if ( parameterset.size() >0 )
+ {
+ for (std::set<asn1::node *>::iterator it = parameterset.begin();
+ it != parameterset.end();
+ ++it)
+ {
+ asn1::parameter *p = dynamic_cast<asn1::parameter *>(*it);
+ if (asn1::node *g = p->get_governor())
+ {
+ asn1::typeref *objr = dynamic_cast<asn1::typeref *>(g);
+ if (objr)
+ {
+ asn1::node *obj = m_gencpp.resolver().resolve(*objr);
+ asn1::module *m = dynamic_cast<asn1::module *>(obj->get_parent());
+ m_os<<"\t// "<<g->name()<<" "<<p->name()<<std::endl;
+ if (!objr->is_simple())
+ {
+ m_os<<"\t"<<m->cpp_name()<<"::I"<<g->name()<<" **"<<p->name()<<";"<<std::endl;
+ }
+ }else
+ {
+ m_os<<"\t// "<<g->name()<<" "<<p->name()<<std::endl;
+ }
+ }
+ }
+ }
+}
+
+
+
+//
+void cghpph_sequence::generate_printf( )
+{
+
+ asn1::node *n = m_seq.identifier();
+ asn1::node *params = (n ) ? n->parameters() :NULL;
+#if 0
+ if (n != NULL)
+ {
+ if (m_seq.is_private())
+ {
+ structName = m_seq.cpp_name();
+ } else
+ structName = n->cpp_name();
+ params = n->parameters();
+ } else
+ {
+ // Anonymous structure
+ structName = m_seq.cpp_name();
+ }
+#endif
+ m_os<<"\tvirtual void printf(std::ostream &os) const;\n";
+
+ m_os<<"\tfriend std::ostream &operator << ";
+ if (params && m_gencpp.is_template(params))
+ m_os<<" <>";
+ m_os<<"(std::ostream &os,const ";
+ m_os<<m_structName;
+
+ if (n && n->parameters() && m_gencpp.is_template(n->parameters()))
+ {
+ m_gencpp.gen_template_params(m_os,n->parameters());
+ }
+ m_os<<" &s"<<")";
+ m_os<<";\n";
+}
+
+
+/**
+ *
+ */
+void cghpph_sequence::generate_ber()
+{
+ std::string scope;
+ //
+ m_os<<"\tvirtual void encode(asn1::context &ctx);"<<std::endl;
+ m_os<<"\tvirtual int decode(asn1::context &ctx);"<<std::endl;
+ //
+ if ( m_seq.tagged()
+ && m_gencpp.is_tag_explicit(m_seq) )
+ {
+ m_os<<"\tvirtual void encode_preamble_ber(asn1::context &ctx);"<<std::endl;
+ m_os<<"\tvirtual void encode_epilogue_ber(asn1::context &ctx);"<<std::endl;
+ m_os<<"\tvirtual int decode_preamble_ber(asn1::streams::ber &ctx);"<<std::endl;
+ m_os<<"\tvirtual int decode_epilogue_ber(asn1::streams::ber &ctx);"<<std::endl;
+ }
+}
+
+/**
+ *
+ */
+void cghpph_sequence::gen_optionals()
+{
+ static const char *typ[] = {"unsigned char","unsigned short","unsigned int","unsigned long","unsigned long long"};
+ int i = 0;
+ long count = 0;
+ int l = m_seq.opt_size();
+ long bits = 1<<(m_seq.opt_size()-1);
+ while ( l > 0)
+ {
+ i++; l = l / 8;
+ }
+ if (i == 0)
+ return;
+ m_os<<"\n\t//Optional bit mask "<<i<<"\n";
+ m_os<<"\tstd::bitset<"<<m_seq.opt_size()<<">\tbit_mask;\n";
+ m_os<<"\tenum {\n";
+ for ( asn1::sequence::OptionalIterator it = m_seq.opt_begin()
+ ; it != m_seq.opt_end()
+ ; ++it)
+ {
+ m_os<<"\t\t";
+ if (it != m_seq.opt_begin())
+ m_os<<",";
+ m_os<<(*it)->cpp_name()<<"_present\t = "<<count<<std::endl;
+ count++;
+ }
+ m_os<<"\t};\n";
+}
--- /dev/null
+#ifndef CGHPPH_SEQUENCE_H
+#define CGHPPH_SEQUENCE_H
+
+
+/**
+ *
+ */
+class cghpph_sequence : public cgh_hconstruct
+{
+ protected:
+ cghpph_sequence(const cghpph_sequence &s)
+ : cgh_hconstruct(s.m_gencpp,s.m_os,s.m_c)
+ , m_seq(s.m_seq)
+ {}
+ public:
+ cghpph_sequence(generate_header &g,std::ostream &os,asn1::sequence &s) ;
+ ~cghpph_sequence();
+
+ // Helper functions
+ virtual void generate() ;
+
+ // generate codec part
+ virtual void generate_per() {};
+ //
+ virtual void generate_ber() ;
+ //
+ virtual void generate_oer() {};
+ //
+ virtual void generate_jer() {};
+ //
+ virtual void generate_xer() {};
+ protected:
+ virtual void generate_prolog() ;
+ virtual void generate_ctors() ;
+ virtual void generate_operators() ;
+ virtual void generate_members() ;
+ virtual void generate_printf();
+ protected:
+ // Generate bit mask for optional flags
+ void gen_optionals();
+ void gen_members();
+ protected:
+ asn1::sequence &m_seq;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_hpp.h"
+#include "asn1_generator_helper.h"
+#include "asn1_gen_codec_cpp.h"
+#include "cgcpp_helper.h"
+#include "cghpph_sequenceof.h"
+
+
+cghpph_sequenceof::cghpph_sequenceof( generate_header &g
+ , std::ostream &os
+ , asn1::sequence_of &s)
+ : m_Gen(g)
+ , generator_helper(os)
+ , m_seqof(s)
+ , m_log(g.logger())
+{
+}
+
+cghpph_sequenceof::~cghpph_sequenceof()
+{
+}
+
+
+/** Helper functions
+ *
+ * It seems that the choice does not always have an identifier. Examples
+ * - SEQUENCE OF CHOICE {}
+ * - Test ::= CHOICE { toto INTEGER, CHOICE { } }
+ * these sequences are anonymous definitions ...
+ */
+void cghpph_sequenceof::generate()
+{
+ asn1::node *ns = NULL;
+ asn1::node *type = &m_seqof;
+ asn1::typenode *seqof_type = m_seqof.get_eltype();
+ asn1::node *params = NULL;
+ std::string structName,eltype;
+ std::string scope("");
+
+ if (m_Gen.with_source_comment())
+ m_os<<"// cghpph_sequenceof helper launched "<<std::endl;
+
+ assert(m_seqof.type_id()() == asn1::type::ASN1_SEQUENCE_OF
+ );
+ structName = m_seqof.identifier_cpp_name();
+
+ if (m_Gen.type_in_imports(seqof_type,&ns))
+ {
+ eltype = ns->cpp_name() + "::" + seqof_type->cpp_name();
+ } else
+ eltype = seqof_type->cpp_name();
+ m_os<<"struct "<<structName<<" : public asn1::Seq<"<<eltype<<">\n{\n";
+
+ //
+ // Initial ctor
+ m_os<<"\t"<<structName<<"(const asn1::tag &t = asn1::tag(";
+ if (m_seqof.tagged())
+ {
+ if ( m_Gen.tag_mode(&m_seqof) == asn1::node::tag_type::TM_EXPLICIT)
+ {
+ m_os<<m_seqof.tag().m_class<<","<<m_seqof.tag().m_value<<",true)) ;\n";
+ } else
+ {
+ m_os<<m_seqof.tag().m_class<<","<<m_seqof.tag().m_value<<",false)) ;\n";
+ }
+ }else {
+ m_os<<"0,"<<"16)) ;\n";
+ }
+
+ // copy
+ m_os<<"\t"<<structName<<"(const "<<structName<<" &t"<<") ;\n";
+ // clone
+ m_os<<"\tvirtual "<<structName<<" *clone() ;\n";
+ //
+ m_os<<"\tinline "<<structName<<" & operator =(const "<<structName<<" &c)\n";
+ m_os<<"\t{ Seq<"<<eltype<<">::operator =(c); return *this; };\n";
+ generate_ber();
+ // equal operator
+ m_os<<scope<<"\tbool operator ==(const "<<structName<<" &_c);\n";
+
+ gen_printf();
+ m_os<<"};\n";
+
+}
+
+//
+void cghpph_sequenceof::gen_printf()
+{
+ std::string structName;
+ std::string scope("");
+ asn1::node *type = &m_seqof;
+ asn1::node *ident = m_seqof.identifier();
+ asn1::node *params = ident->parameters();
+ /*
+ * Try to handler sequence of sequence
+ */
+
+ if (m_seqof.is_private())
+ {
+ structName = type->cpp_name();
+ } else
+ structName = ident->cpp_name();
+
+ m_os<<scope<<"\tfriend std::ostream &operator <<(std::ostream &os,const "<<structName;
+ if (ident->parameters() && m_Gen.is_template(ident->parameters()))
+ {
+ m_Gen.gen_template_params(m_os,ident->parameters());
+ }
+ m_os<<" &s"<<") ;\n";
+
+
+}
+
+// generate codec part
+void cghpph_sequenceof::generate_per()
+{
+ std::string scope;
+ //
+ m_os<<scope<<"\tvirtual void encode_per(asn1::context &ctx);"<<std::endl;
+ m_os<<scope<<"\tvirtual int decode_per(asn1::context &ctx);"<<std::endl;
+}
+
+//
+void cghpph_sequenceof::generate_ber()
+{
+ std::string scope;
+ asn1::node *type = &m_seqof;
+ //
+ if (m_seqof.tagged())
+ {
+ if ( m_Gen.tag_mode(type) == asn1::node::tag_type::TM_EXPLICIT)
+ {
+ //
+ m_os<<scope<<"\tvirtual void encode(asn1::context &ctx);"<<std::endl;
+ m_os<<scope<<"\tvirtual int decode(asn1::context &ctx);"<<std::endl;
+ }
+ }
+}
+
+//
+void cghpph_sequenceof::generate_oer()
+{
+ //
+ std::string scope;
+ m_os<<scope<<"\tvirtual void encode_oer(asn1::context &ctx);"<<std::endl;
+ m_os<<scope<<"\tvirtual int decode_oer(asn1::context &ctx);"<<std::endl;
+}
+
+//
+void cghpph_sequenceof::generate_jer()
+{
+}
+
+//
+void cghpph_sequenceof::generate_xer()
+{
+}
--- /dev/null
+#ifndef CGHPPH_SEQUENCEOF_H
+#define CGHPPH_SEQUENCEOF_H
+
+
+/**
+ *
+ */
+class cghpph_sequenceof : public generator_helper
+{
+ protected:
+ cghpph_sequenceof(const cghpph_sequenceof &s) : generator_helper(s.m_os)
+ , m_Gen(s.m_Gen)
+ , m_log(s.m_log)
+ , m_seqof(s.m_seqof) {}
+ public:
+ cghpph_sequenceof(generate_header &g,std::ostream &os,asn1::sequence_of &s) ;
+
+ ~cghpph_sequenceof();
+
+ // Helper functions
+ virtual void generate() ;
+
+ // generate codec part
+ virtual void generate_per() ;
+ //
+ virtual void generate_ber() ;
+ //
+ virtual void generate_oer() ;
+ //
+ virtual void generate_jer() ;
+ //
+ virtual void generate_xer() ;
+ protected:
+ void gen_printf();
+ protected:
+ std::fstream &m_log;
+ generate_header &m_Gen;
+ asn1::sequence_of &m_seqof;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_hpp.h"
+#include "asn1_generator_helper.h"
+#include "asn1_gen_codec_cpp.h"
+#include "cghpp_helper.h"
+#include "cgh_hconstruct.h"
+#include "cghpph_set.h"
+
+
+
+/**
+ *
+ */
+cghpph_set::cghpph_set(generate_header &g,std::ostream &os,asn1::set &s)
+ : cgh_hconstruct(g,os,s)
+ , m_set(s)
+{
+}
+
+cghpph_set::~cghpph_set()
+{
+}
+
+
+/** Helper functions
+ *
+ * It seems that the choice does not always have an identifier. Examples
+ * - SEQUENCE OF CHOICE {}
+ * - Test ::= CHOICE { toto INTEGER, CHOICE { } }
+ * these sequences are anonymous definitions ...
+ */
+void cghpph_set::generate()
+{
+ cgh_hconstruct::generate() ;
+}
+
+/**
+ *
+ */
+void cghpph_set::generate_prolog( )
+{
+ if (m_gencpp.with_source_comment() )
+ m_os<<"// cghpph_set helper launched "<<std::endl;
+ m_os<<"struct "<<m_structName<<" : asn1::types::sequence_type\n{\n";
+}
+/**
+ *
+ */
+void cghpph_set::generate_ctors( )
+{
+ // Missing constructors
+ if (m_set.tagged())
+ {
+ asn1::node::tag_type lt = m_set.tag();
+ m_os<<"\t"<<m_structName<<"(const asn1::tag &t = asn1::tag("<<lt.m_class<<","<<lt.m_value<<",true)) ;"<<std::endl;
+ } else
+ m_os<<"\t"<<m_structName<<"(const asn1::tag &t = asn1::tag(0,17,true)) ;"<<std::endl;
+}
+/**
+ *
+ */
+void cghpph_set::generate_operators( )
+{
+ // equal operator
+ m_os<<"\tbool operator ==("<<m_structName<<" &_c);\n";
+}
+
+/**
+ *
+ */
+void cghpph_set::generate_members( )
+{
+ std::string scope("");
+ asn1::node *n = m_set.identifier();
+ // Loop over the attributes
+ for ( asn1::node::iterator it = m_set.begin()
+ ; it != m_set.end() ; it++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*it);
+ m_gencpp.gen_composite_attribute(m_os,scope,*f,(n != NULL)?n->parameters():NULL);
+ m_os<<"\n";
+ }
+}
+
+/**
+ *
+ */
+void cghpph_set::generate_printf( )
+{
+ asn1::node::iterator lit;
+ asn1::node *ident = m_set.identifier();
+ asn1::constructed *params = ident->parameters();
+ /*
+ * Try to handler sequence of sequence
+ */
+ lit = m_set.begin();
+#if 0
+ if (m_set.is_private())
+ {
+ structName = type->cpp_name();
+ } else
+ structName = ident->cpp_name();
+#endif
+ m_os<<"\tfriend std::ostream &operator <<(std::ostream &os,const "<<m_structName;
+ if (ident->parameters() && m_gencpp.is_template(ident->parameters()))
+ {
+ m_gencpp.gen_template_params(m_os,ident->parameters());
+ }
+ m_os<<" &s"<<" ) ;";
+
+}
+
+// generate codec part
+void cghpph_set::generate_ber()
+{
+ //
+ m_os<<"\tvirtual void encode(asn1::context &ctx);"<<std::endl;
+ m_os<<"\tvirtual int decode(asn1::context &ctx);"<<std::endl;
+ //
+ if ( m_set.tagged()
+ && m_gencpp.is_tag_explicit(m_set))
+ {
+ m_os<<"\tvirtual void encode_preamble_ber(asn1::context &ctx);"<<std::endl;
+ m_os<<"\tvirtual void encode_epilogue_ber(asn1::context &ctx);"<<std::endl;
+ m_os<<"\tvirtual int decode_preamble_ber(asn1::streams::ber &ctx);"<<std::endl;
+ m_os<<"\tvirtual int decode_epilogue_ber(asn1::streams::ber &ctx);"<<std::endl;
+ }
+}
--- /dev/null
+#ifndef CGHPPH_SET_H
+#define CGHPPH_SET_H
+
+
+/**
+ *
+ */
+class cghpph_set : public cgh_hconstruct
+{
+ protected:
+ cghpph_set(const cghpph_set &s) : cgh_hconstruct(s.m_gencpp,s.m_os,s.m_c)
+ , m_set(s.m_set) {}
+ public:
+ cghpph_set(generate_header &g,std::ostream &os,asn1::set &s) ;
+ ~cghpph_set();
+
+ // Helper functions
+ virtual void generate() ;
+
+ // generate codec part
+ virtual void generate_per() { };
+ //
+ virtual void generate_ber() ;
+ //
+ virtual void generate_oer() { };
+ //
+ virtual void generate_jer() { };
+ //
+ virtual void generate_xer() { };
+ protected:
+ virtual void generate_prolog();
+ virtual void generate_ctors();
+ virtual void generate_members();
+ virtual void generate_operators();
+ virtual void generate_printf();
+ protected:
+ asn1::set &m_set;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_hpp.h"
+#include "asn1_generator_helper.h"
+#include "asn1_gen_codec_cpp.h"
+#include "cgcpp_helper.h"
+#include "cghpph_setof.h"
+
+
+cghpph_setof::cghpph_setof( generate_header &g
+ , std::ostream &os
+ , asn1::set_of &s)
+ : m_Gen(g)
+ , generator_helper(os)
+ , m_setof(s)
+ , m_log(g.logger())
+{
+}
+
+cghpph_setof::~cghpph_setof()
+{
+}
+
+
+/** Helper functions
+ *
+ * It seems that the choice does not always have an identifier. Examples
+ * - SEQUENCE OF CHOICE {}
+ * - Test ::= CHOICE { toto INTEGER, CHOICE { } }
+ * these sequences are anonymous definitions ...
+ */
+void cghpph_setof::generate()
+{
+ asn1::node *ns = NULL;
+ asn1::node *type = &m_setof;
+ asn1::typenode *setof_type = m_setof.get_eltype();
+ asn1::node *params = NULL;
+ std::string structName,eltype;
+ std::string scope("");
+
+ if (m_Gen.with_source_comment())
+ m_os<<"// cghpph_setof helper launched "<<std::endl;
+
+ assert(m_setof.type_id()() == asn1::type::ASN1_SET_OF
+ );
+ structName = m_setof.identifier_cpp_name();
+
+ if (m_Gen.type_in_imports(setof_type,&ns))
+ {
+ eltype = ns->cpp_name() + "::" + setof_type->cpp_name();
+ } else
+ eltype = setof_type->cpp_name();
+ m_os<<"struct "<<structName<<" : public asn1::Set<"<<eltype<<">\n{\n";
+
+ //
+ // Initial ctor
+ m_os<<"\t"<<structName<<"(const asn1::tag &t = asn1::tag(";
+ if (m_setof.tagged())
+ {
+ if ( m_Gen.tag_mode(&m_setof) == asn1::node::tag_type::TM_EXPLICIT)
+ {
+ m_os<<m_setof.tag().m_class<<","<<m_setof.tag().m_value<<",true)) ;\n";
+ } else
+ {
+ m_os<<m_setof.tag().m_class<<","<<m_setof.tag().m_value<<",false)) ;\n";
+ }
+ }else {
+ m_os<<"1,"<<"17)) ;\n";
+ }
+ /*ctor from one element type */
+ m_os<<"\t"<<structName<<"(const "<<eltype<<" &T);\n";
+
+
+ // copy
+ m_os<<"\t"<<structName<<"(const "<<structName<<" &t"<<") ;\n";
+ // clone
+ m_os<<"\tvirtual "<<structName<<" *clone() ;\n";
+ //
+ m_os<<"\tinline "<<structName<<" & operator =(const "<<structName<<" &c)\n";
+ m_os<<"\t{ Set<"<<eltype<<">::operator =(c); return *this; };\n";
+ generate_ber();
+ // equal operator
+ m_os<<scope<<"\tbool operator ==(const "<<structName<<" &_c);\n";
+
+ gen_printf();
+ m_os<<"};\n";
+
+}
+
+//
+void cghpph_setof::gen_printf()
+{
+ std::string structName;
+ std::string scope("");
+ asn1::node *type = &m_setof;
+ asn1::node *ident = m_setof.identifier();
+ asn1::node *params = ident->parameters();
+ /*
+ * Try to handler sequence of sequence
+ */
+ //assert(m_setof.is_private());
+ if (m_setof.is_private())
+ {
+ structName = type->cpp_name();
+ } else
+ structName = ident->cpp_name();
+
+ m_os<<scope<<"\tfriend std::ostream &operator <<(std::ostream &os,const "<<structName;
+ if (ident->parameters() && m_Gen.is_template(ident->parameters()))
+ {
+ m_Gen.gen_template_params(m_os,ident->parameters());
+ }
+ m_os<<" &s"<<") ;\n";
+
+
+}
+
+// generate codec part
+void cghpph_setof::generate_per()
+{
+ std::string scope;
+ //
+ m_os<<scope<<"\tvirtual void encode_per(asn1::context &ctx);"<<std::endl;
+ m_os<<scope<<"\tvirtual int decode_per(asn1::context &ctx);"<<std::endl;
+}
+
+//
+void cghpph_setof::generate_ber()
+{
+ asn1::node *type = &m_setof;
+ //
+ if (m_setof.tagged())
+ {
+ if ( m_Gen.tag_mode(type) == asn1::node::tag_type::TM_EXPLICIT)
+ {
+ //
+ m_os<<"\tvirtual void encode(asn1::context &ctx);"<<std::endl;
+ m_os<<"\tvirtual int decode(asn1::context &ctx);"<<std::endl;
+ }
+ }
+}
+
+//
+void cghpph_setof::generate_oer()
+{
+ //
+ std::string scope;
+ m_os<<scope<<"\tvirtual void encode_oer(asn1::context &ctx);"<<std::endl;
+ m_os<<scope<<"\tvirtual int decode_oer(asn1::context &ctx);"<<std::endl;
+}
+
+//
+void cghpph_setof::generate_jer()
+{
+}
+
+//
+void cghpph_setof::generate_xer()
+{
+}
--- /dev/null
+#ifndef CGHPPH_SETOF_H
+#define CGHPPH_SETOF_H
+
+
+/**
+ *
+ */
+class cghpph_setof : public generator_helper
+{
+ protected:
+ cghpph_setof(const cghpph_setof &s) : generator_helper(s.m_os)
+ , m_Gen(s.m_Gen)
+ , m_log(s.m_log)
+ , m_setof(s.m_setof) {}
+ public:
+ cghpph_setof(generate_header &g,std::ostream &os,asn1::set_of &s) ;
+
+ ~cghpph_setof();
+
+ // Helper functions
+ virtual void generate() ;
+
+ // generate codec part
+ virtual void generate_per() ;
+ //
+ virtual void generate_ber() ;
+ //
+ virtual void generate_oer() ;
+ //
+ virtual void generate_jer() ;
+ //
+ virtual void generate_xer() ;
+ protected:
+ void gen_printf();
+ protected:
+ std::fstream &m_log;
+ generate_header &m_Gen;
+ asn1::set_of &m_setof;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_hpp.h"
+#include "asn1_generator_helper.h"
+#include "asn1_gen_codec_cpp.h"
+#include "cghpp_helper.h"
+#include "cghpph_primitive.h"
+#include "cghpph_string.h"
+
+
+cghpph_string::cghpph_string( generate_header &g
+ , std::ostream &os
+ , asn1::primitive &s)
+ : cghpph_primitive(g,os,s)
+ , m_string(s)
+{
+}
+
+cghpph_string::~cghpph_string()
+{
+}
+
+
+/**
+ *
+ */
+void cghpph_string::generate_prolog()
+{
+ if (m_gencpp.with_source_comment())
+ m_os<<"// cghpph_string helper launched "<<std::endl;
+
+ assert(m_string.type_id()() >= asn1::type::ASN1_STRING
+ && m_string.type_id()() < asn1::type::ASN1_STRING_ObjectDescriptor );
+
+ m_os<<"struct "<<m_structName<<" : public "<<m_string.cpp_name()<<"\n{\n";
+}
+
+/**
+ *
+ */
+void cghpph_string::generate_ctors()
+{
+ m_os<<"\t"<<m_structName<<"(const asn1::tag &t = asn1::tag(";
+ if (m_string.tagged())
+ {
+ if ( m_gencpp.is_tag_explicit(m_string))
+ {
+ m_os<<m_string.tag().m_class<<","<<m_string.tag().m_value<<",true)) ;\n";
+ } else
+ {
+ m_os<<m_string.tag().m_class<<","<<m_string.tag().m_value<<",false)) ;\n";
+ }
+ }else
+ m_os<<"0,"<<m_string.primitive_tag()<<")) ;\n";
+
+ // Two other ctors
+ m_os<<"\t"<<m_structName<<"(const std::string &s);\n";
+ // copy
+ m_os<<"\t"<<m_structName<<"(const "<<m_structName<<" &t"<<") ;\n";
+
+ m_os<<"\t"<<m_structName<<"(const "<<m_string.cpp_name()<<" &c,";
+ m_os<<"const asn1::tag &t = asn1::tag(";
+ if (m_string.tagged())
+ {
+ if ( m_gencpp.is_tag_explicit(m_string) )
+ {
+ m_os<<m_string.tag().m_class<<","<<m_string.tag().m_value<<",true)) ;\n";
+ } else
+ {
+ m_os<<m_string.tag().m_class<<","<<m_string.tag().m_value<<",false)) ;\n";
+ }
+ }else
+ m_os<<"0,"<<m_string.primitive_tag()<<")";
+
+ m_os<<") ;\n";
+ // = copy assignement
+ m_os<<"\t"<<m_structName<<" &operator =(const "<<m_string.cpp_name()<<" &c);\n";
+ m_os<<"\t"<<m_structName<<" &operator =(const std::string &c);\n";
+ m_os<<"\t"<<m_structName<<" &operator =(const char *c);\n";
+ // clone
+ m_os<<"\tvirtual "<<m_structName<<" *clone();\n";
+
+}
+
+/**
+ *
+ */
+void cghpph_string::generate_printf()
+{
+ asn1::node *ident = m_string.identifier();
+ /*
+ * Try to handler sequence of sequence
+ */
+
+ m_os<<"\tfriend std::ostream &operator <<(std::ostream &os,const "<<m_structName;
+ if (ident->parameters() && m_gencpp.is_template(ident->parameters()))
+ {
+ m_gencpp.gen_template_params(m_os,ident->parameters());
+ }
+ m_os<<" &s"<<") ;\n";
+
+
+}
+
+// generate codec part
+void cghpph_string::generate_per()
+{
+}
+
+//
+void cghpph_string::generate_ber()
+{
+ if (m_string.tagged())
+ {
+ if ( m_gencpp.is_tag_explicit(m_string) )
+ {
+ //
+ m_os<<"\tvirtual void encode(asn1::context &ctx);"<<std::endl;
+ m_os<<"\tvirtual int decode(asn1::context &ctx);"<<std::endl;
+ }
+ }
+}
+
+//
+void cghpph_string::generate_oer()
+{
+}
+
+//
+void cghpph_string::generate_jer()
+{
+}
+
+//
+void cghpph_string::generate_xer()
+{
+}
+
--- /dev/null
+#ifndef CGHPPH_STRING_H
+#define CGHPPH_STRING_H
+
+
+/**
+ *
+ */
+class cghpph_string : public cghpph_primitive
+{
+ protected:
+ cghpph_string(const cghpph_string &s) : cghpph_primitive(s.m_gencpp,s.m_os,s.m_string)
+ , m_string(s.m_string) {}
+ public:
+ cghpph_string(generate_header &g,std::ostream &os,asn1::primitive &s) ;
+ ~cghpph_string();
+
+ // Helper functions
+
+ virtual void generate_prolog();
+ virtual void generate_ctors();
+ //virtual void generate_operators() {};
+ virtual void generate_printf();
+ // generate codec part
+ virtual void generate_per() ;
+ //
+ virtual void generate_ber() ;
+ //
+ virtual void generate_oer() ;
+ //
+ virtual void generate_jer() ;
+ //
+ virtual void generate_xer() ;
+ protected:
+ asn1::primitive &m_string;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_hpp.h"
+#include "asn1_generator_helper.h"
+#include "asn1_gen_codec_cpp.h"
+#include "cghpp_helper.h"
+#include "cghpph_typeref.h"
+
+
+cghpph_typeref::cghpph_typeref(generate_header &g,std::ostream &os,asn1::typeref &s)
+ : cghpp_helper(g,os) , m_typeref(s)
+{
+}
+
+cghpph_typeref::~cghpph_typeref()
+{
+}
+
+
+/** Helper functions
+ *
+ * It seems that the choice does not always have an identifier. Examples
+ * - SEQUENCE OF CHOICE {}
+ * - Test ::= CHOICE { toto INTEGER, CHOICE { } }
+ * these sequences are anonymous definitions ...
+ */
+void cghpph_typeref::generate()
+{
+ asn1::node *n = m_typeref.identifier();
+ asn1::node *type = &m_typeref;
+ asn1::node *params = NULL;
+ std::string structName;
+
+ assert( n!= NULL);
+ if (m_gencpp.with_source_comment())
+ {
+ m_os<<"// cghpph_typeref helper launched ";
+ m_os<<n->name()<<std::endl;
+ }
+ if (m_typeref.is_simple())
+ {
+ if (m_gencpp.with_source_comment())
+ m_os<<"// cghpph_typeref simple "<<std::endl;
+ //generate_simple();
+ cghpp_helper::generate();
+ } else if (m_typeref.is_objectclass())
+ {
+ m_os<<"// cghpph_typeref object class"<<std::endl;
+ generate_objectclass();
+ } else
+ {
+ assert(0);
+ }
+}
+
+/**
+ *
+ */
+void cghpph_typeref::generate_prolog( )
+{
+ std::string refName;
+ asn1::node *ns;
+
+ if (m_gencpp.type_in_imports(&m_typeref,&ns) )
+ {
+ refName = ns->cpp_name()+"::"+m_typeref.cpp_name();
+ } else
+ {
+ refName = m_typeref.cpp_name();
+ }
+ m_os<<"//\nclass "<<m_typeref.identifier_cpp_name()<<" : public ";
+ m_os<<refName<<"\n{\n";
+ m_os<<" public:\n";
+}
+
+/**
+ *
+ */
+void cghpph_typeref::generate_ctors( )
+{
+ gen_simple_ctors();
+}
+
+/**
+ *
+ */
+void cghpph_typeref::generate_operators( )
+{
+ m_os<<"\n";
+ m_os<<"\tbool operator==("<<m_typeref.identifier_cpp_name()<<" &o);\n";
+ m_os<<"\n";
+
+ generate_simple();
+}
+//
+//
+//
+void cghpph_typeref::generate_simple()
+{
+ asn1::node *ns = NULL;
+ asn1::node *n = m_typeref.identifier();
+ asn1::typeref *type = &m_typeref;
+ std::string type_name = type->cpp_name();
+ std::string refName = type->cpp_name();
+
+ if (m_gencpp.type_in_imports(type,&ns) )
+ {
+ refName = ns->cpp_name()+"::"+type->cpp_name();
+ } else
+ {
+ refName = type->cpp_name();
+ }
+
+ //generate_ber();
+ // If its the simple
+ if ( !type->tagged())
+ {
+ // Process untagged elements
+ asn1::node *params = type->parameters();
+ if (m_gencpp.type_in_imports(type,&ns) )
+ {
+ // imported case
+ if (type->meta_id()() == asn1::meta::OBJECTCLASS)
+ {
+ m_os<<"// OBJECT CLASS NOT YET SUPPORTED "<<type->cpp_name()<<" ";
+ } else if (std::string("OPERATON").compare(type->cpp_name())==0)
+ {
+ m_os<<"// OBJECT CLASS NOT YET SUPPORTED "<<type->cpp_name()<<" ";
+ } else
+ {
+ //m_os<<"\t"<<ns->cpp_name()<<"::";
+ //m_os<<type->cpp_name()<<" ";
+ }
+ } else if (std::string("TYPE_IDENTIFIER").compare(type->cpp_name())==0)
+ {
+ m_os<<" /* def"<<type->cpp_name()<<"*/INTEGER ";
+
+ } else
+ {
+ // internal case
+ if (m_gencpp.with_source_comment())
+ {
+ m_os<<" /* def no import, has constraints "<<type->has_constraints();
+ m_os<<" */ ";
+ }
+ }
+ }
+}
+//
+//
+//
+void
+cghpph_typeref::gen_simple_ctors()
+{
+ asn1::node *ns = NULL;
+ asn1::node *n = m_typeref.identifier();
+ asn1::typeref *type = &m_typeref;
+ std::string type_name = n->cpp_name();
+ std::string refName = type->cpp_name();
+ std::list<asn1::node *> refs;
+
+ m_gencpp.reference_chaine(type,refs);
+
+ if (m_gencpp.type_in_imports(type,&ns) )
+ {
+ refName = ns->cpp_name()+"::"+type->cpp_name();
+ }
+
+ if (type->tagged())
+ {
+ /**
+ * When tagged explicit, may be build object with tag
+ * from referenced type which needs to be used to
+ * decode what follows
+ */
+ m_os<<"\t"<<type_name<<"(const asn1::tag &_t";
+ m_os<<" = asn1::tag(";
+ m_os<<type->tag().m_class<<","<<type->tag().m_value<<")";
+ m_os<<" ) ;"<<std::endl;
+ } else
+ {
+ m_os<<"\t"<<type_name<<"( ) ;"<<std::endl;
+ m_os<<"\t"<<type_name<<"( const asn1::tag &t) ;"<<std::endl;
+ }
+
+ m_os<<"\t"<<type_name<<"(const "<<type_name<<"&_c) ;"<<std::endl;
+ // Check Type of Initial type
+#if 1
+ if ( refs.size()>0 &&
+ refs.back()->type_id()() == asn1::type::ASN1_CHOICE)
+ {
+ m_os<<"\t"<<type_name<<"(unsigned int i, const asn1::tag &t) ;"<<std::endl;
+ }
+#endif
+ // Add an operator
+ m_os<<"\t"<<type_name<<" &operator =(const "<<refName<<" &_v);\n";
+}
+
+/**
+ *
+ * In order to resolve object class references we need
+ * the resolver. The resolver should be able to return
+ * the appropriate object class. Except for TYPE-IDENTIFIER which is
+ * built in.
+ */
+void
+cghpph_typeref::generate_objectclass()
+{
+ asn1::node *n = m_typeref.identifier();
+ asn1::typeref *type = &m_typeref;
+ asn1::objectclass_reference &_ref = m_typeref.get_objectclass();
+
+ /* TYPE-IDENTIFIER&TYPE*/
+ if (m_typeref.is_type_identifier())
+ {
+ if (type->has_constraints())
+ {
+ // Try to find the constraint type value
+ m_os<<"//\ntypedef "<<type->cpp_name()<<" "<<n->cpp_name()<<";";
+ m_os<<"\n"<<std::endl;
+ } else
+ {
+ // Without constraint it should be a template
+ m_os<<"//\nERROR TI Shall be template"<<type->cpp_name()<<n->cpp_name()<<" ";
+ m_os<<"\n"<<std::endl;
+ }
+ } else
+ {
+ // Use the resolver to figure out what to do.
+ m_os<<"//cghpph_typeref::generate_objectclass TODO ";
+ m_os<<n->cpp_name()<<" ::= ";
+ m_os<<type->cpp_name();
+ m_os<<" Ref="<<_ref.name();
+ if (n->parameters())
+ {
+ m_os<<" TYPE with parameters don't generate code ";;
+ }
+ if (m_typeref.act_parameters())
+ {
+ m_os<<" REF WITH PARAMETERS !!!";
+ }
+ m_os<<"\n"<<std::endl;
+ asn1::node *real_type =
+ m_gencpp.resolver().resolve(m_typeref);
+ if (real_type)
+ {
+ m_os<<"// FOUND REAL TYPE "<<real_type->cpp_name()<<std::endl;
+ m_os<<"typedef I"<<type->cpp_name()<<" I"<<n->cpp_name()<<";";
+ m_os<<"\n"<<std::endl;
+ }
+ }
+}
+
+//
+void cghpph_typeref::gen_printf(const std::string &scope)
+{
+}
+
+// generate codec part
+void cghpph_typeref::generate_per()
+{
+ std::string scope;
+ //
+ m_os<<scope<<"\tvirtual void encode_per(asn1::context &ctx);"<<std::endl;
+ m_os<<scope<<"\tvirtual int decode_per(asn1::context &ctx);"<<std::endl;
+}
+
+/**
+ *
+ * TODO I think signature of the functions should be asn1::streams::ber &ctx and not
+ * asn1::context
+ */
+void cghpph_typeref::generate_ber()
+{
+ std::string scope;
+ asn1::node *ns = NULL;
+ asn1::typeref *type = &m_typeref;
+ std::string type_name = m_typeref.identifier()->cpp_name();
+ std::string refName = type->cpp_name();
+ std::list<asn1::node *> refs;
+
+ m_gencpp.reference_chaine(type,refs);
+
+ if (m_gencpp.type_in_imports(type,&ns) )
+ {
+ refName = ns->cpp_name()+"::"+type->cpp_name();
+ }
+
+ //
+ //
+ if (m_typeref.tagged())
+ {
+ if ( m_gencpp.is_tag_explicit(*type) )
+ {
+ m_os<<scope<<"\tvirtual void encode(asn1::context &ctx);"<<std::endl;
+ m_os<<scope<<"\tvirtual int decode(asn1::context &ctx);"<<std::endl;
+ } else
+ {
+ m_os<<scope<<"\tvirtual void encode(asn1::context &ctx);"<<std::endl;
+ m_os<<scope<<"\tvirtual int decode(asn1::context &ctx);"<<std::endl;
+ }
+ }
+ // What do I define if there is no tag ?
+}
+
+//
+void cghpph_typeref::generate_oer()
+{
+ //
+ std::string scope;
+ //m_os<<scope<<"\tvirtual void encode_oer(asn1::codecs::oer &ctx);"<<std::endl;
+ //m_os<<scope<<"\tvirtual int decode_oer(asn1::codecs::oer &ctx);"<<std::endl;
+ m_os<<scope<<"\tvirtual void encode(asn1::codecs::oer &ctx);"<<std::endl;
+ m_os<<scope<<"\tvirtual int decode(asn1::codecs::oer &ctx);"<<std::endl;
+}
+
+//
+void cghpph_typeref::generate_jer()
+{
+}
+
+//
+void cghpph_typeref::generate_xer()
+{
+}
+
+
--- /dev/null
+#ifndef CGHPPH_TYPEREF_H
+#define CGHPPH_TYPEREF_H
+
+
+/**
+ *
+ */
+class cghpph_typeref : public cghpp_helper
+{
+ protected:
+ cghpph_typeref(const cghpph_typeref &s) : cghpp_helper(s.m_gencpp,s.m_os)
+ , m_typeref(s.m_typeref) {}
+ public:
+ cghpph_typeref(generate_header &g,std::ostream &os,asn1::typeref &s) ;
+ ~cghpph_typeref();
+
+ // Helper functions
+ virtual void generate() ;
+
+ void gen_printf(const std::string &scope);
+ // generate codec part
+ virtual void generate_per() ;
+ //
+ virtual void generate_ber() ;
+ //
+ virtual void generate_oer() ;
+ //
+ virtual void generate_jer() ;
+ //
+ virtual void generate_xer() ;
+ protected:
+ virtual void generate_prolog() ;
+ virtual void generate_ctors() ;
+ virtual void generate_operators() ;
+ protected:
+ // Internal generation functions
+ void generate_simple() ;
+ void gen_simple_ctors() ;
+ void generate_external_type() {} ;
+ void generate_external_value() {} ;
+ // This method will be used to deal with
+ // TYPE-IDENTIFIER and OBJECT CLASS
+ void generate_objectclass() ;
+ void gen_objectclass_ctors() {} ;
+ protected:
+ asn1::typeref &m_typeref;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <assert.h>
+#include <string>
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_hpp.h"
+#include "asn1_generator_helper.h"
+#include "cgcpp_helper.h"
+#include "cghpph_value.h"
+
+
+cghpph_value::cghpph_value( generate_header &g
+ , std::ostream &os
+ , asn1::value &s)
+ : m_Gen(g)
+ , generator_helper(os)
+ , m_value(s)
+ , m_log(g.logger())
+{
+}
+
+cghpph_value::~cghpph_value()
+{
+}
+
+
+/** Helper functions
+ *
+ * It seems that the choice does not always have an identifier. Examples
+ * - SEQUENCE OF CHOICE {}
+ * - Test ::= CHOICE { toto INTEGER, CHOICE { } }
+ * these sequences are anonymous definitions ...
+ */
+void cghpph_value::generate()
+{
+ asn1::node *n = m_value.identifier();
+ asn1::node *type = &m_value;
+ asn1::node *params = NULL;
+ std::string structName;
+ std::string scope("");
+
+ if (m_Gen.with_source_comment())
+ m_os<<"// cghpph_value helper launched "<<std::endl;
+
+}
+
+//
+void cghpph_value::gen_printf()
+{
+}
+
+// generate codec part
+void cghpph_value::generate_per()
+{
+}
+
+//
+void cghpph_value::generate_ber()
+{
+}
+
+//
+void cghpph_value::generate_oer()
+{
+}
+
+//
+void cghpph_value::generate_jer()
+{
+}
+
+//
+void cghpph_value::generate_xer()
+{
+}
--- /dev/null
+#ifndef CGHPPH_VALUE_H
+#define CGHPPH_VALUE_H
+
+
+/**
+ *
+ */
+class cghpph_value : public generator_helper
+{
+ protected:
+ cghpph_value(const cghpph_value &s) : generator_helper(s.m_os)
+ , m_Gen(s.m_Gen)
+ , m_log(s.m_log)
+ , m_value(s.m_value) {}
+ public:
+ cghpph_value(generate_header &g,std::ostream &os,asn1::value &s) ;
+ ~cghpph_value();
+
+ // Helper functions
+ virtual void generate() ;
+
+ // generate codec part
+ virtual void generate_per() ;
+ //
+ virtual void generate_ber() ;
+ //
+ virtual void generate_oer() ;
+ //
+ virtual void generate_jer() ;
+ //
+ virtual void generate_xer() ;
+ protected:
+ void gen_printf();
+ protected:
+ std::fstream &m_log;
+ generate_header &m_Gen;
+ asn1::value &m_value;
+};
+
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <cassert>
+#include "asn1_generator.h"
+#include "asn1_gen_js.h"
+#include "asn1_visitor.h"
+
+/**
+ * Default Cosntructor
+ */
+generate_js::generate_js(asn1::module *n) : asn1::generator(n)
+{}
+
+generate_js::generate_js(asn1::module *n,asn1::module::modules_type &m)
+ : asn1::generator(n,m)
+{
+}
+
+/**
+ * Helper function to look for missing prototypes
+ */
+void generate_js::gen_missing(std::ostream &os,asn1::node *n)
+{
+ asn1::node::iterator it;
+ //= std::find_if(m_module->begin(),m_module->end(),asn1::find_node(n->name()));
+ switch (n->type_id()())
+ {
+ case asn1::type::ASN1_SEQUENCE_OF:
+ case asn1::type::ASN1_SET_OF:
+ {
+#ifdef DEBUG
+ std::cout<<"Find sequence of or set of:\n";
+#endif
+ asn1::node *type = n->as_typenode()->get_eltype();
+ if (type !=NULL)
+ {
+ if (asn1::typeref *tref = type->as_typeref())
+ {
+ it = std::find_if(m_module->begin(),
+ m_module->end(),
+ asn1::find_node(tref->get_reference()->name()));
+ } else
+ it = std::find_if(m_module->begin(),
+ m_module->end(),
+ asn1::find_node(type->name()));
+ } else return;
+
+ }
+ break;
+ case asn1::type::ASN1_SEQUENCE:
+ case asn1::type::ASN1_CHOICE:
+ {
+ asn1::constructed *cons = n->as_constructed();
+#if 1
+ std::cout<<"generate_js::"<<__FUNCTION__<<" Find choice or sequence :\n";
+ asn1::node::iterator lit = cons->begin();
+ for (; lit != cons->end() ; lit++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*lit);
+ if (asn1::typenode *tn = f->get_type()) {
+ gen_missing(os,tn);
+ }
+ }
+#endif
+ }
+ return;
+ break;
+ case asn1::type::ASN1_NULL:
+ return;
+ case asn1::type::ASN1_REFERENCE:
+ {
+ asn1::typeref *tref = n->as_typeref();
+ // Try to check references
+ if (n->parameters() != NULL)
+ {
+ asn1::constructed *params = n->parameters();
+ std::cout<<"generate_js::"<<__FUNCTION__<<" Have parameters\n";
+ for(asn1::node::iterator p = params->begin(); p != params->end() ;++p)
+ {
+ std::cout<<"generate_js::"<<__FUNCTION__<<" Parameter:"<<(*p)->name()<<"\n";
+ it = std::find_if(m_module->begin(),m_module->end(),asn1::find_node((*p)->name()));
+
+ if (it != m_module->end())
+ gen_missing(os,(*it));
+ }
+ }
+ //
+ if (tref->get_reference())
+ {
+ if (std::string("TYPE-IDENTIFIER::&Type").compare(tref->get_reference()->name()) == 0)
+ {
+ asn1::constraint::iterator c = tref->constraint_begin();
+ if ((*c)->type() == asn1::constraint::EL_TYPE)
+ {
+ asn1::node *ctype = (*c)->value();
+ it = std::find_if(m_module->begin(),
+ m_module->end(),
+ asn1::find_node(ctype->name()));
+ }
+ } else {
+ it = std::find_if(m_module->begin(),
+ m_module->end(),
+ asn1::find_node(tref->get_reference()->name()));
+ }
+
+ } else
+ {
+ it = std::find_if(m_module->begin(),m_module->end(),asn1::find_node(n->name()));
+
+ }
+ }
+ break;
+ default:
+ it = std::find_if(m_module->begin(),m_module->end(),asn1::find_node(n->name()));
+ }
+// Found a element to be generated
+ if ( it != m_module->end())
+ {
+ asn1::assignment *ltype = (*it)->as_assignment();
+ if ( (ltype->is_generated() != true))
+ {
+ if (ltype->get_color() == asn1::node::CL_GREEN)
+ {
+ ltype->set_generated(true);
+ std::cout<<" gen minssing:"<<ltype->name()<<std::endl;
+ switch(ltype->get_type()->type_id()())
+ {
+ case asn1::type::ASN1_REFERENCE:
+ gen_typeref(os,ltype->get_type()->as_typeref());
+ break;
+ default:
+ gen_typedef(os,ltype->get_type());
+ }
+ ltype->set_color(asn1::node::CL_RED);
+ } else if (ltype->get_color() == asn1::node::CL_ORANGE)
+ {
+ if (ltype->get_type()->type_id()() == asn1::type::ASN1_SEQUENCE ||
+ ltype->get_type()->type_id()() == asn1::type::ASN1_CHOICE
+ )
+ os<<"struct "<<ltype->cpp_name()<<";"<<std::endl;
+ ltype->set_generated(true);
+ }else {
+ ltype->set_generated(true);
+ }
+ }
+ }
+}
+
+/**
+ *
+ *
+ */
+void generate_js::gen_const(std::ostream &os,asn1::node *type)
+{
+ switch(type->type_id()())
+ {
+ case asn1::type::ASN1_OBJECT_IDENTIFIER:
+ {
+ os<<"struct "<<type->identifier_cpp_name();
+ os<<" : public OBJECT_IDENTIFIER {";
+ //gen_oid_value(os,type->identifier());
+ os<<std::endl;
+ }
+ break;
+ case asn1::type::ASN1_VALUESET:
+ {
+ }
+ break;
+ case asn1::type::ASN1_INTEGER:
+ {
+ os<<" #define "<<type->identifier_cpp_name();
+ os<<"\t "<<type->cpp_name()<<"";
+ }
+ break;
+ default:
+ std::cout<<" DEFAULT"; std::cout.flush();
+ os<<" const "<<type->identifier_cpp_name()<<"\t\t= "<<type->cpp_name()<<";";
+ ;
+ }
+ os<<std::endl;
+
+}
+
+/**
+ *
+ *
+ */
+void
+generate_js::gen_enumerated_printf( std::ostream &os,asn1::enumerated &n
+ , const std::string &name)
+{
+ std::string indent("");
+ asn1::node::iterator it = n.begin();
+ os<<indent<<"\tprintf : function() ";
+ os<<"{\n";
+
+ for (; it != n.end(); it++)
+ {
+ if (asn1::valuetype *vt = dynamic_cast<asn1::valuetype *>(*it))
+ {
+ os<<"\telse if (this.m_value == this.e"<<name<<"."<<(*it)->cpp_name()<<")\n";
+ os<<"\t\tError(\""<<(*it)->cpp_name()<<"\");\n";
+ } else
+ {
+ os<<"\tif (this.m_value === this.e"<<name<<"."<<(*it)->cpp_name()<<")\n";
+ os<<"\t\tError(\""<<(*it)->cpp_name()<<"\");\n";
+ }
+
+ }
+ os<<"\tError(\"(\"+this.m_value+\")\");\n";
+ // os<<"\t\treturn os;\n";
+ os<<"\t}\n";
+
+}
+
+/**
+ *
+ *
+ */
+void generate_js::gen_enumerated( std::ostream &os,asn1::enumerated &_enum
+ , const std::string &name)
+{
+ asn1::enumerated *enumtype = &_enum;
+ assert(enumtype != NULL);
+ std::string indent("");
+ asn1::node::iterator it = enumtype->begin();
+
+ os<<"AEBW.declare(\""<<m_module->cpp_name()<<"."<<name<<"\",AEBW.Asn1, { ";
+ //os<<indent<<"struct "<<name<<" {\n";
+ os<<indent<<"\tconstructor : "<<"function () {this.m_value = ";
+ os<<(*it)->cpp_name()<<" ;},\n";
+ os<<indent<<"\tencode_ber : function(ctx,Stream) ,\n";
+ os<<indent<<"\te"<<name<<": {\n";
+ for (; it != _enum.end(); it++)
+ {
+ if (it != _enum.begin() )
+ os<<",\n";
+ os<<indent<<"\t\t"<<(*it)->cpp_name()<<" : ";
+
+ }
+ os<<"\n"<<indent<<"\t},\n";
+ gen_enumerated_printf(os,_enum,name);
+ os<<indent<<"\n});\n";
+}
+
+//
+// gen_typeref
+//
+void generate_js::gen_typeref(std::ostream &os,asn1::typeref *type)
+{
+ std::string type_name;
+
+ if (type )
+ {
+ std::cout<<"generate_js::"<<__FUNCTION__<<" "<<type->identifier_name();
+ std::cout<<" id="<<type->type_id()()<<" ";
+
+ if (type != NULL)
+ {
+ std::cout<<" typenode is "<<type->name()<<" ";
+ } else
+ {
+ std::cout<<" typenode is NULL ERROR";
+ std::cerr<<"generate_js::"<<__FUNCTION__<<" type is null\n";
+ exit(0);
+ }
+ if (type->parameters() != NULL){
+ std::cout<<" parameterized ";
+ }
+ std::cout<<std::endl;
+ }
+ if (type->get_reference()) {
+ type_name = type->cpp_name();
+ } else {
+ type_name = type->cpp_name();
+ }
+ if (type->type_id()() != asn1::type::ASN1_REFERENCE)
+ {
+ std::cout<<__FUNCTION__<<"ERROR "<<type->cpp_name()<<" type="<<type->type_id()();
+ exit(0);
+ }
+
+
+ gen_missing(os,type);
+ asn1::node *ns = NULL;
+ os<<"AEBW.declare(\""<<m_module->cpp_name()<<"."<<type->identifier_cpp_name()<<"\",";
+ os<<m_module->cpp_name()<<"."<<type_name<<",null);\n";
+}
+
+
+//
+//
+//
+void generate_js::gen_typedef(std::ostream &os,asn1::typenode *type)
+{
+ if (type )
+ {
+ std::cout<<"gen_typedef : "<<type->identifier_name();
+ std::cout<<" id="<<type->type_id()()<<" ";
+ if (type != NULL)
+ {
+ std::cout<<" typenode is "<<type->name()<<" ";
+ } else
+ {
+ std::cout<<" typenode is NULL ";
+ }
+ std::cout<<std::endl;
+ os<<"\n";
+ }
+
+ if (type != NULL)
+ switch (type->type_id()())
+ {
+ case asn1::type::ASN1_REFERENCE:
+ {
+ std::cout<<"__FUNCTION__"<<" ERROR "<<type->cpp_name()<<std::endl;
+ exit(0);
+
+ }
+ break;
+ case asn1::type::ASN1_INTEGER:
+ {
+ if (type->tagged() )
+ {
+ os<<"AEBW.declare(\""<<m_module->cpp_name()<<"."<<type->cpp_name()<<"\",AEBW.Asn1.Integer,null);\n ";
+
+ } else {
+ os<<"AEBW.declare(\""<<m_module->cpp_name()<<"."<<type->identifier_cpp_name()<<"";
+ os<<"\",AEBW.Asn1.Integer,null);\n";
+ }
+ return ;
+ }
+ break;
+ case asn1::type::ASN1_SEQUENCE:
+ {
+ asn1::sequence *seqtype = dynamic_cast<asn1::sequence *>(type);
+ std::string scope("");
+ asn1::node::iterator lit = seqtype->begin();
+ for (; lit != seqtype->end() ; ++lit)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*lit);
+ if ( f->get_type() != NULL) {
+ gen_missing(os,f->get_type());
+ }
+ }
+ gen_seq(os,scope,seqtype);
+ os<<"\n";
+ return ;
+ }
+ break;
+ case asn1::type::ASN1_SEQUENCE_OF:
+ {
+ asn1::node *ns = NULL;
+ asn1::typenode *sty =type->get_eltype();
+ gen_missing(os,sty);
+ if (type_in_imports(sty,&ns) )
+ {
+ os<<"AEBW.declare(\""<<m_module->cpp_name();
+ os<<"."<<type->identifier_cpp_name()<<"\",AEBW.Asn1.SequenceOf /*";
+ os<<"\t"<<ns->cpp_name()<<".";
+ os<<sty->cpp_name()<<"*/,null) ";
+ } else {
+ switch (sty->type_id()())
+ {
+ case asn1::type::ASN1_SEQUENCE:
+ {
+ std::string scope("\t");
+
+ sty->name(type->identifier_cpp_name()+"_type");
+ gen_seq(os,scope,sty->as_sequence());
+ }
+ break;
+ default:
+ if (asn1::typeref *tref = sty->as_typeref())
+ {
+ os<<"AEBW.declare(\""<<m_module->cpp_name();
+ os<<"."<<type->identifier_cpp_name();
+ os<<"\",AEBW.Asn1.SequenceOf/*";
+ os<<tref->get_reference()->cpp_name()<<"*/,null); ";
+ } else
+ {
+ os<<"AEBW.declare(\""<<m_module->cpp_name();
+ os<<"."<<type->identifier_cpp_name();
+ os<<"\",AEBW.Asn1.SequenceOf /*"<<sty->cpp_name();
+ os<<"*/,null); ";
+ }
+ }
+ }
+ }
+ break;
+ case asn1::type::ASN1_SET:
+ {
+ asn1::set *settype = dynamic_cast<asn1::set *>(type);
+ asn1::node::iterator lit = settype->begin();
+ for (; lit != settype->end() ; lit++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*lit);
+ if ( f->get_type() != NULL) {
+ gen_missing(os,f->get_type());
+ }
+ }
+ gen_set(os,settype->identifier());
+ os<<";\n";
+ return ;
+ }
+ break;
+ case asn1::type::ASN1_SET_OF:
+ {
+ asn1::typenode *subtype =type->get_eltype();
+ gen_missing(os,subtype);
+ if (asn1::typeref *tref = subtype->as_typeref())
+ {
+ os<<"typedef SET_OF<"<<tref->get_reference()->name()<<"> ";
+ } else
+ {
+ os<<"typedef SET_OF<"<<subtype->cpp_name()<<"> ";
+ }
+ }
+ break;
+ case asn1::type::ASN1_CHOICE:
+ {
+ asn1::choice *ch = dynamic_cast<asn1::choice *>(type);
+ asn1::node::iterator lit = ch->begin();
+ for (; lit != ch->end() ; lit++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*lit);
+ if ( f->get_type() != NULL) {
+ gen_missing(os,f->get_type());
+ }
+ }
+ gen_choice(os,*ch);
+ os<<";\n";
+ return;
+ }
+ break;
+ case asn1::type::ASN1_ENUMERATED:
+ {
+ //os<<"typedef ";
+ gen_enumerated( os
+ , *type->as_enumerated()
+ , type->identifier_cpp_name());
+ }
+ break;
+ ;
+ case asn1::type::ASN1_BIT_STRING:
+ {
+ std::cerr<<__FUNCTION__<<" BIT_STRING TODO"<<std::endl;
+ return ;
+ }
+ break;
+ default:
+ gen_missing(os,type);
+ asn1::node *ns = NULL;
+ os<<"AEBW.declare(\""<<m_module->cpp_name()<<"."<<type->identifier_cpp_name()<<"";
+ //os<<"typedef ";
+ if (type_in_imports(type,&ns) ) {
+ os<<"\","<<ns->cpp_name()<<"."<<type->cpp_name()<<",null);\n";
+ } else {
+ os<<"\","<<type->cpp_name()<<",null/* default case*/);\n";
+ }
+ return;
+ ;
+ };
+
+
+}
+
+/**
+ *
+ */
+void generate_js::gen_seq_printf(std::ostream &os,std::string &scope,asn1::sequence *type,bool priv)
+{
+ os<<scope<<"\tprintf : function() {\n";
+ os<<scope<<"\t}\n";
+
+}
+/**
+ *
+ */
+void generate_js::gen_seq( std::ostream &os
+ , std::string &scope
+ , asn1::sequence *type,bool priv)
+{
+ asn1::node *n = type->identifier();
+ asn1::node::iterator lit = type->begin();
+ asn1::constructed *params = n->parameters();
+ m_Stack.push_back(n->cpp_name());
+ assert(type != NULL);
+
+ // default constructor
+ // I should probaly push optionnal attributes and OBEJECTS in a stack and add a initializer here.
+ std::vector<asn1::node *> opt_attrs;
+ for (asn1::node::iterator it = type->begin(); it != type->end() ; it++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*lit);
+ asn1::typenode *attr_type = f->get_type();
+ if (attr_type != NULL)
+ {
+ asn1::typeref *tref = attr_type->as_typeref();
+ if ( tref && tref->is_complex())
+ {
+ asn1::reference *r = tref->get_reference();
+ std::string lr = r->back().m_identifier;
+ opt_attrs.push_back((*it));
+ }
+ }
+
+ }
+ os<<scope<<"AEBW.declare(\""<<m_module->cpp_name()<<".";
+ os<<n->cpp_name()<<"\",AEBW.Asn1.Sequence, {\n";
+ // Constructor
+ os<<scope<<"\tconstructor : function "<<"()";
+ os<<" {\n";
+ if (opt_attrs.size() == 1)
+ {
+ os<<"\t\t"<<opt_attrs[0]->cpp_name()<<": \"\"";
+ } else if (opt_attrs.size() > 1)
+ {
+ }
+
+ os<<"\t},\n";
+ // Copy constructor
+ os<<scope<<"\tencode_ber : function(ctx,s";
+ os<<") {},\n";
+
+
+ for (; lit != type->end() ; lit++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*lit);
+ asn1::typenode *attr_type = f->get_type();
+ if (! f->is_extensible())
+ gen_composite_attribute(os,scope,f,n->parameters());
+ }
+
+ gen_seq_printf(os,scope,type,priv);
+ // What is scope for here ?
+ os<<scope<<"});\n ";
+ m_Stack.pop_back();
+}
+
+
+//
+//
+//
+void generate_js::gen_template_params(std::ostream &os,asn1::node *_params)
+{
+ asn1::constructed *params = dynamic_cast<asn1::constructed *>(_params);
+ asn1::node::node_list nl;
+
+ os<<"<";
+ for(asn1::node::iterator p = params->begin(); p != params->end() ;++p)
+ {
+ if (nl.size()>0)
+ {
+ asn1::node::iterator it = std::find_if(nl.begin(),nl.end(),asn1::find_node((*p)->name()));
+ if (it != nl.end() )
+ {
+ //
+ } else {
+ if (p != params->begin()) os<<",";
+ os<<" "<<(*p)->cpp_name();
+ nl.push_back(*p);
+ }
+ } else {
+ if (p != params->begin()) os<<",";
+ os<<" "<<(*p)->cpp_name();
+ nl.push_back(*p);
+ }
+ }
+ os<<"> ";
+}
+//
+//
+//
+void generate_js::gen_template_signature(std::ostream &os,asn1::node *_params)
+{
+ asn1::constructed *params = dynamic_cast<asn1::constructed *>(_params);
+ asn1::node::node_list nl;
+
+ os<<"<";
+ for(asn1::node::iterator p = params->begin(); p != params->end() ;++p)
+ {
+ if (nl.size()>0)
+ {
+ asn1::node::iterator it = std::find_if(nl.begin(),nl.end(),asn1::find_node((*p)->name()));
+ if (it != nl.end() )
+ {
+ //
+ } else {
+ if (p != params->begin()) os<<",";
+ os<<" typename "<<(*p)->cpp_name();
+ nl.push_back(*p);
+ }
+ } else {
+ if (p != params->begin()) os<<",";
+ os<<" typename "<<(*p)->cpp_name();
+ nl.push_back(*p);
+ }
+ }
+ os<<"> ";
+}
+
+/**
+ *
+ *
+ */
+void generate_js::gen_choice_printf(std::ostream &os,asn1::choice *type)
+{
+ asn1::node *n= type->identifier();
+ os<<"\tprintf : function() {";
+ os<<"\n\t},\n";
+}
+
+/**
+ *
+ *
+ */
+void generate_js::gen_choice(std::ostream &os,asn1::choice &_type)
+{
+ std::string scope("");
+ asn1::choice *type = &_type;
+ asn1::node *n= type->identifier();
+ assert(type != NULL);
+ m_Stack.push_back(n->cpp_name());
+ std::cout<<"generate_js::gen_choice"<<std::endl;
+
+ os<<"AEBW.declare(\""<<m_module->cpp_name()<<"."<<n->cpp_name()<<"\",AEBW.Asn1.Choice,{\n";
+ os<<"\tconstructor : function() {\n";
+ os<<"\t\tthis.kind_ = 0;},\n";
+ os<<"\tencode_ber : function(ctx,";
+ // Parameter stuff here
+ if (n->parameters() && is_template(n->parameters()))
+ {
+ gen_template_params(os,n->parameters());
+ }
+ os<<" Stream"<<") {\n";
+ os<<"\t},\n";
+ gen_choice_printf(os,type);
+ // == operator
+ //
+ asn1::node::iterator it;
+ it = type->begin();
+ for (; it != (type)->end() ; it++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*it);
+ asn1::typenode *attr_type = f->get_type();
+ if (! f->is_extensible())
+ gen_composite_attribute(os,scope,f,n->parameters());
+
+ }
+ // Now add an enum tu identifie type
+ os<<"\tenums : { ";
+ asn1::node::iterator lit;
+ lit = type->begin();
+ int count = 0;
+ for (; lit != (type)->end() ; lit++)
+ {
+ os<<" typeof_"<<(*lit)->cpp_name()<<": "<<count++<<" , ";
+ }
+
+ os<<"typeof_end : "<<count<<"}"<<std::endl;
+
+ os<<"}); ";
+ m_Stack.pop_back();
+}
+
+void
+generate_js::gen_composite_attribute_ref( std::ostream &os
+ , std::string &scope
+ , asn1::typeref *attribute
+ , asn1::node *_params)
+{
+ asn1::constructed *params = dynamic_cast<asn1::constructed *>(_params);
+ asn1::reference *ref = attribute->get_reference();
+
+ if (ref->size() > 1)
+ {
+ // find the object and folow the links ....
+ std::string rname = ref->back().m_identifier;
+ os<<"\tasn1::Object * /* GCAT "<<rname<<"*/ ";
+ } else {
+ // easy case
+ asn1::node::iterator refm = std::find_if(m_module->begin(),
+ m_module->end(),
+ asn1::find_node(ref->name()));
+ if (refm != m_module->end())
+ {
+ // Here I have the type definition. I should add
+ os<<"\t"<<ref->cpp_name();
+ if (attribute->parameters()!= NULL)
+ {
+ os<<"<";
+ for (asn1::node::iterator it = attribute->parameters()->begin();
+ it != attribute->parameters()->end(); ++it)
+ {
+ if (it != attribute->parameters()->begin())
+ os<<",";
+ os<<(*it)->cpp_name();
+ }
+ os<<">";
+ }
+ os<<" /*NR c="<<(*refm)->get_color()<<"*/ ";
+ } else
+ {
+ asn1::node *ns = NULL;
+ if (type_in_imports(ref->name(),&ns) ) {
+ asn1::reference::component_const_iterator compit = ref->begin();
+ // Check first element of reference
+ if ( (*compit).type == asn1::reference::component::CAPITALS)
+ {
+ os<<"\t/* GCAT */"<<ns->cpp_name()<<"::"<<ref->name()<<" ";
+ } else
+ os<<"\t"<<ns->cpp_name()<<"::"<<ref->cpp_name()<<" /*NR 2*/ ";
+ // check if attribute has parameters
+ if (attribute->parameters() != NULL)
+ {
+ os<<"<";
+ for (asn1::node::iterator it = attribute->parameters()->begin(); it != attribute->parameters()->end(); ++it)
+ {
+ asn1::node *ns1 = NULL;
+ if (it != attribute->parameters()->begin())
+ os<<",";
+ // check namespace
+ if (type_in_imports((*it)->name(),&ns1) ) {
+ os<<ns1->cpp_name()<<"::"<<(*it)->cpp_name();
+ } else
+ os<<(*it)->cpp_name();
+ }
+ os<<">";
+
+ }
+ } else if (params) // reference in parameters of definition
+ {
+ bool found = false;
+ for (asn1::node::iterator it = params->begin()
+ ; it != params->end(); ++it )
+ {
+ if (ref->name().compare((*it)->name())== 0)
+ {
+ os<<"\t"<<(*it)->cpp_name();
+ found = true;
+ }
+ if (!found)
+ os<<" ERRORNOTPARAMS ";
+
+ }
+
+ } else
+ {
+ os<<" ERROR ";
+ }
+ }
+
+ }
+}
+
+void
+generate_js::gen_composite_attribute( std::ostream &os
+ , std::string &scope
+ , asn1::field *attribute
+ , asn1::node *params)
+{
+ asn1::typenode *attr_type = attribute->get_type();
+ assert(attr_type != NULL);
+ if (attr_type != NULL)
+ {
+ switch (attr_type->type_id()())
+ {
+ case asn1::type::ASN1_ENUMERATED:
+ {
+ gen_enumerated( os
+ , *attr_type->as_enumerated()
+ , attribute->cpp_name()+"_t");
+ os <<attribute->cpp_name()<<";"<<std::endl;
+ }
+ break;
+ case asn1::type::ASN1_SET:
+ {
+ gen_set(os,attribute);
+ os<<"\t\t"<<attribute->cpp_name()<<";\n";
+ }
+ break;
+ case asn1::type::ASN1_CHOICE:
+ {
+ attr_type->name(attribute->cpp_name()+"_t");
+ //gen_choice(os,attr_type);
+ os<<"\t\t"<<attribute->cpp_name()<<": \"\",\n";
+ }
+ break;
+ case asn1::type::ASN1_SEQUENCE:
+ {
+ std::string scope("\t");
+ attribute->get_type()->name(attribute->cpp_name()+"_t");
+
+ os<<"\t\t"<<(attribute)->cpp_name()<<" : \"\",\n";
+ }
+ break;
+ case asn1::type::ASN1_SELECTION:
+ {
+ os<<"\t\tINTEGER "<<(attribute)->cpp_name();
+ os<<"; // SELECTION TO be done\n";
+ }
+ break;
+ case asn1::type::ASN1_SET_OF:
+ case asn1::type::ASN1_SEQUENCE_OF:
+ {
+ asn1::typenode *type = attribute->get_type();
+ asn1::typenode *subtype = type->get_eltype();
+
+ switch (subtype->type_id()())
+ {
+ case asn1::type::ASN1_SEQUENCE:
+ subtype->name((attribute)->cpp_name()+std::string("_type"));
+ gen_seq(os,scope,subtype->as_sequence(),true);
+ os<<";\n\t"<<type->name();
+ os<<"<"<<std::string( (attribute)->cpp_name()+"_type");
+ os<<">\t"<<(attribute)->cpp_name()<<";\n";
+ break;
+ default:
+ asn1::node *ns;
+ if (type_in_imports(subtype,&ns) )
+ {
+ os<<" "<<type->name()<<"<"<<ns->cpp_name();
+ os<<"::"<<subtype->cpp_name();
+ os<<">\t"<<(attribute)->cpp_name()<<";\n";
+ } else
+ {
+ if (asn1::typeref *tref = subtype->as_typeref())
+ {
+ os<<" "<<type->name()<<"<";
+ os<<(tref->get_reference())->cpp_name();
+ os<<">\t"<<(attribute)->cpp_name()<<";\n";
+ } else
+ os<<" "<<type->name()<<"<"<<subtype->cpp_name()<<">\t"<<attribute->cpp_name()<<";\n";
+ }
+ }
+ }
+ break;
+ case asn1::type::ASN1_REFERENCE:
+
+ {
+ os<<"\t"<<(attribute)->cpp_name()<<": \"\",";
+ os<<std::endl;
+ }
+ break;
+ default:
+ {
+ asn1::node *ns = NULL;
+ os<<"\t"<<(attribute)->cpp_name()<<": \"\",";
+ os<<"\n";
+ }
+ }
+ }
+}
+
+
+/**
+ *
+ */
+void generate_js::gen_set_printf(std::ostream &os,std::string &scope,asn1::node *n,bool priv)
+{
+ /*
+ * Try to handler sequence of sequence
+ */
+
+}
+
+
+/**
+ *
+ */
+void generate_js::gen_set(std::ostream &os,asn1::node *n)
+{
+ std::string scope("");
+}
+
+
+void generate_js::gen_object_class_opt(std::ostream &os,asn1::node *n)
+{
+}
+
+/**
+ *
+ *
+ */
+void generate_js::gen_object_class_missing(std::ostream &os,asn1::node *n)
+{
+}
+
+
+/**
+ *
+ *
+ */
+void generate_js::gen_object_class_interface(std::ostream &os,asn1::node *n)
+{
+}
+
+
+void generate_js::gen_object_class_attributes(std::ostream &os,asn1::node *n)
+{
+}
+
+
+void
+generate_js::gen_object_class_printf(std::ostream &os,asn1::node *n)
+{
+}
+/**
+ *
+ *
+ */
+void generate_js::gen_object_class(std::ostream &os,asn1::node *n)
+{
+}
+/**
+ *
+ *
+ */
+void generate_js::gen_object(std::ostream &os,asn1::node *n)
+{
+ os.flush();
+}
+
+/**
+ *
+ *
+ */
+void generate_js::gen_object_object_type(std::ostream &os,asn1::node *n)
+{
+}
+
+
+
+/**
+ *
+ *
+ */
+void generate_js::gen_object_error(std::ostream &os,asn1::node *n)
+{
+ std::cerr<<__FUNCTION__<<" To rewrite"<<std::endl;
+}
+
+
+void generate_js::gen_object_operation(std::ostream &os,asn1::node *n)
+{
+ std::cerr<<__FUNCTION__<<" To rewrite"<<std::endl;
+}
+
+/**
+ *
+ *
+ */
+void generate_js::gen_object_operation_package(std::ostream &os,asn1::node *n)
+{
+}
+
+void generate_js::gen_object_connection(std::ostream &os,asn1::node *n)
+{
+}
+
+
+class do_assignment : public assignment_visitor<do_assignment>
+{
+ protected:
+ generate_js &m_js;
+ std::ostream &m_os;
+ public:
+ do_assignment(generate_js &_js,std::ostream &os)
+ : m_os(os),m_js(_js) {};
+
+ void visit_type(asn1::type_assignment *type)
+ {
+ m_js.gen_typedef(m_os,type->get_type());
+ }
+ void visit_value(asn1::value_assignment *type)
+ {
+ m_js.gen_const(m_os ,type->get_type());
+ }
+#if 0
+ void visit_valueset(asn1::valueset_assignment *type)
+ {
+ }
+ void visit_objectclass(asn1::objectclass_assignment *type)
+ {
+ }
+#endif
+ void visit_object(asn1::object_assignment *type)
+ {
+ m_js.gen_object(m_os,type->get_type());
+ }
+ void visit_typeref(asn1::typeref_assignment *type)
+ {
+ m_js.gen_typeref(m_os,type->get_type()->as_typeref());
+ }
+ void visit_assignment(asn1::assignment *type)
+ {
+ std::cout<<__FUNCTION__<<" Unhandled assignment "<<type->name()<<std::endl;
+ m_os<<"//"<<__FUNCTION__<<" Unhandled assignment "<<type->name()<<std::endl;
+ }
+};
+
+/**
+ *
+ */
+void generate_js::gen_module(std::ostream &os,asn1::module *_module)
+{
+ asn1::import_list *imports = _module->imports();
+ // Add include for external dependencies
+
+ os<<"if ( ! "<<_module->cpp_name()<<")\n {\n"<<std::endl;
+ _module->sort_childs();
+
+ for ( asn1::node::iterator it = _module->begin()
+ ; it != _module->end() ; it++)
+ {
+ asn1::assignment *type = (*it)->as_assignment();
+ std::cout<<"generate_js::"<<__FUNCTION__<<" process "<<type->name();
+ std::cout.flush();
+ if (type->get_type() != NULL)
+ {
+ if ( type->is_generated())
+ {
+ std::cout<<" ALREADY GENERATED "<<std::endl;
+ continue;
+ }
+ do_assignment doa(*this,os);
+ if (type)
+ {
+ doa.visit(type);
+ } else
+ std::cout<<__FUNCTION__<<" Type "<<type->name()<<" is NULL"<<std::endl;
+ os<<std::endl;
+ type->set_color(asn1::node::CL_RED);
+ } else
+ {
+ std::cout<<" no type "<<type->name();
+ os<<"// "<<__FUNCTION__<<" no type "<<type->name();
+ }
+ os<<std::endl;
+ std::cout<<std::endl;
+ }
+ os<<"}"<<std::endl;
+}
+
+/**
+* vim:et:sw=2:ts=2
+*/
--- /dev/null
+#ifndef GEN_HEADER_JS_H__
+#define GEN_HEADER_JS_H__
+#include <iostream>
+#include <algorithm>
+
+
+/**
+ *
+ */
+class generate_js : public asn1::generator
+{
+ public:
+
+ generate_js(asn1::module *n);
+
+ generate_js(asn1::module *n,asn1::module::modules_type &m);
+
+
+ void gen_missing(std::ostream &os,asn1::node *n) ;
+
+ /**
+ *
+ *
+ */
+ void gen_const(std::ostream &os,asn1::node *n);
+
+ void gen_enumerated_printf( std::ostream &os
+ , asn1::enumerated &n
+ , const std::string &name);
+ void gen_enumerated(std::ostream &os,asn1::enumerated &n ,const std::string &name);
+ //
+ //
+ //
+ void gen_typedef(std::ostream &os,asn1::typenode *n);
+ void gen_typeref(std::ostream &os,asn1::typeref *n);
+
+ void gen_seq_printf( std::ostream &os
+ , std::string &scope
+ , asn1::sequence *type,bool priv =false);
+ /**
+ *
+ */
+ void gen_seq( std::ostream &os,std::string &scope
+ , asn1::sequence *n,bool priv = false);
+
+ void gen_choice_printf(std::ostream &os,asn1::choice *n);
+
+ void gen_choice(std::ostream &os,asn1::choice &choice);
+
+ void gen_composite_attribute( std::ostream &os
+ , std::string &scope
+ , asn1::field *attribute,asn1::node *params = NULL);
+ void gen_composite_attribute_ref( std::ostream &os
+ , std::string &scope
+ , asn1::typeref *attribute
+ , asn1::node *params = NULL);
+ void gen_template_params(std::ostream &os,asn1::node *params);
+ void gen_template_signature(std::ostream &os,asn1::node *params);
+
+ /**
+ *
+ */
+ void gen_set(std::ostream &os,asn1::node *n);
+ void gen_set_printf(std::ostream &os,std::string &scope,asn1::node *n,bool priv =false);
+
+ /*
+ * Ros generation Code
+ */
+ void gen_object_class(std::ostream &os,asn1::node *n);
+ void gen_object_class_interface(std::ostream &os,asn1::node *n);
+ void gen_object_class_missing(std::ostream &os,asn1::node *n);
+ void gen_object_class_opt(std::ostream &os,asn1::node *n);
+ void gen_object_class_attributes(std::ostream &os,asn1::node *n);
+
+ void gen_object_class_printf(std::ostream &os, asn1::node *n);
+
+ void gen_object(std::ostream &os,asn1::node *n);
+ void gen_object_object_type(std::ostream &os,asn1::node *n);
+ void gen_object_error(std::ostream &os,asn1::node *n);
+ void gen_object_operation(std::ostream &os,asn1::node *n);
+ void gen_object_operation_package(std::ostream &os,asn1::node *n);
+ void gen_object_connection(std::ostream &os,asn1::node *n);
+ /**
+ *
+ */
+ void gen_module(std::ostream &os,asn1::module *n);
+ protected:
+ std::vector<std::string> m_Stack;
+};
+/**
+ * vim:et:sw=2:ts=2
+ */
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <list>
+#include <assert.h>
+
+#include "asn1_generator.h"
+#include "asn1_gen_lds.h"
+#include "adt/asn1_visitor.h"
+
+
+
+
+/**
+ * Default constructor to be used
+ */
+generate_lds::generate_lds(asn1::module *n,asn1::module::modules_type &m)
+ : generator(n,m)
+{
+}
+
+
+
+/**
+*
+*
+*/
+void
+generate_lds::gen_const(std::ostream &os,asn1::node *n)
+{
+}
+
+
+/**
+ *
+ */
+void
+generate_lds::gen_enumerated( std::ostream &os
+ , asn1::enumerated &_enum
+ )
+{
+}
+
+
+class dolds_typedef : public node_visitor<dolds_typedef>
+{
+ protected:
+ generate_lds &m_gen;
+ std::ostream &m_os;
+ std::fstream &m_log;
+
+ public:
+ dolds_typedef(std::ostream &_os,generate_lds &_gen)
+ : m_os(_os) , m_gen(_gen)
+ , m_log(_gen.logger())
+ {
+ }
+#define DO_TYPEDEF(Tp,Code) \
+ void visit_##Tp(asn1::Tp *type) \
+ Code
+
+ void visit_primitive(asn1::primitive *type)
+ {
+ m_os<<"string "<<type->identifier_name()<<";"<<std::endl;
+ }
+DO_TYPEDEF(boolean,{
+ // Try to create an include file
+ GEN_LOG_DEBUG( "visit_boolean %s \n"
+ , type->identifier_name().c_str());
+ m_os<<"boolean "<<type->identifier_name()<<";"<<std::endl;
+ })
+DO_TYPEDEF(integer,{
+ // Try to create an include file
+ GEN_LOG_DEBUG( "visit_integer %s \n"
+ , type->identifier_name().c_str());
+ m_os<<"integer "<<type->identifier_name()<<";"<<std::endl;
+ })
+DO_TYPEDEF(choice,{
+ // Try to create an include file
+ GEN_LOG_DEBUG( "visit_choice %s \n"
+ , type->identifier_name().c_str());
+ m_os<<"value type "<<type->identifier_name()<<" { choice"<<std::endl;
+ for (asn1::node::iterator it = type->begin(); it != type->end() ; it++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*it);
+ asn1::typenode *attr_type = f->get_type();
+ if (attr_type != NULL)
+ {
+ if (attr_type->type_id()() == asn1::type::ASN1_EXTENSIBLE)
+ {
+ m_os<<"\t// Extensible marker"<<std::endl;
+ } else
+ {
+ m_os<<"\t"<<f->cpp_name()<<"\t"<<attr_type->cpp_name()<<";\n";
+ }
+ }
+ }
+ m_os<<" };"<<std::endl;
+ })
+
+DO_TYPEDEF(sequence,{
+ // Try to create an include file
+ GEN_LOG_DEBUG( "visit_sequence %s \n"
+ , type->identifier_name().c_str());
+ m_os<<"value type "<<type->identifier_name()<<" { struct"<<std::endl;
+ for (asn1::node::iterator it = type->begin(); it != type->end() ; it++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*it);
+ asn1::typenode *attr_type = f->get_type();
+ if (attr_type != NULL)
+ {
+ if (attr_type->type_id()() == asn1::type::ASN1_EXTENSIBLE)
+ {
+ m_os<<"\t// Extensible marker"<<std::endl;
+ } else
+ {
+ m_os<<"\t"<<f->cpp_name()<<"\t"<<attr_type->cpp_name()<<";\n";
+ }
+ }
+ }
+ m_os<<" };"<<std::endl;
+ })
+DO_TYPEDEF(set,{
+ // Try to create an include file
+ GEN_LOG_DEBUG( "visit_set %s \n"
+ , type->identifier_name().c_str());
+ m_os<<"value type "<<type->identifier_name()<<" { struct"<<std::endl;
+ for (asn1::node::iterator it = type->begin(); it != type->end() ; it++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*it);
+ asn1::typenode *attr_type = f->get_type();
+ if (attr_type != NULL)
+ {
+ if (attr_type->type_id()() == asn1::type::ASN1_EXTENSIBLE)
+ {
+ m_os<<"\t// Extensible marker"<<std::endl;
+ } else
+ {
+ m_os<<"\t"<<f->cpp_name()<<"\t"<<attr_type->cpp_name()<<";\n";
+ }
+ }
+ }
+ m_os<<" };"<<std::endl;
+ })
+DO_TYPEDEF(sequence_of,{
+ // Try to create an include file
+ asn1::typenode *seqof_type = type->get_eltype();
+ GEN_LOG_DEBUG( "visit_sequence_of %s \n"
+ , type->identifier_name().c_str());
+ m_os<<"value type "<<type->identifier_name()<<" inherits ";
+ m_os<<"Array <"<<","<<seqof_type->cpp_name()<<">;"<<std::endl;
+ })
+DO_TYPEDEF(octet_string,{
+ // Try to create an include file
+ GEN_LOG_DEBUG( "visit_octet_string %s \n"
+ , type->identifier_name().c_str());
+ m_os<<"octet_string "<<type->identifier_name()<<";"<<std::endl;
+ })
+DO_TYPEDEF(bit_string,{
+ // Try to create an include file
+ GEN_LOG_DEBUG( "visit_bit_string %s \n"
+ , type->identifier_name().c_str());
+ m_os<<"bitstring "<<type->identifier_name()<<";"<<std::endl;
+ })
+DO_TYPEDEF(enumerated,{
+ // Try to create an include file
+ GEN_LOG_DEBUG( "visit_enumerated %s \n"
+ , type->identifier_name().c_str());
+ m_os<<"enumerated "<<type->identifier_name()<<";"<<std::endl;
+ })
+};
+
+/**
+ * I think I should provide a visitor class for that
+ * function as well. For each type I have to decide what
+ * to generate.
+ */
+void
+generate_lds::gen_typedef(std::ostream &os,asn1::typenode *type)
+{
+ dolds_typedef dolds(os,*this);
+ os<<"\n/*\n * "<<type->identifier_name()<<"\n */\n";
+ dolds.visit(type);
+}
+
+
+/**
+ *
+ */
+void
+generate_lds::gen_typeref( std::ostream &os
+ , asn1::typeref &type)
+{
+ os<<"\n/*\n * "<<type.identifier_name()<<"\n * TODO\n */\n";
+ os<<"syntype "<<type.identifier_name()<<" = "<<type.cpp_name()<<" endsyntype "<<type.identifier_name()<<";\n";
+}
+
+
+/**
+*
+*/
+void
+generate_lds::gen_seq( std::ostream &os
+ , asn1::sequence &n)
+{
+}
+
+
+/**
+ *
+ */
+void
+generate_lds::gen_choice( std::ostream &os
+ , asn1::choice &choice)
+{
+}
+
+
+/**
+*
+*/
+void
+generate_lds::gen_set(std::ostream &os,asn1::set &n)
+{
+}
+
+
+/*
+* Ros generation Code
+*/
+void
+generate_lds::gen_object_class(std::ostream &os,asn1::classdef &n)
+{
+}
+
+
+/**
+ *
+ */
+void
+generate_lds::gen_object(std::ostream &os,asn1::object &n)
+{
+}
+
+/**
+* gen_module, main entry point. loops through imports and
+* then through assignments.
+*
+
+*/
+class dolds_assignment : public assignment_visitor<dolds_assignment>
+{
+ public:
+ dolds_assignment(std::ostream &_os,generate_lds &_gen)
+ : m_os(_os) , m_gen(_gen)
+ , m_log(_gen.logger())
+ {
+ }
+ // Main processing function per assignment
+ void operator ()(asn1::node *n)
+ {
+ asn1::typenode *type = n->as_assignment()->get_type();
+ std::string path = n->cpp_name()+".cpp";
+ GEN_LOG_DEBUG( "Process item=%s meta=%d\n"
+ , n->name().c_str()
+ , n->meta_id()());
+ if ( ! type)
+ return;
+
+ if ( n->is_generated())
+ {
+ GEN_LOG_DEBUG("%s already generated\n",n->name().c_str());
+ return;
+ }
+#if 0
+ if (m_gen.with_split_cpp())
+ m_gen.open_assignment_stream(m_sep_os,n->as_assignment());
+#endif
+ visit(n->as_assignment());
+#if 0
+ if (m_sep_os.is_open())
+ m_sep_os.close();
+#endif
+ n->set_color(asn1::node::CL_RED);
+ }
+#define ASSIGNMENT(En,Tp,Parent,Code) \
+ void visit_##Tp(asn1::Tp##_assignment *a) \
+ Code
+ASSIGNMENT(TYPEREF,typeref,assignment,{
+ int params = (a->parameters() != NULL)?1:0;
+ // Try to create an include file
+ GEN_LOG_DEBUG( "visit_Typeref %s parameterized: %d\n"
+ , a->name().c_str(),params);
+ m_gen.gen_typeref(m_os,*a->get_type()->as_typeref());
+ })
+ASSIGNMENT(TYPE,type,assignment,{
+ int params = (a->parameters() != NULL)?1:0;
+ // Try to create an include file
+ GEN_LOG_DEBUG( "visit_Type %s parameterized: %d\n"
+ , a->name().c_str(),params);
+ m_gen.gen_typedef(m_os,a->get_type());
+ })
+ASSIGNMENT(VALUE,value,assignment,{
+ std::cout<<__FUNCTION__<<" TODO "<<a->name()<<std::endl;
+ })
+ASSIGNMENT(VALUESET,valueset,assignment,{
+ std::cout<<__FUNCTION__<<" TODO "<<a->name()<<std::endl;
+ })
+ASSIGNMENT(OBJECT,object,assignment,{
+ std::cout<<__FUNCTION__<<" TODO "<<a->name()<<std::endl;
+ })
+ASSIGNMENT(OBJECTCLASS,objectclass,assignment,{
+ std::cout<<__FUNCTION__<<" TODO "<<a->name()<<std::endl;
+ })
+ASSIGNMENT(OBJECTSET,objectset,assignment,{
+ std::cout<<__FUNCTION__<<" TODO "<<a->name()<<std::endl;
+ })
+ASSIGNMENT(OBJECTFIELD,objectfield,assignment,{
+ std::cout<<__FUNCTION__<<" TODO "<<a->name()<<std::endl;
+ })
+
+ void visit_assignment(asn1::assignment *a)
+ {}
+#undef ASSIGNMENT
+
+ protected:
+ generate_lds &m_gen;
+ std::ostream &m_os;
+ std::fstream &m_log;
+};
+
+void
+generate_lds::gen_module(std::ostream &os,asn1::module *_module)
+{
+ asn1::module &_m = *_module;
+ _m.sort_childs();
+
+ dolds_assignment doa(os,*this);
+ for ( asn1::node::iterator it = _m.begin();
+ it != _m.end() ; it++)
+ {
+ doa.visit((*it)->as_assignment());
+ }
+}
+/*
+ * vim: et sw=2 ts=2 list:
+ */
--- /dev/null
+#ifndef GEN_HEADER_LDS_H__
+#define GEN_HEADER_LDS_H__
+#include <iostream>
+#include <algorithm>
+
+
+/**
+ * When calling the generator, the structure has already been flatten.
+ * There is no need to recurse over sub types and so on.
+ */
+class generate_lds : public asn1::generator
+{
+ public:
+
+
+ generate_lds(asn1::module *n,asn1::module::modules_type &m);
+
+ /**
+ *
+ */
+ void gen_const(std::ostream &os,asn1::node *n);
+
+
+ /**
+ *
+ */
+ void gen_typeref( std::ostream &os
+ , asn1::typeref &n);
+
+ /**
+ *
+ */
+ void gen_typedef(std::ostream &os,asn1::typenode *n);
+ /**
+ *
+ */
+ void gen_seq( std::ostream &os
+ , asn1::sequence &n);
+
+ /**
+ *
+ */
+ void gen_choice( std::ostream &os
+ , asn1::choice &choice);
+
+ /**
+ *
+ */
+ void gen_set(std::ostream &os,asn1::set &n);
+
+ /**
+ *
+ */
+ void gen_enumerated( std::ostream &os
+ , asn1::enumerated &_enum
+ );
+
+ /*
+ * Ros generation Code
+ */
+ void gen_object_class(std::ostream &os,asn1::classdef &n);
+
+ /**
+ *
+ */
+ void gen_object(std::ostream &os,asn1::object &n);
+ /**
+ *
+ */
+ void gen_module(std::ostream &os,asn1::module *_m);
+ protected:
+};
+/**
+ * vim:et:sw=2:ts=2:list
+ */
+#endif
--- /dev/null
+#include <iostream>
+#include <algorithm>
+#include <map>
+#include <cassert>
+#include "asn1_generator.h"
+#include "asn1_gen_uml.h"
+#include "adt/asn1_visitor.h"
+
+static long g_counter = 0;
+
+/**
+ * Default Cosntructor
+ */
+generate_uml::generate_uml(asn1::module *n) : asn1::generator(n)
+{}
+
+generate_uml::generate_uml(asn1::module *n,asn1::module::modules_type &m)
+ : asn1::generator(n,m)
+{
+}
+
+/**
+ * Helper function to look for missing prototypes
+ */
+void generate_uml::gen_missing(std::ostream &os,asn1::typenode *n)
+{
+ asn1::node::iterator it;
+ switch (n->type_id()())
+ {
+ case asn1::type::ASN1_SEQUENCE_OF:
+ case asn1::type::ASN1_SET_OF:
+ {
+#ifdef DEBUG
+ std::cout<<"Find sequence of or set of:\n";
+#endif
+ asn1::typenode *type = n->get_eltype();
+ if (type !=NULL)
+ {
+ if (asn1::typeref *tref = type->as_typeref())
+ {
+ it = std::find_if(m_module->begin(),
+ m_module->end(),
+ asn1::find_node(tref->get_reference()->name()));
+ } else
+ it = std::find_if(m_module->begin(),
+ m_module->end(),
+ asn1::find_node(type->name()));
+ } else return;
+
+ }
+ break;
+ case asn1::type::ASN1_SEQUENCE:
+ case asn1::type::ASN1_CHOICE:
+ {
+ asn1::constructed *ct = n->as_constructed();
+ GEN_LOG_DEBUG("choice or sequence %s\n",n->name().c_str());
+ asn1::node::iterator lit = ct->begin();
+ for (; lit != ct->end() ; lit++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*it);
+ if ( f->get_type() != NULL) {
+ gen_missing(os,f->get_type());
+ }
+ }
+ }
+ return;
+ break;
+ case asn1::type::ASN1_NULL:
+ return;
+ case asn1::type::ASN1_REFERENCE:
+ {
+ asn1::typeref *tref = n->as_typeref();
+ // Try to check references
+ if (tref->parameters() != NULL)
+ {
+ asn1::constructed *params = n->parameters();
+ std::cout<<"generate_uml::"<<__FUNCTION__<<" Have parameters\n";
+// os<<"//generate_uml::"<<__FUNCTION__<<" "<<n->name()<<" Have parameters\n";
+ for(asn1::node::iterator p = params->begin(); p != params->end() ;++p)
+ {
+ std::cout<<"generate_uml::"<<__FUNCTION__<<" Parameter:"<<(*p)->name()<<"\n";
+ it = std::find_if(m_module->begin(),m_module->end(),asn1::find_node((*p)->name()));
+
+ if (it != m_module->end())
+ gen_missing(os,(*it)->as_typenode());
+ }
+ }
+ //
+ if (tref->get_reference())
+ {
+ if (std::string("TYPE-IDENTIFIER::&Type").compare(tref->get_reference()->name()) == 0)
+ {
+ asn1::constraint::iterator c = tref->constraint_begin();
+ if ((*c)->type() == asn1::constraint::EL_TYPE)
+ {
+ asn1::node *ctype = (*c)->value();
+ it = std::find_if(m_module->begin(),
+ m_module->end(),
+ asn1::find_node(ctype->name()));
+ }
+ } else {
+ it = std::find_if(m_module->begin(),
+ m_module->end(),
+ asn1::find_node(tref->get_reference()->name()));
+ }
+
+ } else
+ {
+ it = std::find_if(m_module->begin(),m_module->end(),asn1::find_node(n->name()));
+
+ }
+ }
+ break;
+ default:
+ it = std::find_if(m_module->begin(),m_module->end(),asn1::find_node(n->name()));
+ }
+// Found a element to be generated
+ if ( it != m_module->end())
+ {
+ asn1::assignment *ltype = dynamic_cast<asn1::assignment *>(*it);
+ if ( ltype->is_generated() != true)
+ {
+ if (ltype->get_color() == asn1::node::CL_GREEN)
+ {
+ ltype->set_generated(true);
+ GEN_LOG_DEBUG("missing %s\n",ltype->name().c_str());
+ switch(ltype->get_type()->type_id()())
+ {
+ case asn1::type::ASN1_REFERENCE:
+ gen_typeref(os,ltype->get_type()->as_typeref());
+ break;
+ default:
+ gen_typedef(os,ltype->get_type()->as_typenode());
+ }
+ (*it)->set_color(asn1::node::CL_RED);
+ } else if (ltype->get_color() == asn1::node::CL_ORANGE)
+ {
+ if (ltype->get_type()->type_id()() == asn1::type::ASN1_SEQUENCE ||
+ ltype->get_type()->type_id()() == asn1::type::ASN1_CHOICE
+ )
+ os<<"struct "<<ltype->cpp_name()<<";"<<std::endl;
+ ltype->set_generated(true);
+ }else {
+ ltype->set_generated(true);
+ }
+ }
+ }
+}
+
+
+/**
+ *
+ *
+ */
+void generate_uml::gen_const(std::ostream &os,asn1::node *type)
+{
+ switch(type->type_id()())
+ {
+ case asn1::type::ASN1_OBJECT_IDENTIFIER:
+ {
+ os<<"<packagedElement xmi:id=\""<<type->identifier_cpp_name();
+ os<<g_counter<<"\" xmi:type=\"uml:LiteralInteger\"";
+ os<<" name=\""<<type->identifier_cpp_name()<<"\"/>"<<std::endl;
+ g_counter++;
+ }
+ break;
+ case asn1::type::ASN1_VALUESET:
+ {
+ }
+ break;
+ case asn1::type::ASN1_INTEGER:
+ {
+ os<<"<packagedElement xmi:id=\"Pkg_"<<g_counter;
+ os<<"\" xmi:type=\"uml:LiteralInteger\"";
+ os<<" name=\""<<type->identifier_cpp_name()<<"\"/>"<<std::endl;
+ g_counter++;
+ }
+ break;
+ default:
+ std::cout<<__FUNCTION__<<" ERROR DEFAULT"<<type->identifier_cpp_name();
+ std::cout<<"\n"; std::cout.flush();
+ ;
+ }
+ os<<std::endl;
+
+}
+
+/**
+ *
+ *
+ */
+void generate_uml::gen_enumerated( std::ostream &os
+ , asn1::enumerated &_type
+ , const std::string &name
+ , bool nested)
+{
+ asn1::enumerated *enumt = &_type;
+ std::string indent("");
+ asn1::node::iterator it = enumt->begin();
+ std::string balise;
+ if (nested ) {
+ balise = "nestedClassifier";
+ } else
+ balise = "packagedElement";
+ os<<"<"<<balise<<" xmi:id=\""<<_type.identifier()->uid();
+ os<<"\" xmi:type=\"uml:Class\" name=\""<<name<<"\">";
+ for (; it != enumt->end(); it++)
+ {
+ os<<"<ownedAttribute xmi:id=\""<<(*it)->uid()<<"\" name=\"";
+ os<<(*it)->name()<<"\"/>\n";
+ }
+ os<<indent<<"</"<<balise<<">\n ";
+}
+
+//
+// gen_typeref
+//
+void generate_uml::gen_typeref(std::ostream &os,asn1::typeref *type)
+{
+ std::string type_name;
+
+ if (type )
+ {
+ int par = (type->parameters() == NULL)?0:1;
+ GEN_LOG_DEBUG("type=%s params=%d\n",type->name().c_str(),par);
+
+ if (type->has_constraints())
+ {
+ asn1::constraint *c = *(type->constraint_begin());
+ }
+ }
+ if (type->get_reference()) {
+ //type_name = type->get_reference()->cpp_name();
+ type_name = type->cpp_name();
+ } else {
+ type_name = type->cpp_name();
+ }
+ if (type->type_id()() != asn1::type::ASN1_REFERENCE)
+ {
+ std::cout<<__FUNCTION__<<"ERROR "<<type->cpp_name()<<" type="<<type->type_id()();
+ exit(0);
+ }
+
+
+ gen_missing(os,type);
+ asn1::node *ns = NULL;
+ //os<<"typedef ";
+ os<<"<packagedElement xmi:id=\""<<type->identifier()->uid()<<"\" xmi:type=\"uml:DataType\" name=\""<<type->identifier_cpp_name()<<"\"/>\n";
+ g_counter++;
+ if (type->tagged())
+ {
+ } else {
+ // Process untagged elements
+ asn1::constructed *params = type->parameters();
+ if (type_in_imports(type,&ns) )
+ {
+ // imported case
+ if (type->meta_id()() == asn1::meta::OBJECTCLASS)
+ {
+ //os<<"// OBJECT CLASS NOT YET SUPPORTED "<<type->cpp_name()<<" ";
+ } else if (std::string("OPERATON").compare(type->cpp_name())==0)
+ {
+ //os<<"// OBJECT CLASS NOT YET SUPPORTED "<<type->cpp_name()<<" ";
+ } else
+ {
+ //TODO find reference and add it so we can know
+ //os<<"\t"<<ns->cpp_name()<<"::";
+ //os<<type->cpp_name()<<" ";
+ }
+ } else if (std::string("TYPE_IDENTIFIER").compare(type->cpp_name())==0) {
+ //os<<" /* def"<<type->cpp_name()<<"*/INTEGER ";
+
+ } else {
+ // internal case
+ }
+ // Buuggeeee
+ if (std::string("ROS").compare(type->name()) )
+ if (params && is_template(params))
+ {
+ asn1::node::iterator begin = params->begin();
+ asn1::node::iterator end = params->end();
+ os<<"<";
+ for (; begin != end ; ++begin) {
+ if (begin != params->begin())
+ os<<",";
+ os<<(*begin)->cpp_name();
+ }
+ os<<">";
+ }
+
+ }
+
+ // os<<"\t\t"<<type->identifier_cpp_name()<<";\n\n";
+
+}
+
+
+//
+//
+//
+void generate_uml::gen_typedef(std::ostream &os,asn1::typenode *type)
+{
+ if (type )
+ {
+ GEN_LOG_DEBUG("type %s ident=%s\n",type->name().c_str(),type->identifier_name().c_str());
+
+ if (type->has_constraints())
+ {
+ asn1::constraint *c = *(type->constraint_begin());
+// if (c)
+// os <<c->name();
+
+ }
+ if ( type->identifier() && type->identifier()->parameters())
+ {
+// os<<" parameterized ";
+ }
+ os<<"\n";
+ }
+
+ if (type != NULL)
+ switch (type->type_id()())
+ {
+ case asn1::type::ASN1_REFERENCE:
+ {
+ std::cout<<"__FUNCTION__"<<" ERROR "<<type->cpp_name()<<std::endl;
+ exit(0);
+ // os<<"typedef "<<type->name()<<" ";
+ gen_missing(os,type);
+ asn1::node *ns = NULL;
+ //os<<"typedef ";
+ os<<"AEBW.declare(\""<<type->cpp_name()<<"\",AEBW.Asn1 ";
+ if (type->tag().m_value != -1)
+ {
+ } else {
+ if (type_in_imports(type,&ns) ) {
+ if (type->meta_id()() == asn1::meta::OBJECTCLASS)
+ {
+ os<<"// OBJECT CLASS NOT YET SUPPORTED "<<type->cpp_name()<<" ";
+ } else if (std::string("OPERATON").compare(type->cpp_name())==0)
+ {
+ os<<"// OBJECT CLASS NOT YET SUPPORTED "<<type->cpp_name()<<" ";
+ } else
+ {
+ os<<"\t"<<ns->cpp_name()<<"::";
+ os<<type->cpp_name()<<" ";
+ }
+ } else
+ os<<" /**/ "<<type->cpp_name()<<" ";
+
+ }
+
+ }
+ break;
+ case asn1::type::ASN1_INTEGER:
+ {
+ os<<"<packagedElement xmi:id=\""<<type->identifier()->uid()<<"\" xmi:type=\"uml:DataType\" name=\""<<type->identifier_cpp_name()<<"\"/>"<<std::endl;
+ g_counter++;
+ return ;
+ }
+ break;
+ case asn1::type::ASN1_SEQUENCE:
+ {
+ std::string scope("");
+ asn1::sequence *seq = type->as_sequence();
+ asn1::node::iterator lit = seq->begin();
+ for (; lit != seq->end() ; ++lit)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*lit);
+ if ( asn1::typenode *tn = f->get_type() ) {
+ gen_missing(os,tn);
+ }
+ }
+ gen_seq(os,scope,*seq);
+ os<<"\n";
+ return ;
+ }
+ break;
+ case asn1::type::ASN1_SEQUENCE_OF:
+ {
+ asn1::node *ns = NULL;
+ asn1::typenode *subt =type->get_eltype();
+ gen_missing(os,subt);
+ if (type_in_imports(subt,&ns) ) {
+ os<<"<packagedElement xmi:id=\""<<type->identifier()->uid()<<"\" xmi:type=\"uml:DataType\" name=\""<<type->identifier_cpp_name()<<"\"/>"<<std::endl;
+ g_counter++;
+ } else {
+ switch (subt->type_id()())
+ {
+ case asn1::type::ASN1_SEQUENCE:
+ {
+ std::string scope("\t");
+
+ subt->name(type->identifier_cpp_name()+"_type");
+ gen_seq(os,scope,*subt->as_sequence());
+ //os<<";\ntypedef SEQUENCE_OF<"<<(*it)->cpp_name()<<"> ";
+ os<<"<packagedElement xmi:id=\""<<type->identifier()->uid()<<"\" xmi:type=\"uml:DataType\" name=\""<<type->identifier_cpp_name()<<"\"/>"<<std::endl;
+ }
+ break;
+ default:
+ if (asn1::typeref *tref = subt->as_typeref())
+ {
+ os<<"<packagedElement xmi:id=\""<<type->identifier()->uid()<<"\" xmi:type=\"uml:DataType\" name=\""<<type->identifier_cpp_name()<<"\"/>"<<std::endl;
+ } else
+ {
+ os<<"<packagedElement xmi:id=\""<<type->identifier()->uid()<<"\" xmi:type=\"uml:DataType\" name=\""<<type->identifier_cpp_name()<<"\"/>"<<std::endl;
+ }
+ }
+ }
+ }
+ break;
+ case asn1::type::ASN1_SET:
+ {
+ asn1::set *settype = type->as_set();
+ asn1::node::iterator lit = settype->begin();
+ for (; lit != settype->end() ; lit++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*lit);
+ if ( asn1::typenode *tn = f->get_type()) {
+ gen_missing(os,tn);
+ }
+ }
+ gen_set(os,settype);
+ os<<"\n";
+ return ;
+ }
+ break;
+ case asn1::type::ASN1_SET_OF:
+ {
+ asn1::typenode *it = type->get_eltype();
+ if (it)
+ gen_missing(os,it);
+ if (asn1::typeref *tref = it->as_typeref())
+ {
+ os<<"<packagedElement xmi:id=\""<<g_counter<<"\" xmi:type=\"uml:DataType\" name=\""<<tref->get_reference()->name()<<"\"/>"<<std::endl;
+ g_counter++;
+ } else
+ {
+ os<<"<packagedElement xmi:id=\""<<g_counter<<"\" xmi:type=\"uml:DataType\" name=\""<<type->cpp_name()<<"\"/>"<<std::endl;
+ g_counter++;
+ }
+ }
+ break;
+ case asn1::type::ASN1_CHOICE:
+ {
+ asn1::choice *ct = type->as_choice();
+ asn1::node::iterator lit = ct->begin();
+ for (; lit != ct->end() ; lit++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*lit);
+ if ( asn1::typenode *tn = f->get_type() ) {
+ gen_missing(os,tn);
+ }
+ }
+ gen_choice(os,ct);
+ os<<"\n";
+ return;
+ }
+ break;
+ case asn1::type::ASN1_ENUMERATED:
+ {
+ //os<<"typedef ";
+ gen_enumerated(os,*type->as_enumerated(),type->identifier_cpp_name());
+ }
+ break;
+ ;
+ case asn1::type::ASN1_BIT_STRING:
+ {
+ os<<"<packagedElement xmi:id=\""<<type->identifier()->uid();
+ os<<"\" xmi:type=\"uml:DataType\" name=\""<<type->identifier_cpp_name();
+ os<<"\"/>"<<std::endl;
+ g_counter++;
+ return ;
+ }
+ break;
+ default:
+ gen_missing(os,type);
+ asn1::node *ns = NULL;
+ os<<"<packagedElement xmi:id=\""<<type->identifier()->uid()<<"\" xmi:type=\"uml:DataType\" name=\""<<type->identifier_cpp_name()<<"\"/>"<<std::endl;
+ return;
+ ;
+ };
+
+ //os<<"\t\t"<<type->identifier_cpp_name()<<";\n\n";
+
+}
+
+/**
+ *
+ */
+void generate_uml::gen_seq(std::ostream &os,std::string &scope,asn1::sequence &_type)
+{
+ asn1::sequence * type = &_type;
+ asn1::node * n = _type.identifier();
+ asn1::node::iterator lit;
+ asn1::constructed *params = n->parameters();
+ std::string balise;
+
+ balise = "packagedElement";
+ /*
+ * Try to handler sequence of sequence
+ */
+ if ( type != NULL)
+ {
+ lit = type->begin();
+ }
+
+ m_Stack.push_back(n->cpp_name());
+ // default constructor
+ // I should probaly push optionnal attributes and OBEJECTS in a stack and add a initializer here.
+ std::vector<asn1::node *> opt_attrs;
+ for (asn1::node::iterator it = type->begin()
+ ; it != type->end() ; it++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*it);
+ asn1::typenode *attr_type = f->get_type();
+ if (attr_type != NULL)
+ {
+ asn1::typeref *tref = attr_type->as_typeref();
+ if (tref && tref->get_reference() && tref->is_complex())
+ {
+ asn1::reference *r = tref->get_reference();
+ std::string lr = r->back().m_identifier;
+ opt_attrs.push_back((*it));
+ }
+ }
+
+ }
+ os<<"<"<<balise<<" xmi:id=\""<<n->uid();
+ os<<"\" xmi:type=\"uml:Class\" name=\""<<n->cpp_name()<<"\"> \n";
+ // Constructor
+ // Copy constructor
+
+ for (; lit != type->end() ; lit++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*lit);
+ gen_composite_attribute(os,scope,f,n->parameters());
+ }
+
+ os<<"</"<<balise<<">\n";
+ m_Stack.pop_back();
+}
+
+
+//
+//
+//
+void generate_uml::gen_template_params(std::ostream &os,asn1::node *_params)
+{
+ asn1::constructed *params = _params->as_constructed();
+ asn1::node::node_list nl;
+
+ os<<"<";
+ for(asn1::node::iterator p = params->begin(); p != params->end() ;++p)
+ {
+ if (nl.size()>0)
+ {
+ asn1::node::iterator it = std::find_if(nl.begin(),nl.end(),asn1::find_node((*p)->name()));
+ if (it != nl.end() )
+ {
+ //
+ } else {
+ if (p != params->begin()) os<<",";
+ os<<" "<<(*p)->cpp_name();
+ nl.push_back(*p);
+ }
+ } else {
+ if (p != params->begin()) os<<",";
+ os<<" "<<(*p)->cpp_name();
+ nl.push_back(*p);
+ }
+ }
+ os<<"> ";
+}
+//
+//
+//
+void generate_uml::gen_template_signature(std::ostream &os
+ ,asn1::node *_params)
+{
+ asn1::constructed *params = _params->as_constructed();
+ asn1::node::node_list nl;
+
+ os<<"<";
+ for(asn1::node::iterator p = params->begin(); p != params->end() ;++p)
+ {
+ if (nl.size()>0)
+ {
+ asn1::node::iterator it = std::find_if(nl.begin(),nl.end(),asn1::find_node((*p)->name()));
+ if (it != nl.end() )
+ {
+ //
+ } else {
+ if (p != params->begin()) os<<",";
+ os<<" typename "<<(*p)->cpp_name();
+ nl.push_back(*p);
+ }
+ } else {
+ if (p != params->begin()) os<<",";
+ os<<" typename "<<(*p)->cpp_name();
+ nl.push_back(*p);
+ }
+ }
+ os<<"> ";
+}
+
+/**
+ *
+ *
+ */
+void generate_uml::gen_choice(std::ostream &os,asn1::choice *n,bool nested)
+{
+ std::string scope("");
+ asn1::constructed *type = n->as_constructed();
+ asn1::node::iterator it;
+ std::string balise;
+ if (nested) {
+ balise = "nestedClassifier";
+ } else {
+ balise = "packagedElement";
+ }
+ if (type == NULL)
+ {
+ type = n->as_constructed();
+ }
+ m_Stack.push_back(n->cpp_name());
+ GEN_LOG_DEBUG("node=%s nested=%d\n",n->name().c_str(),nested);
+ it = type->begin();
+ // Handle parameter stuff
+ if (n->parameters() && is_template(n->parameters()))
+ {
+ asn1::node::node_list nl;
+ asn1::constructed *params = n->parameters();
+ // os<<"//"<<__FUNCTION__<<" parameterized\n";
+ // Forward declaration for ostream function
+ os<<"template ";
+ gen_template_signature(os,params);
+ os<<" struct "<<n->cpp_name()<<" /* : public asn1::type */ ;\n";
+ os<<"template ";
+ gen_template_signature(os,params);
+ os<<"\nstd::ostream & operator<<(std::ostream &os,const "<<n->cpp_name();
+ gen_template_params(os,params);
+ os<<" &s) ;\n";
+
+ // Real declation
+ os<<"template ";
+ gen_template_signature(os,params);
+ }
+
+ //os<<"struct "<<n->cpp_name()<<" /* : public asn1::type */ {\n";
+ // os<<" int\t\t"<<"kind_;"<<std::endl;
+ os<<"<"<<balise<<" xmi:id=\""<<n->uid();
+ os<<"\" xmi:type=\"uml:Class\" name=\""<<n->cpp_name()<<"\">"<<std::endl;
+ for (; it != type->end() ; it++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*it);
+ gen_composite_attribute(os,scope,f,n->parameters());
+ }
+ // Now add an enum tu identifie type
+
+ os<<"</"<<balise<<">";
+ m_Stack.pop_back();
+}
+
+void
+generate_uml::gen_composite_attribute_ref(std::ostream &os
+ , std::string &scope
+ , asn1::typeref *attribute
+ , asn1::node *_params)
+{
+ asn1::constructed *params = _params->as_constructed();
+ asn1::reference *ref = attribute->get_reference();
+
+ if (ref->size() > 1)
+ {
+ // find the object and folow the links ....
+ std::string rname = ref->back().m_identifier;
+// os<<"\tasn1::Object * /* GCAT "<<rname<<"*/ ";
+ } else {
+ // easy case
+ asn1::node::iterator refm = std::find_if(m_module->begin(),
+ m_module->end(),
+ asn1::find_node(ref->name()));
+ if (refm != m_module->end())
+ {
+ // Here I have the type definition. I should add
+ //os<<"\t"<<ref->cpp_name();
+ os<<" type=\""<<(*refm)->uid()<<"\"";
+
+ } else
+ {
+ asn1::node *ns = NULL;
+ if (type_in_imports(ref->name(),&ns) ) {
+ asn1::node *target = NULL;
+ get_type_in_module(ns->name(),ref->name(),&target);
+ asn1::reference::component_const_iterator compit = ref->begin();
+ // Check first element of reference
+ if (target) {
+ os<<" type=\""<<target->uid()<<"\"";
+ }
+ // check if attribute has parameters
+ if (attribute->parameters() != NULL)
+ {
+ os<<"<";
+ for ( asn1::node::iterator it = attribute->parameters()->begin()
+ ; it != attribute->parameters()->end()
+ ; ++it)
+ {
+ asn1::node *ns1 = NULL;
+ if (it != attribute->parameters()->begin())
+ os<<",";
+ // check namespace
+ if (type_in_imports((*it)->name(),&ns1) ) {
+ os<<ns1->cpp_name()<<"::"<<(*it)->cpp_name();
+ } else
+ os<<(*it)->cpp_name();
+ }
+ os<<">";
+
+ }
+ } else if (params) // reference in parameters of definition
+ {
+ bool found = false;
+ for ( asn1::node::iterator it = params->begin()
+ ; it != params->end(); ++it)
+ {
+ if (ref->name().compare((*it)->name())== 0)
+ {
+ os<<"\t"<<(*it)->cpp_name();
+ found = true;
+ }
+ }
+
+ } else
+ {
+ // os<<" ERROR ";
+ }
+ }
+
+ }
+}
+
+
+
+void
+generate_uml::gen_composite_attribute( std::ostream &os
+ , std::string &scope
+ , asn1::field *attribute
+ , asn1::node *params)
+{
+ asn1::typenode *attr_type = attribute->get_type();
+ if (attr_type != NULL)
+ {
+ switch (attr_type->type_id()())
+ {
+ case asn1::type::ASN1_ENUMERATED:
+ {
+ gen_enumerated( os
+ , *attr_type->as_enumerated()
+ , attribute->cpp_name()+"_t"
+ , true);
+ os<<"<ownedAttribute xmi:id=\"p_"<<attr_type->uid();
+ os<<"\" type=\""<<attr_type->identifier()->uid();
+ os<<"\" name=\""<<attribute->cpp_name();
+ os<<"\" visibility=\"public\"/>";
+ }
+ break;
+ case asn1::type::ASN1_SET:
+ {
+ os<<"<ownedAttribute xmi:id=\"set_"<<g_counter;
+ os<<"\" type=\"\" name=\""<<attribute->cpp_name();
+ os<<"\" visibility=\"public\"/>";
+ g_counter++;
+ }
+ break;
+ case asn1::type::ASN1_CHOICE:
+ {
+ attr_type->name(attribute->cpp_name()+"_t");
+ gen_choice(os,attr_type->as_choice(),true);
+ os<<"<ownedAttribute xmi:id=\"choice_"<<attribute->uid();
+ os<<"\" type=\""<<attr_type->uid()<<"\" name=\"";
+ os<<attribute->cpp_name()<<"\" visibility=\"public\"/>";
+ }
+ break;
+ case asn1::type::ASN1_SEQUENCE:
+ {
+ std::string scope("\t");
+ attribute->get_type()->name(attribute->cpp_name()+"_t");
+ assert(0);
+ gen_seq(os,scope,*attribute->get_type()->as_sequence());
+ //os<<"\t\t"<<(attribute)->cpp_name()<<" : \"\",\n";
+ os<<"<ownedAttribute xmi:id=\""<<attribute->uid();
+ os<<"\" type=\""<<attribute->get_type()->uid();
+ os<<"\" name=\""<<attribute->cpp_name();
+ os<<"\" visibility=\"public\"/>";
+ g_counter++;
+ }
+ break;
+ case asn1::type::ASN1_SELECTION:
+ {
+ }
+ break;
+ case asn1::type::ASN1_SET_OF:
+ case asn1::type::ASN1_SEQUENCE_OF:
+ {
+ //std::string scope("");
+ asn1::typenode *type = attribute->get_type();
+ asn1::typenode *subtype = type->get_eltype();
+ switch (subtype->type_id()())
+ {
+ case asn1::type::ASN1_SEQUENCE:
+ subtype->name((attribute)->cpp_name()+std::string("_type"));
+ gen_seq(os,scope,*subtype->as_sequence());
+ os<<"\n";
+ os<<"<ownedAttribute xmi:id=\"seq_"<<g_counter;
+ os<<"\" visibility=\"public\"";
+ os<<" name=\""<<(attribute)->cpp_name()<<"\"/>\n";
+ g_counter++;
+ break;
+ default:
+ asn1::node *ns;
+ if (type_in_imports(subtype,&ns) ) {
+ os<<"<ownedAttribute xmi:id=seq1_\""<<g_counter<<"\" visibility=\"public\""<<" name=\""<<(attribute)->cpp_name()<<"\"/>\n";
+ g_counter++;
+ } else
+ {
+ asn1::node *tn;
+ if (get_type_in_module(m_module->name(),subtype->name(),&tn)) {
+ os<<"<ownedAttribute xmi:id=\""<<g_counter<<"\" type=\""<<tn->uid()<<"\" visibility=\"public\""<<" name=\""<<(attribute)->cpp_name()<<"\">\n";
+ os<<"<upperValue xmi:type=\"uml:LiteralUnlimitedNatural\" xmi:id=\"_i1AV"<<g_counter<<"\" value=\"*\"/>\n";
+ os<<"<lowerValue xmi:type=\"uml:LiteralInteger\" xmi:id=\"_i0_uoDsvEeOCl"<<g_counter<<"\"/>\n";
+ os<<"</ownedAttribute>";
+ } else
+ os<<"<ownedAttribute xmi:id=\""<<g_counter<<"\" visibility=\"public\""<<" name=\""<<(attribute)->cpp_name()<<"\"/>\n";
+ g_counter++;
+ }
+ }
+ }
+ break;
+ case asn1::type::ASN1_REFERENCE:
+
+ {
+ os<<"<ownedAttribute xmi:id=\""<<g_counter<<"\" ";
+ if (asn1::typeref *ref = attr_type->as_typeref()) {
+ // New way to handle reference
+ gen_composite_attribute_ref(os,scope,ref,params);
+ } else {
+ os<<"type=\"\"";
+ }
+ os<<" name=\""<<attribute->cpp_name()<<"\" visibility=\"public\"/>";
+ g_counter++;
+ os<<std::endl;
+ }
+ break;
+ default:
+ {
+ asn1::node *ns = NULL;
+ os<<"<ownedAttribute xmi:id=\"def_"<<g_counter;
+ os<<"\" name=\""<<attribute->cpp_name();
+ os<<"\" type=\"\" visibility=\"public\"/>";
+ g_counter++;
+ os<<"\n";
+ }
+ }
+ }
+}
+
+
+
+/**
+ *
+ */
+void generate_uml::gen_set(std::ostream &os,asn1::set *n)
+{
+ std::string scope("");
+ asn1::constructed *tp = n->as_constructed();
+ asn1::node::iterator it = tp->begin();
+
+ os<<"<packagedElement xmi:id=\""<<g_counter;
+ os<<"\" xmi:type=\"uml:class\" name=\""<<n->cpp_name()<<"\" >\n";
+ g_counter++;
+ for (; it != tp->end() ; it++)
+ {
+ asn1::field *f = dynamic_cast<asn1::field *>(*it);
+ asn1::typenode *type = f->get_type();
+ if (type != NULL)
+ {
+
+ switch (type->type_id()())
+ {
+ case asn1::type::ASN1_SEQUENCE_OF:
+ case asn1::type::ASN1_SET_OF:
+ {
+ os<<"<ownedAttribute xmi:id=\"setororseqof"<<g_counter<<"\" type=\"\" name=\""<<f->cpp_name()<<"\" visibility=\"public\"/>";
+ g_counter++;
+ }
+ break;
+ default:
+ os<<"<ownedAttribute xmi:id=\"npsetof"<<g_counter<<"\" type=\"\" name=\""<<f->cpp_name()<<"\" visibility=\"public\"/>";
+ g_counter++;
+ os<<"\n";
+ }
+ }
+ }
+ os<<"</packagedElement>\n";
+
+}
+
+
+
+void generate_uml::gen_object_class_opt(std::ostream &os,asn1::assignment *n)
+{
+ asn1::constructed *type = n->get_type()->as_constructed();
+ asn1::node::iterator it = type->begin();
+ bool opt = false;
+ std::list<std::string> l;
+ for ( ; it != type->end(); ++it)
+ {
+ std::string fieldname = (*it)->cpp_name();
+ fieldname[0] = '_';
+ if ( ((*it)->flags().m_flags & asn1::node::marker_type::FL_OPTIONAL) ) {
+ l.push_back(fieldname);
+ }
+ }
+ if (l.size()>0) {
+ os<<"\tstruct _present { \n";
+ for (std::list<std::string>::const_iterator it = l.begin(); it != l.end(); ++it)
+ {
+ if (1) {
+ os<<"\t\t";
+ os<<"unsigned present"<<(*it)<<" : 1;\n";
+ }else {
+ os<<"\t\tunsigned present"<<(*it)<<" : 1\n";
+ }
+ }
+ os<<"\t} m;\n";
+ }
+}
+
+/**
+ *
+ *
+ */
+void generate_uml::gen_object_class_missing(std::ostream &os,asn1::assignment *n)
+{
+ asn1::constructed *type = n->get_type()->as_constructed();
+ asn1::node::iterator it = type->begin();
+
+
+ // cosntructors
+
+ // generate optionnals
+
+ // public methods
+ for ( ; it != type->end(); ++it)
+ {
+ asn1::field *ltype = dynamic_cast<asn1::field *>(*it);
+ std::string fieldname = (*it)->cpp_name();
+ fieldname[0] = '_';
+ switch(ltype->type_id()())
+ {
+ case asn1::type::ASN1_CLASSFIELD_FTVF: /* Fixed Type Value Field */
+ os<<std::endl;
+ // call missing here
+ gen_missing(os,ltype->get_type());
+ break;
+ case asn1::type::ASN1_CLASSFIELD_TF: /* Type Field */
+ os<<std::endl;
+ break;
+ case asn1::type::ASN1_CLASSFIELD_VTVF: /* Variable Type Value Field */
+ os<<std::endl;
+ break;
+ case asn1::type::ASN1_CLASSFIELD_FTVSF: /* Fixed Type Value Set Field */
+ os<<std::endl;
+ break;
+ case asn1::type::ASN1_CLASSFIELD_VTVSF: /* Variable Type Value Set Field*/
+ os<<std::endl;
+ break;
+ case asn1::type::ASN1_CLASSFIELD_OF: /* Object Field */
+ os<<std::endl;
+ break;
+ case asn1::type::ASN1_CLASSFIELD_OSF: /* Object Set Field */
+ os<<std::endl;
+ break;
+ break;
+ default:
+ os<<std::endl;
+ };
+ }
+}
+
+
+/**
+ *
+ *
+ */
+void generate_uml::gen_object_class_interface(std::ostream &os,asn1::assignment *n)
+{
+ asn1::constructed *type = n->get_type()->as_constructed();
+ asn1::node::iterator it = type->begin();
+
+
+ os<<"<packagedElement xmi:id=\""<<n->uid()<<"\" xmi:type=\"uml:Interface\" name=\"I"<<n->cpp_name()<<"\">\n";
+
+ // public methods
+ for ( ; it != type->end(); ++it)
+ {
+ asn1::node *ltype = (*it);
+ std::string fieldname = (*it)->cpp_name();
+ fieldname[0] = '_';
+ switch(ltype->type_id()())
+ {
+ case asn1::type::ASN1_CLASSFIELD_FTVF: /* Fixed Type Value Field */
+ os<<"<ownedOperation xmi:id=\"ape_"<<ltype->uid()<<"\" name=\""<<fieldname.substr(1)<<"Equals\"/>\n";
+ break;
+ case asn1::type::ASN1_CLASSFIELD_TF: /* Type Field */
+ os<<"<ownedOperation xmi:id=\"op_"<<ltype->uid()<<"\" name=\"codec"<<fieldname<<"\"/>\n";
+ break;
+ case asn1::type::ASN1_CLASSFIELD_VTVF: /* Variable Type Value Field */
+ os<<std::endl;
+ break;
+ case asn1::type::ASN1_CLASSFIELD_FTVSF: /* Fixed Type Value Set Field */
+ os<<std::endl;
+ break;
+ case asn1::type::ASN1_CLASSFIELD_VTVSF: /* Variable Type Value Set Field*/
+ os<<std::endl;
+ break;
+ case asn1::type::ASN1_CLASSFIELD_OF: /* Object Field */
+ os<<std::endl;
+ break;
+ case asn1::type::ASN1_CLASSFIELD_OSF: /* Object Set Field */
+ os<<std::endl;
+ break;
+ break;
+ default:
+ os<<std::endl;
+ };
+ }
+ os<<"</packagedElement>"<<std::endl;
+}
+
+
+void generate_uml::gen_object_class_attributes(std::ostream &os,asn1::assignment *n)
+{
+ asn1::constructed *type = n->get_type()->as_constructed();
+ asn1::node::iterator it = type->begin();
+ for ( ; it != type->end(); ++it)
+ {
+ asn1::classfield *ltype = dynamic_cast<asn1::classfield *>(*it);
+ std::string fieldname = (*it)->cpp_name();
+ fieldname[0] = '_';
+ os<<"\t//"<<(*it)->cpp_name()<<" type_id="<<(*it)->type_id()();
+ //<<std::endl;
+ switch(ltype->type_id()())
+ {
+ case asn1::type::ASN1_CLASSFIELD_FTVF: /* Fixed Type Value Field */
+ break;
+ case asn1::type::ASN1_CLASSFIELD_TF: /* Type Field */
+ break;
+ case asn1::type::ASN1_CLASSFIELD_VTVF: /* Variable Type Value Field */
+ break;
+ case asn1::type::ASN1_CLASSFIELD_FTVSF: /* Fixed Type Value Set Field */
+ break;
+ case asn1::type::ASN1_CLASSFIELD_VTVSF: /* Variable Type Value Set Field*/
+ os<<std::endl;
+ break;
+ case asn1::type::ASN1_CLASSFIELD_OF: /* Object Field */
+ break;
+ case asn1::type::ASN1_CLASSFIELD_OSF: /* Object Set Field */
+ break;
+ break;
+ default:
+ os<<std::endl;
+ };
+ }
+
+}
+
+
+void
+generate_uml::gen_object_class_printf(std::ostream &os,asn1::assignment *n)
+{
+ asn1::constructed *type = n->get_type()->as_constructed();
+ asn1::node::iterator it = type->begin();
+
+ for ( ; it != type->end(); ++it)
+ {
+ asn1::node *ltype = (*it);
+ std::string fieldname = (*it)->cpp_name();
+ fieldname[0] = '_';
+
+ switch(ltype->type_id()())
+ {
+ case asn1::type::ASN1_CLASSFIELD_FTVF: /* Fixed Type Value Field */
+ break;
+ case asn1::type::ASN1_CLASSFIELD_TF: /* Type Field */
+ if ( (ltype->flags().m_flags & asn1::node::marker_type::FL_OPTIONAL) )
+ {
+ os<<"\t if (m.present"<<fieldname<<")"<<std::endl;
+ }
+ os<<"\t\tos<<\""<<ltype->cpp_name();
+ os<<"\t"<<" : \"<<m"<<fieldname<<"<<std::endl;\n";
+ break;
+ default:
+ ;
+ }
+
+ }
+ os<<"\t};\n";
+}
+/**
+ *
+ *
+ */
+void generate_uml::gen_object_class(std::ostream &os,asn1::assignment *n)
+{
+ asn1::constructed *type = n->get_type()->as_constructed();
+
+ gen_object_class_missing(os,n);
+ gen_object_class_interface(os,n);
+
+ // generate optionnals
+ gen_object_class_printf(os,n);
+ gen_object_class_opt(os,n);
+
+ // public methods
+ gen_object_class_attributes(os,n);
+}
+/**
+ *
+ *
+ */
+void generate_uml::gen_object(std::ostream &os,asn1::assignment *n)
+{
+ asn1::constructed *type = n->get_type()->as_constructed();
+ asn1::node::iterator it = type->begin();
+// os<<"// generate_uml::"<<__FUNCTION__<<" "<<n->name()<<"\n";
+ os.flush();
+ if (!type->name().compare("OPERATION"))
+ {
+ gen_object_operation(os,n);
+ } else
+ if (!type->name().compare("ERROR"))
+ {
+ gen_object_error(os,n);
+ } else if (!type->name().compare("OBJECT-TYPE"))
+ {
+ }
+}
+
+
+
+/**
+ *
+ *
+ */
+void generate_uml::gen_object_error(std::ostream &os,asn1::node *n)
+{
+}
+
+
+void generate_uml::gen_object_operation(std::ostream &os,asn1::node *n)
+{
+}
+
+/**
+ *
+ *
+ */
+void generate_uml::gen_object_operation_package(std::ostream &os,asn1::node *n)
+{
+}
+void generate_uml::gen_object_connection(std::ostream &os,asn1::node *n)
+{
+}
+
+
+class douml_assignment : public assignment_visitor<douml_assignment>
+{
+ public:
+ douml_assignment(std::ostream &_os,generate_uml &_gen)
+ : m_os(_os) , m_gen(_gen)
+ {
+ }
+#define ASSIGNMENT(En,Tp,Parent,Code) \
+ void visit_##Tp(asn1::Tp##_assignment *a) \
+ Code
+ASSIGNMENT(TYPEREF,typeref,assignment,{
+ m_gen.gen_typeref(m_os,a->get_type()->as_typeref());
+ })
+ASSIGNMENT(TYPE,type,assignment,{
+ m_gen.gen_typedef(m_os,a->get_type());
+ })
+ASSIGNMENT(VALUE,value,assignment,{
+ m_gen.gen_const(m_os,a->get_type());
+ })
+ASSIGNMENT(VALUESET,valueset,assignment,{
+ std::cout<<__FUNCTION__<<" TODO"<<a->name()<<std::endl;
+ })
+ASSIGNMENT(OBJECT,object,assignment,{
+ m_gen.gen_object(m_os,a);
+ })
+ASSIGNMENT(OBJECTCLASS,objectclass,assignment,{
+ m_gen.gen_object_class(m_os,a);
+ })
+ASSIGNMENT(OBJECTSET,objectset,assignment,{
+ std::cout<<__FUNCTION__<<" TODO"<<a->name()<<std::endl;
+ })
+ASSIGNMENT(OBJECTFIELD,objectfield,assignment,{
+ std::cout<<__FUNCTION__<<" TODO"<<a->name()<<std::endl;
+ })
+
+ void visit_assignment(asn1::assignment *a)
+ {}
+#undef ASSIGNMENT
+
+ protected:
+ generate_uml &m_gen;
+ std::ostream &m_os;
+};
+
+/**
+ *
+ */
+void generate_uml::gen_module(std::ostream &os,asn1::module *n)
+{
+ asn1::import_list *imports = n->imports();
+ std::fstream umlos;
+ std::string umlname = std::string(n->name()+".uml");
+ umlos.open(umlname.c_str(),std::fstream::out);
+ umlos<<"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"<<std::endl;
+ umlos<<"<xmi:XMI xmi:version=\"2.1\" ";
+ umlos<<"xmlns:xmi=\"http://schema.omg.org/spec/XMI/2.1\"";
+ umlos<<" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"";
+ umlos<<" xmlns:Cpp=\"http:///schemas/Cpp/www.ebersold.fr/modeling/cpp/0\" ";
+ umlos<<" xmlns:uml=\"http://www.eclipse.org/uml2/3.0.0/UML\"";
+ umlos<<" xsi:schemaLocation=\"http:///schemas/Cpp/www.ebersold.fr/modeling/cpp/0 \">";
+ umlos<<"<uml:Package xmi:id=\"pkg_"<<n->cpp_name()<<g_counter;
+ umlos<<"\" name=\""<<n->cpp_name()<<"\">"<<std::endl;
+
+ g_counter++;
+ n->sort_childs();
+ asn1::node::iterator it = n->begin();
+
+ for (; it != n->end() ; it++)
+ {
+ asn1::assignment *a = dynamic_cast<asn1::assignment *>(*it);
+ GEN_LOG_DEBUG("Process item %s\n",a->name().c_str());
+ if (a->get_type() != NULL)
+ {
+ if ( a->is_generated())
+ {
+ GEN_LOG_DEBUG("item %s already generated\n",a->name().c_str());
+ continue;
+ }
+ douml_assignment douml(umlos,*this);
+ douml.visit(a);
+ os<<std::endl;
+ (*it)->set_color(asn1::node::CL_RED);
+ } else
+ {
+ GEN_LOG_WARN("item %s of undefined type \n",(*it)->name().c_str());
+ }
+ os<<std::endl;
+
+ }
+ umlos<<"</uml:Package>";
+ umlos<<"</xmi:XMI>";
+ umlos.close();
+}
+
+/**
+* vim:et:sw=2:ts=2
+*/
--- /dev/null
+#ifndef GEN_HEADER_UML_H__
+#define GEN_HEADER_UML_H__
+#include <iostream>
+#include <algorithm>
+
+
+/**
+ *
+ */
+class generate_uml : public asn1::generator
+{
+ public:
+
+ generate_uml(asn1::module *n);
+
+ generate_uml(asn1::module *n,asn1::module::modules_type &m);
+
+ virtual ~generate_uml() {} ;
+
+
+ void gen_missing(std::ostream &os,asn1::typenode *n) ;
+
+ /**
+ *
+ *
+ */
+ void gen_const(std::ostream &os,asn1::node *n);
+
+ void gen_enumerated( std::ostream &os
+ , asn1::enumerated &n
+ , const std::string &name
+ , bool nested = false);
+ //
+ //
+ //
+ void gen_typedef(std::ostream &os,asn1::typenode *n);
+ void gen_typeref(std::ostream &os,asn1::typeref *n);
+
+ /**
+ *
+ */
+ void gen_seq( std::ostream &os
+ , std::string &scope
+ , asn1::sequence &n
+ );
+
+ void gen_choice( std::ostream &os
+ , asn1::choice *n
+ , bool nested=false);
+
+ void gen_composite_attribute( std::ostream &os
+ , std::string &scope
+ , asn1::field *attribute
+ , asn1::node *params = NULL);
+
+ void gen_composite_attribute_ref( std::ostream &os
+ , std::string &scope
+ , asn1::typeref *attribute
+ , asn1::node *params = NULL);
+
+ void gen_template_params(std::ostream &os,asn1::node *params);
+
+ void gen_template_signature(std::ostream &os,asn1::node *params);
+
+ /**
+ *
+ */
+ void gen_set( std::ostream &os
+ , asn1::set *n);
+
+ /*
+ * Ros generation Code
+ */
+ void gen_object_class(std::ostream &os,asn1::assignment *n);
+ void gen_object_class_interface(std::ostream &os,asn1::assignment *n);
+ void gen_object_class_missing(std::ostream &os,asn1::assignment *n);
+ void gen_object_class_opt(std::ostream &os,asn1::assignment *n);
+ void gen_object_class_attributes(std::ostream &os,asn1::assignment *n);
+
+ void gen_object_class_printf(std::ostream &os, asn1::assignment *n);
+
+ void gen_object(std::ostream &os,asn1::assignment *n);
+ void gen_object_error(std::ostream &os,asn1::node *n);
+ void gen_object_operation(std::ostream &os,asn1::node *n);
+ void gen_object_operation_package(std::ostream &os,asn1::node *n);
+ void gen_object_connection(std::ostream &os,asn1::node *n);
+ /**
+ *
+ */
+ void gen_module(std::ostream &os,asn1::module *n);
+ protected:
+ std::vector<std::string> m_Stack;
+};
+/**
+ * vim:et:sw=2:ts=2
+ */
+#endif
--- /dev/null
+PROJECT(libasn1parser)
+
+IF(CMAKE_CROSSCOMPILING)
+ SET(IMPORT_EXECUTABLES "IMPORTFILE-NOTFOUND" CACHE FILEPATH "Point to the
+ export file from native build")
+ INCLUDE(${IMPORT_EXECUTABLES})
+ENDIF(CMAKE_CROSSCOMPILING)
+
+
+# Only for Linux not MAC
+IF(APPLE)
+ SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG ")
+ELSEIF(WIN32)
+ SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG ")
+ELSE(APPLE)
+ SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG -std=c++0x")
+ SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++0x")
+ENDIF(APPLE)
+
+INCLUDE(${rules_SOURCE_DIR}/flex.cmake)
+
+
+LEXGEN(asn1.l lasn1.cpp)
+BISONGEN(asn1.y pasn1.cpp cpp)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../libgen)
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../adt)
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+INCLUDE_DIRECTORIES(${aebutils_SOURCE_DIR})
+
+IF (NOT CMAKE_CROSSCOMPILING)
+ADD_LIBRARY(libasn1p
+ lasn1.cpp
+ pasn1.cpp
+ asn1_parser.cpp
+ )
+TARGET_LINK_LIBRARIES(libasn1p asn1adt)
+
+ MESSAGE("Export Executables to ${CMAKE_BINARY_DIR}")
+ EXPORT(TARGETS libasn1p asn1adt FILE ${CMAKE_BINARY_DIR}/ImportExecutables.cmake
+ NAMESPACE native-)
+ENDIF(NOT CMAKE_CROSSCOMPILING)
+
+#IF(CMAKE_CROSSCOMPILING)
+# SET(asn1p_EXE native-asn1p)
+# GET_TARGET_PROPERTY(test ${asn1p_EXE} IMPORTED_LOCATION_DEBUG)
+# SET(asn1p_EXE ${test})
+#ELSE(CMAKE_CROSSCOMPILING)
+# SET(asn1p_EXE ${CMAKE_CURRENT_BINARY_DIR}/asn1p)
+#ENDIF(CMAKE_CROSSCOMPILING)
+
+
+# Install Stuff
+#IF (NOT CMAKE_CROSSCOMPILING)
+#INSTALL(TARGETS asn1p
+# DESTINATION bin/)
+#ENDIF(NOT CMAKE_CROSSCOMPILING)
+
+
--- /dev/null
+%{
+#include <cstdio>
+#include <stdio.h>
+#include <errno.h>
+
+//#include "lasn1.hpp"
+#include "asn1_node.h"
+#include "asn1_constraint.h"
+#include "asn1_module.h"
+
+/*
+%option never-interactive
+*/
+#if 0
+#undef YYSTYPE
+typedef union
+{
+ asn1::node *node;
+ asn1::constraint *constraint;
+ asn1::module *module;
+} YYSTYPE;
+#define YYSTYPE_IS_DECLARED 1
+//#define YYSTYPE asn1::node
+#define YYPARSER_PARAM yylval
+#define YYLEX_PARAM yylval
+#define YY_DECL int _asn1_lex(asn1::node *yylval)
+ asn1::node *node;
+ asn1::constraint *constraint;
+ asn1::module *module;
+ asn1::reference *reference;
+ asn1::reference::component *ref_comp;
+ asn1::value *value;
+ asn1::node::tag_type tag;
+ asn1::node::marker_type *marker;
+} YYSTYPE;
+#else
+typedef union
+{
+ asn1::node *node;
+ asn1::constraint *constraint;
+ asn1::module *module;
+ asn1::reference *reference;
+ asn1::reference::component *ref_comp;
+} YYSTYPE;
+#define YYSTYPE_IS_DECLARED 1
+#define YY_DECL int _asn1_lex(YYSTYPE *yylval)
+#endif
+
+#include "pasn1.hpp"
+
+long
+asn1_atoi(const char *ptr);
+
+void _asn1_error(const char *s) {
+ printf("Failed line: %d %s <%s>\n",yylineno,s,yytext);
+#if 1
+ exit(1);
+#endif
+};
+
+#define TOK(x) {return x;}
+#define REF_TF { yylval->reference = new asn1::typefield_reference(yytext);return T_TYPEFIELDREFERENCE;}
+#define REF_VF { yylval->reference = new asn1::valuefield_reference(yytext);return T_VALUEFIELDREFERENCE;}
+#define NODE_TOK(x) { yylval->node = new asn1::node(yytext);return x;}
+
+#define NUM_TOK(x) { asn1::valuetype *vt = new asn1::valuetype(std::string(yytext),NULL);\
+ (yylval)->node = vt; \
+ asn1::value *v = new asn1::value(asn1::value::VT_INTEGER); \
+ v->m_integer = asn1_atoi(yytext);\
+ vt->value(v); \
+ vt->value_long(asn1_atoi(yytext)); \
+ return x;\
+ }
+
+#define NUMV_TOK(x,val) { asn1::valuetype *vt = new asn1::valuetype(std::string(yytext),NULL);\
+ (yylval)->node = vt; \
+ asn1::value *v = new asn1::value(asn1::value::VT_INTEGER); \
+ v->m_integer = val;\
+ (yylval)->node->value(v); \
+ (yylval)->node->value_long(val); \
+ return x;\
+ }
+#define DOUBLE_TOK(x) { *yylval = new asn1::valuetype(std::string(yytext),NULL);return x;}
+%}
+
+%option prefix="_asn1_"
+%option stack
+%option yylineno
+/*
+%option noyywrap stack
+%option debug
+*/
+%pointer
+
+%x dash_comment
+%x idash_comment
+%x cpp_comment
+%x quote
+%x opaque
+%x encoding_control
+%x with_syntax
+%x object
+
+/* */
+Digits [0-9]+
+NDigits -{Digits}
+
+Real [-+]?[0-9]+[.]?([eE][-+]?)?[0-9]+
+
+
+
+Char ([^\n\t\"\'\\])
+Char_Literal "'"({Char}|\")"'"
+String_Literal \"({Char}|"'")*\"
+HString '[0-9A-F \r\r\v\f\n]+'H
+BString '[01 \t\r\v\f\n]+'B
+Identifier [a-z][a-zA-Z0-9]*([-][a-zA-Z0-9]+)*
+CapitalReference [A-Z][A-Z0-9]*([-][A-Z0-9]+)*
+TypeReference [A-Z][A-Za-z0-9]*([-][A-Za-z0-9]+)*
+
+TypeFieldReference &{TypeReference}
+ValueFieldReference &{Identifier}
+
+nl [\r\n\v\f]
+
+wsp [\t\r\v\f\n ]
+
+%%
+
+-{3,}/[\r\n] /* Comment */
+
+<INITIAL,with_syntax>-- yy_push_state(dash_comment);
+<INITIAL,object>-- yy_push_state(dash_comment);
+
+<dash_comment>{ /* Very special to treat rules for dash_comment rules */
+ {nl} yy_pop_state();
+ -- yy_pop_state();
+ - /* single dash */
+ [^\r\v\f\n-]+ /* do nothing */
+}
+
+<INITIAL,cpp_comment>"/*" yy_push_state(cpp_comment);
+
+<cpp_comment>{
+ [^*/<] /* skip */
+ "*/" yy_pop_state();
+ . /* skip */
+}
+
+"::=" TOK(T_ASSIGN)
+
+{BString} TOK(T_bstring)
+{Digits} NUM_TOK(T_NUM)
+{NDigits} NUM_TOK(T_NUM)
+
+ABSENT TOK(T_ABSENT)
+ABSTRACT TOK(T_ABSTRACT)
+ABSTRACT-SYNTAX TOK(T_ABSTRACT_SYNTAX)
+ALL TOK(T_ALL)
+ANY TOK(T_ANY)
+APPLICATION TOK(T_APPLICATION)
+AUTOMATIC TOK(T_AUTOMATIC)
+BEGIN TOK(T_BEGIN)
+BIT TOK(T_BIT)
+
+BMPString TOK(T_BMPString)
+BOOLEAN TOK(T_BOOLEAN)
+BY TOK(T_BY)
+CHARACTER TOK(T_CHARACTER)
+CHOICE TOK(T_CHOICE)
+CLASS TOK(T_CLASS)
+COMPONENT TOK(T_COMPONENT)
+COMPONENTS TOK(T_COMPONENTS)
+CONTAINING TOK(T_CONTAINING)
+CONSTRAINED TOK(T_CONSTRAINED)
+DATE TOK(T_DATE)
+DATE-TIME TOK(T_DATE_TIME)
+DEFAULT TOK(T_DEFAULT)
+DEFINED TOK(T_DEFINED) /* Not reserved word in ASN1 may be old parser (ANY DEFINED BY) */
+
+DEFINITIONS TOK(T_DEFINITIONS)
+DURATION TOK(T_DURATION)
+EMBEDDED
+ENCODED TOK(T_ENCODED)
+ENCODING-CONTROL TOK(T_ENCODING_CONTROL)
+END TOK(T_END)
+ENUMERATED TOK(T_ENUMERATED)
+EXCEPT TOK(T_EXCEPT)
+EXPLICIT TOK(T_EXPLICIT)
+EXPORTS TOK(T_EXPORTS)
+EXTENSIBILITY TOK(T_EXTENSIBILITY)
+EXTERNAL TOK(T_EXTERNAL)
+FALSE TOK(T_ASN1_FALSE)
+FROM TOK(T_FROM)
+GeneralizedTime TOK(T_GeneralizedTime)
+GeneralString TOK(T_GeneralizedString)
+GraphicString TOK(T_GraphicString)
+{HString} TOK(T_hstring)
+IA5String TOK(T_IA5String)
+IDENTIFIER TOK(T_STR_IDENTIFIER)
+IMPLICIT TOK(T_IMPLICIT)
+IMPLIED TOK(T_IMPLIED)
+IMPORTS TOK(T_IMPORTS)
+INCLUDES TOK(T_INCLUDES)
+INSTANCE TOK(T_INSTANCE)
+INSTRUCTIONS TOK(T_INSTRUCTIONS)
+INTEGER TOK(T_INTEGER)
+INTERSECTION TOK(T_INTERSECTION)
+ISO64String TOK(T_ISO646String)
+MAX TOK(T_MAX)
+MIN TOK(T_MIN)
+MINUS-INFINITY TOK(T_MINUS_INFINITY)
+NOT-A-NUMBER TOK(T_NOT_A_NUMBER)
+NULL TOK(T_NULL)
+NumericString TOK(T_NumericString)
+ObjectDescriptor TOK(T_ObjectDescriptorString)
+OBJECT TOK(T_OBJECT)
+OCTET TOK(T_OCTET)
+OF TOK(T_OF)
+OID-IRI TOK(T_OID_IRI)
+OPTIONAL TOK(T_OPTIONAL)
+PATTERN TOK(T_PATTERN)
+PDV
+PLUS-INFINITY
+PRESENT TOK(T_PRESENT)
+PrintableString TOK(T_PrintableString)
+PRIVATE
+REAL TOK(T_REAL)
+RELATIVE-OID TOK(T_RELATIVE_OID)
+RELATIVE-OID-IRI TOK(T_RELATIVE_OID_IRI)
+SEQUENCE TOK(T_SEQUENCE)
+SET TOK(T_SET)
+SETTINGS TOK(T_SETTINGS)
+SIZE TOK(T_SIZE)
+STRING TOK(T_STRING)
+SYNTAX TOK(T_SYNTAX)
+T61String TOK(T_T61String)
+TAGS TOK(T_TAGS)
+TeletexString TOK(T_TeletexString)
+TIME TOK(T_TIME)
+TIME-OF-DAY TOK(T_TIME_OF_DAY)
+TRUE TOK(T_ASN1_TRUE)
+UNION TOK(T_UNION)
+UNIQUE TOK(T_UNIQUE)
+UNIVERSAL TOK(T_UNIVERSAL)
+UniversalString TOK(T_UniversalString)
+
+UTCTime TOK(T_UTCTime)
+UTF8String TOK(T_UTF8String)
+
+VideotextString TOK(T_VideotextString)
+VisibleString TOK(T_VisibleString)
+WITH TOK(T_WITH)
+
+
+
+
+{Identifier} NODE_TOK(T_IDENTIFIER)
+{String_Literal} NODE_TOK(T_IDENTIFIER)
+{CapitalReference} NODE_TOK(T_CAPITALREFERENCE)
+{TypeReference} NODE_TOK(T_TYPEREFERENCE)
+{TypeFieldReference} REF_TF
+{ValueFieldReference} REF_VF
+
+[{][\t\r\v\f\n ]*[0-7][,][\t\r\v\f\n ]*[0-9]+[\t\r\v\f\n ]*[}] {
+ TOK(T_Tuple)
+}
+
+
+[{][\t\r\v\f\n ]*[0-9]+[,][\t\r\v\f\n ]*[0-9]+[,][\t\r\v\f\n ]*[0-9]+[,][\t\r\v\f\n ]*[0-9]+[\t\r\v\f\n ]*[}] {
+ TOK(T_Quadruple)
+ }
+
+
+"<" TOK(T_LT)
+"@" TOK(T_AT)
+"!" TOK(T_EXCLAMATION)
+"[" TOK(T_LBRACKET)
+"]" TOK(T_RBRACKET)
+"{" TOK(T_LBRACET)
+"}" TOK(T_RBRACET)
+")" TOK(T_RPARENTHESES)
+"(" TOK(T_LPARENTHESES)
+"." TOK(T_POINT)
+".." TOK(T_TWOPOINT)
+"..." TOK(T_THREEPOINT)
+"," TOK(T_COMMA)
+";" TOK(T_SIMILICON)
+":" TOK(T_COLON)
+"|" TOK(T_UNION)
+"^" TOK(T_EXCEPT)
+"_" TOK(T_USCORE)
+{wsp}+ /* ignore whitespace*/
+
+<with_syntax>{
+ {CapitalReference} NODE_TOK(T_CAPITALREFERENCE)
+ {TypeFieldReference} REF_TF
+ {ValueFieldReference} REF_VF
+ "," TOK(T_COMMA)
+ "}" TOK(T_RBRACET)
+ "[" TOK(T_LBRACKET)
+ "]" TOK(T_RBRACKET)
+ {wsp}+ /* ignore whitespace*/
+}
+
+<object>{
+ INTEGER TOK(T_INTEGER)
+ {Identifier} NODE_TOK(T_IDENTIFIER)
+ {String_Literal} NODE_TOK(T_IDENTIFIER)
+ {CapitalReference} NODE_TOK(T_CAPITALREFERENCE)
+ {TypeReference} NODE_TOK(T_TYPEREFERENCE)
+ {TypeFieldReference} REF_TF
+ {ValueFieldReference} REF_VF
+ "{" TOK(T_LOBJBRACET)
+ "}" TOK(T_RBRACET)
+ "<" TOK(T_LT)
+ "@" TOK(T_AT)
+ "!" TOK(T_EXCLAMATION)
+ "[" TOK(T_LBRACKET)
+ "]" TOK(T_RBRACKET)
+ ")" TOK(T_RPARENTHESES)
+ "(" TOK(T_LPARENTHESES)
+ "." TOK(T_POINT)
+ ".." TOK(T_TWOPOINT)
+ "..." TOK(T_THREEPOINT)
+ "," TOK(T_COMMA)
+ ";" TOK(T_SIMILICON)
+ ":" TOK(T_COLON)
+ "|" TOK(T_UNION)
+ "^" TOK(T_EXCEPT)
+ {wsp}+ /* ignore whitespace*/
+
+}
+
+
+<encoding_control>{
+
+ . /**/
+ END unput('D'); unput('N'); unput('E'); yy_pop_state();
+ }
+
+%%
+#if 0
+itu-t NUMV_TOK(T_NUM,0)
+iso NUMV_TOK(T_NUM,1)
+joint-iso-itu-t NUMV_TOK(T_NUM,2)
+joint-iso-ccitt NUMV_TOK(T_NUM,2)
+#endif
+void enable_with_syntax()
+{
+ yy_push_state(with_syntax);
+}
+void disable_with_syntax()
+{
+ yy_pop_state();
+}
+
+void enable_encoding_control()
+{
+ yy_push_state(encoding_control);
+}
+
+void enable_object()
+{
+ yy_push_state(object);
+}
+void disable_object()
+{
+ yy_pop_state();
+}
+
+
+
+long
+asn1_atoi(const char *ptr)
+{
+ long ret;
+ return atol(ptr);
+}
+
+double
+asn1_atod(const char *ptr)
+{
+ double ret;
+ errno = 0;
+ ret = strtod(ptr,0);
+ if (errno)
+ {
+ std::cerr<<" Value out range : "<<ptr<<std::endl;
+ }
+
+ return ret;
+}
--- /dev/null
+%{\r
+\r
+#include <sstream>\r
+#include <fstream>\r
+#include <cstdio>\r
+#include <assert.h>\r
+#include <stdio.h>\r
+#include <sys/stat.h>\r
+#include <sys/types.h>\r
+#ifndef _WIN32\r
+#include <unistd.h>\r
+#endif\r
+#include "asn1_node.h"\r
+#include "asn1_constraint.h"\r
+#include "asn1_reference.h"\r
+#include "asn1_value.h"\r
+#include "asn1_parser.h"\r
+\r
+typedef union\r
+{\r
+ asn1::node *node;\r
+ asn1::constraint *constraint;\r
+ asn1::module *module;\r
+ asn1::reference *reference;\r
+ asn1::reference::component *ref_comp;\r
+ asn1::value *value;\r
+ asn1::node::tag_type tag;\r
+ asn1::node::marker_type *marker;\r
+ asn1::syntax_parser::fragment *fragment;\r
+ asn1::classfield *classfield;\r
+ asn1::parameter *parameter;\r
+ asn1::assignment *assignment;\r
+} YYSTYPE;\r
+#define YYSTYPE_IS_DECLARED 1\r
+\r
+#if defined(__MINGW32__)\r
+# define SIZE_T_SPECIFIER "%Iu"\r
+#elif defined(__GNUC__) || defined(__APPLE__)\r
+# define SIZE_T_SPECIFIER "%zu"\r
+#else\r
+# define SIZE_T_SPECIFIER "%ld"\r
+#endif\r
+extern void _asn1_error( const char *s);\r
+extern int _asn1_lex(YYSTYPE *yylval);\r
+extern void enable_with_syntax(void);\r
+extern void enable_encoding_control(void);\r
+extern void disable_with_syntax(void);\r
+extern void enable_object(void);\r
+extern void disable_object(void);\r
+//#include "lasn1.cpp"\r
+\r
+static\r
+asn1::parser *gParser = asn1::parser::instance();\r
+\r
+#if defined(__GNUC__) && defined(DEBUG)\r
+#define ASN_LOG_DEBUG(fmt,args...) do {\\r
+ char _lbuf[256]; \\r
+ if ( gLog.is_open()) { \\r
+ gLog<<"DEBUG "; \\r
+ sprintf(_lbuf,fmt,##args); gLog<<_lbuf; \\r
+ sprintf(_lbuf," (asn1.y : %d)\n",__LINE__); gLog<<_lbuf; \\r
+ } else if (gParser->debug_console() ) { \\r
+ fprintf(stderr,"asn1_parser (DEBUG): "); \\r
+ fprintf(stderr,fmt,##args);\\r
+ fprintf(stderr," (asn1.y : %d)\n",__LINE__);\\r
+ } \\r
+} while (0)\r
+\r
+#define ASN_LOG_WARNING(fmt,args...) do {\\r
+ char _lbuf[256]; \\r
+ if (gLog.is_open()) { \\r
+ gLog<<"WARN "; \\r
+ sprintf(_lbuf,fmt,##args); gLog<<_lbuf; \\r
+ sprintf(_lbuf," (asn1.y : %d)\n",__LINE__); gLog<<_lbuf; \\r
+ } \\r
+ fprintf(stderr,"asn1_parser (WARNI): "); \\r
+ fprintf(stderr,fmt,##args);\\r
+ fprintf(stderr," (asn1.y : %d)\n",__LINE__);\\r
+} while (0)\r
+\r
+#define ASN_LOG_ERROR(fmt,args...) do {\\r
+ char _lbuf[256]; \\r
+ if ( gLog.is_open()) { \\r
+ gLog<<"ERROR "; \\r
+ sprintf(_lbuf,fmt,##args); gLog<<_lbuf; \\r
+ sprintf(_lbuf," (asn1.y : %d)\n",__LINE__); gLog<<_lbuf; \\r
+ } \\r
+ fprintf(stderr,"asn1_parser (ERROR): "); \\r
+ fprintf(stderr,fmt,##args);\\r
+ fprintf(stderr," (asn1.y : %d)\n",__LINE__);\\r
+} while (0)\r
+\r
+static std::fstream gLog;\r
+\r
+void open_log(const std::string &fn)\r
+{\r
+ struct stat st;\r
+ // Check if gLog directory exists\r
+ if (stat("log",&st) == -1 ) {\r
+#ifdef WIN32\r
+ mkdir("log");\r
+#else\r
+ mkdir("log",0777);\r
+#endif\r
+ }\r
+ // \r
+ std::string _logname("log/"); _logname.append(fn); _logname.append(".parser.log");\r
+ if ( gLog.is_open())\r
+ {\r
+ std::cerr<<"open_log "<<fn<<" already open ?"<<std::endl;\r
+ } else \r
+ {\r
+ gLog.open(_logname.c_str(),std::fstream::out | std::fstream::app);\r
+ }\r
+}\r
+\r
+void close_log()\r
+{\r
+ if ( gLog.is_open() ) \r
+ gLog.close();\r
+}\r
+#elif defined(_WIN32)\r
+ static std::fstream gLog;\r
+ void open_log(const std::string &fn) {\r
+ }\r
+ void close_log() {\r
+ }\r
+#define ASN_LOG_DEBUG(fmt,...) \\r
+ do { printf(fmt "\n" , __VA_ARGS__); } while(0)\r
+#define ASN_LOG_ERROR(fmt,...) \\r
+ do { printf(fmt "\n" , __VA_ARGS__); } while(0)\r
+#define ASN_LOG_WARNING(fmt,...) \\r
+ do { printf(fmt "\n" , __VA_ARGS__); } while(0)\r
+#else\r
+ static std::fstream gLog;\r
+ void open_log(const std::string &fn) {\r
+ }\r
+ void close_log() {\r
+ }\r
+ static inline void ASN_LOG_DEBUG(const char *fmt,...) {(void)fmt;};\r
+ static inline void ASN_LOG_ERROR(const char *fmt,...) {(void)fmt;};\r
+ static inline void ASN_LOG_WARNING(const char *fmt,...) {(void)fmt;};\r
+#endif\r
+\r
+typedef std::map<std::string,asn1::valuetype *> OidMapType;\r
+typedef OidMapType::iterator OidMapIterator;\r
+typedef OidMapType::const_iterator OidMapConstIterator;\r
+\r
+static OidMapType oid_map;\r
+\r
+static asn1::module * get_current_module ( void )\r
+{\r
+ asn1::parser *p = asn1::parser::instance();\r
+ return (asn1::module *) p->module();\r
+}\r
+static asn1::reference * current_ref;\r
+static asn1::classdef *gCurrentClassDef = NULL;\r
+\r
+%}\r
+\r
+%token T_ABSENT\r
+%token T_ABSTRACT\r
+%token T_ABSTRACT_SYNTAX\r
+%token T_ALL\r
+%token T_ANY\r
+%token T_APPLICATION\r
+%token T_ASN1_TRUE\r
+%token T_ASN1_FALSE\r
+%token T_ASSIGN\r
+%token T_AT\r
+%token T_AUTOMATIC\r
+%token T_BEGIN\r
+%token T_BIT\r
+%token T_BOOLEAN\r
+%token T_BY\r
+%token <node>T_CAPITALREFERENCE\r
+%token T_CHARACTER\r
+%token T_CHOICE\r
+%token T_CLASS\r
+%token T_COLON\r
+%token T_COMPONENT\r
+%token T_COMPONENTS\r
+%token T_CONTAINING\r
+%token T_DATE\r
+%token T_DATE_TIME\r
+%token T_CONSTRAINED\r
+%token T_DEFAULT\r
+%token T_DEFINITIONS\r
+%token T_DURATION\r
+%token T_ENCODED\r
+%token T_ENCODING_CONTROL\r
+%token T_END\r
+%token T_EXPLICIT\r
+%token T_EXCEPT\r
+%token T_EXCLAMATION\r
+%token T_EXPORTS\r
+%token T_EXTENSIBILITY\r
+%token T_EXTERNAL\r
+%token <node>T_IDENTIFIER\r
+%token T_IMPLICIT\r
+%token T_IMPLIED\r
+%token T_INCLUDES\r
+%token T_INSTANCE\r
+%token T_INSTRUCTIONS\r
+%token <node>T_INTEGER\r
+%token T_INTERSECTION\r
+%token T_LT\r
+%token T_MAX\r
+%token T_MIN\r
+%token T_MINUS_INFINITY\r
+%token T_NOT_A_NUMBER\r
+%token T_NULL\r
+%token <node>T_NUM\r
+%token T_OCTET\r
+%token T_OPTIONAL\r
+%token T_OF\r
+%token T_OID_IRI\r
+%token T_OBJECT\r
+%token T_Quadruple\r
+%token T_POINT\r
+%token T_PATTERN\r
+%token T_PRESENT\r
+%token T_PRIVATE\r
+%token T_REAL\r
+%token T_RELATIVE_OID\r
+%token T_RELATIVE_OID_IRI\r
+%token T_SIMILICON\r
+%token T_SEQUENCE\r
+%token T_SET\r
+%token T_SETTINGS\r
+%token T_SIZE\r
+%token T_STRING\r
+%token T_SYNTAX\r
+%token T_Tuple\r
+%token T_UNION\r
+%token T_UNIVERSAL\r
+%token T_UNIQUE\r
+%token T_STR_IDENTIFIER\r
+%token <node>T_TYPEREFERENCE\r
+%token <reference>T_TYPEFIELDREFERENCE\r
+%token <reference>T_VALUEFIELDREFERENCE\r
+%token T_DEFINED\r
+%token T_TAGS\r
+%token T_UTCTime\r
+%token T_GeneralizedTime\r
+%token T_GeneralizedString\r
+%token T_GraphicString\r
+%token T_BMPString\r
+%token T_IA5String\r
+%token T_ISO646String\r
+%token T_NumericString\r
+%token T_ObjectDescriptorString\r
+%token T_PrintableString\r
+%token T_TeletexString\r
+%token T_TIME\r
+%token T_TIME_OF_DAY\r
+%token T_T61String\r
+%token T_UniversalString\r
+%token T_UTF8String\r
+%token T_VideotextString\r
+%token T_VisibleString\r
+%token T_FROM\r
+%token T_IMPORTS\r
+%token T_ENUMERATED\r
+%token T_PLUS\r
+%token T_MINUS\r
+%token T_LPARENTHESES\r
+%token T_RPARENTHESES\r
+%token T_LBRACET\r
+%token T_LOBJBRACET\r
+%token T_RBRACET\r
+%token T_LBRACKET\r
+%token T_RBRACKET\r
+%token T_COMMA\r
+%token T_TWOPOINT\r
+%token T_THREEPOINT\r
+%token T_WITH\r
+%token T_USCORE\r
+%token T_bstring\r
+%token T_hstring\r
+\r
+%type <tag> explicit_implicit opt_explicit_implicit\r
+%type <tag> tag_class\r
+%type <tag> tag\r
+%type <tag> tag_type\r
+%type <tag> opt_tag\r
+\r
+%type <module> definitions\r
+%type <node> alternative_type\r
+%type <node> component_type\r
+%type <node> component_type_lists\r
+%type <node> constant_list\r
+%type <node> constant\r
+%type <node> opt_component_type_lists\r
+%type <node> extension_and_exception \r
+%type <node> exception_spec\r
+%type <constraint> at_notation_list\r
+%type <constraint> at_notation_element \r
+%type <constraint> opt_constraint_def\r
+%type <constraint> constraint_def\r
+%type <constraint> contents_constraint\r
+%type <constraint> general_constraint_def\r
+%type <constraint> user_defined_constraint\r
+%type <constraint> subtype_constraint_def\r
+%type <constraint> set_of_constraints\r
+%type <constraint> value_range\r
+%type <constraint> component_relation_constraint\r
+%type <constraint> constraint_range_spec\r
+%type <constraint> constraint_subtype_element \r
+%type <constraint> constraint_spec_subtype_element\r
+%type <constraint> inner_type_constraint\r
+%type <constraint> table_constraint\r
+%type <constraint> simple_table_constraint\r
+%type <constraint> opt_presence_constraint\r
+%type <node> component_id_list\r
+\r
+%type <constraint> contained_subtype \r
+%type <node> opt_imports\r
+%type <node> imports_def\r
+%type <node> import_item\r
+%type <node> identifier\r
+%type <node> opt_identifier\r
+%type <classfield> oclass_field\r
+%type <node> pos_neg_identifier\r
+%type <node> definitions_id\r
+%type <node> referenced_type\r
+%type <node> token\r
+%type <module> type_constant_list \r
+%type <node> type_constant \r
+%type <node> type\r
+%type <node> type_reference\r
+%type <node> type_declaration\r
+%type <node> builtin_type\r
+%type <node> defined_type\r
+%type <node> type_assign_right\r
+%type <node> type_assign_right_tag\r
+%type <node> type_assign_right_tag_default\r
+%type <node> constant_set_def\r
+%type <node> object_assignment\r
+%type <node> type_assignment\r
+%type <reference> complex_type_reference \r
+%type <ref_comp> complex_type_reference_amp_list\r
+%type <ref_comp> complex_type_reference_element\r
+%type <node> value_assignment\r
+%type <node> object_set_assignment\r
+%type <reference> object_class_reference\r
+%type <node> obj_constant_list\r
+%type <node> obj_constant\r
+%type <node> defined_object \r
+%type <module> definition_module\r
+%type <node> object_defn\r
+%type <node> parameterized_value\r
+%type <node> parameterized_objectset\r
+%type <ref_comp> primitive_field_reference\r
+%type <reference> field_name\r
+%type <node> pos_num\r
+%type <node> neg_num\r
+%type <node> pos_neg_num\r
+%type <node> component_value\r
+%type <node> component_value_list\r
+%type <node> value\r
+%type <node> value_reference\r
+%type <node> character_string_def \r
+%type <node> restricted_character_string_def\r
+%type <node> unrestricted_character_string_def\r
+%type <node> restricted_character_string_value\r
+%type <node> defined_value\r
+%type <node> builtin_value\r
+%type <node> value_from_object\r
+%type <constraint> value_set\r
+%type <constraint> object_set\r
+%type <node> object\r
+%type <reference> defined_object_class \r
+%type <node> set_def\r
+%type <node> set_value\r
+%type <node> sequence_def\r
+%type <node> choice_def \r
+%type <node> defined_syntax_list\r
+%type <node> parameter_list \r
+%type <node> parameter_args \r
+%type <parameter> parameter_arg\r
+%type <node> act_parameter_args\r
+%type <node> act_parameter_arg\r
+%type <node> default_syntax \r
+%type <node> defined_syntax\r
+%type <node> defined_syntax_token\r
+%type <node> general_string_def\r
+%type <constraint> element_set_specs\r
+%type <constraint> element_set_spec\r
+%type <node> integer_def \r
+%type <node> real_def \r
+%type <node> enumerated_def \r
+%type <node> boolean_def \r
+%type <node> time_def \r
+%type <node> any_def \r
+%type <node> octet_string_def \r
+%type <node> object_def\r
+%type <node> object_class_def \r
+%type <node> bit_string_def \r
+%type <node> bit_element_def\r
+%type <node> bit_element_list\r
+%type <node> export_element export_list\r
+%type <constraint> with_components_list\r
+%type <constraint> with_components_element\r
+%type <node> which_list\r
+%type <marker> default\r
+%type <marker> opt_default\r
+\r
+%type <fragment> opt_token syntax_token_list\r
+\r
+%name-prefix="_asn1_"\r
+%pure-parser\r
+\r
+\r
+%%\r
+\r
+definition_files:definitions\r
+ {\r
+ asn1::module *m = get_current_module ( );\r
+ ASN_LOG_DEBUG("definition_files: got definition" ); \r
+ }\r
+ | definition_files definitions\r
+ {\r
+ asn1::module *m = get_current_module ( );\r
+ ASN_LOG_DEBUG("definition_files: got 1 definition" ); \r
+ }\r
+;\r
+\r
+\r
+/**\r
+ * export rules\r
+ */ \r
+opt_exports:\r
+ | exports_def\r
+;\r
+\r
+exports_def:\r
+ T_EXPORTS {\r
+ asn1::parser *p = asn1::parser::instance();\r
+ $<module>$ = get_current_module();\r
+ $<module>$->enter_context(new asn1::exports());\r
+ } export_list T_SIMILICON \r
+ {\r
+ ASN_LOG_DEBUG("exports_def: got exports" ); \r
+ asn1::node *res = $<module>2->leave_context();\r
+ $<node>$ =res;\r
+ }\r
+ | T_EXPORTS T_ALL T_SIMILICON\r
+ {\r
+ ASN_LOG_DEBUG("exports_def: got exports ALL" );\r
+ asn1::exports *exp = new asn1::exports();\r
+ exp->all(true);\r
+ $<node>$ = exp;\r
+ }\r
+ | T_EXPORTS T_SIMILICON\r
+ {\r
+ ASN_LOG_DEBUG("exports_def: got exports nothing" ); \r
+ }\r
+;\r
+\r
+export_list: export_element\r
+ {\r
+ asn1::parser *p = asn1::parser::instance();\r
+ asn1::module *m= (asn1::module *) p->module();\r
+ ASN_LOG_DEBUG("export_list: CM %s Got Item: %s"\r
+ , m->name().c_str() \r
+ , $1->name().c_str()); \r
+ m->enter_symbol($1,$1->type_id()());\r
+ }\r
+ | export_list T_COMMA export_element\r
+ {\r
+ asn1::parser *p = asn1::parser::instance();\r
+ asn1::module *m= (asn1::module *) p->module();\r
+ ASN_LOG_DEBUG("import_list: CM %s Got Item 1: %s"\r
+ , m->name().c_str() \r
+ , $3->name().c_str()); \r
+ m->enter_symbol($3,$3->type_id()());\r
+ }\r
+;\r
+\r
+export_element: T_TYPEREFERENCE\r
+ {\r
+ ASN_LOG_DEBUG("export_element: got typeref" ); \r
+ $$ = new asn1::typeref($1->name(),\r
+ new asn1::simple_reference($1->name())\r
+ );\r
+ delete $1; \r
+ }\r
+ | T_TYPEREFERENCE T_LBRACET T_RBRACET\r
+ {\r
+ ASN_LOG_DEBUG("export_element: got typeref {}" ); \r
+ $$ = new asn1::typeref($1->name(),\r
+ new asn1::simple_reference($1->name())\r
+ );\r
+ delete $1; \r
+ }\r
+ | T_IDENTIFIER\r
+ {\r
+ ASN_LOG_DEBUG("export_element: got identifier" ); \r
+ $$ = new asn1::typeref($1->name(),\r
+ new asn1::simple_reference($1->name())\r
+ );\r
+ delete $1; \r
+ }\r
+;\r
+\r
+/**\r
+ *\r
+ */\r
+opt_imports: /* Empty*/\r
+ {\r
+ $$ = NULL;\r
+ }\r
+ | imports_def {\r
+ $$ = $1;\r
+ }\r
+;\r
+\r
+imports_def:\r
+ T_IMPORTS \r
+ {\r
+ asn1::parser *p = asn1::parser::instance();\r
+ $<module>$ = get_current_module();\r
+ $<module>$->enter_context(new asn1::import_list());\r
+ } import_set T_SIMILICON\r
+ {\r
+ asn1::node *res = $<module>2->leave_context();\r
+ $$ =res;\r
+ }\r
+ | T_IMPORTS T_FROM T_SIMILICON {\r
+ $$ = NULL;\r
+ }\r
+ ;\r
+\r
+import_set: \r
+ import {\r
+ ASN_LOG_DEBUG("import_set got import");\r
+ }\r
+ | import_set import {\r
+ ASN_LOG_DEBUG("import_set: 1 got import");\r
+ }\r
+;\r
+\r
+import: \r
+ {\r
+ $<module>$ = get_current_module();\r
+ ASN_LOG_DEBUG("import: start Module %s "\r
+ ,$<module>$->name().c_str()\r
+ );\r
+ $<module>$->enter_context(new asn1::import("IMPORT"));\r
+ }\r
+ import_list \r
+ {\r
+ $<node>$ = $<module>1->leave_context();\r
+ } T_FROM definitions_id\r
+ {\r
+ \r
+ asn1::module *m = get_current_module();\r
+ ASN_LOG_DEBUG("import: Module %s Got import %s "\r
+ ,m->name().c_str()\r
+ ,$<node>5->name().c_str());\r
+ $<node>3->identifier($5);\r
+ $<node>3->name($5->name());\r
+ m->enter_symbol($<node>3,$<node>3->type_id()());\r
+ }\r
+;\r
+\r
+import_list:\r
+ import_item {\r
+ asn1::parser *p = asn1::parser::instance();\r
+ asn1::module *m= (asn1::module *) p->module();\r
+ ASN_LOG_DEBUG("import_list: CM %s Got Item: %s"\r
+ , m->name().c_str() \r
+ , $1->name().c_str()); \r
+ m->enter_symbol($1,$1->type_id()());\r
+ }\r
+ | import_list T_COMMA import_item {\r
+ asn1::parser *p = asn1::parser::instance();\r
+ asn1::module *m= (asn1::module *) p->module();\r
+ ASN_LOG_DEBUG("import_list: CM %s Got Item 1: %s"\r
+ , m->name().c_str() \r
+ , $3->name().c_str()); \r
+ m->enter_symbol($3,$3->type_id()());\r
+ }\r
+;\r
+\r
+import_item:\r
+ T_TYPEREFERENCE {\r
+ ASN_LOG_DEBUG("import_item: %s typeref",$1->name().c_str()); \r
+ $$ = new asn1::typeref($1->name(),\r
+ new asn1::simple_reference($1->name())\r
+ );\r
+ delete $1; \r
+ }\r
+ | T_TYPEREFERENCE T_LBRACET T_RBRACET {\r
+ ASN_LOG_DEBUG("import_item: %s parameterized typeref",$1->name().c_str()); \r
+ $$ = new asn1::typeref($1->name(),\r
+ new asn1::simple_reference($1->name())\r
+ );\r
+ delete $1;\r
+ }\r
+ | identifier\r
+ {\r
+ ASN_LOG_DEBUG("import_item: %s identifier what is it? value",$1->name().c_str()); \r
+ $$ = new asn1::typeref($1->name(),\r
+ new asn1::simple_reference($1->name(),asn1::reference::component::Lowercase)\r
+ );\r
+ delete $1;\r
+ }\r
+ | T_CAPITALREFERENCE {\r
+ ASN_LOG_DEBUG("import_item: %s CAPITAL what is it?",$1->name().c_str()); \r
+ $$ = new asn1::typeref($1->name(),\r
+ new asn1::objectclass_reference($1->name())\r
+ );\r
+ delete $1;\r
+ }\r
+ | T_CAPITALREFERENCE T_LBRACET T_RBRACET {\r
+ ASN_LOG_DEBUG("import_item: %s CAPITAL {} what is it?",$1->name().c_str()); \r
+ $$ = new asn1::typeref($1->name(),\r
+ new asn1::objectclass_reference($1->name())\r
+ );\r
+ delete $1 ;\r
+ }\r
+;\r
+/**\r
+ * main definition entry \r
+ */\r
+definitions: definitions_id \r
+ T_DEFINITIONS opt_explicit_implicit opt_tags_def T_ASSIGN T_BEGIN /* imports_def */\r
+ {\r
+ asn1::parser *p = asn1::parser::instance();\r
+ $<module>$ = p->module($1->name().c_str());\r
+ $<module>$->tag($3);\r
+#ifdef DEBUG\r
+ if (! gLog.is_open())\r
+ open_log($1->name());\r
+#endif\r
+ ASN_LOG_DEBUG("definitions: start 1 size=%zu %s def=%s pn=%s"\r
+ ,$<module>$->size()\r
+ ,$<module>$->name().c_str()\r
+ ,$1->name().c_str()\r
+ ,p->module()->name().c_str()\r
+ );\r
+ }\r
+ definition_module T_END {\r
+ asn1::parser *p = asn1::parser::instance();\r
+ ASN_LOG_DEBUG("definitions: 1 size=" SIZE_T_SPECIFIER " %s cm=%s"\r
+ ,$8->size()\r
+ ,$8->name().c_str()\r
+ ,p->module()->name().c_str()\r
+ );\r
+ asn1::module *m = $8;\r
+ close_log();\r
+ }\r
+;\r
+\r
+definition_module: opt_exports opt_imports \r
+ {\r
+ asn1::import_list *i = dynamic_cast<asn1::import_list *>($2);\r
+ asn1::exports *e = dynamic_cast<asn1::exports *>($2);\r
+ asn1::module *m = get_current_module();\r
+ m->imports(i);\r
+ m->exports(e);\r
+ } type_constant_list\r
+ {\r
+ $$ = $4;\r
+ }\r
+ ;\r
+\r
+opt_tags_def: /* Empty */\r
+ | T_TAGS \r
+ {\r
+ ASN_LOG_DEBUG("opt_tags_def just TAGS");\r
+ }\r
+ | T_TAGS opt_defs \r
+ {\r
+ ASN_LOG_DEBUG("opt_tags_def ");\r
+ }\r
+;\r
+\r
+opt_defs: opt_def\r
+ | opt_defs opt_def\r
+;\r
+\r
+opt_def: T_EXTENSIBILITY {\r
+ ASN_LOG_DEBUG("opt_def EXTENSIBILITY");\r
+ }\r
+ | T_IMPLIED {\r
+ ASN_LOG_DEBUG("opt_def IMPLIED");\r
+ }\r
+;\r
+\r
+opt_identifier: { $$ = NULL;}\r
+ | identifier \r
+ {\r
+ $$ = $1;\r
+ }\r
+;\r
+identifier: T_IDENTIFIER\r
+ {$$ = $1;}\r
+;\r
+\r
+pos_num: T_NUM {\r
+ ASN_LOG_DEBUG("pos_num got Num: %s",$1->name().c_str());\r
+ $$=$1;\r
+ $$->type_id(asn1::type::ASN1_INTEGER);\r
+ }\r
+ | T_PLUS T_NUM {\r
+ $$=$2;\r
+ $$->type_id(asn1::type::ASN1_INTEGER);\r
+ }\r
+ \r
+;\r
+\r
+neg_num: T_MINUS T_NUM {\r
+ $$ = $2;\r
+ $$->type_id(asn1::type::ASN1_INTEGER);\r
+ }\r
+;\r
+\r
+pos_neg_num: pos_num { \r
+ $$ = $1; \r
+ $$->meta_id(asn1::meta::VALUE);\r
+ }\r
+ | neg_num {\r
+ $$ = $1; \r
+ $$->meta_id(asn1::meta::VALUE);\r
+ }\r
+;\r
+\r
+pos_neg_identifier: \r
+ pos_num {\r
+ $$ = $1;\r
+ }\r
+ | neg_num {\r
+ $$ = $1;\r
+ }\r
+ | identifier {\r
+ ASN_LOG_ERROR("pos_neg_identifier: MUST BE TRANSFORMED TO valuetype%s",$1->cpp_name().c_str());\r
+ $$ = $1;\r
+ $$->type_id(asn1::type::ASN1_REFERENCE);\r
+ $$->meta_id(asn1::meta::VALUE);\r
+ }\r
+;\r
+\r
+constant: T_LPARENTHESES pos_neg_num T_RPARENTHESES\r
+ {\r
+ $$ = $2;\r
+ }\r
+ | T_IDENTIFIER T_LPARENTHESES pos_neg_num T_RPARENTHESES\r
+ {\r
+ $$ = $3;\r
+ $$->name($1->name());\r
+ delete $1;\r
+ }\r
+;\r
+\r
+constant_list:\r
+ constant {\r
+ ASN_LOG_DEBUG("constant_list: %s",$1->cpp_name().c_str());\r
+ asn1::module *m= get_current_module();\r
+ m->enter_symbol($1,$1->type_id()());\r
+ }\r
+ | constant_list T_COMMA constant {\r
+ ASN_LOG_DEBUG("constant_list 1: %s",$3->cpp_name().c_str());\r
+ asn1::module *m= get_current_module();\r
+ m->enter_symbol($3,$3->type_id()());\r
+ }\r
+;\r
+\r
+obj_constant: pos_num {\r
+ ASN_LOG_DEBUG("obj_constant: %s",$1->cpp_name().c_str());\r
+ $$ = $1;\r
+ }\r
+ | T_IDENTIFIER T_LPARENTHESES T_NUM T_RPARENTHESES {\r
+ ASN_LOG_DEBUG("obj_constant 1: %s",$1->cpp_name().c_str());\r
+ $$ = $3;\r
+ oid_map[$<node>1->name()] = dynamic_cast<asn1::valuetype *>($3); \r
+ $$->name($<node>1->name());\r
+ $$->type_id(asn1::type::ASN1_INTEGER);\r
+ delete($1);\r
+ } \r
+/* predefined identifiers \r
+itu-t NUMV_TOK(T_NUM,0)\r
+iso NUMV_TOK(T_NUM,1)\r
+joint-iso-itu-t NUMV_TOK(T_NUM,2)\r
+joint-iso-ccitt NUMV_TOK(T_NUM,2)\r
+*/\r
+ | T_IDENTIFIER {\r
+ OidMapIterator it = oid_map.find($1->name()) ;\r
+ if ( !$1->name().compare("itu-t")) \r
+ {\r
+ asn1::value *v = new asn1::value(asn1::value::VT_INTEGER);\r
+ asn1::valuetype *vt = new asn1::valuetype($1->name(),v);\r
+ $$->type_id(asn1::type::ASN1_INTEGER);\r
+ vt->value_long(0);\r
+ $$ = vt;\r
+ delete($1);\r
+ } else if ( !$1->name().compare("iso")) \r
+ {\r
+ asn1::value *v = new asn1::value(asn1::value::VT_INTEGER);\r
+ asn1::valuetype *vt = new asn1::valuetype($1->name(),v);\r
+ $$->type_id(asn1::type::ASN1_INTEGER);\r
+ vt->value_long(1);\r
+ $$ = vt;\r
+ delete($1);\r
+ } else if ( !$1->name().compare("joint-iso-itu-t")) \r
+ {\r
+ asn1::value *v = new asn1::value(asn1::value::VT_INTEGER);\r
+ asn1::valuetype *vt = new asn1::valuetype($1->name(),v);\r
+ $$->type_id(asn1::type::ASN1_INTEGER);\r
+ vt->value_long(2);\r
+ $$ = vt;\r
+ delete($1);\r
+ } else if ( !$1->name().compare("joint-iso-ccitt"))\r
+ {\r
+ asn1::value *v = new asn1::value(asn1::value::VT_INTEGER);\r
+ asn1::valuetype *vt = new asn1::valuetype($1->name(),v);\r
+ $$->type_id(asn1::type::ASN1_INTEGER);\r
+ vt->value_long(2);\r
+ $$ = vt;\r
+ delete($1);\r
+ } else if (it != oid_map.end())\r
+ {\r
+ ASN_LOG_DEBUG("obj_constant IDENTIFIER found in map %s",$1->cpp_name().c_str());\r
+ $$ = it->second;\r
+ } else \r
+ { \r
+ ASN_LOG_ERROR("obj_constant IDENTIFIER 3 must be referenced: %s",$1->cpp_name().c_str());\r
+ $$ = $1;\r
+ } \r
+ } \r
+;\r
+\r
+obj_constant_list:\r
+ obj_constant {\r
+ ASN_LOG_DEBUG("obj_constant_list: %s",$1->cpp_name().c_str());\r
+ asn1::module *m = get_current_module();\r
+ m->enter_context(new asn1::object_identifier());\r
+ m->enter_symbol($1,$1->type_id()());\r
+ $$ = $1;\r
+ }\r
+ | obj_constant_list obj_constant {\r
+ ASN_LOG_DEBUG("obj_constant_list: append: $1=%s %s",$1->cpp_name().c_str(),$2->cpp_name().c_str());\r
+ asn1::module *m = get_current_module();\r
+ m->enter_symbol($2,$2->type_id()());\r
+ }\r
+;\r
+\r
+tag_class:\r
+ { \r
+ $$.m_class = asn1::node::tag_type::TC_CONTEXT_SPECIFIC;}\r
+ | T_UNIVERSAL {\r
+ $$.m_class = asn1::node::tag_type::TC_UNIVERSAL;\r
+ }\r
+ | T_PRIVATE {\r
+ $$.m_class = asn1::node::tag_type::TC_PRIVATE;\r
+ }\r
+ | T_APPLICATION {\r
+ $$.m_class = asn1::node::tag_type::TC_APPLICATION;\r
+ }\r
+;\r
+\r
+tag_type: \r
+ tag_class T_NUM {\r
+ asn1::node *n = $2;\r
+ asn1::valuetype *vt = dynamic_cast<asn1::valuetype *>(n);\r
+ $$ = $1;\r
+ $$.m_mode = asn1::node::tag_type::TM_DEFAULT;\r
+ $$.m_value = vt->value_long();\r
+ delete $2;\r
+ }\r
+;\r
+\r
+tag: \r
+ tag_type {\r
+ $$ = $1;\r
+ $$.m_set = true;\r
+ }\r
+ | T_LBRACKET tag_type T_RBRACKET {\r
+ ASN_LOG_DEBUG("tag: tag_type 1 [%d,%ld] ",$2.m_class,$2.m_value);\r
+ $$ = $2;\r
+ $$.m_set = true;\r
+ }\r
+ | tag_type explicit_implicit {\r
+ ASN_LOG_DEBUG("tag: tag_type [%d,%ld] explicit_implicit %d",$1.m_class,$1.m_value,$2.m_mode);\r
+ $$ = $1;\r
+ $$.m_mode = $2.m_mode;\r
+ $$.m_set = true;\r
+ }\r
+ | T_LBRACKET tag_type T_RBRACKET explicit_implicit {\r
+ ASN_LOG_DEBUG("tag: tag_type 1 [%d,%ld] explicit_implicit %d",$2.m_class,$2.m_value,$4.m_mode);\r
+ $$ = $2;\r
+ $$.m_mode = $4.m_mode;\r
+ $$.m_set = true;\r
+ \r
+ }\r
+;\r
+\r
+opt_tag: \r
+ {\r
+ $$.m_class = asn1::node::tag_type::TC_NOCLASS;\r
+ $$.m_mode = asn1::node::tag_type::TM_DEFAULT;\r
+ $$.m_value = -1;\r
+ $$.m_set = false;\r
+ }\r
+ | tag {\r
+ ASN_LOG_DEBUG("opt_tag: tag cls=%d mode=%d val=%ld",$1.m_class,$1.m_mode,$1.m_value);\r
+ $$ = $1;\r
+ $$.m_set = true;\r
+ }\r
+;\r
+\r
+default: T_DEFAULT value {\r
+ ASN_LOG_DEBUG("default: with value");\r
+ $$ = new asn1::node::marker_type(asn1::node::marker_type::FL_DEFAULT);\r
+ aeb::intrusive_ptr<asn1::value> p($2->value());\r
+ $$->m_value1 = p; \r
+ }\r
+\r
+;\r
+\r
+opt_default: \r
+ { \r
+ ASN_LOG_DEBUG("opt_default: none");\r
+ $$ = new asn1::node::marker_type();\r
+ }\r
+ | default {\r
+ ASN_LOG_DEBUG("opt_default: default");\r
+ $$ = $1 ;\r
+ }\r
+ | T_OPTIONAL {\r
+ ASN_LOG_DEBUG("opt_default: optional");\r
+ $$ = new asn1::node::marker_type(asn1::node::marker_type::FL_OPTIONAL);\r
+ }\r
+;\r
+\r
+\r
+integer_def: \r
+ T_INTEGER {\r
+ $$ = new asn1::integer();\r
+ $$->meta_id(asn1::meta::TYPE);\r
+ }\r
+ | T_INTEGER T_LBRACET {\r
+ asn1::module *m= get_current_module();\r
+ m->enter_context(new asn1::integer());\r
+ $<module>$ = m;\r
+ } constant_list T_RBRACET {\r
+ $$ = $<module>3->leave_context();\r
+ ASN_LOG_DEBUG("integer_def has constant_list");\r
+ $$->meta_id(asn1::meta::TYPE);\r
+ }\r
+;\r
+\r
+\r
+real_def: \r
+ T_REAL { \r
+ $$ = new asn1::real();\r
+ }\r
+;\r
+\r
+boolean_def: T_BOOLEAN\r
+ { $$ = new asn1::boolean();}\r
+;\r
+\r
+time_def: T_UTCTime\r
+ {$$ = new asn1::utctime();}\r
+ | T_GeneralizedTime\r
+ {$$ = new asn1::generalizedtime();}\r
+;\r
+\r
+/* See X.682 */\r
+general_constraint_def:\r
+ user_defined_constraint {\r
+ ASN_LOG_DEBUG("general_constraint_def: user_defined_constraint %s",($1==NULL)?"none":$1->name().c_str());\r
+ }\r
+ | table_constraint {\r
+ ASN_LOG_DEBUG("general_constraint_def: table_constraint %s",$1->name().c_str());\r
+ }\r
+ | contents_constraint {\r
+ ASN_LOG_DEBUG("general_constraint_def: content_constraint %s ",$1->name().c_str());\r
+ }\r
+;\r
+\r
+user_defined_constraint: \r
+ T_CONSTRAINED T_BY T_LBRACET T_RBRACET {\r
+ ASN_LOG_DEBUG("user_defined_constraint constraint by empty");\r
+ $$ = new asn1::ctype_ctdby();\r
+ }\r
+ | T_CONSTRAINED T_BY T_LBRACET type T_RBRACET {\r
+ ASN_LOG_DEBUG("user_defined_constraint contrained by type: %s",$4->name().c_str());\r
+ $$ = new asn1::ctype_ctdby();\r
+ $$->value($4);\r
+ }\r
+;\r
+\r
+table_constraint:\r
+ simple_table_constraint {\r
+ ASN_LOG_DEBUG("table_constraint:simple_table_constraint TODO %s"\r
+ , $<constraint>1->value()->name().c_str());\r
+ }\r
+ | component_relation_constraint {\r
+ ASN_LOG_DEBUG("component_relation_constraint TODO");\r
+}\r
+;\r
+\r
+simple_table_constraint: \r
+ T_LBRACET type_reference T_RBRACET {\r
+ // The rules is wrong. According to X.681 simple_table_constraint ::= ObjectSet \r
+ // and ObjectSet ::= { ObjectSetSpec} \r
+ // and ObjectSetSpec = RootElementSetSpec, ...\r
+ ASN_LOG_DEBUG("simple_table_constraint {typeref=%s} CHECK constraint type",$2->name().c_str());\r
+ //$$ = new asn1::constraint("VALUE",asn1::constraint::EL_VALUE);\r
+ //TODO Is the line below correct ?\r
+ //$$->value($2);\r
+ $$ = new asn1::celt_type($2->as_typeref());\r
+ asn1::module *m = get_current_module();\r
+ $2->set_parent(m->current_context());\r
+ }\r
+;\r
+\r
+component_relation_constraint: simple_table_constraint T_LBRACET at_notation_list T_RBRACET\r
+ {\r
+ ASN_LOG_DEBUG("component_relation_constraint %s {@ %s}",$1->name().c_str(),$3->name().c_str());\r
+ $$ = new asn1::ca_crc();\r
+ $$->append($1);\r
+ $$->append($3);\r
+ }\r
+;\r
+\r
+at_notation_list: at_notation_element {\r
+ ASN_LOG_WARNING("at_notation_list: simple TODO ");\r
+ }\r
+ | at_notation_list T_COMMA at_notation_element {\r
+ ASN_LOG_WARNING("at_notation_list: TODO ");\r
+ }\r
+;\r
+\r
+at_notation_element: \r
+ T_AT component_id_list {\r
+ ASN_LOG_DEBUG("at_notation_element: TODO @ %s",$<node>2->name().c_str());\r
+ $$ = new asn1::constraint("VALUE",asn1::constraint::EL_VALUE);\r
+ $<node>2->meta_id(asn1::meta::VALUE);\r
+ $$->value($<node>2);\r
+ }\r
+ | T_AT T_POINT component_id_list {\r
+ ASN_LOG_DEBUG("at_notation_element: point TODO");\r
+ $$ = new asn1::constraint("VALUE",asn1::constraint::EL_VALUE);\r
+ $<node>3->meta_id(asn1::meta::VALUE);\r
+ $$->value($<node>3);\r
+}\r
+;\r
+\r
+component_id_list:\r
+ T_IDENTIFIER {\r
+ ASN_LOG_DEBUG("component_id_list: TODO @ %s",$1->name().c_str());\r
+ \r
+ }\r
+ | component_id_list T_POINT T_IDENTIFIER {\r
+ ASN_LOG_ERROR("component_id_list: TODO @. %s ",$3->name().c_str());\r
+ }\r
+;\r
+\r
+contents_constraint: T_CONTAINING type_reference {\r
+ ASN_LOG_DEBUG("contents_contraint %s ",$2->name().c_str());\r
+ $$ = new asn1::ctype_ctng();\r
+ $$->value($2);\r
+ }\r
+ | T_ENCODED T_BY T_IDENTIFIER {\r
+ ASN_LOG_DEBUG("contents_contraint 1 %s ",$3->name().c_str());\r
+ $$ = new asn1::celt_encodedby();\r
+ }\r
+ | T_CONTAINING type_reference T_ENCODED T_BY T_IDENTIFIER {\r
+ ASN_LOG_DEBUG("contents_contraint 2 %s ",$2->name().c_str());\r
+ $$ = new asn1::ctype_ctng();\r
+ $$->value($2);\r
+ }\r
+;\r
+\r
+constraint_def: subtype_constraint_def\r
+ { \r
+ $$ = $1;\r
+ ASN_LOG_DEBUG("constraint_def subtype_constraint_def type=%d %s",$$->type(),$$->name().c_str());\r
+ }\r
+ /* Found in X.682 45.6*/\r
+ /* Rule in set of constraint \r
+ | T_LPARENTHESES element_set_specs exception_spec T_RPARENTHESES\r
+ {\r
+ printf("constraint_def 1\n");\r
+ }\r
+ | T_LPARENTHESES general_constraint_def exception_spec T_RPARENTHESES\r
+ {\r
+ printf("constraint_def\n");\r
+ $$ = $2;\r
+ }\r
+ */\r
+;\r
+\r
+subtype_constraint_def:\r
+ set_of_constraints { \r
+ ASN_LOG_DEBUG("subtype_constraint_def: set_of_constraints");\r
+ if ($1->size() == 1)\r
+ {\r
+ // There is only one constraint, erase set and return element\r
+ $$ = *($1->begin());\r
+ delete($1);\r
+ } else\r
+ $$ = $1;\r
+ }\r
+ | T_SIZE T_LPARENTHESES element_set_specs T_RPARENTHESES {\r
+ ASN_LOG_DEBUG("subtype_constraint_def: T_SIZE %s",$3->name().c_str()); \r
+ $$ = new asn1::ctype_size();\r
+ $$->append($3);\r
+ }\r
+ \r
+;\r
+\r
+set_of_constraints: \r
+ T_LPARENTHESES element_set_specs exception_spec T_RPARENTHESES\r
+ {\r
+ ASN_LOG_DEBUG("set_of_constraints 1 ( %s)",$2->name().c_str());\r
+ $$ = new asn1::ca_set();\r
+ $$->append($2);\r
+ }\r
+ | T_LPARENTHESES general_constraint_def exception_spec T_RPARENTHESES\r
+ {\r
+ ASN_LOG_DEBUG("set_of_constraints 2 ( )");\r
+ $$ = new asn1::ca_set();\r
+ $$->append($2);\r
+ }\r
+ | set_of_constraints T_LPARENTHESES general_constraint_def exception_spec T_RPARENTHESES\r
+ {\r
+ ASN_LOG_DEBUG("set_of_constraints 3 set ( gen) REWORK");\r
+ $$ = $1;\r
+ $$->append($3);\r
+ }\r
+ | set_of_constraints T_LPARENTHESES element_set_specs exception_spec T_RPARENTHESES\r
+ { \r
+ ASN_LOG_DEBUG("set_of_constraints 4 set (elem ) REWORK");\r
+ $$ = $1;\r
+ $$->append($3);\r
+ }\r
+;\r
+\r
+element_set_specs: \r
+ T_THREEPOINT {\r
+ ASN_LOG_DEBUG("element_set_specs ... ");\r
+ $$ = new asn1::celt_ext();\r
+ }\r
+ | element_set_spec {\r
+ if ($1!= NULL) {\r
+ ASN_LOG_DEBUG("element_set_specs got one not null %s",$1->name().c_str());\r
+ } else {\r
+ ASN_LOG_DEBUG("element_set_specs got NULL ");\r
+ }\r
+ $$ = $1;\r
+ }\r
+ | element_set_spec T_COMMA T_THREEPOINT {\r
+ ASN_LOG_DEBUG("element_set_specs , ... ");\r
+ $$ = $1;\r
+ $$->append(new asn1::celt_ext());\r
+ }\r
+ | element_set_spec T_COMMA T_THREEPOINT T_COMMA element_set_spec {\r
+ ASN_LOG_DEBUG("element_set_specs , ... , set_spec ");\r
+ $$ = $1;\r
+ $$->append(new asn1::celt_ext());\r
+ $$->append($5);\r
+ }\r
+;\r
+\r
+\r
+element_set_spec: \r
+ constraint_subtype_element {\r
+ ASN_LOG_DEBUG("element_set_spec: constraint_subtype_element (%s)",($1 == NULL)?"none":$1->name().c_str());\r
+ $$ = $1;\r
+ }\r
+ | T_ALL T_EXCEPT constraint_subtype_element {\r
+ ASN_LOG_DEBUG("element_set_spec: ALL EXCEPT constraint_subtype_element");\r
+ $$ = new asn1::ca_aex();\r
+ $$->append($3);\r
+ }\r
+ | element_set_spec T_UNION constraint_subtype_element {\r
+ ASN_LOG_DEBUG("element_set_spec: UNION constraint_subtype_element");\r
+ $$ = $1;\r
+ if ($$ != NULL) {\r
+ ASN_LOG_DEBUG("element_set_spec: UNION $1 is not NULL");\r
+ if ($1->type() == asn1::constraint::CA_UNI) {\r
+ $$ = $1 ;\r
+ $$->append($3);\r
+ } else {\r
+ $$ = new asn1::ca_uni();\r
+ $$->append($1);\r
+ $$->append($3);\r
+ }\r
+ } else {\r
+ ASN_LOG_ERROR("element_set_spec: UNION $1 is NULL");\r
+ $$ = $3;\r
+ }\r
+ }\r
+ | element_set_spec T_INTERSECTION constraint_subtype_element {\r
+ ASN_LOG_DEBUG("element_set_spec: INTERSECTION constraint_subtype_element");\r
+ $$ = $1;\r
+ $$->append($3);\r
+ }\r
+ | constraint_subtype_element T_EXCEPT constraint_subtype_element {\r
+ ASN_LOG_DEBUG("element_set_spec: EXCEPT constraint_subtype_element");\r
+ $$ = $1;\r
+ $$->append($3);\r
+ }\r
+;\r
+\r
+constraint_subtype_element: \r
+ constraint_spec_subtype_element T_LPARENTHESES \r
+ {\r
+ ASN_LOG_DEBUG("constraint_subtype_element start in constraint ");\r
+ }\r
+ element_set_specs T_RPARENTHESES\r
+ {\r
+ /* This rule is not correct. It should be an ObjectSetElements */\r
+ $1->append($4);\r
+ ASN_LOG_DEBUG("constraint_subtype_element end type_reference 1 %s",$1->name().c_str());\r
+ $$ = $1;\r
+ }\r
+ | T_LPARENTHESES element_set_specs T_RPARENTHESES\r
+ {\r
+ /* This rule is not correct. It should be an ObjectSetElements */\r
+ ASN_LOG_DEBUG("TODO: constraint_subtype_element (element_set_specs %s)",$2->name().c_str());\r
+ $$ = $2;\r
+ }\r
+ | referenced_type \r
+ {\r
+ /* This rule is not correct. It should be an ObjectSetElements */\r
+ ASN_LOG_ERROR("TODO: constraint_subtype_element reference type");\r
+ $$ = new asn1::celt_type();\r
+ $$->value($1);\r
+ }\r
+ | T_LOBJBRACET defined_syntax_list T_RBRACET {\r
+ ASN_LOG_ERROR("TODO: constraint_subtype_element defined syntax list");\r
+ $$ = new asn1::celt_value();\r
+ $$->value($2);\r
+ }\r
+ | value\r
+ {\r
+ ASN_LOG_DEBUG("constraint_subtype_element value");\r
+ $$ = new asn1::celt_value();\r
+ $$->value($1);\r
+ }\r
+ | T_PATTERN value\r
+ {\r
+ ASN_LOG_DEBUG("constraint_subtype_element pattern value");\r
+ $$ = new asn1::celt_value();\r
+ $$->value($2);\r
+ }\r
+ | value_range {\r
+ ASN_LOG_DEBUG("constraint_subtype_element value_range");\r
+ $$ = $1;\r
+ }\r
+ | contained_subtype\r
+ {\r
+ ASN_LOG_DEBUG("TODO: constraint_subtype_element contained_subtype");\r
+ }\r
+ | inner_type_constraint\r
+ {\r
+ ASN_LOG_DEBUG("constraint_subtype_element inner_type_contraint");\r
+ }\r
+ | T_TYPEREFERENCE\r
+ {\r
+ ASN_LOG_DEBUG("constraint_subtype_element type_reference X.680 4.7.6=%s",$1->name().c_str());\r
+ $$ = new asn1::celt_type();\r
+ asn1::typeref *tref = new asn1::typeref($1->name(),\r
+ new asn1::simple_reference($1->name())\r
+ );\r
+ delete $1; \r
+ $$->value(tref);\r
+ }\r
+ | parameterized_objectset\r
+ {\r
+ ASN_LOG_DEBUG("constraint_subtype_element objectset=%s",$1->name().c_str());\r
+ $$ = new asn1::celt_value();\r
+ $$->value($1);\r
+ }\r
+ | type\r
+ {\r
+ ASN_LOG_DEBUG("constraint_subtype_element type %s",$1->name().c_str());\r
+ $$ = new asn1::celt_type();\r
+ $$->value($1);\r
+ }\r
+;\r
+\r
+contained_subtype: T_INCLUDES T_TYPEREFERENCE {\r
+ $$ = new asn1::constraint("INCLUDE TYPE",asn1::constraint::EL_TYPE);\r
+ asn1::typeref *tref = new asn1::typeref($2->name(),\r
+ new asn1::simple_reference($2->name())\r
+ );\r
+ delete $2; \r
+ $$->value(tref);\r
+ }\r
+;\r
+\r
+constraint_spec_subtype_element:\r
+ T_SIZE {\r
+ ASN_LOG_DEBUG("constraint_spec_subtype_element T_SIZE");\r
+ $$ = new asn1::ctype_size();\r
+ }\r
+ | T_FROM {\r
+ ASN_LOG_DEBUG("constraint_spec_subtype_element T_FROM");\r
+ $$ = new asn1::ctype_from();\r
+ }\r
+;\r
+\r
+inner_type_constraint:\r
+ T_WITH T_COMPONENT set_of_constraints {\r
+ ASN_LOG_DEBUG("inner_type_constraint WITH_COMPONENTS ");\r
+ $$ = new asn1::ctype_wcomp();\r
+ $$->append($3);\r
+ }\r
+ | T_WITH T_COMPONENTS T_LBRACET with_components_list T_RBRACET {\r
+ ASN_LOG_DEBUG("inner_type_constraint WITH_COMPONENTS 1 ");\r
+ $$ = $4;\r
+ }\r
+;\r
+\r
+\r
+with_components_list:\r
+ with_components_element {\r
+ ASN_LOG_DEBUG("with_components_list: 1 ");\r
+ $$ = new asn1::ctype_wcomps();\r
+ $$->append($1);\r
+ }\r
+ | with_components_list T_COMMA with_components_element {\r
+ ASN_LOG_DEBUG("with_components_list: 2 ");\r
+ $1->append($3);\r
+ $$ = $1;\r
+ }\r
+;\r
+\r
+with_components_element:\r
+ T_THREEPOINT {\r
+ ASN_LOG_DEBUG("with_components_element: 1 extensible ");\r
+ $$ = new asn1::celt_ext();\r
+ }\r
+ | T_IDENTIFIER opt_constraint_def opt_presence_constraint {\r
+ ASN_LOG_DEBUG("with_components_element: 2 ");\r
+ if ($2 != NULL) \r
+ {\r
+ ASN_LOG_DEBUG("with_components_element: 2 have opt contraint %s",$1->name().c_str());\r
+ $$ = $2;\r
+ } else if ($3 != NULL) {\r
+ ASN_LOG_DEBUG("with_components_element: 3 have presence contraint %s",$1->name().c_str());\r
+ $$ = $3;\r
+ $$->value($1);\r
+ }\r
+ }\r
+;\r
+\r
+opt_presence_constraint: /* NULL */\r
+ { $$ = NULL; }\r
+ | T_PRESENT {\r
+ ASN_LOG_DEBUG("opt_presence_constraint: PRESENT ");\r
+ $$ = new asn1::constraint("PRESENCE",asn1::constraint::EL_TYPE);\r
+ $$->presence(asn1::constraint::PRESENT);\r
+ }\r
+ | T_ABSENT {\r
+ ASN_LOG_DEBUG("opt_presence_constraint: ABSENT ");\r
+ $$ = new asn1::constraint("PRESENCE",asn1::constraint::EL_TYPE);\r
+ $$->presence(asn1::constraint::ABSENT);\r
+ }\r
+ | T_OPTIONAL {\r
+ ASN_LOG_DEBUG("opt_presence_constraint: OPTIONAL ");\r
+ $$ = new asn1::constraint("PRESENCE",asn1::constraint::EL_TYPE);\r
+ $$->presence(asn1::constraint::OPTIONAL_);\r
+ }\r
+;\r
+\r
+opt_constraint_def: /* NULL */\r
+ { $$ = NULL; }\r
+ | constraint_def\r
+ { \r
+ ASN_LOG_DEBUG("opt_constraint_def: %s",$1->name().c_str());\r
+ $$ = $1;\r
+ asn1::parser::instance()->constraint_complet($1);\r
+ }\r
+;\r
+\r
+opt_component_type_lists: /* NULL */\r
+ { $$ = NULL; }\r
+ | component_type_lists\r
+ {\r
+ $$ = $1;\r
+ }\r
+;\r
+\r
+component_type_lists: component_type\r
+ { \r
+ asn1::parser::instance()->got_component_type($1);\r
+ }\r
+ | component_type_lists T_COMMA component_type\r
+ { \r
+ asn1::parser::instance()->got_component_type($3);\r
+ } \r
+;\r
+\r
+\r
+component_type: T_IDENTIFIER type opt_default /*NamedType*/\r
+ { \r
+ ASN_LOG_DEBUG("component_type: (%s) type %s flags=%d"\r
+ , $1->name().c_str()\r
+ , $2->name().c_str()\r
+ , ($3==NULL)?0:$3->m_flags); \r
+ \r
+ asn1::module *m = get_current_module();\r
+ $2->set_parent(m->current_context());\r
+ $$ = new asn1::field($1->name(),$2);\r
+ $$->flags($3);\r
+ if ($2->type_id()() == asn1::type::ASN1_SEQUENCE\r
+ || $2->type_id()() == asn1::type::ASN1_CHOICE\r
+ || $2->type_id()() == asn1::type::ASN1_ENUMERATED\r
+ )\r
+ {\r
+ $2->name($1->name()+"_t");\r
+ }\r
+ delete ($1);\r
+\r
+ }\r
+ | type opt_default /*type_assign*/ /* Needs to be checked */\r
+ { \r
+ asn1::module *m = get_current_module();\r
+ ASN_LOG_DEBUG("component_type: Should go type=%s",$1->name().c_str()); \r
+ std::string ano("anonymous");\r
+ ano = ano+$1->cpp_name();\r
+ $$ = new asn1::field(ano.c_str(),$1);\r
+ $1->set_parent(m->current_context());\r
+ $$->flags($2);\r
+ }\r
+ | T_COMPONENTS T_OF type_assign_right_tag_default\r
+ {\r
+ ASN_LOG_DEBUG("component_type: component of %s",$3->name().c_str()); \r
+ $$ = new asn1::components_of($3);\r
+ }\r
+ | extension_and_exception\r
+ {\r
+ ASN_LOG_DEBUG("component_type: extension and exception %s",$1->name().c_str());\r
+ $$ = $1;\r
+ }\r
+;\r
+\r
+character_string_def: restricted_character_string_def\r
+ { \r
+ $$ = $1;\r
+ }\r
+ | unrestricted_character_string_def\r
+ { \r
+ $$ = $1;\r
+ }\r
+;\r
+\r
+restricted_character_string_def: T_BMPString\r
+ { $$ = new asn1::bmpstring(); }\r
+ | general_string_def\r
+ {$$ = $1;}\r
+ | T_GraphicString\r
+ { $$ = new asn1::graphicstring(); }\r
+ | T_IA5String\r
+ {$$ = new asn1::ia5string();}\r
+ | T_ISO646String\r
+ { $$ = new asn1::iso646string(); }\r
+ | T_NumericString\r
+ { $$ = new asn1::numericstring(); }\r
+ | T_PrintableString\r
+ { $$ = new asn1::printablestring(); }\r
+ | T_TeletexString\r
+ { $$ = new asn1::teletexstring(); }\r
+ | T_T61String\r
+ {$$ = new asn1::node("STRING",asn1::type::ASN1_STRING_T61String);}\r
+ | T_UniversalString\r
+ { $$ = new asn1::universalstring(); }\r
+ | T_UTF8String\r
+ { $$ = new asn1::utf8string(); }\r
+ | T_VideotextString\r
+ { $$ = new asn1::videotexstring(); }\r
+ | T_VisibleString\r
+ {$$ = new asn1::visiblestring(); }\r
+ | T_ObjectDescriptorString\r
+ {$$ = new asn1::objectdescriptor_string(); }\r
+;\r
+\r
+restricted_character_string_value: T_LBRACET rcsv_char_syms T_RBRACET {\r
+ ASN_LOG_ERROR("retricted_character_string_value 1: TODO");\r
+ }\r
+ | rcsv_quadruple {\r
+ ASN_LOG_ERROR("retricted_character_string_value 2: TODO");\r
+ }\r
+ | rcsv_tuple {\r
+ ASN_LOG_ERROR("retricted_character_string_value 3: TODO");\r
+ }\r
+;\r
+\r
+rcsv_char_syms: rcsv_char_sym {\r
+ }\r
+ | rcsv_char_syms T_COMMA rcsv_char_sym {\r
+ }\r
+;\r
+\r
+rcsv_char_sym: rcsv_quadruple {\r
+ ASN_LOG_DEBUG("rcvs_char_sym: "); \r
+ }\r
+ | rcsv_tuple {\r
+ ASN_LOG_DEBUG("rcvs_char_sym: "); \r
+ }\r
+;\r
+\r
+rcsv_quadruple: T_LBRACET T_NUM T_COMMA T_NUM T_COMMA T_NUM T_COMMA T_NUM T_RBRACET {\r
+ ASN_LOG_DEBUG("rcvs_quadruple: "); \r
+ }\r
+ | T_Quadruple\r
+ {\r
+ ASN_LOG_DEBUG("rcvs_quadruple 1: "); \r
+ }\r
+;\r
+\r
+rcsv_tuple: T_LBRACET T_NUM T_COMMA T_NUM T_RBRACET {\r
+ ASN_LOG_DEBUG("rcvs_tuple: "); \r
+ }\r
+ | T_Tuple\r
+ {\r
+ ASN_LOG_DEBUG("rcvs_quadruple: "); \r
+ }\r
+\r
+unrestricted_character_string_def: T_CHARACTER T_STRING\r
+ { $<node>$ = new asn1::node("STRING",asn1::type::ASN1_STRING);}\r
+;\r
+\r
+general_string_def: T_GeneralizedString\r
+ { $$ = new asn1::node("STRING",asn1::type::ASN1_STRING);}\r
+;\r
+\r
+octet_string_def: T_OCTET T_STRING { \r
+ $$ = new asn1::octet_string();\r
+ }\r
+;\r
+\r
+bit_element_def: T_IDENTIFIER T_LPARENTHESES T_NUM T_RPARENTHESES\r
+ { \r
+ ASN_LOG_DEBUG("bit_element_def: %s",$<node>1->name().c_str()); \r
+ $3->name($1->name());\r
+ delete $1;\r
+ $$ = $3;\r
+ }\r
+ | T_THREEPOINT\r
+ {\r
+ ASN_LOG_DEBUG("bit_element_def: %s is extension_filed ",$<node>1->name().c_str()); \r
+ //$$ = new asn1::node("THREEPOINT",asn1::type::ASN1_EXTENSIBLE);\r
+ $$ = new asn1::extension_field();\r
+ }\r
+ | T_IDENTIFIER\r
+ {\r
+ ASN_LOG_ERROR("bit_element_def: value reference %s should return valuetype",$<node>1->name().c_str()); \r
+ $$ = $1;\r
+ $$->meta_id(asn1::meta::VALUE);\r
+ }\r
+;\r
+\r
+bit_element_list: bit_element_def\r
+ { \r
+ asn1::module *m= get_current_module();\r
+ m->enter_symbol($<node>1,$<node>1->type_id()());\r
+ }\r
+ | bit_element_list T_COMMA bit_element_def\r
+ { \r
+ ASN_LOG_DEBUG("bit_element_list: %s %s",$1->name().c_str(),$3->name().c_str()); \r
+ asn1::parser *p = asn1::parser::instance();\r
+ asn1::module *m= (asn1::module *) p->module();\r
+ m->enter_symbol($<node>3,$<node>3->type_id()());\r
+ }\r
+;\r
+\r
+bit_string_def:\r
+ T_BIT T_STRING\r
+ {\r
+ $$ = new asn1::bit_string();\r
+ }\r
+ | T_BIT T_STRING T_LBRACET \r
+ {\r
+ asn1::module *m= get_current_module();\r
+ m->enter_context(new asn1::bit_string());\r
+ $<module>$ = m;\r
+ } constant_list T_RBRACET {\r
+ $$ = $<module>4->leave_context(); \r
+ }\r
+;\r
+\r
+enumerated_def: T_ENUMERATED T_LBRACET \r
+ {\r
+ ASN_LOG_DEBUG("enumerated_def: begin "); \r
+ asn1::parser *p = asn1::parser::instance();\r
+ asn1::module *m= (asn1::module *) p->module();\r
+ m->enter_context(new asn1::enumerated());\r
+ $<module>$ = m;\r
+ } bit_element_list T_RBRACET\r
+ { \r
+ ASN_LOG_DEBUG("enumerated_def: end "); \r
+ asn1::module *m = (asn1::module *)$<module>3;\r
+ asn1::node *res = m->leave_context();\r
+ $$ = res;\r
+ }\r
+;\r
+\r
+\r
+object_def: T_OBJECT T_STR_IDENTIFIER\r
+ {\r
+ ASN_LOG_DEBUG("\nobject_def OBJECT IDENTIFIER type");\r
+ $$ = new asn1::object_identifier();\r
+ }\r
+;\r
+\r
+/**\r
+ *\r
+ */\r
+object_class_def:\r
+ T_CLASS T_LBRACET \r
+ {\r
+ ASN_LOG_DEBUG("\nobject_class_def start");\r
+ asn1::module *m= get_current_module();\r
+ m->enter_context(new asn1::classdef() );\r
+ $<module>$ = m;\r
+ } \r
+ oclass_field_list \r
+ {\r
+ asn1::module *m = (asn1::module *)$<module>3;\r
+ asn1::node *res = m->leave_context();\r
+ ASN_LOG_DEBUG("object_class_def: end %s %s", res->name().c_str()\r
+ ,$<module>3->name().c_str());\r
+ $<node>$ = res; \r
+ gCurrentClassDef = dynamic_cast<asn1::classdef *>(res);\r
+ gCurrentClassDef->sort_fields();\r
+ res->meta_id(asn1::meta::OBJECTCLASS);\r
+ } T_RBRACET opt_with_syntax\r
+ {\r
+ $$ = $<node>5;\r
+ }\r
+;\r
+\r
+opt_with_syntax:\r
+ | T_WITH T_SYNTAX T_LBRACET \r
+ {\r
+ ASN_LOG_DEBUG("\nwith syntax start skip...");\r
+ enable_with_syntax();\r
+ gCurrentClassDef->start_syntax();\r
+ } syntax_token_list T_RBRACET\r
+ {\r
+ disable_with_syntax();\r
+ ASN_LOG_DEBUG("with syntax end skip...");\r
+ if ( $5 == NULL)\r
+ {\r
+ ASN_LOG_ERROR("with syntax end skip $5 IS NULL ");\r
+ }\r
+ gCurrentClassDef->set_nfa($5);\r
+ }\r
+;\r
+\r
+syntax_token_list: /* NULL*/ \r
+ {\r
+ ASN_LOG_DEBUG("syntax_token_list: NULL");\r
+ $$ = NULL;\r
+ }\r
+ | token syntax_token_list\r
+ {\r
+ if ($1 != NULL && $2 != NULL)\r
+ {\r
+ ASN_LOG_DEBUG("syntax_token_list: 1 token %s append %s",$1->name().c_str(),$2->name().c_str());\r
+ asn1::classdef::fragment *f = gCurrentClassDef->parse_token($1);\r
+ $$ = f;\r
+ $$ = gCurrentClassDef->parse_append($$,$2);\r
+ } else if ($1 != NULL)\r
+ {\r
+ asn1::classdef::fragment *f = gCurrentClassDef->parse_token($1);\r
+ ASN_LOG_DEBUG("syntax_token_list: 1 token %s $2 is NULL",f->name().c_str());\r
+ $$ = f;\r
+ } else\r
+ {\r
+ ASN_LOG_DEBUG("syntax_token_list: token NULL");\r
+ }\r
+ }\r
+ | opt_token syntax_token_list\r
+ {\r
+ /* ASN_LOG_DEBUG("syntax_token_list: [ ] "); */\r
+ if ($1 != NULL && $2 != NULL)\r
+ {\r
+ ASN_LOG_DEBUG("syntax_token_list: [ %s ] %s",$1->name().c_str(),$2->name().c_str());\r
+ asn1::classdef::fragment *f = gCurrentClassDef->parse_append($1,$2);\r
+ $$ = f;\r
+ } else if ($1 != NULL)\r
+ {\r
+ /* TODO May be this is a match*/\r
+ ASN_LOG_DEBUG("syntax_token_list: [ %s ] $1 is not NULL ",$1->name().c_str());\r
+ //asn1::classdef::fragment *f = gCurrentClassDef->parse_optional($1);\r
+ $$ = $1;\r
+ } else if ($2 != NULL)\r
+ {\r
+ ASN_LOG_DEBUG("syntax_token_list: [ ] $2 is not NULL ");\r
+ $$ = $2;\r
+ } else \r
+ {\r
+ ASN_LOG_ERROR("syntax_token_list: [ ] $1==NULL && $2 == NULL ");\r
+ }\r
+ }\r
+;\r
+/**\r
+ { $<node>$ = NULL;} \r
+ */\r
+opt_token : \r
+ T_LBRACKET syntax_token_list T_RBRACKET\r
+ {\r
+ ASN_LOG_DEBUG("opt_token : [ %s ] ",$2->name().c_str());\r
+ asn1::classdef::fragment *f = gCurrentClassDef->parse_optional($2);\r
+ $$ = f;\r
+ }\r
+;\r
+\r
+token: T_CAPITALREFERENCE {\r
+ ASN_LOG_DEBUG("token: capitalReference : %s",$1->name().c_str());\r
+ }\r
+ | T_TYPEFIELDREFERENCE {\r
+ ASN_LOG_DEBUG("token: value FieldReference : %s",$1->name().c_str());\r
+ $$ = new asn1::typeref($1);\r
+ }\r
+ | T_VALUEFIELDREFERENCE {\r
+ ASN_LOG_DEBUG("token: value FieldReference : %s",$1->name().c_str());\r
+ $$ = new asn1::typeref($1);\r
+ }\r
+ | T_COMMA {\r
+ ASN_LOG_ERROR("token: comma");\r
+ }\r
+;\r
+\r
+opt_unique: /* Empty */\r
+ | T_UNIQUE { \r
+ ASN_LOG_DEBUG("opt_unique: UNIQUE TO BE CODED NOT IMPORTANT");\r
+ \r
+ }\r
+;\r
+\r
+oclass_field_list: \r
+ oclass_field {\r
+ asn1::parser::instance()->got_class_field($1);\r
+ }\r
+ | oclass_field_list T_COMMA oclass_field {\r
+ asn1::parser::instance()->got_class_field($3);\r
+ }\r
+;\r
+\r
+oclass_field: T_TYPEFIELDREFERENCE opt_default\r
+ {\r
+ ASN_LOG_DEBUG("oclass_field: typefieldref TF %s",$1->name().c_str());\r
+ $$ = new asn1::classfield_tf($1->name());\r
+ delete ($1);\r
+ $$->flags($2);\r
+ }\r
+ | T_VALUEFIELDREFERENCE type_assign_right opt_unique opt_default\r
+ {\r
+ asn1::module *m = get_current_module();\r
+ ASN_LOG_DEBUG("oclass_field: valuefieldref FTVF %s",$1->name().c_str());\r
+ $$ = new asn1::classfield_ftvf($1->name(),$2->as_typenode());\r
+ delete ($1);\r
+ $2->set_parent(m->current_context());\r
+ $$->flags($4);\r
+ }\r
+ | T_VALUEFIELDREFERENCE field_name opt_default\r
+ {\r
+ asn1::module *m = get_current_module();\r
+ ASN_LOG_DEBUG("oclass_field: valuefieldref VTVF %s",$1->name().c_str());\r
+ $$ = new asn1::classfield_vtvf($1->name());\r
+ $$->set_reference($2);\r
+ $2->set_parent(m->current_context());\r
+ delete ($1);\r
+ $$->flags($3);\r
+ }\r
+ | T_VALUEFIELDREFERENCE defined_object_class opt_default\r
+ {\r
+ ASN_LOG_DEBUG("oclass_field: valuefieldref %s",$1->name().c_str());\r
+ $$ = new asn1::classfield_of($1->name());\r
+ delete ($1);\r
+ $$->flags($3);\r
+ }\r
+ | T_TYPEFIELDREFERENCE field_name opt_default\r
+ {\r
+ asn1::module *m = get_current_module();\r
+ ASN_LOG_DEBUG("oclass_field: typefieldref %s",$1->name().c_str());\r
+ $$ = new asn1::classfield_vtvsf($1->name());\r
+ delete ($1);\r
+ $$->set_reference($2);\r
+ $2->set_parent(m->current_context());\r
+ $$->flags($3);\r
+ }\r
+ | T_TYPEFIELDREFERENCE type opt_default\r
+ {\r
+ ASN_LOG_DEBUG("oclass_field: typefieldref %s",$1->name().c_str());\r
+ asn1::module *m = get_current_module();\r
+ $$ = new asn1::classfield_ftvsf($1->name(),$2->as_typenode());\r
+ delete ($1);\r
+ $2->set_parent(m->current_context());\r
+ $$->flags($3);\r
+ }\r
+ | T_TYPEFIELDREFERENCE defined_object_class opt_default\r
+ {\r
+ asn1::module *m = get_current_module();\r
+ ASN_LOG_DEBUG("oclass_field: typefieldref %s",$1->name().c_str());\r
+ asn1::typeref *_ref = new asn1::typeref($2,asn1::meta::TYPE);\r
+ _ref->set_parent(m->current_context());\r
+ $$ = new asn1::classfield_osf($1->name(),_ref);\r
+ $$->flags($3);\r
+ }\r
+;\r
+\r
+defined_object_class: \r
+ object_class_reference {\r
+ ASN_LOG_DEBUG("defined_object_class: object_class_reference");\r
+ $$ = $1; \r
+ }\r
+;\r
+\r
+/*\r
+ * ObjectSet rules X.681 pg 30 \r
+ */\r
+object_set:\r
+ T_LBRACET {ASN_LOG_DEBUG("object_set::Start");enable_object();} element_set_specs {disable_object();} T_RBRACET\r
+ {\r
+ ASN_LOG_DEBUG("object_set::TODO 1 %s",$3->name().c_str() );\r
+ $$ = $3;\r
+ }\r
+ | T_LOBJBRACET element_set_specs T_RBRACET\r
+ {\r
+ ASN_LOG_DEBUG("object_set::TODO 2 %s",$2->name().c_str());\r
+ $$ = $2;\r
+ }\r
+;\r
+\r
+\r
+/**\r
+ *\r
+ */\r
+type_reference: T_TYPEREFERENCE\r
+ { \r
+ if (! gLog.is_open() ) {\r
+ open_log($1->name());\r
+ }\r
+ ASN_LOG_DEBUG("type_reference: %s",$1->name().c_str());\r
+ $$ = new asn1::typeref($1->name(),\r
+ new asn1::simple_reference($1->name())\r
+ );\r
+ delete $1; \r
+ }\r
+ | T_CAPITALREFERENCE\r
+ { // object reference\r
+ $$ = new asn1::typeref($1->name(),\r
+ new asn1::objectclass_reference($1->name())\r
+ );\r
+ delete $1; \r
+ }\r
+;\r
+\r
+value_reference: T_IDENTIFIER\r
+ { \r
+ ASN_LOG_DEBUG("value_reference: Got ValueReference %s",$1->name().c_str());\r
+ $$ = new asn1::typeref($1->name()\r
+ , new asn1::simple_reference($1->name()\r
+ , asn1::reference::component::Lowercase)\r
+ );\r
+ delete $1; \r
+ }\r
+ ;\r
+/** \r
+ *\r
+ */\r
+nstd_marker:\r
+ { \r
+ }\r
+;\r
+\r
+type_declaration:\r
+ nstd_marker type_assign_right\r
+ {\r
+ ASN_LOG_DEBUG("type_declaration: nstd_marker:%s",$2->name().c_str()); \r
+ $$ = $2;\r
+ }\r
+;\r
+\r
+\r
+\r
+type_assign_right: defined_type \r
+ {\r
+ ASN_LOG_DEBUG("type_assign_right: defined_type:%s",$1->name().c_str()); \r
+ $$ = $1;\r
+ $$->type_id(asn1::type::ASN1_REFERENCE);\r
+ $$->meta_id(asn1::meta::TYPEREF);\r
+ }\r
+ | builtin_type {\r
+ ASN_LOG_DEBUG("type_assign_right: builtin :%s",$1->name().c_str()); \r
+ $$ = $1;\r
+ }\r
+;\r
+\r
+type_assign_right_tag: type_assign_right opt_constraint_def {\r
+ ASN_LOG_DEBUG("type_assign_right_tag: %s + opt_constraint_def %s",$1->name().c_str(),\r
+ ($2==NULL)?"none":$2->name().c_str()); \r
+ $$ = $1;\r
+ if ($2 != NULL)\r
+ $$->as_typenode()->constraint($2);\r
+ }\r
+ | tag type_assign_right opt_constraint_def {\r
+ ASN_LOG_DEBUG("type_assing_right_tag: tag type=%s opt_constaint_def",$2->name().c_str());\r
+ $$ = $2;\r
+ if ($2 != NULL)\r
+ $$->as_typenode()->constraint($3);\r
+ $$->tag($1);\r
+ }\r
+;\r
+\r
+type_assign_right_tag_default: \r
+ type_assign_right_tag opt_default {\r
+ ASN_LOG_DEBUG("type_assign_right_tag_default: + opt_default ");\r
+ $$=$1;\r
+ $$->flags($2);\r
+ }\r
+;\r
+\r
+sequence_def: T_SEQUENCE T_LBRACET T_RBRACET\r
+ { \r
+ asn1::module *m= get_current_module();\r
+ m->enter_context(new asn1::sequence() );\r
+ asn1::node *res = m->leave_context();\r
+ $$ = res;\r
+ $$->meta_id(asn1::meta::TYPE);\r
+ }\r
+ | T_SEQUENCE T_LBRACET \r
+ {\r
+ ASN_LOG_DEBUG("sequence_def start -- with component_type_lists ");\r
+ asn1::module *m= get_current_module();\r
+ m->enter_context(new asn1::sequence() );\r
+ $<module>$ = m;\r
+ }\r
+ opt_component_type_lists T_RBRACET\r
+ {\r
+ ASN_LOG_DEBUG("sequence_def: end %s"\r
+ ,$<module>3->name().c_str());\r
+ asn1::module *m = (asn1::module *)$<module>3;\r
+ asn1::node *res = m->leave_context();\r
+ $$ = res; \r
+ $$->meta_id(asn1::meta::TYPE);\r
+ }\r
+ | T_SEQUENCE T_OF opt_identifier opt_tag type_declaration\r
+ {\r
+ ASN_LOG_DEBUG("seq_of type_declaration ");\r
+ asn1::node *ident = NULL;\r
+ $$ = new asn1::sequence_of($5);\r
+ if ( $3 == NULL)\r
+ {\r
+ std::string ano("anonymous_seqof");\r
+ ident = new asn1::node(ano.c_str());\r
+ $5->identifier(ident);\r
+ } else\r
+ {\r
+ ident = $3;\r
+ $5->identifier($3);\r
+ }\r
+ asn1::module *m = get_current_module();\r
+ $5->set_parent(m->current_context());\r
+ if (m->current_context() == NULL)\r
+ {\r
+ ASN_LOG_ERROR("seq_of opt_i opt_taf type_decl NOT GOOD"); \r
+ }\r
+ ident->set_parent(m->current_context());\r
+ if ($<node>4 != NULL)\r
+ $5->tag($4);\r
+ $$->meta_id(asn1::meta::TYPE);\r
+ }\r
+ | T_SEQUENCE opt_constraint_def T_OF opt_identifier type_assign_right\r
+ {\r
+ $$ = new asn1::sequence_of($5);\r
+ if ( $4 == NULL)\r
+ {\r
+ std::string ano("anonymous_seqofc");\r
+ $5->identifier(new asn1::node(ano.c_str()) );\r
+ } else\r
+ $5->identifier($4);\r
+ asn1::module *m = get_current_module();\r
+ $5->set_parent(m->current_context());\r
+ $$->as_typenode()->constraint($2);\r
+ $$->meta_id(asn1::meta::TYPE);\r
+ }\r
+;\r
+\r
+set_def: \r
+ T_SET T_LBRACET {\r
+ asn1::module *m = get_current_module();\r
+ m->enter_context(new asn1::set());\r
+ $<module>$ = m;\r
+ }\r
+ /*type_assign_list T_RBRACET */ \r
+ opt_component_type_lists T_RBRACET \r
+ {\r
+ asn1::module *m = get_current_module();\r
+ asn1::node *res = m->leave_context();\r
+ $$=res;\r
+ $$->meta_id(asn1::meta::TYPE);\r
+ }\r
+ | T_SET T_OF type_assign_right {\r
+ $$ = new asn1::set_of($3);\r
+ $$->meta_id(asn1::meta::TYPE);\r
+ asn1::module *m = get_current_module();\r
+ $3->set_parent(m->current_context());\r
+ std::string ano("anonymous_setof");\r
+ asn1::node *ident = new asn1::node(ano.c_str());\r
+ $3->identifier(ident);\r
+ ident->set_parent(m->current_context());\r
+ }\r
+ | T_SET T_OF T_IDENTIFIER type_assign_right {\r
+ $$ = new asn1::set_of($3);\r
+ $$->meta_id(asn1::meta::TYPE);\r
+ asn1::module *m = get_current_module();\r
+ $4->set_parent(m->current_context());\r
+ $4->identifier($3);\r
+ }\r
+ | T_SET opt_constraint_def T_OF type_assign_right {\r
+ $$ = new asn1::set_of($4);\r
+ if ($2) $$->as_typenode()->constraint($2);\r
+ asn1::module *m = get_current_module();\r
+ if (m)\r
+ $4->set_parent(m->current_context());\r
+ $$->meta_id(asn1::meta::TYPE);\r
+ std::string ano("anonymous_setofc");\r
+ $4->identifier(new asn1::node(ano.c_str()) );\r
+ }\r
+ | T_SET opt_constraint_def T_OF T_IDENTIFIER type_assign_right {\r
+ $$ = new asn1::set_of($5);\r
+ asn1::module *m = get_current_module();\r
+ if (m)\r
+ $5->set_parent(m->current_context());\r
+ if ($2) $$->as_typenode()->constraint($2);\r
+ $$->meta_id(asn1::meta::TYPE);\r
+ $5->identifier($4);\r
+ };\r
+;\r
+\r
+choice_def: T_CHOICE T_LBRACET \r
+ {\r
+ asn1::module *m = get_current_module();\r
+ m->enter_context( new asn1::choice());\r
+ $<module>$ = m;\r
+ }\r
+ /*type_assign_list */ alternative_type_lists T_RBRACET\r
+ {\r
+ asn1::module *m = get_current_module();\r
+ asn1::node *res = m->leave_context();\r
+ $$ = res;\r
+ $$->meta_id(asn1::meta::TYPE);\r
+ }\r
+;\r
+\r
+alternative_type_lists: alternative_type\r
+ {\r
+ asn1::parser::instance()->got_alternative_choice($1);\r
+ }\r
+ | alternative_type_lists T_COMMA alternative_type\r
+ {\r
+ asn1::parser::instance()->got_alternative_choice($3);\r
+ }\r
+;\r
+\r
+alternative_type:\r
+ T_IDENTIFIER type\r
+ {\r
+ asn1::module *m = get_current_module();\r
+ ASN_LOG_DEBUG("altenative_type: ident %s type %s",$1->name().c_str(),$2->name().c_str());\r
+ $$ = new asn1::field($1->name(),$2);\r
+ $2->set_parent(m->current_context());\r
+ if ($2->type_id()() == asn1::type::ASN1_SET_OF\r
+ || $2->type_id()() == asn1::type::ASN1_SEQUENCE_OF\r
+ )\r
+ {\r
+ asn1::typenode *subtype = $2->as_typenode()->get_eltype();\r
+ if (subtype && subtype->identifier()->get_parent() == NULL)\r
+ {\r
+ ASN_LOG_ERROR("altenative_type: ident %s type %s",$1->name().c_str(),$2->name().c_str());\r
+ }\r
+ $2->name($1->name()+"_t");\r
+ }\r
+ delete($1);\r
+ } \r
+ | extension_and_exception\r
+ {\r
+ ASN_LOG_DEBUG("altenative_type: extension and exception %s",$1->name().c_str());\r
+ $$ = $1;\r
+ }\r
+ | type \r
+ {\r
+ asn1::module *m = get_current_module();\r
+ ASN_LOG_WARNING("altenative_type: type =%s anonymous CHOICE attribute _%s(_t) %d",$1->name().c_str(),$1->name().c_str(),$1->type_id()());\r
+ std::string nm("_");\r
+ nm = nm+$1->name();\r
+ $$ = new asn1::field(nm.c_str(),$1);\r
+ $1->set_parent(m->current_context());\r
+ if ($1->type_id()() == asn1::type::ASN1_SEQUENCE\r
+ || $1->type_id()() == asn1::type::ASN1_CHOICE\r
+ )\r
+ {\r
+ $1->name($$->name()+"_t");\r
+ }\r
+ }\r
+;\r
+\r
+any_def: T_ANY\r
+ {\r
+ $$ = new asn1::any();\r
+ }\r
+ | T_ANY T_DEFINED T_BY T_IDENTIFIER {\r
+ ASN_LOG_DEBUG("any_def: DEPRECATED any defined by");\r
+ $$ = new asn1::any();\r
+ delete $4;\r
+ }\r
+;\r
+\r
+type: opt_tag builtin_type opt_constraint_def {\r
+ ASN_LOG_DEBUG("type: opt_tag builtin_type %s %s"\r
+ ,$2->name().c_str()\r
+ ,($3 != NULL)?$3->name().c_str():"No constraint"\r
+ );\r
+ $$= $2;\r
+ if ($3 != NULL)\r
+ {\r
+ $$->as_typenode()->constraint($3);\r
+ }\r
+ $$->tag($1);\r
+ }\r
+ | opt_tag referenced_type opt_constraint_def {\r
+ ASN_LOG_DEBUG( "type: opt_tag referenced_type %s %s"\r
+ , $2->name().c_str()\r
+ , ($3 != NULL)?$3->name().c_str():"No constraint"\r
+ );\r
+ $$ = $2;\r
+ if ($3 != NULL)\r
+ $$->as_typenode()->constraint($3);\r
+ $$->tag($1);\r
+ }\r
+;\r
+\r
+builtin_type: boolean_def \r
+ {$$ = $1;}\r
+ /**\r
+ * Enum Int and bit String have someting in common. They can contain a list of literals\r
+ */\r
+ | integer_def { $$ = $1; }\r
+ | enumerated_def {$$ = $1;}\r
+ | bit_string_def {$$ = $1;} \r
+ | real_def {$$ = $1;}\r
+ | time_def { $$ = $1;}\r
+ | octet_string_def {$$ =$1;}\r
+ | object_def {$$ = $1;}\r
+ | object_class_def {$$ = $1;}\r
+ | character_string_def \r
+ {\r
+ $$ =$1;\r
+ }\r
+ | sequence_def { $$ = $1;}\r
+ | choice_def { $$ = $1;}\r
+ | any_def {$$ = $1;}\r
+ | set_def {$$ = $1;}\r
+ | T_EXTERNAL {\r
+ $$ = new asn1::external();\r
+ }\r
+ | T_RELATIVE_OID {\r
+ ASN_LOG_DEBUG("builtin_type: relative_OID");\r
+ $$ = new asn1::relative_oid();\r
+ }\r
+ | T_NULL {$$ =new asn1::null();}\r
+;\r
+\r
+/**\r
+ * Don't used type_reference as defined_type already references it\r
+ */\r
+referenced_type: defined_type\r
+ {\r
+ // defined_type is of type asn1::typeref\r
+ if ($1 != NULL)\r
+ {\r
+ $$ = $1;\r
+ // Should not be required\r
+ $$->type_id(asn1::type::ASN1_REFERENCE);\r
+ $$->meta_id(asn1::meta::TYPEREF);\r
+ ASN_LOG_DEBUG("referenced_type: defined_type %s",$1->name().c_str());\r
+ } else {\r
+ ASN_LOG_ERROR("referenced_type: defined_type NULL %lx",(long)$1);\r
+ }\r
+ }\r
+ | identifier T_LT type\r
+ {\r
+ ASN_LOG_DEBUG("referenced_type got selection type %s",$1->name().c_str());\r
+ $$ = new asn1::selection($1->name(),$3);;\r
+ delete($1);\r
+ }\r
+ ;\r
+\r
+field_name: T_TYPEFIELDREFERENCE\r
+ {\r
+ ASN_LOG_WARNING("field_name : %s",$1->name().c_str());\r
+ $$ = $1;\r
+ }\r
+ | field_name T_POINT T_TYPEFIELDREFERENCE\r
+ {\r
+ ASN_LOG_WARNING("field_name 2 %s . %s ",$1->name().c_str(),$3->name().c_str());\r
+ $$->add_components($3->get_components());\r
+ delete($3);\r
+ }\r
+ | field_name T_POINT T_VALUEFIELDREFERENCE\r
+ {\r
+ ASN_LOG_WARNING("field_name 3 %s %s",$1->name().c_str(),$3->name().c_str());\r
+ $$->add_components($3->get_components());\r
+ delete($3);\r
+ }\r
+;\r
+\r
+/* TypeAssignment X.680 TypeAssignment -> typereference "::=" Type */\r
+type_assignment: T_TYPEREFERENCE T_ASSIGN type_assign_right_tag \r
+ {\r
+ // Set parent of type.\r
+ asn1::module *m= get_current_module();\r
+ $3->set_parent(m);\r
+\r
+ if ($3->type_id()() == asn1::type::ASN1_CHOICE) {\r
+ ASN_LOG_DEBUG("type is CHOICE set name to %s_t",$1->cpp_name().c_str());\r
+ $3->name($1->cpp_name()+"_t");\r
+ }\r
+#ifdef DEBUG\r
+ if ($3 == NULL) {printf("ERROR type is NULL"); }\r
+ ASN_LOG_DEBUG("\ntype_assignment : T_TYPEREFERENCE %s en tant que: %s %d\n",\r
+ $1->name().c_str()\r
+ ,$3->name().c_str()\r
+ ,$3->type_id()());\r
+#endif\r
+ if ( ($3->type_id() >= asn1::type::ASN1_SEQUENCE ) &&\r
+ ($3->type_id() <= asn1::type::ASN1_TYPE_MAX))\r
+ {\r
+ $$ = new asn1::type_assignment($1->name());\r
+ } else if ($3->type_id() == asn1::type::ASN1_VALUESET)\r
+ {\r
+ $$ = new asn1::valueset_assignment($1->name());\r
+ } else if ($3->type_id() == asn1::type::ASN1_REFERENCE)\r
+ {\r
+ /* THIS IS WRONG A::= B Is a TYPE definition \r
+ * B Is Ref and A Is new Type */\r
+ $$ = new asn1::typeref_assignment($1->name());\r
+ //$$ = new asn1::type_assignment($1->name());\r
+ }\r
+ $$->type_node($3);\r
+ $3->identifier($$);\r
+ delete($1);\r
+ }\r
+ | type_reference parameter_list T_ASSIGN type_assign_right_tag\r
+ {\r
+ ASN_LOG_DEBUG("type_assignment : type_reference %s {} en tant que:",$1->name().c_str());\r
+ ASN_LOG_DEBUG("");\r
+ // Set parent of type.\r
+ asn1::module *m= get_current_module();\r
+ $4->set_parent(m);\r
+ \r
+ if ( ($4->type_id() >= asn1::type::ASN1_SEQUENCE ) &&\r
+ ($4->type_id() <= asn1::type::ASN1_TYPE_MAX))\r
+ {\r
+ $$ = new asn1::type_assignment($1->name());\r
+ } else if ($4->type_id() == asn1::type::ASN1_VALUESET)\r
+ {\r
+ std::cerr<<"p "<<$1->name()<<std::endl;\r
+ $$ = new asn1::valueset_assignment($1->name());\r
+ //$$->set_reference($1->get_reference()); \r
+ } else if ($4->type_id() == asn1::type::ASN1_REFERENCE)\r
+ {\r
+ $$ = new asn1::typeref_assignment($1->name());\r
+ }\r
+ $4->identifier($$);\r
+ $$->type_node($4);\r
+ $$->parameters($2->as_parameters());\r
+ delete($1); \r
+\r
+ }\r
+ | T_CAPITALREFERENCE T_ASSIGN type_assign_right_tag\r
+ {\r
+ ASN_LOG_DEBUG("\ntype_assignement: T_CAPITALREFERENCE Object Class or type %s meta=%d"\r
+ ,$1->name().c_str()\r
+ ,$3->meta_id()()\r
+ );\r
+ ASN_LOG_DEBUG("");\r
+ // Set parent of type.\r
+ asn1::module *m= get_current_module();\r
+ $3->set_parent(m);\r
+ // $1 is either object class assignment or type assignment \r
+ switch($3->meta_id()())\r
+ {\r
+#define ASSIGNMENT(tp,cls,parent) \\r
+ case asn1::meta::tp: \\r
+ $$ = new asn1::cls##_assignment($1->name()); \\r
+ break;\r
+ default:\r
+ ;\r
+#include "adt/asn1_meta.inc"\r
+ }\r
+ $3->identifier($$);\r
+ //$$ = $1;\r
+ $$->type_node($3);\r
+ }\r
+;\r
+\r
+parameter_list: T_LBRACET {\r
+ asn1::module *m = get_current_module();\r
+ m->enter_context(new asn1::parameters());\r
+ $<module>$ = m;\r
+ ASN_LOG_DEBUG("parameter_list enter (params ...)");\r
+ } parameter_args T_RBRACET\r
+ {\r
+ asn1::module *m = (asn1::module *)$<module>2;\r
+ asn1::node *res = m->leave_context();\r
+ ASN_LOG_DEBUG("parameter_list leave (params %s)",res->name().c_str());\r
+ $$ = res;\r
+ }\r
+;\r
+\r
+parameter_args: parameter_arg\r
+ {\r
+ ASN_LOG_DEBUG("parameter_args: %s",$1->cpp_name().c_str());\r
+ asn1::parser::instance()->got_parameter($1);\r
+ }\r
+ | parameter_args T_COMMA parameter_arg\r
+ {\r
+ ASN_LOG_DEBUG("parameter_args: %s",$3->cpp_name().c_str());\r
+ asn1::parser::instance()->got_parameter($3);\r
+ }\r
+;\r
+\r
+parameter_arg: \r
+ type_reference {\r
+ ASN_LOG_DEBUG("parameter_arg 0: %s(tp=%d)",$1->name().c_str(),$1->type_id()());\r
+ $$ = new asn1::parameter(NULL,$1->as_typeref());\r
+ }\r
+ | type_reference T_COLON type_reference {\r
+ ASN_LOG_DEBUG("parameter_arg 1: %s(tp=%d) : %s(tp=%d)",$1->name().c_str(),$1->type_id()(),\r
+ $3->name().c_str(),$3->type_id()()); \r
+ $$ = new asn1::parameter($1,$3->as_typeref());\r
+ }\r
+ | type_reference T_COLON value_reference {\r
+ ASN_LOG_DEBUG("parameter_arg 2: %s(tp=%d) : %s(tp=%d)",$1->name().c_str(),$1->type_id()(),\r
+ $3->name().c_str(),$3->type_id()()); \r
+ $$ = new asn1::parameter($1,$3->as_typeref());\r
+ }\r
+ | type T_COLON type_reference {\r
+ ASN_LOG_DEBUG("parameter_arg 3: %s(tp=%d) : %s(tp=%d)",$1->name().c_str(),$1->type_id()(),\r
+ $3->name().c_str(),$3->type_id()()); \r
+ $$ = new asn1::parameter($1,$3->as_typeref());\r
+ }\r
+ | type T_COLON value_reference {\r
+ ASN_LOG_DEBUG("parameter_arg 4: %s(tp=%d):%s",$1->name().c_str(),$1->type_id()(),$3->name().c_str());\r
+ $$ = new asn1::parameter($1,$3->as_typeref());\r
+ }\r
+;\r
+/**\r
+| type_reference T_COLON T_IDENTIFIER {\r
+ ASN_LOG_DEBUG("parameter_arg 2: %s:%s",$1->name().c_str(),$3->name().c_str());\r
+ $$ = $1;\r
+ $$->identifier($3);\r
+ }\r
+*/\r
+\r
+act_parameter_args:act_parameter_arg\r
+ {\r
+ ASN_LOG_DEBUG("act_parameter_args %s",$1->name().c_str());\r
+ asn1::parser::instance()->got_act_parameter($1);\r
+ $$ = $1;\r
+ }\r
+ | act_parameter_args T_COMMA act_parameter_arg\r
+ {\r
+ ASN_LOG_DEBUG("act_parameter_args next %s",$3->name().c_str());\r
+ asn1::parser::instance()->got_act_parameter($3);\r
+ }\r
+;\r
+\r
+act_parameter_arg: type\r
+ {\r
+ if ($1 != NULL)\r
+ { \r
+ ASN_LOG_DEBUG("act_parameter_arg:type declaration:%s",$1->name().c_str());\r
+ } else {\r
+ ASN_LOG_DEBUG("act_parameter_arg:type declaration: without identifier");\r
+ }\r
+ $$ = $1;\r
+ }\r
+ | value_set\r
+ {\r
+ ASN_LOG_DEBUG("act_parameter_arg : value_set");\r
+ $$= new asn1::valueset($1); \r
+ }\r
+ | object_set\r
+ {\r
+ ASN_LOG_DEBUG("act_parameter_arg : object_set %s",$1->name().c_str());\r
+ $$= new asn1::objectset($1); \r
+ }\r
+ | value\r
+ {\r
+ ASN_LOG_DEBUG("act_parameter_arg: value ");\r
+ $$ = $1;\r
+ }\r
+ | type_reference {\r
+ ASN_LOG_DEBUG("act_parameter_arg:reference %s",$1->name().c_str());\r
+ }\r
+ /*\r
+ | defined_object_class\r
+ | object\r
+ \r
+ */\r
+;\r
+\r
+/* */\r
+value_assignment: \r
+ T_IDENTIFIER T_OBJECT T_STR_IDENTIFIER T_ASSIGN T_LBRACET \r
+ obj_constant_list T_RBRACET\r
+ {\r
+ ASN_LOG_DEBUG( "value_assignment : ident %s OID "\r
+ , $1->name().c_str()\r
+ );\r
+ asn1::module *m = get_current_module();\r
+ asn1::node *i = m->leave_context(); \r
+ i->meta_id(asn1::meta::VALUE);\r
+ i->set_parent(m->current_context());\r
+ $$ = new asn1::value_assignment($1->name()); \r
+ i->identifier($$);\r
+ $$->type_node(i);\r
+ delete ($1);\r
+ }\r
+ | identifier T_TYPEREFERENCE T_ASSIGN T_LBRACET \r
+ obj_constant_list T_RBRACET\r
+ {\r
+ ASN_LOG_WARNING("value_assignment : ident %s type=%s OID 1 TO BE FINALIZED",$1->name().c_str(),$2->name().c_str());\r
+ asn1::module *m = get_current_module();\r
+ asn1::node *i = m->leave_context(); \r
+ i->set_parent(m->current_context());\r
+ $$ = new asn1::value_assignment($1->name());\r
+ i->identifier($$);\r
+ $$->type_node(i);\r
+ // Missing typeref somewhere\r
+ }\r
+ | identifier T_TYPEREFERENCE T_ASSIGN T_LBRACET restricted_character_string_value T_RBRACET {\r
+ ASN_LOG_WARNING("value_assignment : ident %s type=%s STR value=%s TO BE FINALIZED",$1->name().c_str(),$2->name().c_str(),$5->name().c_str());\r
+ asn1::node *i = new asn1::node("CONST STRING",asn1::meta::VALUE);\r
+ i->type_id(asn1::type::ASN1_OBJECT_IDENTIFIER);\r
+ $$ = new asn1::value_assignment($1->name());\r
+ $5->identifier($$);\r
+ i->identifier($$);\r
+ $$->type_node(i);\r
+ $2->type_id(asn1::type::ASN1_REFERENCE);\r
+ delete($1);\r
+ }\r
+ | identifier restricted_character_string_def T_ASSIGN restricted_character_string_value \r
+ {\r
+ ASN_LOG_WARNING("value_assignment : ident type=%s string"\r
+ , $1->name().c_str());\r
+ asn1::node *i = new asn1::node("CONST STRING",asn1::meta::VALUE);\r
+ i->type_id(asn1::type::ASN1_STRING);\r
+ $$ = new asn1::value_assignment($1->name());\r
+ $4->identifier($$);\r
+ i->identifier($$);\r
+ $$->type_node(i);\r
+ $$->value(new asn1::value(asn1::value::VT_STRING));\r
+ delete($1);\r
+ }\r
+ | identifier T_INTEGER T_ASSIGN value {\r
+ ASN_LOG_WARNING("value_assignment : ident %s type INTEGER value=%s TO BE FINALIZED",$1->name().c_str(),$4->name().c_str());\r
+ asn1::node *i = $4;\r
+ $$ = new asn1::value_assignment($1->name());\r
+ i->identifier($$);\r
+ $$->type_node(i); //TODO remove\r
+ $$->meta_id(asn1::meta::VALUE);\r
+ $$->value($4->value());\r
+ delete($1);\r
+ }\r
+ | identifier T_TYPEREFERENCE T_ASSIGN value {\r
+ ASN_LOG_WARNING("value_assignment : ident %s type=%s value=%s TO BE FINALIZED",$1->name().c_str(),$2->name().c_str(),$4->name().c_str());\r
+ asn1::node *tr = new asn1::typeref( new asn1::simple_reference($2->name()));\r
+ delete($2); \r
+ $$ = new asn1::value_assignment($1->name());\r
+ tr->identifier($$);\r
+ $$->type_node(tr);\r
+ if ($4->meta_id()() == asn1::meta::VALUE) \r
+ {\r
+ $$->value($4->value());\r
+ }\r
+ delete($1);\r
+ }\r
+ | identifier T_TYPEREFERENCE T_ASSIGN T_LBRACET value T_RBRACET {\r
+ /* Needed for Attribute-ASN1Module.asn1 line 205 */\r
+ ASN_LOG_WARNING("value_assignment : N ident %s type=%s value=%s TO BE FINALIZED",$1->name().c_str(),$2->name().c_str(),$5->name().c_str());\r
+ asn1::node *tr = new asn1::typeref( new asn1::simple_reference($2->name()));\r
+ delete($2); \r
+ $$ = new asn1::value_assignment($1->name());\r
+ tr->identifier($$);\r
+ tr->meta_id(asn1::meta::TYPEREF);\r
+ tr->type_id(asn1::type::ASN1_REFERENCE);\r
+ $$->type_node(tr);\r
+ if ($5->meta_id()() == asn1::meta::VALUE) \r
+ {\r
+ $$->value($5->value());\r
+ }\r
+ delete($1);\r
+ }\r
+/*\r
+*/\r
+;\r
+\r
+/**\r
+ * value_range rules\r
+ */\r
+value_range:\r
+ value constraint_range_spec value {\r
+ ASN_LOG_DEBUG("value_range %s .. %s",$1->name().c_str(),$3->name().c_str());\r
+ asn1::constraint_range *cr = dynamic_cast<asn1::constraint_range *>($2);\r
+ cr->set_min_max($1,$3);\r
+ $$ = $2;\r
+ }\r
+;\r
+\r
+constraint_range_spec : T_TWOPOINT {\r
+ ASN_LOG_DEBUG("constraint_range_spec .. ");\r
+ $$= new asn1::celt_range(); \r
+ }\r
+ | T_TWOPOINT T_LT {\r
+ ASN_LOG_DEBUG("constraint_range_spec ..< ");\r
+ $$= new asn1::celt_rlrange(); \r
+ }\r
+ | T_LT T_TWOPOINT {\r
+ ASN_LOG_DEBUG("constraint_range_spec < .. ");\r
+ $$= new asn1::celt_llrange(); \r
+ }\r
+ | T_LT T_TWOPOINT T_LT {\r
+ ASN_LOG_DEBUG("constraint_range_spec <..< ");\r
+ $$= new asn1::celt_ulrange(); \r
+ }\r
+;\r
+\r
+/**\r
+ *\r
+ */\r
+value: builtin_value {\r
+ ASN_LOG_DEBUG( "value: builtin_value : %s id=%d"\r
+ , ($1 != NULL)?$1->cpp_name().c_str():"null"\r
+ , ($1 != NULL)?$1->type_id()(): -1\r
+ );\r
+ $$ = $1;\r
+ $$->meta_id(asn1::meta::VALUE);\r
+ }\r
+ /* ReferencedValue */\r
+ | defined_value\r
+ {\r
+ ASN_LOG_DEBUG("value: defined_value ..");\r
+ $$->meta_id(asn1::meta::VALUE);\r
+ asn1::value *v = new asn1::value($1->name());\r
+ $$->value(v);\r
+ $$ = $1;\r
+ }\r
+ | value_from_object {\r
+ ASN_LOG_DEBUG("value: value_from_object ..");\r
+ $$ = $1;\r
+ $$->meta_id(asn1::meta::VALUE);\r
+ }\r
+;\r
+/* Refuse empty builtin value\r
+ ASN_LOG_WARNING("builtin_value: NONE return NULL");\r
+ $$=NULL;\r
+ }\r
+ */\r
+builtin_value: \r
+ /* Boolean value*/\r
+ T_ASN1_TRUE {\r
+ ASN_LOG_DEBUG("builtin_value: Boolean Value TRUE ");\r
+ $$ = new asn1::valuetype( new asn1::value(asn1::value::VT_TRUE));\r
+ }\r
+ | T_ASN1_FALSE {\r
+ ASN_LOG_DEBUG("builtin_value: Boolean Value FALSE ");\r
+ $$ = new asn1::valuetype(new asn1::value(asn1::value::VT_FALSE));\r
+ }\r
+ | T_NULL {\r
+ ASN_LOG_DEBUG("builtin_value: NullValue NULL ");\r
+ $$ = new asn1::valuetype(new asn1::value(asn1::value::VT_NULL));\r
+ }\r
+ | pos_neg_num {\r
+ ASN_LOG_DEBUG("builtin_value: IntegerValue pos_neg_num %s",$1->name().c_str());\r
+ $$ = $1;\r
+ }\r
+ | T_IDENTIFIER T_COLON value {\r
+ ASN_LOG_DEBUG("builtin_value: ChoiceValue identifier:value %s:%s (%d)"\r
+ , $1->name().c_str()\r
+ , $3->name().c_str()\r
+ , $3->type_id()()\r
+ );\r
+ asn1::valuetype *vt = new asn1::valuetype(std::string($1->name()),NULL);\r
+ vt->type_id(asn1::type::ASN1_CHOICE);\r
+ vt->identifier($1);\r
+ asn1::value *v = new asn1::value(asn1::value::VT_COLON);\r
+ v->m_node = $3;\r
+ vt->value(v);\r
+ $$ = vt;\r
+ }\r
+ | set_value {\r
+ /* SET_value can actually be an oid or {component_list }\r
+ * VALUESET is element_set_specs !!!\r
+ */\r
+ ASN_LOG_ERROR("builtin_value: set_value %s id=%d wrong VT_VALUESET for set"\r
+ ,$1->name().c_str()\r
+ ,$1->type_id()()\r
+ );\r
+ if ($1->is_object_identifier())\r
+ {\r
+ $$ = $1;\r
+ } else\r
+ {\r
+ asn1::valuetype *vt = new asn1::valuetype(std::string($1->name()),NULL);\r
+ asn1::value *v = new asn1::value(asn1::value::VT_SETVALUE);\r
+ v->m_node = $1;\r
+ vt->value(v);\r
+ $$ = vt;\r
+ }\r
+ }\r
+ | T_bstring {\r
+ ASN_LOG_ERROR("builtin_value got binary string");\r
+ $$ = new asn1::valuetype(new asn1::value(asn1::value::VT_BITVECTOR));\r
+ }\r
+ | T_hstring {\r
+ ASN_LOG_ERROR("builtin_value got hstring string");\r
+ $$ = new asn1::valuetype(new asn1::value(asn1::value::VT_BITVECTOR));\r
+ }\r
+ | T_MIN {\r
+ $$ = new asn1::valuetype(new asn1::value(asn1::value::VT_MIN));\r
+ }\r
+ | T_MAX {\r
+ $$ = new asn1::valuetype(new asn1::value(asn1::value::VT_MAX));\r
+ }\r
+ | T_Quadruple {\r
+ ASN_LOG_WARNING("builtin_value got quadruple TO BE CODED");\r
+ $$ = new asn1::valuetype(std::string("Quadrupple"),NULL);\r
+ }\r
+ | T_Tuple {\r
+ ASN_LOG_WARNING("builtin_value got tuple TO BE CODED");\r
+ $$ = new asn1::valuetype(std::string("TUPLE"),NULL);\r
+ }\r
+;\r
+\r
+defined_value:\r
+ identifier {\r
+ asn1::value *v = new asn1::value(asn1::value::VT_REFERENCED);\r
+ v->m_string = $1->name();\r
+ $$ = new asn1::valuetype($1->name(),v);\r
+ ASN_LOG_DEBUG("defined_value: %s",$1->name().c_str());\r
+ delete $1;\r
+ }\r
+ | parameterized_value { \r
+ ASN_LOG_DEBUG("defined_value: parameterized_value %s",$1->name().c_str());\r
+ $$ = $1; \r
+ }\r
+;\r
+\r
+parameterized_value: \r
+ identifier T_LBRACET {\r
+ asn1::parser *p = asn1::parser::instance();\r
+ asn1::module *m= (asn1::module *) p->module();\r
+ m->enter_context(new asn1::act_parameters());\r
+ $<module>$ = m;\r
+ ASN_LOG_DEBUG("parameterized_value enter %s (params ...)",$1->name().c_str());\r
+ } act_parameter_args T_RBRACET\r
+ {\r
+ asn1::module *m = (asn1::module *)$<module>3;\r
+ asn1::node *res = m->leave_context();\r
+ ASN_LOG_DEBUG("parameterized_value leave (params %s)",res->name().c_str());\r
+ $$ = $1;\r
+ $$->parameters(res->as_parameters());\r
+ }\r
+;\r
+\r
+parameterized_objectset: \r
+ T_TYPEREFERENCE T_LOBJBRACET {\r
+ asn1::parser *p = asn1::parser::instance();\r
+ asn1::module *m= (asn1::module *) p->module();\r
+ m->enter_context(new asn1::act_parameters());\r
+ $<module>$ = m;\r
+ ASN_LOG_DEBUG("parameterized_objectset enter %s (params ...)",$1->name().c_str());\r
+ } act_parameter_args T_RBRACET\r
+ {\r
+ asn1::module *m = (asn1::module *)$<module>3;\r
+ asn1::node *res = m->leave_context();\r
+ ASN_LOG_DEBUG("parameterized_objectset leave (params %s { %s })",$1->name().c_str(),res->name().c_str());\r
+ $$ = $1;\r
+ $$->parameters(res->as_constructed());\r
+ }\r
+;\r
+\r
+\r
+\r
+\r
+value_from_object: \r
+ T_CAPITALREFERENCE T_POINT field_name { \r
+ ASN_LOG_WARNING("value_from_object(0) Capital INCOMPLETE %s.%s",\r
+ $1->name().c_str()\r
+ , $3->name().c_str());\r
+ //asn1::reference *ref = new asn1::objectclass_reference($1->name());\r
+ //$$ = new asn1::typeref(ref);\r
+ $$ = $1; \r
+ }\r
+ | T_TYPEREFERENCE T_POINT field_name {\r
+ ASN_LOG_DEBUG("value_from_object(1) Reference %s.%s",\r
+ $1->name().c_str()\r
+ , $3->name().c_str());\r
+ asn1::typeref *tref = new asn1::typeref($1->name(),\r
+ new asn1::simple_reference($1->name())\r
+ );\r
+ tref->get_reference()->add_components($3->get_components());\r
+ $$ = tref;\r
+ delete $1;\r
+ }\r
+ | identifier T_POINT primitive_field_reference {\r
+ ASN_LOG_WARNING("value_from_object(2) Identifier INCOMPLETE %s.%s"\r
+ , $1->name().c_str()\r
+ , $3->m_identifier.c_str());\r
+ $$ = $1;\r
+ delete $3;\r
+ }\r
+;\r
+/* value set */\r
+constant_set_def: \r
+ type_reference defined_type T_ASSIGN value_set {\r
+ ASN_LOG_ERROR("constant_set_def:%s",$1->name().c_str());\r
+ $$ = new asn1::valueset_assignment($1->name());\r
+ $$->type_node($2);\r
+ $2->identifier($$);\r
+ $2->as_typenode()->constraint($4);\r
+ delete($1);\r
+ }\r
+ | type_reference builtin_type T_ASSIGN value_set {\r
+ ASN_LOG_ERROR("constant_set_def:%s of type: %s",$1->name().c_str(),$2->cpp_name().c_str());\r
+ $$ = new asn1::valueset_assignment($1->name());\r
+ //$$->set_reference($1->get_reference()); \r
+ $$->type_node($2);\r
+ $2->identifier($$);\r
+ //$$->constraint($4);\r
+ $2->as_typenode()->constraint($4);\r
+ delete($1);\r
+ }\r
+;\r
+\r
+\r
+defined_type: /* * More complex types */ \r
+ complex_type_reference T_LBRACET {\r
+ ASN_LOG_DEBUG("defined_type: 1 %s start (params:...)",$1->name().c_str());\r
+ asn1::parser *p = asn1::parser::instance();\r
+ asn1::module *m= (asn1::module *) p->module();\r
+ m->enter_context(new asn1::act_parameters());\r
+ $<module>$ = m;\r
+ }\r
+ act_parameter_args T_RBRACET {\r
+ asn1::module *m = (asn1::module *)$<module>3;\r
+ asn1::node *res = m->leave_context();\r
+ ASN_LOG_DEBUG( "defined_type: 1 end (params: %s) %p"\r
+ , res->name().c_str()\r
+ , res->as_constructed()\r
+ );\r
+ $$ = new asn1::typeref($1);\r
+ $$->act_parameters(res->as_constructed());\r
+ }\r
+ | complex_type_reference {\r
+ ASN_LOG_DEBUG("defined_type: complex_type_reference <%s>",$1->name().c_str());\r
+ $$ = new asn1::typeref($1);\r
+ }\r
+;\r
+\r
+complex_type_reference: \r
+ T_TYPEREFERENCE {\r
+ /* simple_defined_type reference */\r
+ $$ = new asn1::simple_reference($1->name());\r
+ delete($1);\r
+ }\r
+ | T_TYPEREFERENCE T_POINT type_reference {\r
+ /* External reference : Module reference . type_reference */\r
+ $$ = new asn1::reference();\r
+ asn1::reference::component c;\r
+ c.m_identifier =$1->name();\r
+ c.type = asn1::reference::component::Uppercase;\r
+ $$->add_component(c);\r
+ delete($1);\r
+ c.m_identifier = $3->name();\r
+ $$->add_component(c);\r
+ delete $3;\r
+\r
+ }\r
+ | object_class_reference T_POINT type_reference {\r
+ $$ = $1;\r
+ ASN_LOG_DEBUG("complex_type_reference: %s . %s",$1->name().c_str(),$3->name().c_str());\r
+ asn1::reference::component c;\r
+ c.m_identifier = $3->name();\r
+ c.type = asn1::reference::component::Uppercase;\r
+ $1->add_component(c);\r
+ delete $3;\r
+ }\r
+ | T_TYPEREFERENCE T_POINT T_IDENTIFIER {\r
+ /* External reference : Module reference . value_reference */\r
+ $$ = new asn1::reference();\r
+ asn1::reference::component c;\r
+ c.m_identifier =$1->name();\r
+ c.type = asn1::reference::component::Uppercase;\r
+ $$->add_component(c);\r
+ delete($1);\r
+ c.m_identifier = $3->name();\r
+ c.type = asn1::reference::component::Lowercase;\r
+ $$->add_component(c);\r
+ delete $3;\r
+ }\r
+ | object_class_reference\r
+ {\r
+ ASN_LOG_DEBUG("complex_type_reference: %s ",$1->name().c_str());\r
+ $$ = $1;\r
+ }\r
+ | object_class_reference T_POINT {current_ref = $1;} complex_type_reference_amp_list {\r
+ $$ = $1;\r
+ ASN_LOG_DEBUG("complex_type_reference: %s .& %s",$1->name().c_str(),$4->m_identifier.c_str());\r
+ delete $4;\r
+ }\r
+;\r
+\r
+complex_type_reference_amp_list:\r
+ complex_type_reference_element {\r
+ ASN_LOG_DEBUG("complex_type_reference_apm_list 1: %s ",$1->m_identifier.c_str());\r
+ current_ref->add_component(*$1);\r
+ }\r
+ | complex_type_reference_amp_list T_POINT complex_type_reference_element {\r
+ ASN_LOG_DEBUG("complex_type_reference_apm_list 2: should add %s ",$3->m_identifier.c_str());\r
+ // Its' a ref_comp\r
+ current_ref->add_component(*$3);\r
+ }\r
+;\r
+\r
+complex_type_reference_element: primitive_field_reference\r
+ ;\r
+primitive_field_reference:\r
+ T_TYPEFIELDREFERENCE\r
+ {\r
+ ASN_LOG_DEBUG("primitive_field_reference: TYPEFIELDREFRENE %s",$1->name().c_str());\r
+ asn1::reference::component *c = new asn1::reference::component;\r
+ c->m_identifier =$1->name();\r
+ c->type = asn1::reference::component::AmpUppercase;\r
+ delete $1;\r
+ $$ = c;\r
+ }\r
+ | T_VALUEFIELDREFERENCE\r
+ {\r
+ ASN_LOG_DEBUG("primitive_field_reference: VALUEREFERENCE %s",$1->name().c_str());\r
+ asn1::reference::component *c = new asn1::reference::component;\r
+ c->m_identifier =$1->name();\r
+ c->type = asn1::reference::component::AmpLowercase;\r
+ delete $1;\r
+ $$ = c;\r
+ }\r
+;\r
+\r
+object_class_reference: T_CAPITALREFERENCE /* X.681 7.1 */\r
+ {\r
+ ASN_LOG_DEBUG("object_class_reference: %s",$1->name().c_str());\r
+ \r
+ $$ = new asn1::objectclass_reference($1->name());\r
+ delete($1);\r
+ }\r
+;\r
+\r
+// Be carefull value_set and set_value are two different things .\r
+// I don't think that enter context is required. As element_set_specs is a constraint.\r
+value_set: T_LBRACET \r
+ {\r
+ ASN_LOG_DEBUG("value_set start");\r
+ }\r
+ element_set_specs T_RBRACET\r
+ {\r
+ /**\r
+ */\r
+ ASN_LOG_DEBUG("value_set END");\r
+ $$ = $3;\r
+ }\r
+;\r
+\r
+/** \r
+ * In term of BRACET cant be a set or an OID\r
+ * -> set_value which_list = component_value_list\r
+ * -> OID obj_constant_list\r
+ * -> constraint ? why\r
+ */\r
+set_value: T_LBRACET {\r
+ ASN_LOG_DEBUG("set_value start");\r
+ asn1::parser *p = asn1::parser::instance();\r
+ asn1::module *m= (asn1::module *) p->module();\r
+ //m->enter_context("set_value",asn1::type::INVALID);\r
+ m->enter_context(new asn1::constructed(std::string("set_value 1")));\r
+ $<module>$ = m;\r
+ } \r
+ which_list T_RBRACET\r
+ {\r
+\r
+ asn1::module *m = (asn1::module *)$<module>2;\r
+ asn1::node *res = m->leave_context(); \r
+ $$ = res;\r
+ if ($3 != NULL && $3->type_id()() == asn1::type::ASN1_OBJECT_IDENTIFIER)\r
+ {\r
+ $$ = $3;\r
+ $$->type_id(asn1::type::ASN1_OBJECT_IDENTIFIER);\r
+ $$->meta_id(asn1::meta::VALUE);\r
+ $$->name("OBJECT_IDENTIFIER");\r
+ delete res;\r
+ ASN_LOG_DEBUG("set_value end GOT OID %d",$3->type_id()());\r
+ } else if ($3 != NULL && $3->type_id()() == asn1::type::ASN1_REFERENCE)\r
+ {\r
+ $$->meta_id(asn1::meta::VALUE);\r
+ res->as_typenode()->constraint(*($3->as_typeref()->constraint_begin()));\r
+ delete $3;\r
+ ASN_LOG_DEBUG("set_value end GOT VALUE probably ref");\r
+ assert( 0 && "set_value list contains reference ! is this possible ?");\r
+ } else {\r
+ $$->meta_id(asn1::meta::VALUE);\r
+ ASN_LOG_DEBUG("set_value end GOT VALUE NULL");\r
+ }\r
+ } \r
+;\r
+\r
+which_list: obj_constant_list {\r
+ // node\r
+ ASN_LOG_DEBUG("which_list obj_constant_list");\r
+ asn1::parser *p = asn1::parser::instance();\r
+ asn1::module *m= (asn1::module *) p->module();\r
+ asn1::node *ids = m->leave_context();\r
+ $$ = ids;\r
+ }\r
+ | opt_component_value_list {\r
+ // node\r
+ ASN_LOG_DEBUG("which_list component_value");\r
+ $$ = NULL;\r
+ }\r
+;\r
+opt_component_value_list: /* Empty */\r
+ | component_value_list {\r
+ ASN_LOG_DEBUG("opt_component_value_list");\r
+ }\r
+;\r
+component_value_list:component_value {\r
+ asn1::parser *p = asn1::parser::instance();\r
+ asn1::module *m= (asn1::module *) p->module();\r
+ m->enter_symbol($1,$1->type_id()());\r
+ $$ = $1;\r
+ }\r
+ | component_value_list T_COMMA component_value {\r
+ asn1::parser *p = asn1::parser::instance();\r
+ asn1::module *m= (asn1::module *) p->module();\r
+ m->enter_symbol($3,$3->type_id()());\r
+ $$ = $1;\r
+ }\r
+;\r
+\r
+component_value: T_IDENTIFIER value {\r
+ ASN_LOG_ERROR("component_value Should be Named Not anonymous got value =%s ",$1->name().c_str());\r
+ }\r
+;\r
+\r
+/**\r
+ *\r
+ */\r
+extension_and_exception: \r
+ T_THREEPOINT {\r
+ ASN_LOG_DEBUG("extension_and_exception (...)");\r
+ $<node>$ = new asn1::extension_field();\r
+ }\r
+ | T_THREEPOINT exception_spec {\r
+ ASN_LOG_WARNING("extension_and_exception (...) and missing exception_spec");\r
+ $<node>$ = new asn1::extension_field();\r
+ $$->meta_id(asn1::meta::TYPE);\r
+ // $$->value($2);\r
+ }\r
+;\r
+\r
+\r
+exception_spec: /* Empty */\r
+ { $$ = NULL; } \r
+ | T_EXCLAMATION defined_value {\r
+ ASN_LOG_DEBUG("exception_spec: %s",$2->name().c_str());\r
+ $$ = $2;\r
+ }\r
+ | T_EXCLAMATION type_reference T_COLON value\r
+ {\r
+ ASN_LOG_DEBUG("exception_spec: ! %s : %s",$2->name().c_str(),$4->name().c_str());\r
+ $$ = $2;\r
+ }\r
+ | T_EXCLAMATION pos_neg_identifier {\r
+ ASN_LOG_DEBUG("exception_spec: ! %s",$2->name().c_str());\r
+ $$ = $2;\r
+}\r
+;\r
+\r
+object_set_assignment: \r
+ type_reference parameter_list defined_object_class T_ASSIGN {\r
+ ASN_LOG_DEBUG("object_set_assignment parameterized start %s",$1->name().c_str());\r
+ }\r
+ object_set\r
+ {\r
+ ASN_LOG_DEBUG("object_set_assignment parameterized end %s",$1->name().c_str());\r
+ $$ = new asn1::objectset_assignment($1->name());\r
+ $$->parameters($2->as_parameters());\r
+ asn1::objectset *objs = new asn1::objectset($6);\r
+ asn1::typeref *typeref = new asn1::typeref($3);\r
+ objs->set_classref(typeref);\r
+ objs->name($1->name());\r
+ objs->identifier($$);\r
+ $$->type_node(objs);\r
+ delete($1);\r
+ }\r
+ |\r
+ type_reference defined_object_class T_ASSIGN {\r
+ ASN_LOG_DEBUG("object_set_assignment start %s",$1->name().c_str());\r
+ }\r
+ object_set\r
+ {\r
+ ASN_LOG_DEBUG("object_set_assignment end %s",$1->name().c_str());\r
+ asn1::typeref *typeref = new asn1::typeref($2);\r
+ $$ = new asn1::objectset_assignment($1->name());\r
+ asn1::objectset *objs = new asn1::objectset($5);\r
+ objs->identifier($$);\r
+ objs->name($1->name());\r
+ objs->set_classref(typeref);\r
+ $$->type_node(objs);\r
+ delete($1);\r
+ }\r
+;\r
+\r
+\r
+/*\r
+ *\r
+ */\r
+object_assignment: \r
+ identifier defined_type T_ASSIGN \r
+ {\r
+ ASN_LOG_DEBUG("\nobject_assignment start 1 object:%s class:%s",$1->name().c_str(),$2->name().c_str());\r
+\r
+ $<module>$ = get_current_module();\r
+ $<module>$->enter_context(new asn1::object());\r
+ }\r
+ object\r
+ {\r
+ asn1::node *res = $<module>4->leave_context();\r
+ $$ = new asn1::object_assignment($1->name());\r
+ res->identifier($$);\r
+ $2->type_node(res);\r
+ $$->type_node($2);\r
+ delete($1);\r
+ ASN_LOG_DEBUG("object_assignment end");\r
+ }\r
+ | identifier T_LBRACET { /*3*/\r
+ ASN_LOG_DEBUG("object_assignment: start %s {params}",$1->cpp_name().c_str());\r
+ asn1::module *m= get_current_module();\r
+ m->enter_context(new asn1::parameters());\r
+ $<module>$ = m;\r
+ } parameter_args T_RBRACET \r
+ { /*6*/\r
+ ASN_LOG_DEBUG("object_assignment: %s",$1->cpp_name().c_str());\r
+ asn1::module *m = (asn1::module *)$<module>3;\r
+ asn1::node *res = m->leave_context();\r
+ } object_class_reference T_ASSIGN { /*9*/\r
+ ASN_LOG_DEBUG("\nobject_assignment with params start object:%s class:%s"\r
+ ,$1->name().c_str()\r
+ ,$7->name().c_str());\r
+ asn1::module *m= get_current_module();\r
+ $<module>$= m;\r
+ m->enter_context(new asn1::object());\r
+ } object {\r
+ ASN_LOG_DEBUG("object_assignment: end %s {params}",$1->cpp_name().c_str());\r
+ $$ = new asn1::object_assignment($1->name());\r
+ asn1::node *res = $<module>9->leave_context();\r
+ res->identifier($$);\r
+ res->meta_id(asn1::meta::OBJECT);\r
+ asn1::typeref *ref = new asn1::typeref($7,asn1::meta::TYPE);\r
+ ref->type_node(res);\r
+ $$->type_node(ref);\r
+ $$->parameters($4->as_parameters());\r
+ delete($1);\r
+ }\r
+;\r
+\r
+object:\r
+ defined_object {\r
+ $$ = $1;\r
+ }\r
+ | object_defn {\r
+ $$ = $1;\r
+ }\r
+;\r
+\r
+\r
+\r
+defined_object:\r
+ T_IDENTIFIER {\r
+ }\r
+;\r
+\r
+object_defn:\r
+ default_syntax {\r
+ ASN_LOG_DEBUG("object_defn: default_syntax");\r
+ $$ = $1;\r
+ }\r
+ | defined_syntax {\r
+ ASN_LOG_DEBUG("object_defn: defined_syntax");\r
+ $$ = $1;\r
+ }\r
+;\r
+\r
+default_syntax: {\r
+ $$ = NULL;\r
+ }\r
+;\r
+\r
+defined_syntax: \r
+ T_LBRACET defined_syntax_list T_RBRACET {\r
+ ASN_LOG_DEBUG("defined_syntax: defined_syntax_list");\r
+ $$ =$2;\r
+ }\r
+;\r
+\r
+defined_syntax_list:\r
+ defined_syntax_token {\r
+ ASN_LOG_DEBUG("defined_syntax_list got item :%s",$1->name().c_str());\r
+ asn1::module *m = get_current_module ( );\r
+ m->enter_symbol($1,$1->type_id()());\r
+ }\r
+ | defined_syntax_list defined_syntax_token {\r
+ ASN_LOG_DEBUG("defined_syntax_list got item 1");\r
+ asn1::module *m = get_current_module ( );\r
+ m->enter_symbol($2,$2->type_id()());\r
+ }\r
+;\r
+\r
+defined_syntax_token: \r
+ object_set {\r
+ ASN_LOG_DEBUG("defined_syntax_token object_set:");\r
+ $$= new asn1::objectset($1); \r
+ }\r
+ | value {\r
+ ASN_LOG_DEBUG("defined_syntax_token value:%s type id=%d",$1->name().c_str(),$1->type_id()());\r
+ $$ = $1;\r
+ }\r
+ | type\r
+ {\r
+ $$ = $1;\r
+ if ($$->type_id()() == asn1::type::ASN1_SET_OF\r
+ && $$->identifier() == NULL)\r
+ {\r
+ $$->identifier(new asn1::node("anonmyous"));\r
+ }\r
+ ASN_LOG_DEBUG("defined_syntax_token type %s",$1->name().c_str());\r
+ }\r
+ | T_OPTIONAL {\r
+ ASN_LOG_DEBUG("defined_syntax_token OPTIONAL");\r
+ $$ = new asn1::node("OPTIONAL",asn1::type::INVALID);\r
+ }\r
+ | T_BY {\r
+ ASN_LOG_DEBUG("defined_syntax_token BY");\r
+ $$ = new asn1::node("BY",asn1::type::INVALID);\r
+ }\r
+ | T_SYNTAX {\r
+ $$ = new asn1::node("SYNTAX",asn1::type::INVALID);\r
+ }\r
+ | type_reference {\r
+ ASN_LOG_DEBUG("defined_syntax_token type_reference %s",$1->name().c_str());\r
+ $$ = $1;\r
+ }\r
+ | T_TYPEREFERENCE T_POINT type_reference {\r
+ /* External reference : Module reference . type_reference */\r
+ asn1::reference *r = $3->as_typeref()->get_reference();\r
+ asn1::module *mod = get_current_module();\r
+ asn1::import *imp = mod->get_import($1->name());\r
+ // If import does not exists, add it to module\r
+ if ( ! imp)\r
+ {\r
+ ASN_LOG_DEBUG( "defined_syntax_token type_reference No import:%s"\r
+ , $1->name().c_str());\r
+ imp = new asn1::import($1->name());\r
+ imp->identifier($1);\r
+ mod->imports()->append(imp);\r
+ }\r
+ // Simple reference\r
+ asn1::typeref *tref = new asn1::typeref($3->name(), r);\r
+ // If reference not in import add one in import too\r
+ if (! imp->get_item($3->name() ) )\r
+ {\r
+ imp->append(tref->clone());\r
+ }\r
+ $$ = tref;\r
+ delete $3;\r
+ }\r
+;\r
+\r
+/*\r
+ *\r
+ */\r
+\r
+type_constant: \r
+ type_assignment {\r
+ ASN_LOG_DEBUG("type_constant: Got type_assignment ");\r
+ $$ = $1;\r
+ }\r
+ | value_assignment {\r
+ ASN_LOG_DEBUG("type_constant: Got value assignement ");\r
+ $$ = $1;\r
+ }\r
+ | object_assignment {\r
+ ASN_LOG_DEBUG("type_constant: Got object assignement ");\r
+ $$ =$1;\r
+ }\r
+ | object_set_assignment { \r
+ ASN_LOG_DEBUG("type_constant: object_set_assignment");\r
+ $$ =$1;\r
+ }\r
+ | constant_set_def {\r
+ ASN_LOG_DEBUG("type_constant: constant_set_def");\r
+ $$ = $1;\r
+ } \r
+ | T_ENCODING_CONTROL T_CAPITALREFERENCE {\r
+ ASN_LOG_DEBUG("type_constant: encoding control start enable ignored for now");\r
+ enable_encoding_control();\r
+ }\r
+ {\r
+ ASN_LOG_DEBUG("type_constant: encoding control ignored for now");\r
+ $$ = NULL;\r
+ }\r
+\r
+ \r
+;\r
+\r
+type_constant_list: type_constant\r
+ {\r
+ asn1::parser *p = asn1::parser::instance();\r
+ $$ = p->module(NULL);\r
+ ASN_LOG_DEBUG("Got type_constant_list: %s type_constant %s"\r
+ ,$$->name().c_str()\r
+ ,$1->name().c_str());\r
+ $$->add_type( $1->as_assignment());\r
+ }\r
+ | type_constant_list type_constant\r
+ {\r
+ if ($2 != NULL) {\r
+ ASN_LOG_DEBUG("type_constant_list %s append:%s"\r
+ , $1->name().c_str()\r
+ , $2->name().c_str()\r
+ );\r
+ $$->add_type( $2->as_assignment());\r
+ } else\r
+ ASN_LOG_DEBUG("type_constant_list append NOTHING ");\r
+ $$ =$1;\r
+ }\r
+;\r
+\r
+definitions_id: \r
+ type_reference T_LBRACET {\r
+ // Special case\r
+ if (! gLog.is_open()) \r
+ open_log($1->name());\r
+ ASN_LOG_DEBUG("definitions_id :%s",$1->name().c_str());\r
+ asn1::parser *p = asn1::parser::instance();\r
+ asn1::module *m = NULL;\r
+ if (p->begin() == p->end())\r
+ {\r
+ m= p->module($1->name().c_str());\r
+ } else\r
+ {\r
+ m= p->module();\r
+ }\r
+ $<module>$ = m;\r
+ } obj_constant_list T_RBRACET\r
+ {\r
+ ASN_LOG_DEBUG("Go definitions ID %s",static_cast<asn1::node *>($1)->name().c_str());\r
+ asn1::node *ids = $<module>3->leave_context();\r
+ $$ = $1;\r
+ $$->type_node(ids);\r
+ }\r
+ | T_IDENTIFIER T_LBRACET T_RBRACET\r
+ { $$ = $1;}\r
+ | T_TYPEREFERENCE \r
+ { \r
+ // Special case\r
+ if (! gLog.is_open()) \r
+ open_log($1->name());\r
+ ASN_LOG_DEBUG("definitions_id :%s",$1->name().c_str());\r
+ $$ = $1;\r
+ }\r
+ | T_CAPITALREFERENCE \r
+ { \r
+ // Special case\r
+ if (! gLog.is_open()) \r
+ open_log($1->name());\r
+ $$ = $1;\r
+ }\r
+;\r
+\r
+opt_explicit_implicit: {\r
+ $$.m_mode = asn1::node::tag_type::TM_DEFAULT;\r
+ }\r
+ | explicit_implicit {\r
+ $$ = $1;\r
+ }\r
+;\r
+\r
+explicit_implicit: T_EXPLICIT {\r
+ $$.m_mode = asn1::node::tag_type::TM_EXPLICIT;\r
+ }\r
+ | T_IMPLICIT {\r
+ $$.m_mode = asn1::node::tag_type::TM_IMPLICIT;\r
+ }\r
+ | T_AUTOMATIC {\r
+ ASN_LOG_DEBUG("explicit_implicit: TM_AUTOMATIC");\r
+ $$.m_mode = asn1::node::tag_type::TM_AUTOMATIC;\r
+ }\r
+;\r
+\r
+%%\r
+/*\r
+ vim:et:sw=2:ts=2:\r
+*/\r
+\r
--- /dev/null
+#include <sstream>
+#include <fstream>
+#include <cstdio>
+#include <stdio.h>
+#include <list>
+#include <algorithm>
+#include <sys/stat.h>
+#include <sys/types.h>
+#if defined(__APPLE__) || defined(HAVE_UNISTD_H) || defined(__GNUC__)
+// for access function I need unistd
+#include <unistd.h>
+#endif
+#if defined (_WIN32)
+#include <io.h>
+#define access _access_s
+#define F_OK 0
+#endif
+
+#include "asn1_node.h"
+#include "asn1_module.h"
+#include "asn1_constraint.h"
+#include "asn1_reference.h"
+#include "asn1_value.h"
+
+#include "asn1_parser_listener.h"
+#include "asn1_parser.h"
+
+extern int _asn1_parse();
+extern FILE *_asn1_in;
+extern "C" int _asn1_wrap(void);
+extern "C" int _asn1_lineno;
+asn1::parser *
+asn1::parser::m_instance = NULL;
+
+/**
+ * wrap function to handle multiple file parsing other than through stdin
+ */
+int _asn1_wrap()
+{
+ asn1::parser *asn1p = asn1::parser::instance();
+ std::string fullname;
+ // If they are files to parse, return 0, but first,
+ // close the current in, and open the new one
+ if ((asn1p->file_mode() ) && _asn1_in != NULL)
+ {
+ fclose(_asn1_in);
+ _asn1_in = NULL;
+ } else if (!asn1p->file_mode())
+ {
+ return 1;
+ }
+ // Only process files if specified
+ if (asn1p->files().size() > 0)
+ {
+ if (asn1p->includes().size() > 0) {
+ std::list<std::string>::iterator it;
+ for ( it = asn1p->includes().begin()
+ ; it != asn1p->includes().end(); ++it)
+ {
+ fullname = (*it) + asn1p->files().back();
+ if (!access(fullname.c_str(),F_OK))
+ {
+ break;
+ }
+ }
+ }
+ if (fullname.size() > 0)
+ {
+ _asn1_in = fopen(fullname.c_str(),"r");
+ if (_asn1_in != NULL)
+ {
+ std::cout<<"New File : "<<fullname<<std::endl;
+ asn1p->files().pop_back();
+ return 0;
+ } else {
+ return 1;
+ }
+ } else
+ return 1;
+ }
+ return 1;
+}
+
+
+namespace asn1
+{
+
+//
+struct got_constraint
+{
+ got_constraint(asn1::constraint *c) : m_c(c) {};
+ void operator ()(parser_listener *l)
+ {
+ l->onConstraint(m_c);
+ }
+ asn1::constraint *m_c;
+};
+
+//
+struct create_module
+{
+ create_module(asn1::module *m) : m_c(m) {};
+ void operator ()(parser_listener *l)
+ {
+ l->onModule(m_c);
+ }
+ asn1::module *m_c;
+};
+
+
+
+/**
+ *
+ */
+asn1::module *
+parser::module(const char *n )
+{
+ iterator it;
+ if (m_modules.size() == 0)
+ {
+ //std::cerr<<"parser::module Create module new 0 :"<<n<<std::endl;
+ m_modules.push_back(new asn1::module(n));
+
+ std::for_each(m_listeners.begin()
+ , m_listeners.end()
+ ,create_module(m_modules.back()));
+ return m_modules.back();
+ }
+ if (n !=NULL)
+ {
+ // std::cout<<"parser::module("<<n<<") modules size="<<m_modules.size()<<std::endl;
+ it = std::find_if(m_modules.begin(),
+ m_modules.end(),asn1::find_module(std::string(n)));
+ // Return found module
+ if (it != m_modules.end() && ! m_modules.empty())
+ {
+ //std::cerr<<"parser::module Found "<<n<<" module:"<<(*it)->name()<<std::endl;
+ return (*it);
+ } else
+ {
+
+ //std::cerr<<"parser::module Create new module:"<<n<<std::endl;
+ m_modules.push_back(new asn1::module(n));
+ std::for_each(m_listeners.begin()
+ , m_listeners.end()
+ ,create_module(m_modules.back()));
+ }
+ }
+ return m_modules.back();
+}
+
+
+/**
+ *
+ */
+void parser::register_listener(parser_listener *l)
+{
+m_listeners.push_back(l);
+}
+
+/**
+ *
+ */
+void parser::constraint_complet(asn1::constraint *c)
+{
+ std::for_each(m_listeners.begin()
+ , m_listeners.end()
+ , got_constraint(c));
+}
+
+/**
+ * Called for each component in a sequence
+ * Get the appropriate module and cast
+ * the container to sequence.
+ */
+void parser::got_component_type(asn1::node *c)
+{
+ asn1::module *m = m_modules.back();
+ asn1::sequence *seq = dynamic_cast<asn1::sequence *>(m->current_context());
+ asn1::set *set = dynamic_cast<asn1::set *>(m->current_context());
+
+ if (seq && c->get_parent() == NULL)
+ {
+ c->set_parent(seq);
+ }
+ if (seq)
+ {
+ seq->add_component(c);
+ } else if (set)
+ {
+ c->set_parent(set);
+ set->append(c);
+ } else
+ {
+ }
+}
+/**
+ * Called for each alternative choice
+ */
+void parser::got_alternative_choice(asn1::node *c)
+{
+ asn1::module *m = m_modules.back();
+ asn1::choice *s = dynamic_cast<asn1::choice *>(m->current_context());
+
+ if (c->get_parent() == NULL)
+ {
+ c->set_parent(s);
+ }
+ s->add_alternative(c);
+}
+//
+void
+parser::got_class_field(asn1::classfield *c)
+{
+ asn1::module *m = m_modules.back();
+ asn1::classdef *s = dynamic_cast<asn1::classdef *>(m->current_context());
+
+ if (c->get_parent() == NULL)
+ {
+ c->set_parent(s);
+ }
+ s->add_field(c);
+}
+
+
+void
+parser::got_parameter(asn1::parameter *p)
+{
+ asn1::module *m = m_modules.back();
+ asn1::parameters *pl = dynamic_cast<asn1::parameters *>(m->current_context());
+ if (p->get_parent() == NULL)
+ {
+ p->set_parent(pl);
+ }
+ pl->add_parameter(p);
+}
+
+void
+parser::got_act_parameter(asn1::node *c)
+{
+ asn1::module *m = m_modules.back();
+ asn1::act_parameters *pl = dynamic_cast<asn1::act_parameters *>(m->current_context());
+ if (c->get_parent() == NULL)
+ {
+ c->set_parent(pl);
+ }
+ pl->add_parameter(c);
+}
+
+int
+parser::parse()
+{
+ if ( file_mode() )
+ {
+ _asn1_in = NULL;
+ if ( !_asn1_wrap() )
+ {
+ _asn1_parse();
+ return 0;
+ } else
+ {
+ return 1;
+ }
+ } else if (! file_mode())
+ {
+ _asn1_parse();
+ return 0;
+ }
+ {
+ return 1;
+ }
+}
+
+}
--- /dev/null
+#ifndef ASN1_PARSER_H__
+#define ASN1_PARSER_H__
+
+#include "asn1_node.h"
+#include "asn1_module.h"
+#include "asn1_parser_listener.h"
+
+namespace asn1 {
+
+class asn1_parser_listener;
+
+class parser
+{
+ public:
+ typedef std::vector<asn1::module *> modules_type;
+ typedef std::vector<asn1::module *>::iterator iterator;
+
+ typedef std::list<asn1::parser_listener *> listener_list;
+
+ typedef std::list<std::string> string_list;
+
+ static parser *instance()
+ {
+ if (m_instance == NULL)
+ {
+ m_instance = new parser();
+ }
+ return m_instance;
+ }
+
+ inline iterator begin() {return m_modules.begin();}
+ inline iterator end() {return m_modules.end();}
+
+ asn1::module * module(const char *n = NULL);
+
+ modules_type &modules() { return m_modules;};
+
+ /**
+ *
+ */
+ void register_listener(parser_listener *l);
+
+ /**
+ * Entry point to notify listeners that a constraint definition
+ * has occured.
+ */
+ void constraint_complet(asn1::constraint *c);
+
+ /**
+ * Called for each component in a sequence
+ */
+ void got_component_type(asn1::node *c);
+ /**
+ * Called for each alternative choice
+ */
+ void got_alternative_choice(asn1::node *c);
+ /**
+ * Called for each alternative choice
+ */
+ void got_class_field(asn1::classfield *c);
+
+ void got_parameter(asn1::parameter *p);
+
+ void got_act_parameter(asn1::node *n);
+
+ int parse();
+
+ inline bool debug_console() const
+ { return m_debug_console ; }
+
+ inline void debug_console(bool b)
+ { m_debug_console = true; }
+ inline string_list &includes() { return m_includes; }
+ inline string_list &files() { return m_files; }
+ inline bool file_mode() { return m_file_mode;}
+ inline void set_file_mode(bool fm)
+ { m_file_mode = fm;}
+ private:
+ parser()
+ : m_file_mode(false) , m_root(NULL)
+ {};
+ parser(const parser &p)
+ {};
+ parser &operator =(const parser &p) { return *this;};
+
+
+ private:
+ modules_type m_modules;
+ static parser *m_instance;
+
+ protected:
+ bool m_debug_console;
+ node *m_root;
+ listener_list m_listeners;
+ string_list m_includes;
+ string_list m_files;
+ bool m_file_mode;
+};
+
+//parser::m_instance = NULL;
+}
+
+/*
+ * vim:et:sw=2:ts=2
+ */
+
+#endif
--- /dev/null
+#ifndef ASN1_PARSER_LISTENER_H
+#define ASN1_PARSER_LISTENER_H
+
+namespace asn1
+{
+
+/**
+ * @brief This class is an interface that is used by the parser. It allows an application
+ * to listen to some events from the parser.
+ * Example: a contraints has been parsed
+ * a typedefinition is completed
+ * a component of a set or sequence has been parser.
+ */
+class parser_listener
+{
+ public:
+ parser_listener () {};
+
+ // Constraint
+ virtual void onConstraint(asn1::constraint *c) {};
+
+ virtual void onModule(asn1::module *m) {};
+ protected:
+};
+
+}
+#endif /*ASN1_PARSER_LISTENER_H*/
--- /dev/null
+#include <iostream>
+#include <fstream>
+#include <string.h>
+#include <map>
+#include <list>
+
+// For open / close
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "asn1_generator.h"
+#include "asn1_gen_cpp.h"
+#include "asn1_gen_hpp.h"
+#include "js/asn1_gen_js.h"
+#include "uml/asn1_gen_uml.h"
+#include "lds/asn1_gen_lds.h"
+#include "asn1_gen_codec_cpp.h"
+#include "asn1_gen_auto_tag.h"
+#include "asn1_gen_optimizer.h"
+#include "libparser/asn1_parser.h"
+#include "asn1_gen_constraints.h"
+
+#include "optionparser.h"
+
+/**
+ * Global Variables for the parser / lexer
+ */
+
+
+enum optionIndex {
+ UNKNOWN, HELP
+ ,UML,ERULE
+ ,FICHIER,OUTPUT,INCLUDE
+ ,PLANG,COMMENT,CODEC,OPTSPLIT,OPTDBG,OPT_END};
+/*----------------------------------------------------------------------------*/
+const option::Descriptor usage[] = {
+ {UNKNOWN, 0, "", "", option::Arg::None,"Welcome to asn1p compiler (c) aeb"
+ " 2016-2018 " BUILD_TYPE " " BUILD_VERSION "\n"
+ "Usage asn1p [options]\n\texample:"
+ " asn1p -e ber -f toto.asn1 -I[path]\n"},
+ {HELP, 0, "h", "help",option::Arg::None,"--help,-h \tPrint help and quit."},
+ {UML, 0, "u", "uml", option::Arg::Optional,"--uml,-u \tGenerate UML model of asn1 model."},
+ {ERULE, 0, "e", "ecoding_rule", option::Arg::Required,"--encoding_rule ,-e \t Encoding rules to use"
+ " accepted ER: ber,per,oer,jer,xer "},
+ {FICHIER, 0, "f", "file", option::Arg::Required,"--file,-f \tAsn1 input file to parse"},
+ {OUTPUT, 0, "o", "ouput", option::Arg::Required,"--output,-o \toutput file without extension to be generated"},
+ {INCLUDE, 0, "I", "include", option::Arg::Required,"--include,-I\tInclude path to look for other asn1 files."},
+ {PLANG, 0, "l", "language", option::Arg::Required,"--language,-l\t"
+ "Programming language cpp, uml, javascript, lds, sql [default: cpp]"},
+ {COMMENT, 0, "n", "comment", option::Arg::Required,"--comment,-n\t"
+ "(true or ON)/(false or OFF) generate comment in source def true"},
+ {CODEC, 0, "c", "codec", option::Arg::Required,"--codec,-c\tCodecs"
+ " functions ON or OFF [default: OFF]"
+ },
+ {OPTSPLIT, 0, "s", "split", option::Arg::None,"--split,-s\t"
+ " put codec code in separated cpp files. Needed for huge definitions"
+ },
+ {OPTDBG, 0, "d", "debug", option::Arg::Required,"--debug,-d\tconsole=1 "
+ " msg=1 debug messages in code parser=<1-8> parser debug traces"},
+ {0,0,0,0,0,0}
+};
+
+struct language_config
+{
+ language_config()
+ : m_cpp(true)
+ , m_uml(true)
+ , m_javascript(false)
+ , m_lds(false)
+ , m_java(false)
+ , m_csharp(true)
+ , m_sql(true)
+ , m_c(false)
+ {};
+#define WITH_PLANG(nm) \
+ bool with_##nm() { return m_##nm; } ; \
+ void with_##nm(bool b) { m_##nm = b ; } ;
+ WITH_PLANG(cpp)
+ WITH_PLANG(javascript)
+ WITH_PLANG(lds)
+ WITH_PLANG(java)
+ WITH_PLANG(csharp)
+ WITH_PLANG(sql)
+ WITH_PLANG(c)
+ WITH_PLANG(uml)
+#undef WITH_PLANG
+ // generator configuration flags
+ bool m_cpp;
+ bool m_uml;
+ bool m_javascript;
+ bool m_lds;
+ bool m_java;
+ bool m_csharp;
+ bool m_sql;
+ bool m_c;
+};
+
+
+/**
+ * Main entry point
+ */
+int main(int argc,char **argv)
+{
+ std::map<std::string,std::string> module_map;
+ std::string umlname;
+ asn1::parser::iterator it;
+ asn1::parser *p = asn1::parser::instance();
+ asn1::generator_config g_config;
+ language_config l_config;
+ gen_constraints constraints;
+ // Option stuff must go here
+ option::Stats stats(usage,argc-1,&argv[1]);
+ //const int max(stats.options_max);
+ option::Option options[OPT_END*3],buffer[OPT_END*4];
+ option::Parser parser(usage,argc-1,&argv[1],options,buffer);
+
+ p->register_listener(&constraints);
+ if (parser.error()) {
+ return 1;
+ }
+ if (options[HELP] )
+ {
+ option::printUsage(std::cout,usage);
+ return 1;
+ }
+ if (options[INCLUDE])
+ {
+ for ( option::Option *opts = options[INCLUDE]
+ ; opts; opts = opts->next())
+ {
+ if (opts->arg)
+ p->includes().push_back(std::string(opts->arg));
+ }
+ }
+ if (options[OPTSPLIT])
+ {
+ g_config.with_split_cpp(true);
+ }
+ /**
+ * Codecs included in structures
+ */
+ if (options[CODEC])
+ {
+ for (option::Option *opts = options[CODEC] ;opts; opts = opts->next())
+ {
+ while (* opts->arg == ' ') opts->arg++;
+ if (opts->arg &&
+ (! strcmp(opts->arg,"false") || !strcmp(opts->arg,"OFF")))
+ {
+ g_config.with_codec(false);
+ } else if (opts->arg &&
+ (! strcmp(opts->arg,"true") || !strcmp(opts->arg,"ON")))
+ {
+ g_config.with_codec(true);
+ } else
+ {
+ std::cerr<<"Wrong argument for CODEC"<<std::endl;
+ }
+ }
+ }
+ /**
+ * Codecs included in structures
+ */
+ if (options[PLANG])
+ {
+ for (option::Option *opts = options[PLANG] ;opts; opts = opts->next())
+ {
+ while (* opts->arg == ' ') opts->arg++;
+ if (opts->arg && ! strcmp(opts->arg,"uml"))
+ { l_config.with_uml(true); continue; }
+
+ if (opts->arg && ! strcmp(opts->arg,"cpp"))
+ { l_config.with_cpp(true); continue; }
+
+ if (opts->arg && ! strcmp(opts->arg,"javascript"))
+ { l_config.with_javascript(true); continue; }
+
+ if (opts->arg && ! strcmp(opts->arg,"lds"))
+ { l_config.with_lds(true); continue; }
+
+
+ std::cerr<<"Unsuported language. "<<opts->arg<<std::endl;
+ exit(1);
+ }
+ }
+ /**
+ * Encoding rules to be implemented in structures
+ */
+ if (options[ERULE])
+ {
+ for (option::Option *opts = options[ERULE] ;opts; opts = opts->next())
+ {
+ /* remove spaces */
+ while (* opts->arg == ' ') opts->arg++;
+ if (opts->arg && ! strcmp(opts->arg,"ber"))
+ { g_config.with_ber(true); continue; }
+
+ if (opts->arg && ! strcmp(opts->arg,"jer"))
+ { g_config.with_jer(true); continue; }
+
+ if (opts->arg && ! strcmp(opts->arg,"oer"))
+ { g_config.with_oer(true); continue; }
+
+ if (opts->arg && ! strcmp(opts->arg,"per"))
+ { g_config.with_per(true); continue; }
+
+ if (opts->arg && ! strcmp(opts->arg,"xer"))
+ { g_config.with_xer(true); continue; }
+
+
+ std::cerr<<"Unsuported encoding rule. <"<<opts->arg<<">"<<std::endl;
+ exit(1);
+ }
+ }
+ if (options[OPTDBG])
+ {
+ for (option::Option *opts = options[OPTDBG] ;opts; opts = opts->next())
+ {
+ if (opts->arg && ! strcmp(opts->arg,"msg=1"))
+ { g_config.with_source_debug(true); continue; }
+
+
+ if (opts->arg && ! strcmp(opts->arg,"console=1"))
+ { std::cout<<"TODO"<<std::endl; continue; }
+
+ if (opts->arg && ! strncmp(opts->arg,"parser=",7))
+ { std::cout<<"TODO parser debug level"; continue; }
+
+ std::cerr<<"Unsuported option "<<opts->arg<<std::endl;
+ exit(1);
+ }
+ }
+ if (options[COMMENT])
+ {
+ for ( option::Option *opts = options[COMMENT]
+ ; opts; opts = opts->next())
+ {
+ if (opts->arg && (
+ (! strcmp(opts->arg,"false") ||!strcmp(opts->arg,"OFF")) ))
+ {
+ g_config.with_source_comment(false);
+ }
+ }
+ }
+
+ if (options[FICHIER] )
+ {
+ for ( option::Option *opts = options[FICHIER]
+ ; opts; opts = opts->next())
+ {
+ if (opts->arg)
+ p->files().push_back(std::string(opts->arg));
+ }
+ p->set_file_mode(true);
+ std::cout<<"Main: start with wrap feature"<<std::endl;
+ if (p->parse())
+ {
+ std::cout<<"Main: start with wrap failed "<<std::endl;
+ }
+ } else
+ {
+ // Parsing of stdin this might change in the future
+ //_asn1_parse();
+ p->parse();
+ }
+
+ if (options[UML] && options[UML].arg != NULL) {
+ umlname = std::string(options[UML].arg);
+ std::cout<<"Will generate : "<<umlname<<std::endl;
+ } else
+ umlname = std::string("_model.uml");
+
+ // Launch optimization on all modules
+ // before any generation....
+ // Does not work for cstav1 2017-05-02
+
+ // Launch generation
+ //
+ for ( it = p->begin(); it != p->end(); it++ )
+ {
+ std::fstream os;
+ std::fstream osauto;
+ std::string fname = (*it)->cpp_name() + std::string(".h");
+ std::string fcname = (*it)->name() + std::string(".cpp");
+ std::string jsname = (*it)->name() + std::string(".js");
+ std::string autoname = (*it)->name() + std::string(".auto");
+ asn1::gen_auto_tag gen_auto((*it),p->modules());
+
+ // If OUTPUT option is set, only generate the specified module
+ if (options[OUTPUT] && (options[OUTPUT].arg != NULL ))
+ {
+ bool found = false;
+ for ( option::Option *opts = options[OUTPUT]
+ ; opts; opts = opts->next())
+ {
+ if (! (*it)->name().compare(opts->arg))
+ {
+ found = true;
+ break;
+ }
+ }
+ if (!found )
+ continue;
+ }
+ // Launch optimization
+ asn1::gen_optimizer ogen((*it),p->modules());
+ ogen.set_config(g_config);
+ ogen.gen(std::cout,".optimize" );
+ // Do automatic tagging
+ osauto.open(autoname.c_str(),std::fstream::out);
+ gen_auto.gen(osauto,".auto");
+ osauto.close();
+ //
+ if (l_config.with_javascript())
+ {
+ os.open(jsname.c_str(),std::fstream::out);
+ std::cout<<"\n*\n*Process javascript generation for Definition :";
+ std::cout<<(*it)->name()<<"\n*"<<std::endl;
+ generate_js gen((*it),p->modules());
+ // Generate automatic tag.
+ // This class goes through the module for automatic tagging
+ gen.gen(os,".js");
+ os.close();
+
+ } else if (options[UML] )
+ {
+ std::fstream umlos;
+ std::cout<<"\n*\n*Process uml generation for Definition :";
+ std::cout<<(*it)->name()<<"\n*"<<std::endl;
+ umlos.open(umlname.c_str(),std::fstream::out);
+ generate_uml gen_uml((*it),p->modules());
+ gen_uml.gen(umlos,".uml");
+ umlos.close();
+ } else
+ {
+ os.open(fname.c_str(),std::fstream::out);
+ std::cout<<"\n*\n*Process cpp generation for Definition :";
+ std::cout<<(*it)->name()<<"\n*"<<std::endl;
+ // Lets go and generate headers
+ generate_header gen((*it),p->modules());
+ gen.set_config(g_config);
+ gen.gen(os,".hpp");
+ os.close();
+
+ // Reset generated flag
+ asn1::node::iterator nit = (*it)->begin();
+ for (; nit != (*it)->end() ; nit++)
+ {
+ (*nit)->set_generated(false);
+ }
+ // Generate codec cod
+ os.open(fcname.c_str(),std::fstream::out);
+ generate_codec_cpp genc((*it),p->modules(),constraints);
+ genc.set_config(g_config);
+ genc.gen(os,".cpp");
+ os.close();
+ }
+ if (l_config.with_lds())
+ {
+ std::string ldsname = (*it)->name() + std::string(".lds");
+ os.open(ldsname.c_str(),std::fstream::out);
+ generate_lds genlds((*it),p->modules());
+ std::cout<<"\n*\n*Process lds generation for Definition :";
+ std::cout<<(*it)->name()<<"\n*"<<std::endl;
+ genlds.gen(os,".lds");
+ os.close();
+ }
+ }
+ std::cout<<"Bye "<<argv[0]<<std::endl;
+}
+
+/*
+ * vim: et sw=2 ts=2 :
+ */
--- /dev/null
+PROJECT(megaco)
+
+SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
+ "${rules_SOURCE_DIR}/")
+
+SET(MEGACO_ERULE -e jer -e ber -c ON)
+FIND_PACKAGE(PCAP REQUIRED)
+INCLUDE_DIRECTORIES(${PCAP_INCLUDE_DIRS})
+
+FIND_PACKAGE(Sqlite3)
+FIND_PACKAGE(Fcgi)
+
+FILE(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/modules.txt MEGACOMODULES)
+
+FOREACH(ITEM ${MEGACOMODULES})
+ STRING(REGEX REPLACE "-" "_" HITEM ${ITEM})
+ SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/${HITEM}.h GENERATED)
+ SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/${ITEM}.cpp GENERATED)
+ SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/${HITEM}_codec.cpp GENERATED)
+ SET(MEGACOSRC ${MEGACOSRC} ${CMAKE_CURRENT_BINARY_DIR}/${ITEM}.cpp)
+ SET(MEGACOSRC ${MEGACOSRC} ${CMAKE_CURRENT_BINARY_DIR}/${HITEM}_codec.cpp)
+ SET(MEGACOHDR ${MEGACOHDR} ${CMAKE_CURRENT_BINARY_DIR}/${HITEM}.h)
+
+SET_DIRECTORY_PROPERTIES(PROPERTIES
+ ADDITIONAL_MAKE_CLEAN_FILES "${CMAKE_CURRENT_BINARY_DIR}/${ITEM}.cpp"
+ )
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/${ITEM}.cpp COMPILE_FLAGS "-DASN1_ATTRIBUTE_OPTIONAL_AS_SHARED_POINTER")
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/${HITEM}_codec.cpp COMPILE_FLAGS "-DASN1_ATTRIBUTE_OPTIONAL_AS_SHARED_POINTER")
+
+SET_DIRECTORY_PROPERTIES(PROPERTIES
+ ADDITIONAL_MAKE_CLEAN_FILES "${CMAKE_CURRENT_BINARY_DIR}/${HITEM}.h"
+ )
+
+ENDFOREACH(ITEM)
+
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+
+#
+#
+#
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote_Operations_Information_Objects.h
+ ${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Information-Objects.cpp
+ COMMAND ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ ARGS -I ${asn1-data-models_SOURCE_DIR}/cstav1/
+ -f Remote-Operations-Information-Objects.asn1
+ -o Remote-Operations-Information-Objects
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ COMMENT "Build ROIO .h and .cpp"
+ )
+
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/Remote_Operations_Information_Objects.h
+ GENERATED)
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Information-Objects.cpp
+ GENERATED)
+
+SET_DIRECTORY_PROPERTIES(PROPERTIES
+ ADDITIONAL_MAKE_CLEAN_FILES
+ "${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Information-Objects.h ${CMAKE_CURRENT_BINARY_DIR}/Remote-Operations-Information-Objects.cpp"
+ )
+
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${MEGACOSRC}
+ ${MEGACOHDR}
+ COMMAND ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ ARGS ${MEGACO_ERULE} -I ${asn1-data-models_SOURCE_DIR}/
+ -f rfc3525-MEDIA-GATEWAY-CONTROL.asn1
+ -o MEDIA-GATEWAY-CONTROL
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ COMMENT "Build MEDIA-GATEWAY-CONTROL .h and .cpp"
+ )
+
+
+
+ADD_LIBRARY(megaco
+ ${MEGACOSRC}
+ )
+
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_SOURCE_DIR}/main.cpp COMPILE_FLAGS "-DASN1_ATTRIBUTE_OPTIONAL_AS_SHARED_POINTER")
+ADD_EXECUTABLE(test_megaco
+ main.cpp
+ )
+
+TARGET_LINK_LIBRARIES(test_megaco megaco asn1)
+
+
+
+
+#
+# Install stuff
+#
+INSTALL(TARGETS test_megaco megaco
+ RUNTIME DESTINATION bin
+ LIBRARY DESTINATION lib
+ ARCHIVE DESTINATION lib
+ COMPONENT megaco
+ )
+
+#
+# Ok start working with Packaging stuff
+#
+INCLUDE(InstallRequiredSystemLibraries)
+
+SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Graphical user interface to visualize
+csta phase 2 and sip messages from pcap files")
+SET(CPACK_PACKAGE_VENDOR "Aeb")
+#SET(CPACK_PACKAGE_DESCRIPTION_FILE "")
+#SET(CPACK_RESOURCE_FILE_LICENSE "")
+SET(CPACK_PACKAGE_VERSION_MAJOR "1")
+SET(CPACK_PACKAGE_VERSION_MINOR "0")
+SET(CPACK_PACKAGE_VERSION_PATCH "0")
+
+SET(CPACK_PACKAGE_FILE_NAME "CstaSpyInstaller")
+SET(CPACK_PACKAGE_NAME "CstaSpy")
+
+IF(WIN32)
+ SET(CPACK_GENERATOR "NSIS")
+ENDIF()
+
+IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux" )
+ SET(CPACK_GENERATOR "RPM")
+ENDIF()
+#SET(CPACK_PACKAGE_EXECUTABLES "cstaspy")
+#SET(CPACK_PACKAGE_EXECUTABLES "cstaspy" "CSTA Spy")
+INCLUDE(CPack)
--- /dev/null
+#include <iostream>
+#include <fstream>
+#include <string.h>
+#include <typeinfo>
+#include <stdlib.h>
+#include "rtasn1/asn1_config.h"
+
+#include "rtasn1/asn1.h"
+#include "rtasn1/asn1_codec.h"
+#include "rtasn1/asn1_codec_ber.h"
+#include "rtasn1/asn1_codec_jer.h"
+
+#include "MEDIA_GATEWAY_CONTROL.h"
+#include "MEDIA_GATEWAY_CONTROL_codec.hpp"
+
+using namespace MEDIA_GATEWAY_CONTROL;
+
+void test_message() {
+ asn1::streams::ber ctx;
+ asn1::streams::jer ctx_jer;
+ IP4Address ip4;
+ Message m,mjer;
+ m.version = 2;
+ ip4.address = std::string("0345");
+ ip4.portNumber.get() = 1045;
+ Transaction trans;
+ CommandRequest cr;
+ ActionRequest ar;
+ TerminationID tid;
+ WildcardField wf; wf = std::string("*");
+ ar.contextId = 0xFFFFFFFF;
+ tid.id = std::string("100");
+ cr.command.get_addReq().terminationID.push_back(tid);
+ tid.id = std::string("101");
+ tid.wildcard.push_back(wf);
+ tid.wildcard.push_back(wf);
+ cr.command.get_addReq().terminationID.push_back(tid);
+ ar.commandRequests.push_back(cr);
+ //m.mId.ip4Address = ip4;
+ //m.mId.kind_ = MId::typeof_ip4Address;
+ //m.mId.set_tag(asn1::tag(asn1::types::CONTEXT_SPECIFIC,MId::typeof_ip4Address));
+ //m.mId.set_tag(asn1::tag(asn1::types::CONTEXT_SPECIFIC,0));
+ m.mId.set_ip4Address ( ip4 );
+ trans.get_transactionRequest().transactionId = 5;
+ trans.get_transactionRequest().actions.push_back(ar);
+ m.messageBody.get_transactions().push_back(trans);
+ //m.messageBody.get_transactions().push_back(trans);
+#if 0
+ // This should be possible as well;
+ mIP4Address &ip4 = m.mId.get_ip4Addres();
+ ip4.address = std::string("0345");
+ ip4.portNumber.get() = 1045;
+#endif
+ std::cout<<"Message:\n"<<m<<"\nmId should be:\n "<<ip4<<"\n"<<std::endl;
+ m.encode(ctx);
+ std::cout<<"encoded\n"<<m<<"\nmId encode JER:\n "<<std::endl;
+ asn1::codecJER cb;
+ cb.encode(ctx_jer,m);
+ std::cout<<"JER:<"<<ctx_jer<<">"<<std::endl;
+ asn1::streams::jer cddec(ctx_jer.buffer(),512);
+ if ( cb.decode(cddec,mjer) != asn1::ok)
+ {
+ std::cout<<"JER: Failed decode"<<std::endl;
+ } else
+ {
+ std::cout<<"Decode JER:\n"<<mjer<<"\n"<<std::endl;
+ }
+
+}
+
+void message(const char *program)
+{
+ printf("%s [OPTIONS]\n",program);
+ printf("\t-d\tdebug level [0-7]\n");
+}
+
+int main(int argc,char **argv)
+{
+#ifdef HAVE_UNISTD_H
+ char ch;
+ while ( (ch = getopt(argc,argv,"d:h")) != -1)
+ {
+ switch (ch)
+ {
+ case 'd':
+ {
+ asn1::types::debug_level = atoi(optarg);
+ }
+ break;
+ case 'h':
+ case '?':
+ default:
+ message(argv[0]);
+
+ }
+ }
+#endif
+ test_message();
+}
+
--- /dev/null
+MEDIA-GATEWAY-CONTROL
--- /dev/null
+/*
+ * The Lean Mean C++ Option Parser
+ *
+ * Copyright (C) 2012 Matthias S. Benkmann
+ *
+ * The "Software" in the following 2 paragraphs refers to this file containing
+ * the code to The Lean Mean C++ Option Parser.
+ * The "Software" does NOT refer to any other files which you
+ * may have received alongside this file (e.g. as part of a larger project that
+ * incorporates The Lean Mean C++ Option Parser).
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software, to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to permit
+ * persons to whom the Software is furnished to do so, subject to the following
+ * conditions:
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/*
+ * NOTE: It is recommended that you read the processed HTML doxygen documentation
+ * rather than this source. If you don't know doxygen, it's like javadoc for C++.
+ * If you don't want to install doxygen you can find a copy of the processed
+ * documentation at
+ *
+ * http://optionparser.sourceforge.net/
+ *
+ */
+
+/**
+ * @file
+ *
+ * @brief This is the only file required to use The Lean Mean C++ Option Parser.
+ * Just \#include it and you're set.
+ *
+ * The Lean Mean C++ Option Parser handles the program's command line arguments
+ * (argc, argv).
+ * It supports the short and long option formats of getopt(), getopt_long()
+ * and getopt_long_only() but has a more convenient interface.
+ * The following features set it apart from other option parsers:
+ *
+ * @par Highlights:
+ * <ul style="padding-left:1em;margin-left:0">
+ * <li> It is a header-only library. Just <code>\#include "optionparser.h"</code> and you're set.
+ * <li> It is freestanding. There are no dependencies whatsoever, not even the
+ * C or C++ standard library.
+ * <li> It has a usage message formatter that supports column alignment and
+ * line wrapping. This aids localization because it adapts to
+ * translated strings that are shorter or longer (even if they contain
+ * Asian wide characters).
+ * <li> Unlike getopt() and derivatives it doesn't force you to loop through
+ * options sequentially. Instead you can access options directly like this:
+ * <ul style="margin-top:.5em">
+ * <li> Test for presence of a switch in the argument vector:
+ * @code if ( options[QUIET] ) ... @endcode
+ * <li> Evaluate --enable-foo/--disable-foo pair where the last one used wins:
+ * @code if ( options[FOO].last()->type() == DISABLE ) ... @endcode
+ * <li> Cumulative option (-v verbose, -vv more verbose, -vvv even more verbose):
+ * @code int verbosity = options[VERBOSE].count(); @endcode
+ * <li> Iterate over all --file=<fname> arguments:
+ * @code for (Option* opt = options[FILE]; opt; opt = opt->next())
+ * fname = opt->arg; ... @endcode
+ * <li> If you really want to, you can still process all arguments in order:
+ * @code
+ * for (int i = 0; i < p.optionsCount(); ++i) {
+ * Option& opt = buffer[i];
+ * switch(opt.index()) {
+ * case HELP: ...
+ * case VERBOSE: ...
+ * case FILE: fname = opt.arg; ...
+ * case UNKNOWN: ...
+ * @endcode
+ * </ul>
+ * </ul> @n
+ * Despite these features the code size remains tiny.
+ * It is smaller than <a href="http://uclibc.org">uClibc</a>'s GNU getopt() and just a
+ * couple 100 bytes larger than uClibc's SUSv3 getopt(). @n
+ * (This does not include the usage formatter, of course. But you don't have to use that.)
+ *
+ * @par Download:
+ * Tarball with examples and test programs:
+ * <a style="font-size:larger;font-weight:bold" href="http://sourceforge.net/projects/optionparser/files/optionparser-1.3.tar.gz/download">optionparser-1.3.tar.gz</a> @n
+ * Just the header (this is all you really need):
+ * <a style="font-size:larger;font-weight:bold" href="http://optionparser.sourceforge.net/optionparser.h">optionparser.h</a>
+ *
+ * @par Changelog:
+ * <b>Version 1.3:</b> Compatible with Microsoft Visual C++. @n
+ * <b>Version 1.2:</b> Added @ref option::Option::namelen "Option::namelen" and removed the extraction
+ * of short option characters into a special buffer. @n
+ * Changed @ref option::Arg::Optional "Arg::Optional" to accept arguments if they are attached
+ * rather than separate. This is what GNU getopt() does and how POSIX recommends
+ * utilities should interpret their arguments.@n
+ * <b>Version 1.1:</b> Optional mode with argument reordering as done by GNU getopt(), so that
+ * options and non-options can be mixed. See
+ * @ref option::Parser::parse() "Parser::parse()".
+ *
+ * @par Feedback:
+ * Send questions, bug reports, feature requests etc. to: <tt><b>optionparser-feedback<span id="antispam"> (a) </span>lists.sourceforge.net</b></tt>
+ * @htmlonly <script type="text/javascript">document.getElementById("antispam").innerHTML="@"</script> @endhtmlonly
+ *
+ *
+ * @par Example program:
+ * (Note: @c option::* identifiers are links that take you to their documentation.)
+ * @code
+ * #include <iostream>
+ * #include "optionparser.h"
+ *
+ * enum optionIndex { UNKNOWN, HELP, PLUS };
+ * const option::Descriptor usage[] =
+ * {
+ * {UNKNOWN, 0,"" , "" ,option::Arg::None, "USAGE: example [options]\n\n"
+ * "Options:" },
+ * {HELP, 0,"" , "help",option::Arg::None, " --help \tPrint usage and exit." },
+ * {PLUS, 0,"p", "plus",option::Arg::None, " --plus, -p \tIncrement count." },
+ * {UNKNOWN, 0,"" , "" ,option::Arg::None, "\nExamples:\n"
+ * " example --unknown -- --this_is_no_option\n"
+ * " example -unk --plus -ppp file1 file2\n" },
+ * {0,0,0,0,0,0}
+ * };
+ *
+ * int main(int argc, char* argv[])
+ * {
+ * argc-=(argc>0); argv+=(argc>0); // skip program name argv[0] if present
+ * option::Stats stats(usage, argc, argv);
+ * option::Option options[stats.options_max], buffer[stats.buffer_max];
+ * option::Parser parse(usage, argc, argv, options, buffer);
+ *
+ * if (parse.error())
+ * return 1;
+ *
+ * if (options[HELP] || argc == 0) {
+ * option::printUsage(std::cout, usage);
+ * return 0;
+ * }
+ *
+ * std::cout << "--plus count: " <<
+ * options[PLUS].count() << "\n";
+ *
+ * for (option::Option* opt = options[UNKNOWN]; opt; opt = opt->next())
+ * std::cout << "Unknown option: " << opt->name << "\n";
+ *
+ * for (int i = 0; i < parse.nonOptionsCount(); ++i)
+ * std::cout << "Non-option #" << i << ": " << parse.nonOption(i) << "\n";
+ * }
+ * @endcode
+ *
+ * @par Option syntax:
+ * @li The Lean Mean C++ Option Parser follows POSIX <code>getopt()</code> conventions and supports
+ * GNU-style <code>getopt_long()</code> long options as well as Perl-style single-minus
+ * long options (<code>getopt_long_only()</code>).
+ * @li short options have the format @c -X where @c X is any character that fits in a char.
+ * @li short options can be grouped, i.e. <code>-X -Y</code> is equivalent to @c -XY.
+ * @li a short option may take an argument either separate (<code>-X foo</code>) or
+ * attached (@c -Xfoo). You can make the parser accept the additional format @c -X=foo by
+ * registering @c X as a long option (in addition to being a short option) and
+ * enabling single-minus long options.
+ * @li an argument-taking short option may be grouped if it is the last in the group, e.g.
+ * @c -ABCXfoo or <code> -ABCX foo </code> (@c foo is the argument to the @c -X option).
+ * @li a lone minus character @c '-' is not treated as an option. It is customarily used where
+ * a file name is expected to refer to stdin or stdout.
+ * @li long options have the format @c --option-name.
+ * @li the option-name of a long option can be anything and include any characters.
+ * Even @c = characters will work, but don't do that.
+ * @li [optional] long options may be abbreviated as long as the abbreviation is unambiguous.
+ * You can set a minimum length for abbreviations.
+ * @li [optional] long options may begin with a single minus. The double minus form is always
+ * accepted, too.
+ * @li a long option may take an argument either separate (<code> --option arg </code>) or
+ * attached (<code> --option=arg </code>). In the attached form the equals sign is mandatory.
+ * @li an empty string can be passed as an attached long option argument: <code> --option-name= </code>.
+ * Note the distinction between an empty string as argument and no argument at all.
+ * @li an empty string is permitted as separate argument to both long and short options.
+ * @li Arguments to both short and long options may start with a @c '-' character. E.g.
+ * <code> -X-X </code>, <code>-X -X</code> or <code> --long-X=-X </code>. If @c -X
+ * and @c --long-X take an argument, that argument will be @c "-X" in all 3 cases.
+ * @li If using the built-in @ref option::Arg::Optional "Arg::Optional", optional arguments must
+ * be attached.
+ * @li the special option @c -- (i.e. without a name) terminates the list of
+ * options. Everything that follows is a non-option argument, even if it starts with
+ * a @c '-' character. The @c -- itself will not appear in the parse results.
+ * @li the first argument that doesn't start with @c '-' or @c '--' and does not belong to
+ * a preceding argument-taking option, will terminate the option list and is the
+ * first non-option argument. All following command line arguments are treated as
+ * non-option arguments, even if they start with @c '-' . @n
+ * NOTE: This behaviour is mandated by POSIX, but GNU getopt() only honours this if it is
+ * explicitly requested (e.g. by setting POSIXLY_CORRECT). @n
+ * You can enable the GNU behaviour by passing @c true as first argument to
+ * e.g. @ref option::Parser::parse() "Parser::parse()".
+ * @li Arguments that look like options (i.e. @c '-' followed by at least 1 character) but
+ * aren't, are NOT treated as non-option arguments. They are treated as unknown options and
+ * are collected into a list of unknown options for error reporting. @n
+ * This means that in order to pass a first non-option
+ * argument beginning with the minus character it is required to use the
+ * @c -- special option, e.g.
+ * @code
+ * program -x -- --strange-filename
+ * @endcode
+ * In this example, @c --strange-filename is a non-option argument. If the @c --
+ * were omitted, it would be treated as an unknown option. @n
+ * See @ref option::Descriptor::longopt for information on how to collect unknown options.
+ *
+ */
+
+#ifndef OPTIONPARSER_H_
+#define OPTIONPARSER_H_
+
+/** @brief The namespace of The Lean Mean C++ Option Parser. */
+namespace option
+{
+
+#ifdef _MSC_VER
+#include <intrin.h>
+#pragma intrinsic(_BitScanReverse)
+struct MSC_Builtin_CLZ
+{
+ static int builtin_clz(unsigned x)
+ {
+ unsigned long index;
+ _BitScanReverse(&index, x);
+ return 32-index; // int is always 32bit on Windows, even for target x64
+ }
+};
+#define __builtin_clz(x) MSC_Builtin_CLZ::builtin_clz(x)
+#endif
+
+class Option;
+
+/**
+ * @brief Possible results when checking if an argument is valid for a certain option.
+ *
+ * In the case that no argument is provided for an option that takes an
+ * optional argument, return codes @c ARG_OK and @c ARG_IGNORE are equivalent.
+ */
+enum ArgStatus
+{
+ //! The option does not take an argument.
+ ARG_NONE,
+ //! The argument is acceptable for the option.
+ ARG_OK,
+ //! The argument is not acceptable but that's non-fatal because the option's argument is optional.
+ ARG_IGNORE,
+ //! The argument is not acceptable and that's fatal.
+ ARG_ILLEGAL
+};
+
+/**
+ * @brief Signature of functions that check if an argument is valid for a certain type of option.
+ *
+ * Every Option has such a function assigned in its Descriptor.
+ * @code
+ * Descriptor usage[] = { {UNKNOWN, 0, "", "", Arg::None, ""}, ... };
+ * @endcode
+ *
+ * A CheckArg function has the following signature:
+ * @code ArgStatus CheckArg(const Option& option, bool msg); @endcode
+ *
+ * It is used to check if a potential argument would be acceptable for the option.
+ * It will even be called if there is no argument. In that case @c option.arg will be @c NULL.
+ *
+ * If @c msg is @c true and the function determines that an argument is not acceptable and
+ * that this is a fatal error, it should output a message to the user before
+ * returning @ref ARG_ILLEGAL. If @c msg is @c false the function should remain silent (or you
+ * will get duplicate messages).
+ *
+ * See @ref ArgStatus for the meaning of the return values.
+ *
+ * While you can provide your own functions,
+ * often the following pre-defined checks (which never return @ref ARG_ILLEGAL) will suffice:
+ *
+ * @li @c Arg::None @copybrief Arg::None
+ * @li @c Arg::Optional @copybrief Arg::Optional
+ *
+ */
+typedef ArgStatus (*CheckArg)(const Option& option, bool msg);
+
+/**
+ * @brief Describes an option, its help text (usage) and how it should be parsed.
+ *
+ * The main input when constructing an option::Parser is an array of Descriptors.
+
+ * @par Example:
+ * @code
+ * enum OptionIndex {CREATE, ...};
+ * enum OptionType {DISABLE, ENABLE, OTHER};
+ *
+ * const option::Descriptor usage[] = {
+ * { CREATE, // index
+ * OTHER, // type
+ * "c", // shortopt
+ * "create", // longopt
+ * Arg::None, // check_arg
+ * "--create Tells the program to create something." // help
+ * }
+ * , ...
+ * };
+ * @endcode
+ */
+struct Descriptor
+{
+ /**
+ * @brief Index of this option's linked list in the array filled in by the parser.
+ *
+ * Command line options whose Descriptors have the same index will end up in the same
+ * linked list in the order in which they appear on the command line. If you have
+ * multiple long option aliases that refer to the same option, give their descriptors
+ * the same @c index.
+ *
+ * If you have options that mean exactly opposite things
+ * (e.g. @c --enable-foo and @c --disable-foo ), you should also give them the same
+ * @c index, but distinguish them through different values for @ref type.
+ * That way they end up in the same list and you can just take the last element of the
+ * list and use its type. This way you get the usual behaviour where switches later
+ * on the command line override earlier ones without having to code it manually.
+ *
+ * @par Tip:
+ * Use an enum rather than plain ints for better readability, as shown in the example
+ * at Descriptor.
+ */
+ const unsigned index;
+
+ /**
+ * @brief Used to distinguish between options with the same @ref index.
+ * See @ref index for details.
+ *
+ * It is recommended that you use an enum rather than a plain int to make your
+ * code more readable.
+ */
+ const int type;
+
+ /**
+ * @brief Each char in this string will be accepted as a short option character.
+ *
+ * The string must not include the minus character @c '-' or you'll get undefined
+ * behaviour.
+ *
+ * If this Descriptor should not have short option characters, use the empty
+ * string "". NULL is not permitted here!
+ *
+ * See @ref longopt for more information.
+ */
+ const char* const shortopt;
+
+ /**
+ * @brief The long option name (without the leading @c -- ).
+ *
+ * If this Descriptor should not have a long option name, use the empty
+ * string "". NULL is not permitted here!
+ *
+ * While @ref shortopt allows multiple short option characters, each
+ * Descriptor can have only a single long option name. If you have multiple
+ * long option names referring to the same option use separate Descriptors
+ * that have the same @ref index and @ref type. You may repeat
+ * short option characters in such an alias Descriptor but there's no need to.
+ *
+ * @par Dummy Descriptors:
+ * You can use dummy Descriptors with an
+ * empty string for both @ref shortopt and @ref longopt to add text to
+ * the usage that is not related to a specific option. See @ref help.
+ * The first dummy Descriptor will be used for unknown options (see below).
+ *
+ * @par Unknown Option Descriptor:
+ * The first dummy Descriptor in the list of Descriptors,
+ * whose @ref shortopt and @ref longopt are both the empty string, will be used
+ * as the Descriptor for unknown options. An unknown option is a string in
+ * the argument vector that is not a lone minus @c '-' but starts with a minus
+ * character and does not match any Descriptor's @ref shortopt or @ref longopt. @n
+ * Note that the dummy descriptor's @ref check_arg function @e will be called and
+ * its return value will be evaluated as usual. I.e. if it returns @ref ARG_ILLEGAL
+ * the parsing will be aborted with <code>Parser::error()==true</code>. @n
+ * if @c check_arg does not return @ref ARG_ILLEGAL the descriptor's
+ * @ref index @e will be used to pick the linked list into which
+ * to put the unknown option. @n
+ * If there is no dummy descriptor, unknown options will be dropped silently.
+ *
+ */
+ const char* const longopt;
+
+ /**
+ * @brief For each option that matches @ref shortopt or @ref longopt this function
+ * will be called to check a potential argument to the option.
+ *
+ * This function will be called even if there is no potential argument. In that case
+ * it will be passed @c NULL as @c arg parameter. Do not confuse this with the empty
+ * string.
+ *
+ * See @ref CheckArg for more information.
+ */
+ const CheckArg check_arg;
+
+ /**
+ * @brief The usage text associated with the options in this Descriptor.
+ *
+ * You can use option::printUsage() to format your usage message based on
+ * the @c help texts. You can use dummy Descriptors where
+ * @ref shortopt and @ref longopt are both the empty string to add text to
+ * the usage that is not related to a specific option.
+ *
+ * See option::printUsage() for special formatting characters you can use in
+ * @c help to get a column layout.
+ *
+ * @attention
+ * Must be UTF-8-encoded. If your compiler supports C++11 you can use the "u8"
+ * prefix to make sure string literals are properly encoded.
+ */
+ const char* help;
+};
+
+/**
+ * @brief A parsed option from the command line together with its argument if it has one.
+ *
+ * The Parser chains all parsed options with the same Descriptor::index together
+ * to form a linked list. This allows you to easily implement all of the common ways
+ * of handling repeated options and enable/disable pairs.
+ *
+ * @li Test for presence of a switch in the argument vector:
+ * @code if ( options[QUIET] ) ... @endcode
+ * @li Evaluate --enable-foo/--disable-foo pair where the last one used wins:
+ * @code if ( options[FOO].last()->type() == DISABLE ) ... @endcode
+ * @li Cumulative option (-v verbose, -vv more verbose, -vvv even more verbose):
+ * @code int verbosity = options[VERBOSE].count(); @endcode
+ * @li Iterate over all --file=<fname> arguments:
+ * @code for (Option* opt = options[FILE]; opt; opt = opt->next())
+ * fname = opt->arg; ... @endcode
+ */
+class Option
+{
+ Option* next_;
+ Option* prev_;
+public:
+ /**
+ * @brief Pointer to this Option's Descriptor.
+ *
+ * Remember that the first dummy descriptor (see @ref Descriptor::longopt) is used
+ * for unknown options.
+ *
+ * @attention
+ * @c desc==NULL signals that this Option is unused. This is the default state of
+ * elements in the result array. You don't need to test @c desc explicitly. You
+ * can simply write something like this:
+ * @code
+ * if (options[CREATE])
+ * {
+ * ...
+ * }
+ * @endcode
+ * This works because of <code> operator const Option*() </code>.
+ */
+ const Descriptor* desc;
+
+ /**
+ * @brief The name of the option as used on the command line.
+ *
+ * The main purpose of this string is to be presented to the user in messages.
+ *
+ * In the case of a long option, this is the actual @c argv pointer, i.e. the first
+ * character is a '-'. In the case of a short option this points to the option
+ * character within the @c argv string.
+ *
+ * Note that in the case of a short option group or an attached option argument, this
+ * string will contain additional characters following the actual name. Use @ref namelen
+ * to filter out the actual option name only.
+ *
+ */
+ const char* name;
+
+ /**
+ * @brief Pointer to this Option's argument (if any).
+ *
+ * NULL if this option has no argument. Do not confuse this with the empty string which
+ * is a valid argument.
+ */
+ const char* arg;
+
+ /**
+ * @brief The length of the option @ref name.
+ *
+ * Because @ref name points into the actual @c argv string, the option name may be
+ * followed by more characters (e.g. other short options in the same short option group).
+ * This value is the number of bytes (not characters!) that are part of the actual name.
+ *
+ * For a short option, this length is always 1. For a long option this length is always
+ * at least 2 if single minus long options are permitted and at least 3 if they are disabled.
+ *
+ * @note
+ * In the pathological case of a minus within a short option group (e.g. @c -xf-z), this
+ * length is incorrect, because this case will be misinterpreted as a long option and the
+ * name will therefore extend to the string's 0-terminator or a following '=" character
+ * if there is one. This is irrelevant for most uses of @ref name and @c namelen. If you
+ * really need to distinguish the case of a long and a short option, compare @ref name to
+ * the @c argv pointers. A long option's @c name is always identical to one of them,
+ * whereas a short option's is never.
+ */
+ int namelen;
+
+ /**
+ * @brief Returns Descriptor::type of this Option's Descriptor, or 0 if this Option
+ * is invalid (unused).
+ *
+ * Because this method (and last(), too) can be used even on unused Options with desc==0, you can (provided
+ * you arrange your types properly) switch on type() without testing validity first.
+ * @code
+ * enum OptionType { UNUSED=0, DISABLED=0, ENABLED=1 };
+ * enum OptionIndex { FOO };
+ * const Descriptor usage[] = {
+ * { FOO, ENABLED, "", "enable-foo", Arg::None, 0 },
+ * { FOO, DISABLED, "", "disable-foo", Arg::None, 0 },
+ * { 0, 0, 0, 0, 0, 0 } };
+ * ...
+ * switch(options[FOO].last()->type()) // no validity check required!
+ * {
+ * case ENABLED: ...
+ * case DISABLED: ... // UNUSED==DISABLED !
+ * }
+ * @endcode
+ */
+ int type() const
+ {
+ return desc == 0 ? 0 : desc->type;
+ }
+
+ /**
+ * @brief Returns Descriptor::index of this Option's Descriptor, or -1 if this Option
+ * is invalid (unused).
+ */
+ int index() const
+ {
+ return desc == 0 ? -1 : desc->index;
+ }
+
+ /**
+ * @brief Returns the number of times this Option (or others with the same Descriptor::index)
+ * occurs in the argument vector.
+ *
+ * This corresponds to the number of elements in the linked list this Option is part of.
+ * It doesn't matter on which element you call count(). The return value is always the same.
+ *
+ * Use this to implement cumulative options, such as -v, -vv, -vvv for
+ * different verbosity levels.
+ *
+ * Returns 0 when called for an unused/invalid option.
+ */
+ int count()
+ {
+ int c = (desc == 0 ? 0 : 1);
+ Option* p = first();
+ while (!p->isLast())
+ {
+ ++c;
+ p = p->next_;
+ };
+ return c;
+ }
+
+ /**
+ * @brief Returns true iff this is the first element of the linked list.
+ *
+ * The first element in the linked list is the first option on the command line
+ * that has the respective Descriptor::index value.
+ *
+ * Returns true for an unused/invalid option.
+ */
+ bool isFirst() const
+ {
+ return isTagged(prev_);
+ }
+
+ /**
+ * @brief Returns true iff this is the last element of the linked list.
+ *
+ * The last element in the linked list is the last option on the command line
+ * that has the respective Descriptor::index value.
+ *
+ * Returns true for an unused/invalid option.
+ */
+ bool isLast() const
+ {
+ return isTagged(next_);
+ }
+
+ /**
+ * @brief Returns a pointer to the first element of the linked list.
+ *
+ * Use this when you want the first occurrence of an option on the command line to
+ * take precedence. Note that this is not the way most programs handle options.
+ * You should probably be using last() instead.
+ *
+ * @note
+ * This method may be called on an unused/invalid option and will return a pointer to the
+ * option itself.
+ */
+ Option* first()
+ {
+ Option* p = this;
+ while (!p->isFirst())
+ p = p->prev_;
+ return p;
+ }
+
+ /**
+ * @brief Returns a pointer to the last element of the linked list.
+ *
+ * Use this when you want the last occurrence of an option on the command line to
+ * take precedence. This is the most common way of handling conflicting options.
+ *
+ * @note
+ * This method may be called on an unused/invalid option and will return a pointer to the
+ * option itself.
+ *
+ * @par Tip:
+ * If you have options with opposite meanings (e.g. @c --enable-foo and @c --disable-foo), you
+ * can assign them the same Descriptor::index to get them into the same list. Distinguish them by
+ * Descriptor::type and all you have to do is check <code> last()->type() </code> to get
+ * the state listed last on the command line.
+ */
+ Option* last()
+ {
+ return first()->prevwrap();
+ }
+
+ /**
+ * @brief Returns a pointer to the previous element of the linked list or NULL if
+ * called on first().
+ *
+ * If called on first() this method returns NULL. Otherwise it will return the
+ * option with the same Descriptor::index that precedes this option on the command
+ * line.
+ */
+ Option* prev()
+ {
+ return isFirst() ? 0 : prev_;
+ }
+
+ /**
+ * @brief Returns a pointer to the previous element of the linked list with wrap-around from
+ * first() to last().
+ *
+ * If called on first() this method returns last(). Otherwise it will return the
+ * option with the same Descriptor::index that precedes this option on the command
+ * line.
+ */
+ Option* prevwrap()
+ {
+ return untag(prev_);
+ }
+
+ /**
+ * @brief Returns a pointer to the next element of the linked list or NULL if called
+ * on last().
+ *
+ * If called on last() this method returns NULL. Otherwise it will return the
+ * option with the same Descriptor::index that follows this option on the command
+ * line.
+ */
+ Option* next()
+ {
+ return isLast() ? 0 : next_;
+ }
+
+ /**
+ * @brief Returns a pointer to the next element of the linked list with wrap-around from
+ * last() to first().
+ *
+ * If called on last() this method returns first(). Otherwise it will return the
+ * option with the same Descriptor::index that follows this option on the command
+ * line.
+ */
+ Option* nextwrap()
+ {
+ return untag(next_);
+ }
+
+ /**
+ * @brief Makes @c new_last the new last() by chaining it into the list after last().
+ *
+ * It doesn't matter which element you call append() on. The new element will always
+ * be appended to last().
+ *
+ * @attention
+ * @c new_last must not yet be part of a list, or that list will become corrupted, because
+ * this method does not unchain @c new_last from an existing list.
+ */
+ void append(Option* new_last)
+ {
+ Option* p = last();
+ Option* f = first();
+ p->next_ = new_last;
+ new_last->prev_ = p;
+ new_last->next_ = tag(f);
+ f->prev_ = tag(new_last);
+ }
+
+ /**
+ * @brief Casts from Option to const Option* but only if this Option is valid.
+ *
+ * If this Option is valid (i.e. @c desc!=NULL), returns this.
+ * Otherwise returns NULL. This allows testing an Option directly
+ * in an if-clause to see if it is used:
+ * @code
+ * if (options[CREATE])
+ * {
+ * ...
+ * }
+ * @endcode
+ * It also allows you to write loops like this:
+ * @code for (Option* opt = options[FILE]; opt; opt = opt->next())
+ * fname = opt->arg; ... @endcode
+ */
+ operator const Option*() const
+ {
+ return desc ? this : 0;
+ }
+
+ /**
+ * @brief Casts from Option to Option* but only if this Option is valid.
+ *
+ * If this Option is valid (i.e. @c desc!=NULL), returns this.
+ * Otherwise returns NULL. This allows testing an Option directly
+ * in an if-clause to see if it is used:
+ * @code
+ * if (options[CREATE])
+ * {
+ * ...
+ * }
+ * @endcode
+ * It also allows you to write loops like this:
+ * @code for (Option* opt = options[FILE]; opt; opt = opt->next())
+ * fname = opt->arg; ... @endcode
+ */
+ operator Option*()
+ {
+ return desc ? this : 0;
+ }
+
+ /**
+ * @brief Creates a new Option that is a one-element linked list and has NULL
+ * @ref desc, @ref name, @ref arg and @ref namelen.
+ */
+ Option() :
+ desc(0), name(0), arg(0), namelen(0)
+ {
+ prev_ = tag(this);
+ next_ = tag(this);
+ }
+
+ /**
+ * @brief Creates a new Option that is a one-element linked list and has the given
+ * values for @ref desc, @ref name and @ref arg.
+ *
+ * If @c name_ points at a character other than '-' it will be assumed to refer to a
+ * short option and @ref namelen will be set to 1. Otherwise the length will extend to
+ * the first '=' character or the string's 0-terminator.
+ */
+ Option(const Descriptor* desc_, const char* name_, const char* arg_)
+ {
+ init(desc_, name_, arg_);
+ }
+
+ /**
+ * @brief Makes @c *this a copy of @c orig except for the linked list pointers.
+ *
+ * After this operation @c *this will be a one-element linked list.
+ */
+ void operator=(const Option& orig)
+ {
+ init(orig.desc, orig.name, orig.arg);
+ }
+
+ /**
+ * @brief Makes @c *this a copy of @c orig except for the linked list pointers.
+ *
+ * After this operation @c *this will be a one-element linked list.
+ */
+ Option(const Option& orig)
+ {
+ init(orig.desc, orig.name, orig.arg);
+ }
+
+private:
+ /**
+ * @internal
+ * @brief Sets the fields of this Option to the given values (extracting @c name if necessary).
+ *
+ * If @c name_ points at a character other than '-' it will be assumed to refer to a
+ * short option and @ref namelen will be set to 1. Otherwise the length will extend to
+ * the first '=' character or the string's 0-terminator.
+ */
+ void init(const Descriptor* desc_, const char* name_, const char* arg_)
+ {
+ desc = desc_;
+ name = name_;
+ arg = arg_;
+ prev_ = tag(this);
+ next_ = tag(this);
+ namelen = 0;
+ if (name == 0)
+ return;
+ namelen = 1;
+ if (name[0] != '-')
+ return;
+ while (name[namelen] != 0 && name[namelen] != '=')
+ ++namelen;
+ }
+
+ static Option* tag(Option* ptr)
+ {
+ return (Option*) ((unsigned long long) ptr | 1);
+ }
+
+ static Option* untag(Option* ptr)
+ {
+ return (Option*) ((unsigned long long) ptr & ~1ull);
+ }
+
+ static bool isTagged(Option* ptr)
+ {
+ return ((unsigned long long) ptr & 1);
+ }
+};
+
+/**
+ * @brief Functions for checking the validity of option arguments.
+ *
+ * @copydetails CheckArg
+ *
+ * The following example code
+ * can serve as starting place for writing your own more complex CheckArg functions:
+ * @code
+ * struct Arg: public option::Arg
+ * {
+ * static void printError(const char* msg1, const option::Option& opt, const char* msg2)
+ * {
+ * fprintf(stderr, "ERROR: %s", msg1);
+ * fwrite(opt.name, opt.namelen, 1, stderr);
+ * fprintf(stderr, "%s", msg2);
+ * }
+ *
+ * static option::ArgStatus Unknown(const option::Option& option, bool msg)
+ * {
+ * if (msg) printError("Unknown option '", option, "'\n");
+ * return option::ARG_ILLEGAL;
+ * }
+ *
+ * static option::ArgStatus Required(const option::Option& option, bool msg)
+ * {
+ * if (option.arg != 0)
+ * return option::ARG_OK;
+ *
+ * if (msg) printError("Option '", option, "' requires an argument\n");
+ * return option::ARG_ILLEGAL;
+ * }
+ *
+ * static option::ArgStatus NonEmpty(const option::Option& option, bool msg)
+ * {
+ * if (option.arg != 0 && option.arg[0] != 0)
+ * return option::ARG_OK;
+ *
+ * if (msg) printError("Option '", option, "' requires a non-empty argument\n");
+ * return option::ARG_ILLEGAL;
+ * }
+ *
+ * static option::ArgStatus Numeric(const option::Option& option, bool msg)
+ * {
+ * char* endptr = 0;
+ * if (option.arg != 0 && strtol(option.arg, &endptr, 10)){};
+ * if (endptr != option.arg && *endptr == 0)
+ * return option::ARG_OK;
+ *
+ * if (msg) printError("Option '", option, "' requires a numeric argument\n");
+ * return option::ARG_ILLEGAL;
+ * }
+ * };
+ * @endcode
+ */
+struct Arg
+{
+ //! @brief For options that don't take an argument: Returns ARG_NONE.
+ static ArgStatus None(const Option&, bool)
+ {
+ return ARG_NONE;
+ }
+ static void printError(const char* msg1, const option::Option& opt, const char* msg2)
+ {
+ fprintf(stderr, "ERROR: %s", msg1);
+ fwrite(opt.name, opt.namelen, 1, stderr);
+ fprintf(stderr, "%s", msg2);
+ }
+
+ //! @brief Returns ARG_OK if the argument is attached and ARG_IGNORE otherwise.
+ static ArgStatus Optional(const Option& option, bool)
+ {
+ if (option.arg && option.name[option.namelen] != 0)
+ return ARG_OK;
+ else
+ return ARG_IGNORE;
+ }
+ static option::ArgStatus Required(const option::Option& option, bool msg)
+ {
+ if (option.arg != 0)
+ return option::ARG_OK;
+
+ if (msg) printError("Option '", option, "' requires an argument\n");
+ return option::ARG_ILLEGAL;
+ }
+};
+
+/**
+ * @brief Determines the minimum lengths of the buffer and options arrays used for Parser.
+ *
+ * Because Parser doesn't use dynamic memory its output arrays have to be pre-allocated.
+ * If you don't want to use fixed size arrays (which may turn out too small, causing
+ * command line arguments to be dropped), you can use Stats to determine the correct sizes.
+ * Stats work cumulative. You can first pass in your default options and then the real
+ * options and afterwards the counts will reflect the union.
+ */
+struct Stats
+{
+ /**
+ * @brief Number of elements needed for a @c buffer[] array to be used for
+ * @ref Parser::parse() "parsing" the same argument vectors that were fed
+ * into this Stats object.
+ *
+ * @note
+ * This number is always 1 greater than the actual number needed, to give
+ * you a sentinel element.
+ */
+ unsigned buffer_max;
+
+ /**
+ * @brief Number of elements needed for an @c options[] array to be used for
+ * @ref Parser::parse() "parsing" the same argument vectors that were fed
+ * into this Stats object.
+ *
+ * @note
+ * @li This number is always 1 greater than the actual number needed, to give
+ * you a sentinel element.
+ * @li This number depends only on the @c usage, not the argument vectors, because
+ * the @c options array needs exactly one slot for each possible Descriptor::index.
+ */
+ unsigned options_max;
+
+ /**
+ * @brief Creates a Stats object with counts set to 1 (for the sentinel element).
+ */
+ Stats() :
+ buffer_max(1), options_max(1) // 1 more than necessary as sentinel
+ {
+ }
+
+ /**
+ * @brief Creates a new Stats object and immediately updates it for the
+ * given @c usage and argument vector. You may pass 0 for @c argc and/or @c argv,
+ * if you just want to update @ref options_max.
+ *
+ * @note
+ * The calls to Stats methods must match the later calls to Parser methods.
+ * See Parser::parse() for the meaning of the arguments.
+ */
+ Stats(bool gnu, const Descriptor usage[], int argc, const char** argv, int min_abbr_len = 0, //
+ bool single_minus_longopt = false) :
+ buffer_max(1), options_max(1) // 1 more than necessary as sentinel
+ {
+ add(gnu, usage, argc, argv, min_abbr_len, single_minus_longopt);
+ }
+
+ //! @brief Stats(...) with non-const argv.
+ Stats(bool gnu, const Descriptor usage[], int argc, char** argv, int min_abbr_len = 0, //
+ bool single_minus_longopt = false) :
+ buffer_max(1), options_max(1) // 1 more than necessary as sentinel
+ {
+ add(gnu, usage, argc, (const char**) argv, min_abbr_len, single_minus_longopt);
+ }
+
+ //! @brief POSIX Stats(...) (gnu==false).
+ Stats(const Descriptor usage[], int argc, const char** argv, int min_abbr_len = 0, //
+ bool single_minus_longopt = false) :
+ buffer_max(1), options_max(1) // 1 more than necessary as sentinel
+ {
+ add(false, usage, argc, argv, min_abbr_len, single_minus_longopt);
+ }
+
+ //! @brief POSIX Stats(...) (gnu==false) with non-const argv.
+ Stats(const Descriptor usage[], int argc, char** argv, int min_abbr_len = 0, //
+ bool single_minus_longopt = false) :
+ buffer_max(1), options_max(1) // 1 more than necessary as sentinel
+ {
+ add(false, usage, argc, (const char**) argv, min_abbr_len, single_minus_longopt);
+ }
+
+ /**
+ * @brief Updates this Stats object for the
+ * given @c usage and argument vector. You may pass 0 for @c argc and/or @c argv,
+ * if you just want to update @ref options_max.
+ *
+ * @note
+ * The calls to Stats methods must match the later calls to Parser methods.
+ * See Parser::parse() for the meaning of the arguments.
+ */
+ void add(bool gnu, const Descriptor usage[], int argc, const char** argv, int min_abbr_len = 0, //
+ bool single_minus_longopt = false);
+
+ //! @brief add() with non-const argv.
+ void add(bool gnu, const Descriptor usage[], int argc, char** argv, int min_abbr_len = 0, //
+ bool single_minus_longopt = false)
+ {
+ add(gnu, usage, argc, (const char**) argv, min_abbr_len, single_minus_longopt);
+ }
+
+ //! @brief POSIX add() (gnu==false).
+ void add(const Descriptor usage[], int argc, const char** argv, int min_abbr_len = 0, //
+ bool single_minus_longopt = false)
+ {
+ add(false, usage, argc, argv, min_abbr_len, single_minus_longopt);
+ }
+
+ //! @brief POSIX add() (gnu==false) with non-const argv.
+ void add(const Descriptor usage[], int argc, char** argv, int min_abbr_len = 0, //
+ bool single_minus_longopt = false)
+ {
+ add(false, usage, argc, (const char**) argv, min_abbr_len, single_minus_longopt);
+ }
+private:
+ class CountOptionsAction;
+};
+
+/**
+ * @brief Checks argument vectors for validity and parses them into data
+ * structures that are easier to work with.
+ *
+ * @par Example:
+ * @code
+ * int main(int argc, char* argv[])
+ * {
+ * argc-=(argc>0); argv+=(argc>0); // skip program name argv[0] if present
+ * option::Stats stats(usage, argc, argv);
+ * option::Option options[stats.options_max], buffer[stats.buffer_max];
+ * option::Parser parse(usage, argc, argv, options, buffer);
+ *
+ * if (parse.error())
+ * return 1;
+ *
+ * if (options[HELP])
+ * ...
+ * @endcode
+ */
+class Parser
+{
+ int op_count; //!< @internal @brief see optionsCount()
+ int nonop_count; //!< @internal @brief see nonOptionsCount()
+ const char** nonop_args; //!< @internal @brief see nonOptions()
+ bool err; //!< @internal @brief see error()
+public:
+
+ /**
+ * @brief Creates a new Parser.
+ */
+ Parser() :
+ op_count(0), nonop_count(0), nonop_args(0), err(false)
+ {
+ }
+
+ /**
+ * @brief Creates a new Parser and immediately parses the given argument vector.
+ * @copydetails parse()
+ */
+ Parser(bool gnu, const Descriptor usage[], int argc, const char** argv, Option options[], Option buffer[],
+ int min_abbr_len = 0, bool single_minus_longopt = false, int bufmax = -1) :
+ op_count(0), nonop_count(0), nonop_args(0), err(false)
+ {
+ parse(gnu, usage, argc, argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
+ }
+
+ //! @brief Parser(...) with non-const argv.
+ Parser(bool gnu, const Descriptor usage[], int argc, char** argv, Option options[], Option buffer[],
+ int min_abbr_len = 0, bool single_minus_longopt = false, int bufmax = -1) :
+ op_count(0), nonop_count(0), nonop_args(0), err(false)
+ {
+ parse(gnu, usage, argc, (const char**) argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
+ }
+
+ //! @brief POSIX Parser(...) (gnu==false).
+ Parser(const Descriptor usage[], int argc, const char** argv, Option options[], Option buffer[], int min_abbr_len = 0,
+ bool single_minus_longopt = false, int bufmax = -1) :
+ op_count(0), nonop_count(0), nonop_args(0), err(false)
+ {
+ parse(false, usage, argc, argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
+ }
+
+ //! @brief POSIX Parser(...) (gnu==false) with non-const argv.
+ Parser(const Descriptor usage[], int argc, char** argv, Option options[], Option buffer[], int min_abbr_len = 0,
+ bool single_minus_longopt = false, int bufmax = -1) :
+ op_count(0), nonop_count(0), nonop_args(0), err(false)
+ {
+ parse(false, usage, argc, (const char**) argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
+ }
+
+ /**
+ * @brief Parses the given argument vector.
+ *
+ * @param gnu if true, parse() will not stop at the first non-option argument. Instead it will
+ * reorder arguments so that all non-options are at the end. This is the default behaviour
+ * of GNU getopt() but is not conforming to POSIX. @n
+ * Note, that once the argument vector has been reordered, the @c gnu flag will have
+ * no further effect on this argument vector. So it is enough to pass @c gnu==true when
+ * creating Stats.
+ * @param usage Array of Descriptor objects that describe the options to support. The last entry
+ * of this array must have 0 in all fields.
+ * @param argc The number of elements from @c argv that are to be parsed. If you pass -1, the number
+ * will be determined automatically. In that case the @c argv list must end with a NULL
+ * pointer.
+ * @param argv The arguments to be parsed. If you pass -1 as @c argc the last pointer in the @c argv
+ * list must be NULL to mark the end.
+ * @param options Each entry is the first element of a linked list of Options. Each new option
+ * that is parsed will be appended to the list specified by that Option's
+ * Descriptor::index. If an entry is not yet used (i.e. the Option is invalid),
+ * it will be replaced rather than appended to. @n
+ * The minimum length of this array is the greatest Descriptor::index value that
+ * occurs in @c usage @e PLUS ONE.
+ * @param buffer Each argument that is successfully parsed (including unknown arguments, if they
+ * have a Descriptor whose CheckArg does not return @ref ARG_ILLEGAL) will be stored in this
+ * array. parse() scans the array for the first invalid entry and begins writing at that
+ * index. You can pass @c bufmax to limit the number of options stored.
+ * @param min_abbr_len Passing a value <code> min_abbr_len > 0 </code> enables abbreviated long
+ * options. The parser will match a prefix of a long option as if it was
+ * the full long option (e.g. @c --foob=10 will be interpreted as if it was
+ * @c --foobar=10 ), as long as the prefix has at least @c min_abbr_len characters
+ * (not counting the @c -- ) and is unambiguous.
+ * @n Be careful if combining @c min_abbr_len=1 with @c single_minus_longopt=true
+ * because the ambiguity check does not consider short options and abbreviated
+ * single minus long options will take precedence over short options.
+ * @param single_minus_longopt Passing @c true for this option allows long options to begin with
+ * a single minus. The double minus form will still be recognized. Note that
+ * single minus long options take precedence over short options and short option
+ * groups. E.g. @c -file would be interpreted as @c --file and not as
+ * <code> -f -i -l -e </code> (assuming a long option named @c "file" exists).
+ * @param bufmax The greatest index in the @c buffer[] array that parse() will write to is
+ * @c bufmax-1. If there are more options, they will be processed (in particular
+ * their CheckArg will be called) but not stored. @n
+ * If you used Stats::buffer_max to dimension this array, you can pass
+ * -1 (or not pass @c bufmax at all) which tells parse() that the buffer is
+ * "large enough".
+ * @attention
+ * Remember that @c options and @c buffer store Option @e objects, not pointers. Therefore it
+ * is not possible for the same object to be in both arrays. For those options that are found in
+ * both @c buffer[] and @c options[] the respective objects are independent copies. And only the
+ * objects in @c options[] are properly linked via Option::next() and Option::prev().
+ * You can iterate over @c buffer[] to
+ * process all options in the order they appear in the argument vector, but if you want access to
+ * the other Options with the same Descriptor::index, then you @e must access the linked list via
+ * @c options[]. You can get the linked list in options from a buffer object via something like
+ * @c options[buffer[i].index()].
+ */
+ void parse(bool gnu, const Descriptor usage[], int argc, const char** argv, Option options[], Option buffer[],
+ int min_abbr_len = 0, bool single_minus_longopt = false, int bufmax = -1);
+
+ //! @brief parse() with non-const argv.
+ void parse(bool gnu, const Descriptor usage[], int argc, char** argv, Option options[], Option buffer[],
+ int min_abbr_len = 0, bool single_minus_longopt = false, int bufmax = -1)
+ {
+ parse(gnu, usage, argc, (const char**) argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
+ }
+
+ //! @brief POSIX parse() (gnu==false).
+ void parse(const Descriptor usage[], int argc, const char** argv, Option options[], Option buffer[],
+ int min_abbr_len = 0, bool single_minus_longopt = false, int bufmax = -1)
+ {
+ parse(false, usage, argc, argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
+ }
+
+ //! @brief POSIX parse() (gnu==false) with non-const argv.
+ void parse(const Descriptor usage[], int argc, char** argv, Option options[], Option buffer[], int min_abbr_len = 0,
+ bool single_minus_longopt = false, int bufmax = -1)
+ {
+ parse(false, usage, argc, (const char**) argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
+ }
+
+ /**
+ * @brief Returns the number of valid Option objects in @c buffer[].
+ *
+ * @note
+ * @li The returned value always reflects the number of Options in the buffer[] array used for
+ * the most recent call to parse().
+ * @li The count (and the buffer[]) includes unknown options if they are collected
+ * (see Descriptor::longopt).
+ */
+ int optionsCount()
+ {
+ return op_count;
+ }
+
+ /**
+ * @brief Returns the number of non-option arguments that remained at the end of the
+ * most recent parse() that actually encountered non-option arguments.
+ *
+ * @note
+ * A parse() that does not encounter non-option arguments will leave this value
+ * as well as nonOptions() undisturbed. This means you can feed the Parser a
+ * default argument vector that contains non-option arguments (e.g. a default filename).
+ * Then you feed it the actual arguments from the user. If the user has supplied at
+ * least one non-option argument, all of the non-option arguments from the default
+ * disappear and are replaced by the user's non-option arguments. However, if the
+ * user does not supply any non-option arguments the defaults will still be in
+ * effect.
+ */
+ int nonOptionsCount()
+ {
+ return nonop_count;
+ }
+
+ /**
+ * @brief Returns a pointer to an array of non-option arguments (only valid
+ * if <code>nonOptionsCount() >0 </code>).
+ *
+ * @note
+ * @li parse() does not copy arguments, so this pointer points into the actual argument
+ * vector as passed to parse().
+ * @li As explained at nonOptionsCount() this pointer is only changed by parse() calls
+ * that actually encounter non-option arguments. A parse() call that encounters only
+ * options, will not change nonOptions().
+ */
+ const char** nonOptions()
+ {
+ return nonop_args;
+ }
+
+ /**
+ * @brief Returns <b><code>nonOptions()[i]</code></b> (@e without checking if i is in range!).
+ */
+ const char* nonOption(int i)
+ {
+ return nonOptions()[i];
+ }
+
+ /**
+ * @brief Returns @c true if an unrecoverable error occurred while parsing options.
+ *
+ * An illegal argument to an option (i.e. CheckArg returns @ref ARG_ILLEGAL) is an
+ * unrecoverable error that aborts the parse. Unknown options are only an error if
+ * their CheckArg function returns @ref ARG_ILLEGAL. Otherwise they are collected.
+ * In that case if you want to exit the program if either an illegal argument
+ * or an unknown option has been passed, use code like this
+ *
+ * @code
+ * if (parser.error() || options[UNKNOWN])
+ * exit(1);
+ * @endcode
+ *
+ */
+ bool error()
+ {
+ return err;
+ }
+
+private:
+ friend struct Stats;
+ class StoreOptionAction;
+ struct Action;
+
+ /**
+ * @internal
+ * @brief This is the core function that does all the parsing.
+ * @retval false iff an unrecoverable error occurred.
+ */
+ static bool workhorse(bool gnu, const Descriptor usage[], int numargs, const char** args, Action& action,
+ bool single_minus_longopt, bool print_errors, int min_abbr_len);
+
+ /**
+ * @internal
+ * @brief Returns true iff @c st1 is a prefix of @c st2 and
+ * in case @c st2 is longer than @c st1, then
+ * the first additional character is '='.
+ *
+ * @par Examples:
+ * @code
+ * streq("foo", "foo=bar") == true
+ * streq("foo", "foobar") == false
+ * streq("foo", "foo") == true
+ * streq("foo=bar", "foo") == false
+ * @endcode
+ */
+ static bool streq(const char* st1, const char* st2)
+ {
+ while (*st1 != 0)
+ if (*st1++ != *st2++)
+ return false;
+ return (*st2 == 0 || *st2 == '=');
+ }
+
+ /**
+ * @internal
+ * @brief Like streq() but handles abbreviations.
+ *
+ * Returns true iff @c st1 and @c st2 have a common
+ * prefix with the following properties:
+ * @li (if min > 0) its length is at least @c min characters or the same length as @c st1 (whichever is smaller).
+ * @li (if min <= 0) its length is the same as that of @c st1
+ * @li within @c st2 the character following the common prefix is either '=' or end-of-string.
+ *
+ * Examples:
+ * @code
+ * streqabbr("foo", "foo=bar",<anything>) == true
+ * streqabbr("foo", "fo=bar" , 2) == true
+ * streqabbr("foo", "fo" , 2) == true
+ * streqabbr("foo", "fo" , 0) == false
+ * streqabbr("foo", "f=bar" , 2) == false
+ * streqabbr("foo", "f" , 2) == false
+ * streqabbr("fo" , "foo=bar",<anything>) == false
+ * streqabbr("foo", "foobar" ,<anything>) == false
+ * streqabbr("foo", "fobar" ,<anything>) == false
+ * streqabbr("foo", "foo" ,<anything>) == true
+ * @endcode
+ */
+ static bool streqabbr(const char* st1, const char* st2, long long min)
+ {
+ const char* st1start = st1;
+ while (*st1 != 0 && (*st1 == *st2))
+ {
+ ++st1;
+ ++st2;
+ }
+
+ return (*st1 == 0 || (min > 0 && (st1 - st1start) >= min)) && (*st2 == 0 || *st2 == '=');
+ }
+
+ /**
+ * @internal
+ * @brief Returns true iff character @c ch is contained in the string @c st.
+ *
+ * Returns @c true for @c ch==0 .
+ */
+ static bool instr(char ch, const char* st)
+ {
+ while (*st != 0 && *st != ch)
+ ++st;
+ return *st == ch;
+ }
+
+ /**
+ * @internal
+ * @brief Rotates <code>args[-count],...,args[-1],args[0]</code> to become
+ * <code>args[0],args[-count],...,args[-1]</code>.
+ */
+ static void shift(const char** args, int count)
+ {
+ for (int i = 0; i > -count; --i)
+ {
+ const char* temp = args[i];
+ args[i] = args[i - 1];
+ args[i - 1] = temp;
+ }
+ }
+};
+
+/**
+ * @internal
+ * @brief Interface for actions Parser::workhorse() should perform for each Option it
+ * parses.
+ */
+struct Parser::Action
+{
+ /**
+ * @brief Called by Parser::workhorse() for each Option that has been successfully
+ * parsed (including unknown
+ * options if they have a Descriptor whose Descriptor::check_arg does not return
+ * @ref ARG_ILLEGAL.
+ *
+ * Returns @c false iff a fatal error has occured and the parse should be aborted.
+ */
+ virtual bool perform(Option&)
+ {
+ return true;
+ }
+
+ /**
+ * @brief Called by Parser::workhorse() after finishing the parse.
+ * @param numargs the number of non-option arguments remaining
+ * @param args pointer to the first remaining non-option argument (if numargs > 0).
+ *
+ * @return
+ * @c false iff a fatal error has occurred.
+ */
+ virtual bool finished(int numargs, const char** args)
+ {
+ (void) numargs;
+ (void) args;
+ return true;
+ }
+};
+
+/**
+ * @internal
+ * @brief An Action to pass to Parser::workhorse() that will increment a counter for
+ * each parsed Option.
+ */
+class Stats::CountOptionsAction: public Parser::Action
+{
+ unsigned* buffer_max;
+public:
+ /**
+ * Creates a new CountOptionsAction that will increase @c *buffer_max_ for each
+ * parsed Option.
+ */
+ CountOptionsAction(unsigned* buffer_max_) :
+ buffer_max(buffer_max_)
+ {
+ }
+
+ bool perform(Option&)
+ {
+ if (*buffer_max == 0x7fffffff)
+ return false; // overflow protection: don't accept number of options that doesn't fit signed int
+ ++*buffer_max;
+ return true;
+ }
+};
+
+/**
+ * @internal
+ * @brief An Action to pass to Parser::workhorse() that will store each parsed Option in
+ * appropriate arrays (see Parser::parse()).
+ */
+class Parser::StoreOptionAction: public Parser::Action
+{
+ Parser& parser;
+ Option* options;
+ Option* buffer;
+ int bufmax; //! Number of slots in @c buffer. @c -1 means "large enough".
+public:
+ /**
+ * @brief Creates a new StoreOption action.
+ * @param parser_ the parser whose op_count should be updated.
+ * @param options_ each Option @c o is chained into the linked list @c options_[o.desc->index]
+ * @param buffer_ each Option is appended to this array as long as there's a free slot.
+ * @param bufmax_ number of slots in @c buffer_. @c -1 means "large enough".
+ */
+ StoreOptionAction(Parser& parser_, Option options_[], Option buffer_[], int bufmax_) :
+ parser(parser_), options(options_), buffer(buffer_), bufmax(bufmax_)
+ {
+ // find first empty slot in buffer (if any)
+ int bufidx = 0;
+ while ((bufmax < 0 || bufidx < bufmax) && buffer[bufidx])
+ ++bufidx;
+
+ // set parser's optionCount
+ parser.op_count = bufidx;
+ }
+
+ bool perform(Option& option)
+ {
+ if (bufmax < 0 || parser.op_count < bufmax)
+ {
+ if (parser.op_count == 0x7fffffff)
+ return false; // overflow protection: don't accept number of options that doesn't fit signed int
+
+ buffer[parser.op_count] = option;
+ int idx = buffer[parser.op_count].desc->index;
+ if (options[idx])
+ options[idx].append(buffer[parser.op_count]);
+ else
+ options[idx] = buffer[parser.op_count];
+ ++parser.op_count;
+ }
+ return true; // NOTE: an option that is discarded because of a full buffer is not fatal
+ }
+
+ bool finished(int numargs, const char** args)
+ {
+ // only overwrite non-option argument list if there's at least 1
+ // new non-option argument. Otherwise we keep the old list. This
+ // makes it easy to use default non-option arguments.
+ if (numargs > 0)
+ {
+ parser.nonop_count = numargs;
+ parser.nonop_args = args;
+ }
+
+ return true;
+ }
+};
+
+inline void Parser::parse(bool gnu, const Descriptor usage[], int argc, const char** argv, Option options[],
+ Option buffer[], int min_abbr_len, bool single_minus_longopt, int bufmax)
+{
+ StoreOptionAction action(*this, options, buffer, bufmax);
+ err = !workhorse(gnu, usage, argc, argv, action, single_minus_longopt, true, min_abbr_len);
+}
+
+inline void Stats::add(bool gnu, const Descriptor usage[], int argc, const char** argv, int min_abbr_len,
+ bool single_minus_longopt)
+{
+ // determine size of options array. This is the greatest index used in the usage + 1
+ int i = 0;
+ while (usage[i].shortopt != 0)
+ {
+ if (usage[i].index + 1 >= options_max)
+ options_max = (usage[i].index + 1) + 1; // 1 more than necessary as sentinel
+
+ ++i;
+ }
+
+ CountOptionsAction action(&buffer_max);
+ Parser::workhorse(gnu, usage, argc, argv, action, single_minus_longopt, false, min_abbr_len);
+}
+
+inline bool Parser::workhorse(bool gnu, const Descriptor usage[], int numargs, const char** args, Action& action,
+ bool single_minus_longopt, bool print_errors, int min_abbr_len)
+{
+ // protect against NULL pointer
+ if (args == 0)
+ numargs = 0;
+
+ int nonops = 0;
+
+ while (numargs != 0 && *args != 0)
+ {
+ const char* param = *args; // param can be --long-option, -srto or non-option argument
+
+ // in POSIX mode the first non-option argument terminates the option list
+ // a lone minus character is a non-option argument
+ if (param[0] != '-' || param[1] == 0)
+ {
+ if (gnu)
+ {
+ ++nonops;
+ ++args;
+ if (numargs > 0)
+ --numargs;
+ continue;
+ }
+ else
+ break;
+ }
+
+ // -- terminates the option list. The -- itself is skipped.
+ if (param[1] == '-' && param[2] == 0)
+ {
+ shift(args, nonops);
+ ++args;
+ if (numargs > 0)
+ --numargs;
+ break;
+ }
+
+ bool handle_short_options;
+ const char* longopt_name;
+ if (param[1] == '-') // if --long-option
+ {
+ handle_short_options = false;
+ longopt_name = param + 2;
+ }
+ else
+ {
+ handle_short_options = true;
+ longopt_name = param + 1; //for testing a potential -long-option
+ }
+
+ bool try_single_minus_longopt = single_minus_longopt;
+ bool have_more_args = (numargs > 1 || numargs < 0); // is referencing argv[1] valid?
+
+ do // loop over short options in group, for long options the body is executed only once
+ {
+ int idx;
+
+ const char* optarg;
+
+ /******************** long option **********************/
+ if (handle_short_options == false || try_single_minus_longopt)
+ {
+ idx = 0;
+ while (usage[idx].longopt != 0 && !streq(usage[idx].longopt, longopt_name))
+ ++idx;
+
+ if (usage[idx].longopt == 0 && min_abbr_len > 0) // if we should try to match abbreviated long options
+ {
+ int i1 = 0;
+ while (usage[i1].longopt != 0 && !streqabbr(usage[i1].longopt, longopt_name, min_abbr_len))
+ ++i1;
+ if (usage[i1].longopt != 0)
+ { // now test if the match is unambiguous by checking for another match
+ int i2 = i1 + 1;
+ while (usage[i2].longopt != 0 && !streqabbr(usage[i2].longopt, longopt_name, min_abbr_len))
+ ++i2;
+
+ if (usage[i2].longopt == 0) // if there was no second match it's unambiguous, so accept i1 as idx
+ idx = i1;
+ }
+ }
+
+ // if we found something, disable handle_short_options (only relevant if single_minus_longopt)
+ if (usage[idx].longopt != 0)
+ handle_short_options = false;
+
+ try_single_minus_longopt = false; // prevent looking for longopt in the middle of shortopt group
+
+ optarg = longopt_name;
+ while (*optarg != 0 && *optarg != '=')
+ ++optarg;
+ if (*optarg == '=') // attached argument
+ ++optarg;
+ else
+ // possibly detached argument
+ optarg = (have_more_args ? args[1] : 0);
+ }
+
+ /************************ short option ***********************************/
+ if (handle_short_options)
+ {
+ if (*++param == 0) // point at the 1st/next option character
+ break; // end of short option group
+
+ idx = 0;
+ while (usage[idx].shortopt != 0 && !instr(*param, usage[idx].shortopt))
+ ++idx;
+
+ if (param[1] == 0) // if the potential argument is separate
+ optarg = (have_more_args ? args[1] : 0);
+ else
+ // if the potential argument is attached
+ optarg = param + 1;
+ }
+
+ const Descriptor* descriptor = &usage[idx];
+
+ if (descriptor->shortopt == 0) /************** unknown option ********************/
+ {
+ // look for dummy entry (shortopt == "" and longopt == "") to use as Descriptor for unknown options
+ idx = 0;
+ while (usage[idx].shortopt != 0 && (usage[idx].shortopt[0] != 0 || usage[idx].longopt[0] != 0))
+ ++idx;
+ descriptor = (usage[idx].shortopt == 0 ? 0 : &usage[idx]);
+ }
+
+ if (descriptor != 0)
+ {
+ Option option(descriptor, param, optarg);
+ switch (descriptor->check_arg(option, print_errors))
+ {
+ case ARG_ILLEGAL:
+ return false; // fatal
+ case ARG_OK:
+ // skip one element of the argument vector, if it's a separated argument
+ if (optarg != 0 && have_more_args && optarg == args[1])
+ {
+ shift(args, nonops);
+ if (numargs > 0)
+ --numargs;
+ ++args;
+ }
+
+ // No further short options are possible after an argument
+ handle_short_options = false;
+
+ break;
+ case ARG_IGNORE:
+ case ARG_NONE:
+ option.arg = 0;
+ break;
+ }
+
+ if (!action.perform(option))
+ return false;
+ }
+
+ } while (handle_short_options);
+
+ shift(args, nonops);
+ ++args;
+ if (numargs > 0)
+ --numargs;
+
+ } // while
+
+ if (numargs > 0 && *args == 0) // It's a bug in the caller if numargs is greater than the actual number
+ numargs = 0; // of arguments, but as a service to the user we fix this if we spot it.
+
+ if (numargs < 0) // if we don't know the number of remaining non-option arguments
+ { // we need to count them
+ numargs = 0;
+ while (args[numargs] != 0)
+ ++numargs;
+ }
+
+ return action.finished(numargs + nonops, args - nonops);
+}
+
+/**
+ * @internal
+ * @brief The implementation of option::printUsage().
+ */
+struct PrintUsageImplementation
+{
+ /**
+ * @internal
+ * @brief Interface for Functors that write (part of) a string somewhere.
+ */
+ struct IStringWriter
+ {
+ /**
+ * @brief Writes the given number of chars beginning at the given pointer somewhere.
+ */
+ virtual void operator()(const char*, int)
+ {
+ }
+ };
+
+ /**
+ * @internal
+ * @brief Encapsulates a function with signature <code>func(string, size)</code> where
+ * string can be initialized with a const char* and size with an int.
+ */
+ template<typename Function>
+ struct FunctionWriter: public IStringWriter
+ {
+ Function* write;
+
+ virtual void operator()(const char* str, int size)
+ {
+ (*write)(str, size);
+ }
+
+ FunctionWriter(Function* w) :
+ write(w)
+ {
+ }
+ };
+
+ /**
+ * @internal
+ * @brief Encapsulates a reference to an object with a <code>write(string, size)</code>
+ * method like that of @c std::ostream.
+ */
+ template<typename OStream>
+ struct OStreamWriter: public IStringWriter
+ {
+ OStream& ostream;
+
+ virtual void operator()(const char* str, int size)
+ {
+ ostream.write(str, size);
+ }
+
+ OStreamWriter(OStream& o) :
+ ostream(o)
+ {
+ }
+ };
+
+ /**
+ * @internal
+ * @brief Like OStreamWriter but encapsulates a @c const reference, which is
+ * typically a temporary object of a user class.
+ */
+ template<typename Temporary>
+ struct TemporaryWriter: public IStringWriter
+ {
+ const Temporary& userstream;
+
+ virtual void operator()(const char* str, int size)
+ {
+ userstream.write(str, size);
+ }
+
+ TemporaryWriter(const Temporary& u) :
+ userstream(u)
+ {
+ }
+ };
+
+ /**
+ * @internal
+ * @brief Encapsulates a function with the signature <code>func(fd, string, size)</code> (the
+ * signature of the @c write() system call)
+ * where fd can be initialized from an int, string from a const char* and size from an int.
+ */
+ template<typename Syscall>
+ struct SyscallWriter: public IStringWriter
+ {
+ Syscall* write;
+ int fd;
+
+ virtual void operator()(const char* str, int size)
+ {
+ (*write)(fd, str, size);
+ }
+
+ SyscallWriter(Syscall* w, int f) :
+ write(w), fd(f)
+ {
+ }
+ };
+
+ /**
+ * @internal
+ * @brief Encapsulates a function with the same signature as @c std::fwrite().
+ */
+ template<typename Function, typename Stream>
+ struct StreamWriter: public IStringWriter
+ {
+ Function* fwrite;
+ Stream* stream;
+
+ virtual void operator()(const char* str, int size)
+ {
+ (*fwrite)(str, size, 1, stream);
+ }
+
+ StreamWriter(Function* w, Stream* s) :
+ fwrite(w), stream(s)
+ {
+ }
+ };
+
+ /**
+ * @internal
+ * @brief Sets <code> i1 = max(i1, i2) </code>
+ */
+ static void upmax(int& i1, int i2)
+ {
+ i1 = (i1 >= i2 ? i1 : i2);
+ }
+
+ /**
+ * @internal
+ * @brief Moves the "cursor" to column @c want_x assuming it is currently at column @c x
+ * and sets @c x=want_x .
+ * If <code> x > want_x </code>, a line break is output before indenting.
+ *
+ * @param write Spaces and possibly a line break are written via this functor to get
+ * the desired indentation @c want_x .
+ * @param[in,out] x the current indentation. Set to @c want_x by this method.
+ * @param want_x the desired indentation.
+ */
+ static void indent(IStringWriter& write, int& x, int want_x)
+ {
+ int indent = want_x - x;
+ if (indent < 0)
+ {
+ write("\n", 1);
+ indent = want_x;
+ }
+
+ if (indent > 0)
+ {
+ char space = ' ';
+ for (int i = 0; i < indent; ++i)
+ write(&space, 1);
+ x = want_x;
+ }
+ }
+
+ /**
+ * @brief Returns true if ch is the unicode code point of a wide character.
+ *
+ * @note
+ * The following character ranges are treated as wide
+ * @code
+ * 1100..115F
+ * 2329..232A (just 2 characters!)
+ * 2E80..A4C6 except for 303F
+ * A960..A97C
+ * AC00..D7FB
+ * F900..FAFF
+ * FE10..FE6B
+ * FF01..FF60
+ * FFE0..FFE6
+ * 1B000......
+ * @endcode
+ */
+ static bool isWideChar(unsigned ch)
+ {
+ if (ch == 0x303F)
+ return false;
+
+ return ((0x1100 <= ch && ch <= 0x115F) || (0x2329 <= ch && ch <= 0x232A) || (0x2E80 <= ch && ch <= 0xA4C6)
+ || (0xA960 <= ch && ch <= 0xA97C) || (0xAC00 <= ch && ch <= 0xD7FB) || (0xF900 <= ch && ch <= 0xFAFF)
+ || (0xFE10 <= ch && ch <= 0xFE6B) || (0xFF01 <= ch && ch <= 0xFF60) || (0xFFE0 <= ch && ch <= 0xFFE6)
+ || (0x1B000 <= ch));
+ }
+
+ /**
+ * @internal
+ * @brief Splits a @c Descriptor[] array into tables, rows, lines and columns and
+ * iterates over these components.
+ *
+ * The top-level organizational unit is the @e table.
+ * A table begins at a Descriptor with @c help!=NULL and extends up to
+ * a Descriptor with @c help==NULL.
+ *
+ * A table consists of @e rows. Due to line-wrapping and explicit breaks
+ * a row may take multiple lines on screen. Rows within the table are separated
+ * by \\n. They never cross Descriptor boundaries. This means a row ends either
+ * at \\n or the 0 at the end of the help string.
+ *
+ * A row consists of columns/cells. Columns/cells within a row are separated by \\t.
+ * Line breaks within a cell are marked by \\v.
+ *
+ * Rows in the same table need not have the same number of columns/cells. The
+ * extreme case are interjections, which are rows that contain neither \\t nor \\v.
+ * These are NOT treated specially by LinePartIterator, but they are treated
+ * specially by printUsage().
+ *
+ * LinePartIterator iterates through the usage at 3 levels: table, row and part.
+ * Tables and rows are as described above. A @e part is a line within a cell.
+ * LinePartIterator iterates through 1st parts of all cells, then through the 2nd
+ * parts of all cells (if any),... @n
+ * Example: The row <code> "1 \v 3 \t 2 \v 4" </code> has 2 cells/columns and 4 parts.
+ * The parts will be returned in the order 1, 2, 3, 4.
+ *
+ * It is possible that some cells have fewer parts than others. In this case
+ * LinePartIterator will "fill up" these cells with 0-length parts. IOW, LinePartIterator
+ * always returns the same number of parts for each column. Note that this is different
+ * from the way rows and columns are handled. LinePartIterator does @e not guarantee that
+ * the same number of columns will be returned for each row.
+ *
+ */
+ class LinePartIterator
+ {
+ const Descriptor* tablestart; //!< The 1st descriptor of the current table.
+ const Descriptor* rowdesc; //!< The Descriptor that contains the current row.
+ const char* rowstart; //!< Ptr to 1st character of current row within rowdesc->help.
+ const char* ptr; //!< Ptr to current part within the current row.
+ int col; //!< Index of current column.
+ int len; //!< Length of the current part (that ptr points at) in BYTES
+ int screenlen; //!< Length of the current part in screen columns (taking narrow/wide chars into account).
+ int max_line_in_block; //!< Greatest index of a line within the block. This is the number of \\v within the cell with the most \\vs.
+ int line_in_block; //!< Line index within the current cell of the current part.
+ int target_line_in_block; //!< Line index of the parts we should return to the user on this iteration.
+ bool hit_target_line; //!< Flag whether we encountered a part with line index target_line_in_block in the current cell.
+
+ /**
+ * @brief Determines the byte and character lengths of the part at @ref ptr and
+ * stores them in @ref len and @ref screenlen respectively.
+ */
+ void update_length()
+ {
+ screenlen = 0;
+ for (len = 0; ptr[len] != 0 && ptr[len] != '\v' && ptr[len] != '\t' && ptr[len] != '\n'; ++len)
+ {
+ ++screenlen;
+ unsigned ch = (unsigned char) ptr[len];
+ if (ch > 0xC1) // everything <= 0xC1 (yes, even 0xC1 itself) is not a valid UTF-8 start byte
+ {
+ // int __builtin_clz (unsigned int x)
+ // Returns the number of leading 0-bits in x, starting at the most significant bit
+ unsigned mask = (unsigned) -1 >> __builtin_clz(ch ^ 0xff);
+ ch = ch & mask; // mask out length bits, we don't verify their correctness
+ while (((unsigned char) ptr[len + 1] ^ 0x80) <= 0x3F) // while next byte is continuation byte
+ {
+ ch = (ch << 6) ^ (unsigned char) ptr[len + 1] ^ 0x80; // add continuation to char code
+ ++len;
+ }
+ // ch is the decoded unicode code point
+ if (ch >= 0x1100 && isWideChar(ch)) // the test for 0x1100 is here to avoid the function call in the Latin case
+ ++screenlen;
+ }
+ }
+ }
+
+ public:
+ //! @brief Creates an iterator for @c usage.
+ LinePartIterator(const Descriptor usage[]) :
+ tablestart(usage), rowdesc(0), rowstart(0), ptr(0), col(-1), len(0), max_line_in_block(0), line_in_block(0),
+ target_line_in_block(0), hit_target_line(true)
+ {
+ }
+
+ /**
+ * @brief Moves iteration to the next table (if any). Has to be called once on a new
+ * LinePartIterator to move to the 1st table.
+ * @retval false if moving to next table failed because no further table exists.
+ */
+ bool nextTable()
+ {
+ // If this is NOT the first time nextTable() is called after the constructor,
+ // then skip to the next table break (i.e. a Descriptor with help == 0)
+ if (rowdesc != 0)
+ {
+ while (tablestart->help != 0 && tablestart->shortopt != 0)
+ ++tablestart;
+ }
+
+ // Find the next table after the break (if any)
+ while (tablestart->help == 0 && tablestart->shortopt != 0)
+ ++tablestart;
+
+ restartTable();
+ return rowstart != 0;
+ }
+
+ /**
+ * @brief Reset iteration to the beginning of the current table.
+ */
+ void restartTable()
+ {
+ rowdesc = tablestart;
+ rowstart = tablestart->help;
+ ptr = 0;
+ }
+
+ /**
+ * @brief Moves iteration to the next row (if any). Has to be called once after each call to
+ * @ref nextTable() to move to the 1st row of the table.
+ * @retval false if moving to next row failed because no further row exists.
+ */
+ bool nextRow()
+ {
+ if (ptr == 0)
+ {
+ restartRow();
+ return rowstart != 0;
+ }
+
+ while (*ptr != 0 && *ptr != '\n')
+ ++ptr;
+
+ if (*ptr == 0)
+ {
+ if ((rowdesc + 1)->help == 0) // table break
+ return false;
+
+ ++rowdesc;
+ rowstart = rowdesc->help;
+ }
+ else // if (*ptr == '\n')
+ {
+ rowstart = ptr + 1;
+ }
+
+ restartRow();
+ return true;
+ }
+
+ /**
+ * @brief Reset iteration to the beginning of the current row.
+ */
+ void restartRow()
+ {
+ ptr = rowstart;
+ col = -1;
+ len = 0;
+ screenlen = 0;
+ max_line_in_block = 0;
+ line_in_block = 0;
+ target_line_in_block = 0;
+ hit_target_line = true;
+ }
+
+ /**
+ * @brief Moves iteration to the next part (if any). Has to be called once after each call to
+ * @ref nextRow() to move to the 1st part of the row.
+ * @retval false if moving to next part failed because no further part exists.
+ *
+ * See @ref LinePartIterator for details about the iteration.
+ */
+ bool next()
+ {
+ if (ptr == 0)
+ return false;
+
+ if (col == -1)
+ {
+ col = 0;
+ update_length();
+ return true;
+ }
+
+ ptr += len;
+ while (true)
+ {
+ switch (*ptr)
+ {
+ case '\v':
+ upmax(max_line_in_block, ++line_in_block);
+ ++ptr;
+ break;
+ case '\t':
+ if (!hit_target_line) // if previous column did not have the targetline
+ { // then "insert" a 0-length part
+ update_length();
+ hit_target_line = true;
+ return true;
+ }
+
+ hit_target_line = false;
+ line_in_block = 0;
+ ++col;
+ ++ptr;
+ break;
+ case 0:
+ case '\n':
+ if (!hit_target_line) // if previous column did not have the targetline
+ { // then "insert" a 0-length part
+ update_length();
+ hit_target_line = true;
+ return true;
+ }
+
+ if (++target_line_in_block > max_line_in_block)
+ {
+ update_length();
+ return false;
+ }
+
+ hit_target_line = false;
+ line_in_block = 0;
+ col = 0;
+ ptr = rowstart;
+ continue;
+ default:
+ ++ptr;
+ continue;
+ } // switch
+
+ if (line_in_block == target_line_in_block)
+ {
+ update_length();
+ hit_target_line = true;
+ return true;
+ }
+ } // while
+ }
+
+ /**
+ * @brief Returns the index (counting from 0) of the column in which
+ * the part pointed to by @ref data() is located.
+ */
+ int column()
+ {
+ return col;
+ }
+
+ /**
+ * @brief Returns the index (counting from 0) of the line within the current column
+ * this part belongs to.
+ */
+ int line()
+ {
+ return target_line_in_block; // NOT line_in_block !!! It would be wrong if !hit_target_line
+ }
+
+ /**
+ * @brief Returns the length of the part pointed to by @ref data() in raw chars (not UTF-8 characters).
+ */
+ int length()
+ {
+ return len;
+ }
+
+ /**
+ * @brief Returns the width in screen columns of the part pointed to by @ref data().
+ * Takes multi-byte UTF-8 sequences and wide characters into account.
+ */
+ int screenLength()
+ {
+ return screenlen;
+ }
+
+ /**
+ * @brief Returns the current part of the iteration.
+ */
+ const char* data()
+ {
+ return ptr;
+ }
+ };
+
+ /**
+ * @internal
+ * @brief Takes input and line wraps it, writing out one line at a time so that
+ * it can be interleaved with output from other columns.
+ *
+ * The LineWrapper is used to handle the last column of each table as well as interjections.
+ * The LineWrapper is called once for each line of output. If the data given to it fits
+ * into the designated width of the last column it is simply written out. If there
+ * is too much data, an appropriate split point is located and only the data up to this
+ * split point is written out. The rest of the data is queued for the next line.
+ * That way the last column can be line wrapped and interleaved with data from
+ * other columns. The following example makes this clearer:
+ * @code
+ * Column 1,1 Column 2,1 This is a long text
+ * Column 1,2 Column 2,2 that does not fit into
+ * a single line.
+ * @endcode
+ *
+ * The difficulty in producing this output is that the whole string
+ * "This is a long text that does not fit into a single line" is the
+ * 1st and only part of column 3. In order to produce the above
+ * output the string must be output piecemeal, interleaved with
+ * the data from the other columns.
+ */
+ class LineWrapper
+ {
+ static const int bufmask = 15; //!< Must be a power of 2 minus 1.
+ /**
+ * @brief Ring buffer for length component of pair (data, length).
+ */
+ int lenbuf[bufmask + 1];
+ /**
+ * @brief Ring buffer for data component of pair (data, length).
+ */
+ const char* datbuf[bufmask + 1];
+ /**
+ * @brief The indentation of the column to which the LineBuffer outputs. LineBuffer
+ * assumes that the indentation has already been written when @ref process()
+ * is called, so this value is only used when a buffer flush requires writing
+ * additional lines of output.
+ */
+ int x;
+ /**
+ * @brief The width of the column to line wrap.
+ */
+ int width;
+ int head; //!< @brief index for next write
+ int tail; //!< @brief index for next read - 1 (i.e. increment tail BEFORE read)
+
+ /**
+ * @brief Multiple methods of LineWrapper may decide to flush part of the buffer to
+ * free up space. The contract of process() says that only 1 line is output. So
+ * this variable is used to track whether something has output a line. It is
+ * reset at the beginning of process() and checked at the end to decide if
+ * output has already occurred or is still needed.
+ */
+ bool wrote_something;
+
+ bool buf_empty()
+ {
+ return ((tail + 1) & bufmask) == head;
+ }
+
+ bool buf_full()
+ {
+ return tail == head;
+ }
+
+ void buf_store(const char* data, int len)
+ {
+ lenbuf[head] = len;
+ datbuf[head] = data;
+ head = (head + 1) & bufmask;
+ }
+
+ //! @brief Call BEFORE reading ...buf[tail].
+ void buf_next()
+ {
+ tail = (tail + 1) & bufmask;
+ }
+
+ /**
+ * @brief Writes (data,len) into the ring buffer. If the buffer is full, a single line
+ * is flushed out of the buffer into @c write.
+ */
+ void output(IStringWriter& write, const char* data, int len)
+ {
+ if (buf_full())
+ write_one_line(write);
+
+ buf_store(data, len);
+ }
+
+ /**
+ * @brief Writes a single line of output from the buffer to @c write.
+ */
+ void write_one_line(IStringWriter& write)
+ {
+ if (wrote_something) // if we already wrote something, we need to start a new line
+ {
+ write("\n", 1);
+ int _ = 0;
+ indent(write, _, x);
+ }
+
+ if (!buf_empty())
+ {
+ buf_next();
+ write(datbuf[tail], lenbuf[tail]);
+ }
+
+ wrote_something = true;
+ }
+ public:
+
+ /**
+ * @brief Writes out all remaining data from the LineWrapper using @c write.
+ * Unlike @ref process() this method indents all lines including the first and
+ * will output a \\n at the end (but only if something has been written).
+ */
+ void flush(IStringWriter& write)
+ {
+ if (buf_empty())
+ return;
+ int _ = 0;
+ indent(write, _, x);
+ wrote_something = false;
+ while (!buf_empty())
+ write_one_line(write);
+ write("\n", 1);
+ }
+
+ /**
+ * @brief Process, wrap and output the next piece of data.
+ *
+ * process() will output at least one line of output. This is not necessarily
+ * the @c data passed in. It may be data queued from a prior call to process().
+ * If the internal buffer is full, more than 1 line will be output.
+ *
+ * process() assumes that the a proper amount of indentation has already been
+ * output. It won't write any further indentation before the 1st line. If
+ * more than 1 line is written due to buffer constraints, the lines following
+ * the first will be indented by this method, though.
+ *
+ * No \\n is written by this method after the last line that is written.
+ *
+ * @param write where to write the data.
+ * @param data the new chunk of data to write.
+ * @param len the length of the chunk of data to write.
+ */
+ void process(IStringWriter& write, const char* data, int len)
+ {
+ wrote_something = false;
+
+ while (len > 0)
+ {
+ if (len <= width) // quick test that works because utf8width <= len (all wide chars have at least 2 bytes)
+ {
+ output(write, data, len);
+ len = 0;
+ }
+ else // if (len > width) it's possible (but not guaranteed) that utf8len > width
+ {
+ int utf8width = 0;
+ int maxi = 0;
+ while (maxi < len && utf8width < width)
+ {
+ int charbytes = 1;
+ unsigned ch = (unsigned char) data[maxi];
+ if (ch > 0xC1) // everything <= 0xC1 (yes, even 0xC1 itself) is not a valid UTF-8 start byte
+ {
+ // int __builtin_clz (unsigned int x)
+ // Returns the number of leading 0-bits in x, starting at the most significant bit
+ unsigned mask = (unsigned) -1 >> __builtin_clz(ch ^ 0xff);
+ ch = ch & mask; // mask out length bits, we don't verify their correctness
+ while ((maxi + charbytes < len) && //
+ (((unsigned char) data[maxi + charbytes] ^ 0x80) <= 0x3F)) // while next byte is continuation byte
+ {
+ ch = (ch << 6) ^ (unsigned char) data[maxi + charbytes] ^ 0x80; // add continuation to char code
+ ++charbytes;
+ }
+ // ch is the decoded unicode code point
+ if (ch >= 0x1100 && isWideChar(ch)) // the test for 0x1100 is here to avoid the function call in the Latin case
+ {
+ if (utf8width + 2 > width)
+ break;
+ ++utf8width;
+ }
+ }
+ ++utf8width;
+ maxi += charbytes;
+ }
+
+ // data[maxi-1] is the last byte of the UTF-8 sequence of the last character that fits
+ // onto the 1st line. If maxi == len, all characters fit on the line.
+
+ if (maxi == len)
+ {
+ output(write, data, len);
+ len = 0;
+ }
+ else // if (maxi < len) at least 1 character (data[maxi] that is) doesn't fit on the line
+ {
+ int i;
+ for (i = maxi; i >= 0; --i)
+ if (data[i] == ' ')
+ break;
+
+ if (i >= 0)
+ {
+ output(write, data, i);
+ data += i + 1;
+ len -= i + 1;
+ }
+ else // did not find a space to split at => split before data[maxi]
+ { // data[maxi] is always the beginning of a character, never a continuation byte
+ output(write, data, maxi);
+ data += maxi;
+ len -= maxi;
+ }
+ }
+ }
+ }
+ if (!wrote_something) // if we didn't already write something to make space in the buffer
+ write_one_line(write); // write at most one line of actual output
+ }
+
+ /**
+ * @brief Constructs a LineWrapper that wraps its output to fit into
+ * screen columns @c x1 (incl.) to @c x2 (excl.).
+ *
+ * @c x1 gives the indentation LineWrapper uses if it needs to indent.
+ */
+ LineWrapper(int x1, int x2) :
+ x(x1), width(x2 - x1), head(0), tail(bufmask)
+ {
+ if (width < 2) // because of wide characters we need at least width 2 or the code breaks
+ width = 2;
+ }
+ };
+
+ /**
+ * @internal
+ * @brief This is the implementation that is shared between all printUsage() templates.
+ * Because all printUsage() templates share this implementation, there is no template bloat.
+ */
+ static void printUsage(IStringWriter& write, const Descriptor usage[], int width = 80, //
+ int last_column_min_percent = 50, int last_column_own_line_max_percent = 75)
+ {
+ if (width < 1) // protect against nonsense values
+ width = 80;
+
+ if (width > 10000) // protect against overflow in the following computation
+ width = 10000;
+
+ int last_column_min_width = ((width * last_column_min_percent) + 50) / 100;
+ int last_column_own_line_max_width = ((width * last_column_own_line_max_percent) + 50) / 100;
+ if (last_column_own_line_max_width == 0)
+ last_column_own_line_max_width = 1;
+
+ LinePartIterator part(usage);
+ while (part.nextTable())
+ {
+
+ /***************** Determine column widths *******************************/
+
+ const int maxcolumns = 8; // 8 columns are enough for everyone
+ int col_width[maxcolumns];
+ int lastcolumn;
+ int leftwidth;
+ int overlong_column_threshold = 10000;
+ do
+ {
+ lastcolumn = 0;
+ for (int i = 0; i < maxcolumns; ++i)
+ col_width[i] = 0;
+
+ part.restartTable();
+ while (part.nextRow())
+ {
+ while (part.next())
+ {
+ if (part.column() < maxcolumns)
+ {
+ upmax(lastcolumn, part.column());
+ if (part.screenLength() < overlong_column_threshold)
+ // We don't let rows that don't use table separators (\t or \v) influence
+ // the width of column 0. This allows the user to interject section headers
+ // or explanatory paragraphs that do not participate in the table layout.
+ if (part.column() > 0 || part.line() > 0 || part.data()[part.length()] == '\t'
+ || part.data()[part.length()] == '\v')
+ upmax(col_width[part.column()], part.screenLength());
+ }
+ }
+ }
+
+ /*
+ * If the last column doesn't fit on the same
+ * line as the other columns, we can fix that by starting it on its own line.
+ * However we can't do this for any of the columns 0..lastcolumn-1.
+ * If their sum exceeds the maximum width we try to fix this by iteratively
+ * ignoring the widest line parts in the width determination until
+ * we arrive at a series of column widths that fit into one line.
+ * The result is a layout where everything is nicely formatted
+ * except for a few overlong fragments.
+ * */
+
+ leftwidth = 0;
+ overlong_column_threshold = 0;
+ for (int i = 0; i < lastcolumn; ++i)
+ {
+ leftwidth += col_width[i];
+ upmax(overlong_column_threshold, col_width[i]);
+ }
+
+ } while (leftwidth > width);
+
+ /**************** Determine tab stops and last column handling **********************/
+
+ int tabstop[maxcolumns];
+ tabstop[0] = 0;
+ for (int i = 1; i < maxcolumns; ++i)
+ tabstop[i] = tabstop[i - 1] + col_width[i - 1];
+
+ int rightwidth = width - tabstop[lastcolumn];
+ bool print_last_column_on_own_line = false;
+ if (rightwidth < last_column_min_width && rightwidth < col_width[lastcolumn])
+ {
+ print_last_column_on_own_line = true;
+ rightwidth = last_column_own_line_max_width;
+ }
+
+ // If lastcolumn == 0 we must disable print_last_column_on_own_line because
+ // otherwise 2 copies of the last (and only) column would be output.
+ // Actually this is just defensive programming. It is currently not
+ // possible that lastcolumn==0 and print_last_column_on_own_line==true
+ // at the same time, because lastcolumn==0 => tabstop[lastcolumn] == 0 =>
+ // rightwidth==width => rightwidth>=last_column_min_width (unless someone passes
+ // a bullshit value >100 for last_column_min_percent) => the above if condition
+ // is false => print_last_column_on_own_line==false
+ if (lastcolumn == 0)
+ print_last_column_on_own_line = false;
+
+ LineWrapper lastColumnLineWrapper(width - rightwidth, width);
+ LineWrapper interjectionLineWrapper(0, width);
+
+ part.restartTable();
+
+ /***************** Print out all rows of the table *************************************/
+
+ while (part.nextRow())
+ {
+ int x = -1;
+ while (part.next())
+ {
+ if (part.column() > lastcolumn)
+ continue; // drop excess columns (can happen if lastcolumn == maxcolumns-1)
+
+ if (part.column() == 0)
+ {
+ if (x >= 0)
+ write("\n", 1);
+ x = 0;
+ }
+
+ indent(write, x, tabstop[part.column()]);
+
+ if ((part.column() < lastcolumn)
+ && (part.column() > 0 || part.line() > 0 || part.data()[part.length()] == '\t'
+ || part.data()[part.length()] == '\v'))
+ {
+ write(part.data(), part.length());
+ x += part.screenLength();
+ }
+ else // either part.column() == lastcolumn or we are in the special case of
+ // an interjection that doesn't contain \v or \t
+ {
+ // NOTE: This code block is not necessarily executed for
+ // each line, because some rows may have fewer columns.
+
+ LineWrapper& lineWrapper = (part.column() == 0) ? interjectionLineWrapper : lastColumnLineWrapper;
+
+ if (!print_last_column_on_own_line)
+ lineWrapper.process(write, part.data(), part.length());
+ }
+ } // while
+
+ if (print_last_column_on_own_line)
+ {
+ part.restartRow();
+ while (part.next())
+ {
+ if (part.column() == lastcolumn)
+ {
+ write("\n", 1);
+ int _ = 0;
+ indent(write, _, width - rightwidth);
+ lastColumnLineWrapper.process(write, part.data(), part.length());
+ }
+ }
+ }
+
+ write("\n", 1);
+ lastColumnLineWrapper.flush(write);
+ interjectionLineWrapper.flush(write);
+ }
+ }
+ }
+
+}
+;
+
+/**
+ * @brief Outputs a nicely formatted usage string with support for multi-column formatting
+ * and line-wrapping.
+ *
+ * printUsage() takes the @c help texts of a Descriptor[] array and formats them into
+ * a usage message, wrapping lines to achieve the desired output width.
+ *
+ * <b>Table formatting:</b>
+ *
+ * Aside from plain strings which are simply line-wrapped, the usage may contain tables. Tables
+ * are used to align elements in the output.
+ *
+ * @code
+ * // Without a table. The explanatory texts are not aligned.
+ * -c, --create |Creates something.
+ * -k, --kill |Destroys something.
+ *
+ * // With table formatting. The explanatory texts are aligned.
+ * -c, --create |Creates something.
+ * -k, --kill |Destroys something.
+ * @endcode
+ *
+ * Table formatting removes the need to pad help texts manually with spaces to achieve
+ * alignment. To create a table, simply insert \\t (tab) characters to separate the cells
+ * within a row.
+ *
+ * @code
+ * const option::Descriptor usage[] = {
+ * {..., "-c, --create \tCreates something." },
+ * {..., "-k, --kill \tDestroys something." }, ...
+ * @endcode
+ *
+ * Note that you must include the minimum amount of space desired between cells yourself.
+ * Table formatting will insert further spaces as needed to achieve alignment.
+ *
+ * You can insert line breaks within cells by using \\v (vertical tab).
+ *
+ * @code
+ * const option::Descriptor usage[] = {
+ * {..., "-c,\v--create \tCreates\vsomething." },
+ * {..., "-k,\v--kill \tDestroys\vsomething." }, ...
+ *
+ * // results in
+ *
+ * -c, Creates
+ * --create something.
+ * -k, Destroys
+ * --kill something.
+ * @endcode
+ *
+ * You can mix lines that do not use \\t or \\v with those that do. The plain
+ * lines will not mess up the table layout. Alignment of the table columns will
+ * be maintained even across these interjections.
+ *
+ * @code
+ * const option::Descriptor usage[] = {
+ * {..., "-c, --create \tCreates something." },
+ * {..., "----------------------------------" },
+ * {..., "-k, --kill \tDestroys something." }, ...
+ *
+ * // results in
+ *
+ * -c, --create Creates something.
+ * ----------------------------------
+ * -k, --kill Destroys something.
+ * @endcode
+ *
+ * You can have multiple tables within the same usage whose columns are
+ * aligned independently. Simply insert a dummy Descriptor with @c help==0.
+ *
+ * @code
+ * const option::Descriptor usage[] = {
+ * {..., "Long options:" },
+ * {..., "--very-long-option \tDoes something long." },
+ * {..., "--ultra-super-mega-long-option \tTakes forever to complete." },
+ * {..., 0 }, // ---------- table break -----------
+ * {..., "Short options:" },
+ * {..., "-s \tShort." },
+ * {..., "-q \tQuick." }, ...
+ *
+ * // results in
+ *
+ * Long options:
+ * --very-long-option Does something long.
+ * --ultra-super-mega-long-option Takes forever to complete.
+ * Short options:
+ * -s Short.
+ * -q Quick.
+ *
+ * // Without the table break it would be
+ *
+ * Long options:
+ * --very-long-option Does something long.
+ * --ultra-super-mega-long-option Takes forever to complete.
+ * Short options:
+ * -s Short.
+ * -q Quick.
+ * @endcode
+ *
+ * <b>Output methods:</b>
+ *
+ * Because TheLeanMeanC++Option parser is freestanding, you have to provide the means for
+ * output in the first argument(s) to printUsage(). Because printUsage() is implemented as
+ * a set of template functions, you have great flexibility in your choice of output
+ * method. The following example demonstrates typical uses. Anything that's similar enough
+ * will work.
+ *
+ * @code
+ * #include <unistd.h> // write()
+ * #include <iostream> // cout
+ * #include <sstream> // ostringstream
+ * #include <cstdio> // fwrite()
+ * using namespace std;
+ *
+ * void my_write(const char* str, int size) {
+ * fwrite(str, size, 1, stdout);
+ * }
+ *
+ * struct MyWriter {
+ * void write(const char* buf, size_t size) const {
+ * fwrite(str, size, 1, stdout);
+ * }
+ * };
+ *
+ * struct MyWriteFunctor {
+ * void operator()(const char* buf, size_t size) {
+ * fwrite(str, size, 1, stdout);
+ * }
+ * };
+ * ...
+ * printUsage(my_write, usage); // custom write function
+ * printUsage(MyWriter(), usage); // temporary of a custom class
+ * MyWriter writer;
+ * printUsage(writer, usage); // custom class object
+ * MyWriteFunctor wfunctor;
+ * printUsage(&wfunctor, usage); // custom functor
+ * printUsage(write, 1, usage); // write() to file descriptor 1
+ * printUsage(cout, usage); // an ostream&
+ * printUsage(fwrite, stdout, usage); // fwrite() to stdout
+ * ostringstream sstr;
+ * printUsage(sstr, usage); // an ostringstream&
+ *
+ * @endcode
+ *
+ * @par Notes:
+ * @li the @c write() method of a class that is to be passed as a temporary
+ * as @c MyWriter() is in the example, must be a @c const method, because
+ * temporary objects are passed as const reference. This only applies to
+ * temporary objects that are created and destroyed in the same statement.
+ * If you create an object like @c writer in the example, this restriction
+ * does not apply.
+ * @li a functor like @c MyWriteFunctor in the example must be passed as a pointer.
+ * This differs from the way functors are passed to e.g. the STL algorithms.
+ * @li All printUsage() templates are tiny wrappers around a shared non-template implementation.
+ * So there's no penalty for using different versions in the same program.
+ * @li printUsage() always interprets Descriptor::help as UTF-8 and always produces UTF-8-encoded
+ * output. If your system uses a different charset, you must do your own conversion. You
+ * may also need to change the font of the console to see non-ASCII characters properly.
+ * This is particularly true for Windows.
+ * @li @b Security @b warning: Do not insert untrusted strings (such as user-supplied arguments)
+ * into the usage. printUsage() has no protection against malicious UTF-8 sequences.
+ *
+ * @param prn The output method to use. See the examples above.
+ * @param usage the Descriptor[] array whose @c help texts will be formatted.
+ * @param width the maximum number of characters per output line. Note that this number is
+ * in actual characters, not bytes. printUsage() supports UTF-8 in @c help and will
+ * count multi-byte UTF-8 sequences properly. Asian wide characters are counted
+ * as 2 characters.
+ * @param last_column_min_percent (0-100) The minimum percentage of @c width that should be available
+ * for the last column (which typically contains the textual explanation of an option).
+ * If less space is available, the last column will be printed on its own line, indented
+ * according to @c last_column_own_line_max_percent.
+ * @param last_column_own_line_max_percent (0-100) If the last column is printed on its own line due to
+ * less than @c last_column_min_percent of the width being available, then only
+ * @c last_column_own_line_max_percent of the extra line(s) will be used for the
+ * last column's text. This ensures an indentation. See example below.
+ *
+ * @code
+ * // width=20, last_column_min_percent=50 (i.e. last col. min. width=10)
+ * --3456789 1234567890
+ * 1234567890
+ *
+ * // width=20, last_column_min_percent=75 (i.e. last col. min. width=15)
+ * // last_column_own_line_max_percent=75
+ * --3456789
+ * 123456789012345
+ * 67890
+ *
+ * // width=20, last_column_min_percent=75 (i.e. last col. min. width=15)
+ * // last_column_own_line_max_percent=33 (i.e. max. 5)
+ * --3456789
+ * 12345
+ * 67890
+ * 12345
+ * 67890
+ * @endcode
+ */
+template<typename OStream>
+void printUsage(OStream& prn, const Descriptor usage[], int width = 80, int last_column_min_percent = 50,
+ int last_column_own_line_max_percent = 75)
+{
+ PrintUsageImplementation::OStreamWriter<OStream> write(prn);
+ PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);
+}
+
+template<typename Function>
+void printUsage(Function* prn, const Descriptor usage[], int width = 80, int last_column_min_percent = 50,
+ int last_column_own_line_max_percent = 75)
+{
+ PrintUsageImplementation::FunctionWriter<Function> write(prn);
+ PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);
+}
+
+template<typename Temporary>
+void printUsage(const Temporary& prn, const Descriptor usage[], int width = 80, int last_column_min_percent = 50,
+ int last_column_own_line_max_percent = 75)
+{
+ PrintUsageImplementation::TemporaryWriter<Temporary> write(prn);
+ PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);
+}
+
+template<typename Syscall>
+void printUsage(Syscall* prn, int fd, const Descriptor usage[], int width = 80, int last_column_min_percent = 50,
+ int last_column_own_line_max_percent = 75)
+{
+ PrintUsageImplementation::SyscallWriter<Syscall> write(prn, fd);
+ PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);
+}
+
+template<typename Function, typename Stream>
+void printUsage(Function* prn, Stream* stream, const Descriptor usage[], int width = 80, int last_column_min_percent =
+ 50,
+ int last_column_own_line_max_percent = 75)
+{
+ PrintUsageImplementation::StreamWriter<Function, Stream> write(prn, stream);
+ PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);
+}
+
+}
+// namespace option
+
+#endif /* OPTIONPARSER_H_ */
--- /dev/null
+
+%module pasn1
+%{
+#include "asn1_parser.h"
+%}
+
+%include <std_vector.i>
+%include <std_list.i>
+
+namespace ans1 {
+
+/*
+%rename(ASN1Parser) parser
+%nodefaultctor
+*/
+class module ;
+
+
+class parser
+{
+ public:
+ typedef std::vector<asn1::module *> modules_type;
+
+ typedef std::vector<asn1::module *>::iterator iterator;
+
+ typedef std::list<asn1::parser_listener *> listener_list;
+
+ typedef std::list<std::string> string_list;
+
+ modules_type &modules() { return m_modules;};
+
+ static parser *instance();
+
+ inline string_list &includes();
+
+ inline string_list &files();
+
+ inline bool file_mode();
+
+ inline void set_file_mode(bool fm);
+
+ private:
+ parser();
+};
+
+
+}
--- /dev/null
+PROJECT(test-pkix)
+# Libraries first
+
+INCLUDE(${rules_SOURCE_DIR}/flex.cmake)
+
+
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../../../utils)
+
+SET(PKIX PKIX1Explicit88)
+
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/PKIX1Explicit88.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/PKIX1Explicit88.h
+ COMMAND ${asn1p_EXE}
+ ARGS -I ${asn1-data-models_SOURCE_DIR}/
+ -d parser=8
+ -d msg=1
+ -f rfc3280-PKIX1Explicit88.asn1
+ -oPKIX1Explicit88
+ DEPENDS ${asn1p_EXE}
+ COMMENT "Build PKIX1Explicit88.h and .cpp"
+ )
+
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/${PKIX}.h GENERATED)
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/${PKIX}.cpp GENERATED)
+
+ADD_EXECUTABLE(pkix_test
+ main_pkix.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/${PKIX}.cpp
+ )
+TARGET_LINK_LIBRARIES(pkix_test asn1)
--- /dev/null
+#include <iostream>
+#include <fstream>
+#include "rtasn1/asn1_config.h"
+#include "rtasn1/asn1.h"
+#include "PKIX1Explicit88.h"
+//#include "PKIX1Explicit88.cpp"
+#include "rtasn1/asn1_codec.h"
+#include "rtasn1/asn1_codec_ber.h"
+
+using namespace PKIX1Explicit88;
+
+int main(int argc,char **argv)
+{
+ asn1::streams::ber ctx;
+ asn1::prim::types::Integer i(1);
+ PKIX1Explicit88::Certificate cert,read_cert;
+ PKIX1Explicit88::Name name(PKIX1Explicit88::Name::typeof_rdnSequence,MAKE_TAG(0,0,16));
+ AttributeTypeAndValue issuer_t;
+ PKIX1Explicit88::TBSCertificate tb;
+
+ issuer_t.type = id_domainComponent();
+ PKIX1Explicit88::AttributeTypeAndValue issuer = issuer_t;
+ RelativeDistinguishedName rdn= issuer;
+ asn1::PrintableString str(asn1::prim::types::String("Andre EBERSOLD "));
+ PDSParameter pd;
+ pd.printable_string = str;
+
+ OBJECT_IDENTIFIER pk = pkcs_9();
+ //name.get_rdnSequence() = rdn;
+ name.get_rdnSequence().push_back(rdn);
+ std::cout<<"Hello world"<<std::endl;
+ tb.version = i;
+ tb.serialNumber = 123;
+ tb.issuer = name;
+ std::cout<<"Set Version="<<tb.version<<std::endl;
+ cert.tbsCertificate = PKIX1Explicit88::TBSCertificate(tb);
+ cert.signature[0] = 0x23;
+ PKIX1Explicit88::Certificate certs = PKIX1Explicit88::Certificate(cert);
+
+ //certs.codec(ctx,certs ,asn1::CODEC_ENCODE);
+ certs.encode(ctx);
+ std::cout<<"-- pkcs-9 is :"<<pk<<std::endl;
+ if (argc > 1)
+ {
+ std::cout<<"Try to read file given as parameter : "<<argv[1]<<std::endl;
+ std::ifstream pkix_file;
+ pkix_file.open(argv[1]);
+ pkix_file.seekg(0,std::ios::end);
+ int len = pkix_file.tellg();
+ pkix_file.seekg(0,std::ios::beg);
+ unsigned char *b = (unsigned char *)malloc(len+1);
+ pkix_file.read((char *)b,len);
+ asn1::streams::ber cr(b,len);
+ //asn1::context cr(b,len);
+
+ asn1::types::debug_level = 7;
+ int result = read_cert.decode(cr);
+ std::cout<<"See how it looks like "<<result<<": "<<std::endl;
+ std::cout<<read_cert<<std::endl;;
+ pkix_file.close();
+ }
+}
--- /dev/null
+<Certificate>
+ <tbsCertificate>
+ <version>2</version>
+ <serialNumber>44:BE:0C:8B:50:00:24:B4:11:D3:36:30:4B:C0:33:77</serialNumber>
+ <signature>
+ <algorithm>1.2.840.113549.1.1.5</algorithm>
+ <parameters>05 00</parameters>
+ </signature>
+ <issuer>
+ <rdnSequence>
+ <RelativeDistinguishedName>
+ <AttributeTypeAndValue>
+ <type>2.5.4.6</type>
+ <value>13 02 55 53</value>
+ </AttributeTypeAndValue>
+ </RelativeDistinguishedName>
+ <RelativeDistinguishedName>
+ <AttributeTypeAndValue>
+ <type>2.5.4.8</type>
+ <value>13 02 55 54</value>
+ </AttributeTypeAndValue>
+ </RelativeDistinguishedName>
+ <RelativeDistinguishedName>
+ <AttributeTypeAndValue>
+ <type>2.5.4.7</type>
+ <value>13 0E 53 61 6C 74 20 4C 61 6B 65 20 43 69 74 79</value>
+ </AttributeTypeAndValue>
+ </RelativeDistinguishedName>
+ <RelativeDistinguishedName>
+ <AttributeTypeAndValue>
+ <type>2.5.4.10</type>
+ <value>
+ 13 15 54 68 65 20 55 53 45 52 54 52 55 53 54 20
+ 4E 65 74 77 6F 72 6B
+ </value>
+ </AttributeTypeAndValue>
+ </RelativeDistinguishedName>
+ <RelativeDistinguishedName>
+ <AttributeTypeAndValue>
+ <type>2.5.4.11</type>
+ <value>
+ 13 18 68 74 74 70 3A 2F 2F 77 77 77 2E 75 73 65
+ 72 74 72 75 73 74 2E 63 6F 6D
+ </value>
+ </AttributeTypeAndValue>
+ </RelativeDistinguishedName>
+ <RelativeDistinguishedName>
+ <AttributeTypeAndValue>
+ <type>2.5.4.3</type>
+ <value>
+ 13 22 55 54 4E 2D 55 53 45 52 46 69 72 73 74 2D
+ 4E 65 74 77 6F 72 6B 20 41 70 70 6C 69 63 61 74
+ 69 6F 6E 73
+ </value>
+ </AttributeTypeAndValue>
+ </RelativeDistinguishedName>
+ </rdnSequence>
+ </issuer>
+ <validity>
+ <notBefore>
+ <utcTime>990709184839Z</utcTime>
+ </notBefore>
+ <notAfter>
+ <utcTime>190709185749Z</utcTime>
+ </notAfter>
+ </validity>
+ <subject>
+ <rdnSequence>
+ <RelativeDistinguishedName>
+ <AttributeTypeAndValue>
+ <type>2.5.4.6</type>
+ <value>13 02 55 53</value>
+ </AttributeTypeAndValue>
+ </RelativeDistinguishedName>
+ <RelativeDistinguishedName>
+ <AttributeTypeAndValue>
+ <type>2.5.4.8</type>
+ <value>13 02 55 54</value>
+ </AttributeTypeAndValue>
+ </RelativeDistinguishedName>
+ <RelativeDistinguishedName>
+ <AttributeTypeAndValue>
+ <type>2.5.4.7</type>
+ <value>13 0E 53 61 6C 74 20 4C 61 6B 65 20 43 69 74 79</value>
+ </AttributeTypeAndValue>
+ </RelativeDistinguishedName>
+ <RelativeDistinguishedName>
+ <AttributeTypeAndValue>
+ <type>2.5.4.10</type>
+ <value>
+ 13 15 54 68 65 20 55 53 45 52 54 52 55 53 54 20
+ 4E 65 74 77 6F 72 6B
+ </value>
+ </AttributeTypeAndValue>
+ </RelativeDistinguishedName>
+ <RelativeDistinguishedName>
+ <AttributeTypeAndValue>
+ <type>2.5.4.11</type>
+ <value>
+ 13 18 68 74 74 70 3A 2F 2F 77 77 77 2E 75 73 65
+ 72 74 72 75 73 74 2E 63 6F 6D
+ </value>
+ </AttributeTypeAndValue>
+ </RelativeDistinguishedName>
+ <RelativeDistinguishedName>
+ <AttributeTypeAndValue>
+ <type>2.5.4.3</type>
+ <value>
+ 13 22 55 54 4E 2D 55 53 45 52 46 69 72 73 74 2D
+ 4E 65 74 77 6F 72 6B 20 41 70 70 6C 69 63 61 74
+ 69 6F 6E 73
+ </value>
+ </AttributeTypeAndValue>
+ </RelativeDistinguishedName>
+ </rdnSequence>
+ </subject>
+ <subjectPublicKeyInfo>
+ <algorithm>
+ <algorithm>1.2.840.113549.1.1.1</algorithm>
+ <parameters>05 00</parameters>
+ </algorithm>
+ <subjectPublicKey>
+ 0011000010000010000000010000101000000010100000100000000100000001
+ 0000000010110011111110111001000110100001111001000011011001010101
+ 1000010110101100000001100011010001011011101000001001101001011000
+ 1011001011111000101101010000111100000101011101111000001110101110
+ 0011001010110001011101101001001001101000111011000010001101001010
+ 1100100101110110001111111110001110011100101101100011011101111001
+ 0000001110111001101010110110100110001101000001110010010110110110
+ 0001100101100111111001001011000000011011000110000111001101100001
+ 0100101011101000011111101100110111010011001011110110010011100011
+ 1010011001111100000011001111101000010111100000001010001100001101
+ 0100011110001001010011110101000101110001001011111110111011111100
+ 0011111111111001101110000001011010000000100001111000100110010011
+ 0010010100100000100110100100001110000010011010010010010001110110
+ 0010100001011001001101011010000100011101110000000111111110000011
+ 0000011001100100000101100010000000101100110100110100100110100100
+ 1000010110110100110000000110000101111111010100010000100011111000
+ 0110100000010101100100011000000011001011101001011101010111101110
+ 0011101100111010111101001000010000000100010111100110000001011001
+ 1010011110001100001101000111001011101110101110000111100011000101
+ 1101000100111011000100100100101001101111011111100110010100100111
+ 1011100110100100010101011100010110111001011011110100001110100100
+ 1100010100011101001011001001100111000000010100101010010001111000
+ 0100110000010101101100110100000010011000000010000110101101000011
+ 1100011000000001101100000111101001111011111101010110101100011100
+ 0010001000111111110010111110111111111111101010001101000000111010
+ 0100101101110110000101011001111011010010110100011100011000101110
+ 1110001111011011010101110001101100110010101000101011100001101111
+ 1110100010000110101001100011111101110000101010111110010101110000
+ 1001001010101011010001000001111001000000010100001111101110011100
+ 1010001101100010111001000110110001101110101000001100100011011110
+ 1110001010000000010000101111101011101001001011111110100011001110
+ 0011001000000100100011110111110010001101101101110001110010100011
+ 0011010100111100000101011101110110011110110000111010111010010111
+ 101001010000001000000011000000010000000000000001
+ </subjectPublicKey>
+ </subjectPublicKeyInfo>
+ <extensions>
+ <Extension>
+ <extnID>2.5.29.15</extnID>
+ <extnValue>03 02 01 C6</extnValue>
+ </Extension>
+ <Extension>
+ <extnID>2.5.29.19</extnID>
+ <critical><true/></critical>
+ <extnValue>30 03 01 01 FF</extnValue>
+ </Extension>
+ <Extension>
+ <extnID>2.5.29.14</extnID>
+ <extnValue>
+ 04 14 FA 86 C9 DB E0 BA E9 78 F5 4B A8 D6 15 DF
+ F0 D3 E1 6A 14 3C
+ </extnValue>
+ </Extension>
+ <Extension>
+ <extnID>2.5.29.31</extnID>
+ <extnValue>
+ 30 46 30 44 A0 42 A0 40 86 3E 68 74 74 70 3A 2F
+ 2F 63 72 6C 2E 75 73 65 72 74 72 75 73 74 2E 63
+ 6F 6D 2F 55 54 4E 2D 55 53 45 52 46 69 72 73 74
+ 2D 4E 65 74 77 6F 72 6B 41 70 70 6C 69 63 61 74
+ 69 6F 6E 73 2E 63 72 6C
+ </extnValue>
+ </Extension>
+ </extensions>
+ </tbsCertificate>
+ <signatureAlgorithm>
+ <algorithm>1.2.840.113549.1.1.5</algorithm>
+ <parameters>05 00</parameters>
+ </signatureAlgorithm>
+ <signature>
+ 1010010011110011001001011100110011010001110101001001000110000011
+ 0010001011010000110011000011001010101011100110111001011001001110
+ 0011010010010001010101000010000000100101001101000110000101011111
+ 0010101000000010000101011110000110001011101010101111111101111101
+ 0110010001010001110011110000101011111111101111000111110111011000
+ 0010000101101010011110001100101100101111010100010110111111111000
+ 0100001000011101001100111011110111101011101101010111101110010100
+ 1100001111000011101010011010000000101101110111111101000100101001
+ 0001111100011101111111101000111100111111101110111010100001000101
+ 0010101001111111110100010110111001010101001001001110001010111011
+ 0000001011111011001100010011111110111110111010001011110011101100
+ 0100000000101011111110000000000111010100010101100011100011100100
+ 1100101001000100100000101011010101100001001000000010000101100111
+ 0110010111110110111100000000101111100111001101001111100010100101
+ 1100001010011100101000110101110001000000000111111000010110010011
+ 1001010100000110110111100100111111010100001001111010100110110110
+ 1010010111111100000101101100110101110011001100010011111110111000
+ 0110010100100111110011111101010001010011000110101111000010101100
+ 0110111010011111010011110000010100001100000000111000000110100111
+ 1000010000101001110001000101101010111101011001000101011101110010
+ 1010110100111011110011110011011100011000101001101001100011000110
+ 1010110100000110101101001101110000001000101000110000010011010101
+ 0010100110100100100101101001101000010010011001110100101010001100
+ 0110000001000101100111011111000100100011100110101011000000000000
+ 1001110001101000101101011001100001010000110100111110111110001110
+ 0010111010010010011001011011000101001000001111100010000110111110
+ 0001010100110000001010100000110110110101000011001010001101101011
+ 0011111110101110011111110101011111110101000111111001011001111100
+ 1101111101101111110111011000001000110000001011000110010100011011
+ 0100000001001010110011010110100010111001011100101110110001110001
+ 0111011011101100010101001000111000011111100001010000110000000001
+ 0110101011111010101001100011100010101100000111111100010010000100
+ </signature>
+</Certificate>
--- /dev/null
+PROJECT(libasn1)
+SUBDIRS(cpp)
+
+CONFIGURE_FILE(asn1_config.h.in asn1_config.h)
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/asn1_config.h GENERATED)
+
+ADD_LIBRARY(asn1
+ asn1_context.cpp
+ asn1_codec_ber.cpp
+ asn1_codec_jer.cpp
+ asn1_codec_oer.cpp
+ asn1_codec_per.cpp
+ prim_types.cpp
+ asn1_types.cpp
+ cpp/prim_oid.cpp
+ cjson/cJSON.c
+ )
+#
+# Install stuff
+#
+IF(APPLE)
+ INSTALL(TARGETS asn1
+ COMPONENT RuntimeLibraries
+ LIBRARY DESTINATION Smartasn1.app/Contents/lib/
+ ARCHIVE DESTINATION Smartasn1.app/Contents/lib/
+ )
+ INSTALL(FILES
+ asn1.h
+ ${CMAKE_CURRENT_BINARY_DIR}/asn1_config.h
+ asn1_types.h
+ asn1_context.h
+ asn1_errors.h
+ asn1_codec.h
+ asn1_tag.h
+ prim_types.h
+ asn1_types.inc
+ asn1_rose.h
+ asn1_types.hpp
+ asn1_codec_ber.h
+ asn1_codec_jer.h
+ asn1_codec_oer.h
+ asn1_codec_per.h
+ asn1_debug.h
+ COMPONENT Asn1Headers
+ DESTINATION Smartasn1.app/Contents/include/asn1/)
+ELSE(APPLE)
+ INSTALL(TARGETS asn1
+ COMPONENT RuntimeLibraries
+ LIBRARY DESTINATION lib/
+ ARCHIVE DESTINATION lib/
+ )
+ INSTALL(FILES
+ asn1.h
+ asn1_types.h
+ asn1_types.inc
+ asn1_context.h
+ asn1_errors.h
+ asn1_codec.h
+ asn1_tag.h
+ prim_types.h
+ asn1_rose.h
+ asn1_types.hpp
+ asn1_codec_ber.h
+ asn1_codec_jer.h
+ asn1_codec_oer.h
+ asn1_codec_per.h
+ asn1_debug.h
+ COMPONENT Asn1Headers
+ DESTINATION include/asn1/)
+
+ENDIF(APPLE)
--- /dev/null
+#ifndef ASN1_H__
+#define ASN1_H__
+
+#include "rtasn1/asn1_config.h"
+#include "rtasn1/asn1_debug.h"
+#include "rtasn1/asn1_errors.h"
+#include "rtasn1/asn1_tag.h"
+#include "rtasn1/prim_types.h"
+namespace asn1 { class context; };
+namespace asn1 { namespace streams { class ber;} };
+#include "rtasn1/asn1_types.h"
+#include "rtasn1/asn1_codec.h"
+#include "rtasn1/asn1_context.h"
+#include "rtasn1/asn1_rose.h"
+#include "rtasn1/asn1_types.hpp"
+#include <typeinfo>
+#if defined(__GNUC__) ||defined(_WIN32)
+#include <bitset>
+#endif
+
+#if defined (ASN1_ATTRIBUTE_OPTIONAL_AS_SHARED_POINTER)
+// ASN1_OPTIONAL_AS_SHARED_POINTER
+# define ASN1_ATTRIBUTE_OPTIONAL(x) asn1::intrusive_ptr<x >
+
+# define ASN1_ATTRIBUTE_OPTIONAL_ENCODE(x) do { \
+ if( !(x.is_nul() ) ) { \
+ (x)->encode(ctx); \
+ } \
+ } while (0)
+
+# define ASN1_ATTRIBUTE_OPTIONAL_DECODE(x) do { \
+ if( ! x.is_nul() ) { \
+ x->decode(ctx); \
+ } else { \
+ x.create(); \
+ if (x->decode(ctx) != asn1::ok) { \
+ x.release(); \
+ }\
+ } \
+ } while(0)
+
+# define ASN1_ATTRIBUTE_OPTIONAL_DECODE_IMPLICIT(x,tg) do { \
+ if( ! c.x.is_nul() ) { \
+ c.x->set_tag(tg); \
+ if (c.x->decode(ctx) != asn1::ok) { \
+ c.x.release(); \
+ }\
+ } else { \
+ c.x.create(tg); \
+ if (c.x->decode(ctx) != asn1::ok) { \
+ c.x.release(); \
+ }\
+ } \
+ } while(0)
+
+
+#elif defined (ASN1_ATTRIBUTE_OPTIONA_AS_POINTER)
+// ASN1_OPTIONAL_AS_POINTER
+# define ASN1_ATTRIBUTE_OPTIONAL(x) x *
+# define ASN1_ATTRIBUTE_OPTIONAL_ENCODE(x) x
+# define ASN1_ATTRIBUTE_OPTIONAL_DECODE(x) x
+#else
+// ASN1_OPTIONAL_AS_NOT_SUPPORTED
+# define ASN1_ATTRIBUTE_OPTIONAL(x) x
+# define ASN1_ATTRIBUTE_OPTIONAL_ENCODE(x) { \
+ x.encode(ctx); \
+ }
+# define ASN1_ATTRIBUTE_OPTIONAL_DECODE(x) do { \
+ x.decode(ctx); \
+ } while(0)
+
+# define ASN1_ATTRIBUTE_OPTIONAL_DECODE_IMPLICIT(x,tg) do { \
+ x.set_tag(tg);\
+ x.decode(ctx); \
+ } while(0)
+#endif
+
+namespace asn1 {
+namespace types {
+}
+}
+
+/*
+vim:et:sw=2:ts=2:
+ */
+#endif
--- /dev/null
+#ifndef ASN1_CODEC_H__
+#define ASN1_CODEC_H__
+#include <string.h>
+#include "rtasn1/asn1.h"
+namespace asn1 {
+ namespace types {
+ extern int debug_level;
+ }
+ namespace codecs {
+ class ber;
+ }
+};
+
+//
+namespace asn1
+{
+
+
+class context_base;
+
+/**
+ *
+ * @brief Base class to Implement encode and docode
+ * functions related to ASN1 types.
+ *
+ * put in this class methods that are common to all
+ * type of encoders / decoders BER,JER,OER,PER,XER
+ * Eventual parameters, allocator
+ */
+ class codec
+ {
+ public:
+ codec( ) {};
+ };
+
+};
+#endif
+/*
+ * vim: et sw=2 ts=2 list:
+ */
--- /dev/null
+#include <iostream>
+#include <string>
+#include <typeinfo>
+#include "rtasn1/asn1.h"
+#include "rtasn1/asn1_codec.h"
+#include "rtasn1/asn1_context.h"
+#include "rtasn1/asn1_codec_ber.h"
+
+/*
+vim:et:sw=2:ts=2
+ */
+namespace asn1 {
+
+
+#define ASN1_TYPE_CLS(PrimType,TagType,TagNum,Asn1Type) \
+ template <> \
+ void codecBER::encode(streams::ber &ctx, const asn1::Asn1Type &t) \
+ { \
+ encode_ber(ctx,t); \
+ } \
+ template <> \
+ int \
+ codecBER::decode(streams::ber &ctx, asn1::Asn1Type &t) \
+ { \
+ return decode_ber(ctx,t); \
+ }
+
+ASN1_TYPE_CLS(asn1::prim::types::ObjectIdentifier,asn1::types::UNIVERSAL,6,ObjectIdentifier)
+
+#include "rtasn1/asn1_types.inc"
+
+# if 0
+ std::cerr<<"codecBER::"<<__FUNCTION__<<" good "; \
+ std::cerr<<#Asn1Type<<std::endl; \
+ std::cerr<<"codecBER::"<<__FUNCTION__<<" good "; \
+ std::cerr<<#Asn1Type<<std::endl; \
+
+#endif
+
+
+
+/**
+ * Why not providing the real implementation directly.
+ * I could save an inderection between the template function
+ * and the code.
+ *
+ */
+#define ASN1_CODEC_IMPL(Type,Encode,Decode) \
+void codecBER::encode_ber(streams::ber &ctx,const asn1::Type &t) \
+Encode \
+int codecBER::decode_ber(streams::ber &ctx,asn1::Type &t) \
+Decode
+
+ASN1_CODEC_IMPL(BOOLEAN,
+{
+ ctx.encode_boolean(t);
+},
+{
+ return ctx.decode_boolean(t);
+})
+ASN1_CODEC_IMPL(INTEGER,
+{
+ ctx.encode_integer(t);
+},
+{
+ return ctx.decode_integer(t);
+})
+ASN1_CODEC_IMPL(Int8,
+{
+ ctx.encode_integer(t);
+},
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+ //return ctx.decode_integer(t);
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(Int16,
+{
+ ctx.encode_integer(t);
+},
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+ //return ctx.decode_integer(t);
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(Int32,
+{
+ ctx.encode_integer(t);
+},
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+ //return ctx.decode_integer(t);
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(Int64,
+{
+ ctx.encode_integer(t);
+},
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+ //return ctx.decode_integer(t);
+ return asn1::ok;
+})
+
+
+ASN1_CODEC_IMPL(UInt8,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(UInt16,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(UInt32,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+
+ASN1_CODEC_IMPL(UInt64,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+ ctx.encode_integer(t);
+},
+{
+ return ctx.decode_integer(t);
+ //return asn1::ok;
+})
+
+ASN1_CODEC_IMPL(BIT_STRING,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+ ctx.encode_bitstring(t);
+},
+{
+ return ctx.decode_bitstring(t);
+})
+ASN1_CODEC_IMPL(OCTET_STRING,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(STRING,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(Null,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+#if 0
+ASN1_CODEC_IMPL(OBJECT_IDENTIFIER,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+#else
+ASN1_CODEC_IMPL(ObjectIdentifier,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+
+ASN1_CODEC_IMPL(OBJECT_IDENTIFIER_NG,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+#endif
+ASN1_CODEC_IMPL(EXTERNAL,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(GeneralizedTime,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(UTCTime,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(REAL,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(ENUMERATED,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+// typedef asn1::types::any_type ANY;
+ASN1_CODEC_IMPL(UTF8String,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(NumericString,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(PrintableString,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(TeletexString,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(VideotexString,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(IA5String,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+ ctx.encode_string(t);
+},
+{
+ return ctx.decode_string(t);
+})
+ASN1_CODEC_IMPL(GraphicString,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(VisibleString,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(GeneralString,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(UniversalString,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(BMPString,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+
+
+
+//
+void
+codecBER::encode_header(streams::ber &ctx,const asn1::types::type &obj,const size_t len)
+{
+ asn1::tag t(obj.tag());
+ unsigned long pos = ctx.bytes();
+ unsigned char *b = ctx.buffer();
+ size_t i = 0;
+ long required = 1;
+
+ ASN1_BER_LOG_DEBUG("codecBER::encode_header code tag: cls=%d id=%d ",t.get_class(),t.get_id());
+ // Encode Tag, check the tag value ....
+ b[pos] = ((t.get_class() & 0x03)<<6 )| ( (t.get_id() < 31) ? t.get_id() : 0x1F);
+ if ( ! obj.primitive() )
+ b[pos] |= 0x20;
+ long tgv = t.get_id();
+
+ if ( t.get_id() > 31 )
+ {
+ //required = (types::count_bits(tgv) + 6 ) / 7 ;
+ // Compute required size for id > 31
+ for ( required = 1, i = 7 ; i < sizeof(long) * 8 ; i+=7)
+ {
+ if (t.get_id() >> i )
+ {
+ required++;
+ } else
+ break;
+ }
+ // Encode id ...
+ unsigned char * end = b + required ;
+ for ( i-= 7, ++pos; &b[pos] < end; i-=7 , pos++)
+ {
+ b[pos] = 0x80 | (( tgv >> i) & 0x7F);
+ }
+ b[pos] = (( tgv >> i) & 0x7F);
+ required++;
+ }
+
+ // Get Length of underlying data objects length, and encode length.
+ size_t data_len = obj.get_data_length();
+ ASN1_BER_LOG_DEBUG("codecBER::encode_header data_length = %ld len=%ld",data_len,len);
+ if (data_len < 128)
+ { // Don't know how to do this for now
+ b[++pos] = data_len;
+ ctx.nb_bits(8 + ((required)<<3));
+ } else
+ {
+ int count = (types::count_bits(data_len +1)+7)/8;
+ b[++pos] = count | 0x80;
+ while (count-- > 0)
+ {
+ b[++pos] = (len >> (count+8));
+ }
+ }
+}
+//
+void
+codecBER::encode_tag(streams::ber &ctx,const asn1::tag &t,const size_t data_len)
+{
+ unsigned long pos = ctx.bytes();
+ unsigned char *b = ctx.buffer();
+ size_t i = 0;
+ long required = 1;
+
+ ASN1_BER_LOG_DEBUG("ber::encode_tag code tag: cls=%d id=%d ",t.get_class(),t.get_id());
+ // Encode Tag, check the tag value ....
+ b[pos] = ((t.get_class() & 0x03)<<6 )| ( (t.get_id() < 31) ? t.get_id() : 0x1F);
+ if ( t.get_constructed() )
+ b[pos] |= 0x20;
+ long tgv = t.get_id();
+
+ if ( t.get_id() > 31 )
+ {
+ //required = (types::count_bits(tgv) + 6 ) / 7 ;
+ // Compute required size for id > 31
+ for ( required = 1, i = 7 ; i < sizeof(long) * 8 ; i+=7)
+ {
+ if (t.get_id() >> i )
+ {
+ required++;
+ } else
+ break;
+ }
+ // Encode id ...
+ unsigned char * end = b + required ;
+ for ( i-= 7, ++pos; &b[pos] < end; i-=7 , pos++)
+ {
+ b[pos] = 0x80 | (( tgv >> i) & 0x7F);
+ }
+ b[pos] = (( tgv >> i) & 0x7F);
+ required++;
+ }
+
+ // Get Length of underlying data objects length, and encode length.
+ ASN1_BER_LOG_DEBUG("ber::encode_header data_length = %ld ",data_len);
+ if (data_len < 128)
+ { // Don't know how to do this for now
+ b[++pos] = data_len;
+ ctx.nb_bits(8 + ((required)<<3));
+ } else
+ {
+ int count = (types::count_bits(data_len +1)+7)/8;
+ b[++pos] = count | 0x80;
+ while (count-- > 0)
+ {
+ b[++pos] = (data_len >> (count+8));
+ }
+ }
+}
+
+
+
+
+namespace streams {
+
+
+
+ber::ber(int sz) : asn1::context(sz)
+{
+ ASN1_BER_LOG_DEBUG("ber::ber %d ",sz);
+}
+
+ber::ber(const ber &_codec) : asn1::context()
+{
+ ASN1_BER_LOG_DEBUG("ber::ber(const ber &_codec ) ");
+}
+
+long ber::decode_length(unsigned char *buf, long *readed)
+{
+ long result = 0;
+ long nb_octet = *buf & 0x7f;
+
+ *readed = 1;
+ if ((*buf & 0x80) && (*buf & 0x7F)) {
+ // Long form number ...
+ *readed = (*buf & 0x7F) + 1;
+ buf++;
+ while (nb_octet-- ) {
+ result = (result<<8) | (*buf);
+ buf++;
+ }
+ ASN1_BER_LOG_DEBUG("asn1::codec::ber::length long form value=%ld readed=%ld",result,*readed);
+ return result;
+ } else if (!(*buf & 0x80) && (*buf & 0x7F)){
+ result = *buf & 0x7F;
+ // Short one byte
+ *readed = 1;
+ ASN1_BER_LOG_DEBUG("ans1::codec::ber::length short form result=%ld ",result);
+ return result;
+ } else if (*buf == 0) {
+ *readed = 1;
+ ASN1_BER_LOG_DEBUG("ber::length: 0 ");
+ return 0;
+ }else {
+ // Indefinit form
+ std::cout<<"ber::length indefinit form not yet supported TO BE CODED"<<std::endl;
+ }
+ return 0;
+}
+
+void
+ber::encode_byte(unsigned char c)
+{
+ unsigned long pos = bytes();
+ unsigned char *b = buffer();
+ nb_bits(8);
+ b[pos] = c;
+}
+
+unsigned char
+ber::decode_byte()
+{
+ unsigned long pos = bytes();
+ nb_bits(8);
+ return buffer()[pos] ;
+}
+
+
+// Null
+// 5
+void ber::encode_null(const asn1::Null &b)
+{
+ int len = 0;
+ ASN1_BER_LOG_DEBUG("ber::encode Null tag=%d ",b.tag().byte());
+ encode_header(b,len);
+}
+
+int ber::decode_null(asn1::Null &b)
+{
+ int len = 0;
+ ASN1_BER_LOG_DEBUG("ber::decode Null ");
+ if (decode_header(b.tag(),len)) {
+ return asn1::ok;
+ } else
+ return asn1::unknown;
+}
+
+
+// Bool
+//
+void ber::encode_boolean(const asn1::BOOLEAN &b)
+{
+ int len = 1;
+ ASN1_BER_LOG_DEBUG("ber::encode boolean tag=%d",b.tag().byte());
+ encode_header(b,len);
+ encode_byte((b == true)?0xFF:0x00);
+}
+
+int ber::decode_boolean(asn1::BOOLEAN &b)
+{
+ int len = 0;
+ ASN1_BER_LOG_DEBUG("ber::decode boolean tag=%d",b.tag().byte());
+ if (decode_header(b.tag(),len))
+ {
+ unsigned long pos = bytes();
+ unsigned char *bu = buffer();
+ nb_bits(1<<3);
+ b.get_value() = bu[pos];
+ return asn1::ok;
+ } else
+ return asn1::unknown;
+}
+
+
+/**
+ * Integer
+ * \brief this function needs to be reviewed in one way or another.
+ * I just wont use rtti to guess the caller.
+ */
+void ber::encode_integer(const asn1::types::type &b)
+{
+ int len = 0;
+ long long integer = 0;
+ if (const INTEGER *i = dynamic_cast< const INTEGER *>(&b))
+ {
+ integer = i->get_sys_value();
+ } else if (const UInt64 *i = dynamic_cast< const UInt64 *>(&b))
+ {
+ integer = i->get_sys_value();
+ } else if (const ENUMERATED *i = dynamic_cast< const ENUMERATED *>(&b))
+ {
+ integer = i->get_sys_value();
+ }
+ int intsize = 4;
+ long mask = 0x1FF <<23; // Shift 8 *3 - 1 ? 0xFF800000
+
+ while ( ( ((integer & mask) == 0) || ((integer & mask) == mask))
+ && intsize > 1) {
+ intsize--;
+ integer <<=8;
+ }
+ ASN1_BER_LOG_DEBUG("ber::encode integer tag.byte()=%d value=%lld intsize=%d decale =%d"
+ ,b.tag().byte()
+ ,(long long)integer
+ ,(int)intsize
+ ,(intsize<<3));
+
+ encode_header(b,intsize);
+
+ unsigned long pos = bytes();
+ unsigned char *bu = buffer();
+
+ nb_bits(intsize<<3);
+
+
+ if ((integer & 0x7F000000)) {
+
+ }
+ while ( (intsize--) > 0)
+ {
+ bu[pos++] = ( (integer & 0xFF000000)>>24 );
+ integer<<=8;
+ }
+}
+
+/**
+ * Decode Integer
+ */
+int ber::decode_integer(asn1::INTEGER &t)
+{
+ int len = 0;
+ int result = 0;
+
+ ASN1_BER_LOG_DEBUG("ber::decode integer tag=%d",t.tag().byte());
+
+ if ( ! decode_header(t.tag(),len) || ( len == 0 ))
+ {
+ ASN1_BER_LOG_DEBUG("ber::decode_integer WRONG TAG expected=%d",t.tag().byte());
+ return asn1::wrong_tag;
+ }
+ unsigned long pos = bytes();
+ unsigned char *bu = buffer();
+ nb_bits(len<<3);
+ // I don't know yet how to handle this case
+ if (len> 16 )
+ {
+ ASN1_BER_LOG_ERROR("ber::decode_integer too long len = %d",len);
+ return asn1::wrong_length;
+ }
+
+ ASN1_BER_LOG_DEBUG("ber::decode_integer start result=%d check_tag=%d len =%d",(int)result,check_tag(),len);
+ result = (char) bu[pos]; /* Keep sign */
+ while (--len)
+ {
+ result = (result<<8) | ((unsigned char)bu[++pos] & 0xFF);
+ }
+ ASN1_BER_LOG_DEBUG("ber::decode_integer end result=%d",(int)result);
+ t.get_value() = result;
+ return asn1::ok;
+}
+
+int ber::decode_integer(asn1::UInt64 &t)
+{
+ int len = 0;
+ if (! decode_header(t.tag(),len) || (len == 0) )
+ return asn1::wrong_tag;
+ unsigned long acc = decode_byte(); /* No signess */
+ while (--len > 0)
+ {
+ acc = (acc<< 8) | decode_byte();
+ }
+ t = acc;
+ return asn1::ok;
+}
+
+
+// Bit String
+//
+void ber::encode_bitstring(const asn1::BIT_STRING &t)
+{
+ int len = t.size() + 1;
+ ASN1_BER_LOG_DEBUG("ber::encode bit string len=%d blen=%lu"
+ ,len
+ ,t.get_nb_bits()
+ );
+ encode_header(t,len);
+ unsigned long pos = bytes();
+ unsigned char *bu = buffer();
+
+ if (t.size() > 0)
+ {
+ unsigned char last = t[t.size()-1];
+ unsigned char padding = 0;
+ unsigned char mask = 1;
+
+ padding = t.get_nb_bits() % 8;
+
+ if (padding )
+ {
+ padding = 8 - padding;
+ } else
+ { // Cannot be 0 there is a problem here
+ while (last)
+ {
+ padding++; last>>=1;
+ mask<<=1; mask |=1;
+ }
+ padding = 8 - padding;
+ }
+ bu[pos++] = padding;
+ len = t.size() - 1;
+
+ nb_bits(((1+ t.size()) <<3));
+ while (len > 0)
+ {
+ bu[pos++] = t[len]<<padding | (t[len-1] & ~mask)>>(8-padding);
+ len--;
+ }
+ bu[pos] = t[0]<<padding;
+ } else
+ {
+ bu[pos++] = 0;
+ nb_bits(8);
+ }
+}
+
+int ber::decode_bitstring(asn1::BIT_STRING &t)
+{
+ ASN1_BER_LOG_DEBUG("ber::decode bit string tag=%d ",t.tag().byte());
+ int len = 0;
+ long nb=0;
+ if ( !decode_header(t.tag(),len) ) {
+ return asn1::wrong_tag;
+ }
+
+ unsigned long pos = bytes();
+ unsigned char *bu = buffer();
+ nb_bits((len<<3));
+ unsigned char padding = bu[pos++]; // add padding
+ std::cerr<<"decode_bitstrring padding "<<(int)padding;
+ std::cerr<<" len="<<len<<std::endl;
+ len --; //remove padding
+ t.set_nb_bits(len*8-padding);
+ if (padding)
+ {
+ nb++;
+ }
+ while ( (len ) > 1)
+ {
+ if (nb)
+ {
+ t[len-2] = (bu[pos]<<(8 - padding)) | (bu[pos + 1]>>padding);
+ } else
+ t[len-1] = bu[pos];
+ len--;pos++;
+ }
+ t[0] |= bu[pos]>>padding ;
+
+ return asn1::ok;
+}
+
+
+// Octet string
+//
+void ber::encode_octetstring(const asn1::OCTET_STRING &b)
+{
+ int len = 0;
+ ASN1_BER_LOG_DEBUG("ber::encode octet string tag=%d",b.tag().byte());
+ len = (b.get_value()).size(); // Length
+
+ encode_header(b,len);
+
+ unsigned long pos = bytes();
+ unsigned char *buf = buffer();
+
+ for ( int i = 0; i< len ; i++)
+ buf[pos++] =(b.get_value()).c_str()[i];
+ nb_bits(len*8);
+}
+
+int ber::decode_octetstring(asn1::OCTET_STRING &b_)
+{
+ int len = 0;
+ ASN1_BER_LOG_DEBUG("ber::decode octet string ");
+ if (decode_header(b_.tag(),len))
+ {
+ unsigned long pos = bytes();
+ unsigned char *b = buffer();
+ std::string result;
+ result.assign((const char *)&b[pos],len);
+
+ b_.get_value()= result;
+ nb_bits((len<<3));
+ } else {
+ return asn1::wrong_tag;
+ }
+ return asn1::ok;
+}
+
+void ber::encode_string(const asn1::types::strtype &b)
+{
+ int len = 0;
+ ASN1_BER_LOG_DEBUG("ber::encode string tag=%d",b.tag().get_id());
+ //const asn1::prim::types::String &s = dynamic_cast< const asn1::prim::types::String &>(b);
+ const asn1::prim::types::String &s = b.get_prim();
+ len = s.get_value().size(); // Length
+
+ encode_header(b,len);
+
+ unsigned long pos = bytes();
+ unsigned char *buf = buffer();
+
+ for ( int i = 0; i< len ; i++)
+ buf[pos++] = s.get_value().c_str()[i];
+ nb_bits(len*8);
+}
+
+
+int ber::decode_string(asn1::types::strtype &b)
+{
+ int len = 0;
+ ASN1_BER_LOG_DEBUG("ber::decode string tag_id=%d",b.tag().get_id());
+ //asn1::prim::types::String &s = dynamic_cast<asn1::prim::types::String &>(b);
+ asn1::prim::types::String &s = b.get_prim();
+
+ if (decode_header(b.type::tag(),len))
+ {
+ unsigned long pos = bytes();
+ unsigned char *bu = buffer();
+ std::string result;
+ result.assign((const char *)&bu[pos],len);
+ s = asn1::prim::types::String(result);
+ nb_bits((len<<3));
+ } else {
+ return asn1::wrong_tag;
+ }
+ return asn1::ok;
+}
+
+// Any
+//
+void ber::encode_any(const asn1::types::any_type &b)
+{
+ ASN1_BER_LOG_DEBUG("ber::encode_any ");
+}
+
+int ber::decode_any(asn1::types::any_type &b)
+{
+ asn1::tag t(0,0);
+ int len = 0;
+ ASN1_BER_LOG_DEBUG("ber::decode_any ");
+ if (decode_tag(t,len))
+ {
+ nb_bits((len<<3));
+ }
+ std::cerr<<"ber::decode_any len="<<len<<std::endl;
+ return asn1::ok;
+}
+
+
+// Choice
+//
+void ber::encode_choice(asn1::types::choice_type &b)
+{
+ int len = 0;
+ unsigned long pos = bytes();
+ unsigned char *bu = buffer();
+ ASN1_BER_LOG_DEBUG("ber::encode_choice tag.byte=%d get_tag=%ld"
+ ,b.tag().byte()
+ ,b.tag().get_tag());
+ // Is This correct ?
+ bu[pos] = b.tag().byte();
+ b.encode_ber(*this);
+}
+
+int ber::decode_choice(asn1::types::choice_type &b)
+{
+ ASN1_BER_LOG_DEBUG("ber::decode choice b.decode_ber");
+ return b.decode_ber(*this);
+}
+
+
+// Sequence
+void ber::encode_sequence_preamble(asn1::types::sequence_type &b)
+{
+ int len = 0;
+ unsigned long pos = bytes();
+ unsigned char *bu = buffer();
+ ASN1_BER_LOG_DEBUG("ber::encode sequence preamble tag=%d",b.tag().byte());
+ b.encode_preamble_ber(*this);
+}
+void ber::encode_sequence_epilogue(asn1::types::sequence_type &b)
+{
+ b.encode_epilogue_ber(*this);
+}
+
+void ber::encode_sequence_preamble(const asn1::types::sequence_type &b)
+{
+ int len = 0;
+ ASN1_BER_LOG_DEBUG("ber::encode sequence preamble tag=%d const ",b.tag().byte());
+ //const_cast<asn1::types::sequence_type &>(b).encode_preamble_ber(*this);
+ encode_header(b,len);
+}
+void ber::encode_sequence_epilogue(const asn1::types::sequence_type &b)
+{
+ ASN1_BER_LOG_DEBUG("ber::encode_sequence_epilogue tag=%d const ",b.tag().byte());
+ //b.encode_epilogue_ber(*this);
+}
+
+
+
+int ber::decode_sequence_preamble(asn1::types::sequence_type &b)
+{
+ int len;
+ std::string n = typeid(b).name();
+ ASN1_BER_LOG_DEBUG("ber::decode sequence preamble %s",n.c_str());
+ if (decode_header(b.tag(),len))
+ {
+ return b.decode_preamble_ber(*this);
+ } else
+ {
+ return asn1::unknown;
+ }
+}
+
+int ber::decode_sequence_epilogue(asn1::types::sequence_type &b)
+{
+ return b.decode_epilogue_ber(*this);
+}
+
+
+//
+void ber::encode_header(const asn1::types::type &obj, int &len)
+{
+ asn1::tag t = obj.tag();
+ unsigned long pos = bytes();
+ unsigned char *b = buffer();
+ size_t i = 0;
+ long required = 1;
+
+ ASN1_BER_LOG_DEBUG("ber::encode_header code tag: cls=%d id=%d ",t.get_class(),t.get_id());
+ // Encode Tag, check the tag value ....
+ b[pos] = ((t.get_class() & 0x03)<<6 )| ( (t.get_id() < 31) ? t.get_id() : 0x1F);
+ if ( ! obj.primitive() )
+ b[pos] |= 0x20;
+ long tgv = t.get_id();
+
+ if ( t.get_id() > 31 )
+ {
+ //required = (types::count_bits(tgv) + 6 ) / 7 ;
+ // Compute required size for id > 31
+ for ( required = 1, i = 7 ; i < sizeof(long) * 8 ; i+=7)
+ {
+ if (t.get_id() >> i )
+ {
+ required++;
+ } else
+ break;
+ }
+ // Encode id ...
+ unsigned char * end = b + required ;
+ for ( i-= 7, ++pos; &b[pos] < end; i-=7 , pos++)
+ {
+ b[pos] = 0x80 | (( tgv >> i) & 0x7F);
+ }
+ b[pos] = (( tgv >> i) & 0x7F);
+ required++;
+ }
+
+ // Get Length of underlying data objects length, and encode length.
+ size_t data_len = obj.get_data_length();
+ ASN1_BER_LOG_DEBUG("ber::encode_header data_length = %ld len=%d",data_len,len);
+ if (data_len < 128)
+ { // Don't know how to do this for now
+ b[++pos] = data_len;
+ nb_bits(8 + ((required)<<3));
+ } else
+ {
+ int count = (types::count_bits(data_len +1)+7)/8;
+ b[++pos] = count | 0x80;
+ while (count-- > 0)
+ {
+ b[++pos] = (len >> (count+8));
+ }
+ }
+}
+//
+void ber::encode_tag(const asn1::tag &t,const int &len)
+{
+ unsigned long pos = bytes();
+ unsigned char *b = buffer();
+ size_t i = 0;
+ long required = 1;
+
+ ASN1_BER_LOG_DEBUG("ber::encode_tag code tag: cls=%d id=%d ",t.get_class(),t.get_id());
+ // Encode Tag, check the tag value ....
+ b[pos] = ((t.get_class() & 0x03)<<6 )| ( (t.get_id() < 31) ? t.get_id() : 0x1F);
+ if ( t.get_constructed() )
+ b[pos] |= 0x20;
+ long tgv = t.get_id();
+
+ if ( t.get_id() > 31 )
+ {
+ //required = (types::count_bits(tgv) + 6 ) / 7 ;
+ // Compute required size for id > 31
+ for ( required = 1, i = 7 ; i < sizeof(long) * 8 ; i+=7)
+ {
+ if (t.get_id() >> i )
+ {
+ required++;
+ } else
+ break;
+ }
+ // Encode id ...
+ unsigned char * end = b + required ;
+ for ( i-= 7, ++pos; &b[pos] < end; i-=7 , pos++)
+ {
+ b[pos] = 0x80 | (( tgv >> i) & 0x7F);
+ }
+ b[pos] = (( tgv >> i) & 0x7F);
+ required++;
+ }
+
+ // Get Length of underlying data objects length, and encode length.
+ size_t data_len = len;
+ ASN1_BER_LOG_DEBUG("ber::encode_header data_length = %ld len=%d",data_len,len);
+ if (data_len < 128)
+ { // Don't know how to do this for now
+ b[++pos] = data_len;
+ nb_bits(8 + ((required)<<3));
+ } else
+ {
+ int count = (types::count_bits(data_len +1)+7)/8;
+ b[++pos] = count | 0x80;
+ while (count-- > 0)
+ {
+ b[++pos] = (len >> (count+8));
+ }
+ }
+}
+
+
+/**
+ *
+ */
+int ber::decode_tag(asn1::tag &t)
+{
+ int len;
+ return decode_header(t,len);
+}
+/**
+ * @brief Decodes tag and length without any check
+ */
+bool ber::decode_tag(asn1::tag &tag,int &len)
+{
+ long nb = 0;
+ long nbt = 1;
+ long tval = 0;
+
+ unsigned long pos = bytes();
+ unsigned char *b = buffer();
+ ASN1_BER_LOG_DEBUG("ber::decode_tag tag : cls=%d id=%d pos=%ld have tag in stream=%d"
+ , tag.get_class()
+ , tag.get_id()
+ , pos
+ , b[pos]);
+ int tcls = (b[pos] >> 6);
+ tval = b[pos];
+ tag.byte(tval);
+ if ((tval &= 0x1F) != 0x1F)
+ {
+ len = decode_length(&b[pos+1],&nb);
+ nb_bits( (nb + 1)<<3);
+ ASN1_BER_LOG_DEBUG("ber::decode_tag sf tag : cls=%d id=%d tval=%ld nbt=%ld pos=%lu"
+ , tag.get_class()
+ , tag.get_id()
+ , tval,nbt,pos);
+ return true;
+ }
+ // Long Form... be sure not to read too far....
+ for (pos++, tval = 0; /* Stop Before end of buffer*/ nbt < 3
+ ;pos++ , nbt++)
+ {
+ if ( b[pos] & 0x80 )
+ {
+ tval = tval<<7 | (b[pos] & 0x7F);
+ } else
+ { // Last 7 bits
+ tval = tval<<7 | b[pos] ;
+ break;
+ }
+ }
+ ASN1_BER_LOG_DEBUG("ber::decode_tag lf tag : cls=%d id=%d tval=%ld nbt=%ld pos=%lu"
+ , tag.get_class()
+ , tag.get_id()
+ , tval,nbt,pos);
+ len = decode_length(&b[pos+1],&nb);
+ tag.byte(tval);
+ nb_bits( (nb + nbt + 1)<<3);
+ return true;
+}
+
+/**
+ * @brief Decode header
+ * @param tag
+ * @len TODO should be of type size_t len cannot be negatif
+ * @return return true if tag matches decoded tag false otherwise
+ * Buffer position changed to data position if function returns true.
+ */
+bool ber::decode_header(const asn1::tag &tag,int &len,bool check)
+{
+ long nb = 0;
+ long nbt = 1;
+ long tval = 0;
+ unsigned long pos = bytes();
+ unsigned char *b = buffer();
+ ASN1_BER_LOG_DEBUG("ber::decode_header tag : cls=%d id=%d pos=%ld expected=%d stream has=%d "
+ , tag.get_class()
+ , tag.get_id()
+ , pos
+ , tag.byte(),b[pos]);
+ int tcls = (b[pos] >> 6);
+ tval = b[pos];
+ if ((tval &= 0x1F) != 0x1F)
+ {
+ // Short From
+ if ( b[pos] != tag.byte() )
+ return false;
+
+ len = decode_length(&b[pos+1],&nb);
+
+ nb_bits( (nb + 1)<<3);
+ return true;
+ }
+ // Long Form... be sure not to read too far....
+ for (pos++, tval = 0; /* Stop Before end of buffer*/ nbt < 3
+ ;pos++ , nbt++)
+ {
+ if ( b[pos] & 0x80 )
+ {
+ tval = tval<<7 | (b[pos] & 0x7F);
+ } else
+ { // Last 7 bits
+ tval = tval<<7 | b[pos] ;
+ break;
+ }
+ }
+ ASN1_BER_LOG_DEBUG("ber::decode_header lf tag : cls=%d id=%d tval=%ld nbt=%ld pos=%lu"
+ , tag.get_class()
+ , tag.get_id()
+ , tval,nbt,pos);
+ if (tag.get_id() != tval)
+ return false;
+ len = decode_length(&b[pos+1],&nb);
+ nb_bits( (nb + nbt + 1)<<3);
+ return true;
+}
+
+
+
+
+
+/**
+ :vim et sw=2 ts=2:
+ */
+}
+}
--- /dev/null
+#ifndef CODEC_BER_H
+#define CODEC_BER_H
+#include <iostream>
+#if 0
+#if defined(__GNUC__) && defined(DEBUG) & not(defined(ASN1_BER_LOG_DEBUG))
+#define ASN1_BER_LOG_DEBUG(fmt,args...) do {\
+ fprintf(stderr,fmt,##args);\
+ fprintf(stderr," (asn1.y : %d)\n",__LINE__);\
+} while (0)
+#elseif not(defined(ASN1_BER_LOG_DEBUG))
+ static inline void ASN1_BER_LOG_DEBUG(const char *fmt,...) {(void)fmt;};
+#endif
+
+#else
+#include "rtasn1/asn1_debug.h"
+#endif
+namespace asn1 {
+class context;
+class codecBER;
+namespace streams {
+//#define DEBUG
+/**
+ *
+ */
+
+class ber : public asn1::context
+{
+ public:
+ ber( int sz = 512) ;
+ ber(unsigned char *b,size_t size)
+ : asn1::context(b,size) {};
+ ber(const ber &c) ;
+ ~ber() {}
+
+ virtual int decode_tag(asn1::tag &t) ;
+
+ // Null
+ // 5
+ virtual void encode_null(const asn1::Null &b) ;
+ virtual int decode_null(asn1::Null &b) ;
+
+ // Bool
+ //
+ virtual void encode_boolean(const asn1::BOOLEAN &b) ;
+ virtual int decode_boolean(asn1::BOOLEAN &b) ;
+
+ // Integer
+ //
+ virtual void encode_integer(const asn1::types::type &b) ;
+ virtual int decode_integer(asn1::INTEGER &b) ;
+ int decode_integer(asn1::UInt64 &b) ;
+
+ // Bit String
+ //
+ virtual void encode_bitstring(const asn1::BIT_STRING &b) ;
+ virtual int decode_bitstring(asn1::BIT_STRING &b) ;
+
+ // Octet string
+ //
+ virtual void encode_octetstring(const asn1::OCTET_STRING &b) ;
+ virtual int decode_octetstring(asn1::OCTET_STRING &b) ;
+
+ virtual void encode_string(const asn1::types::strtype &b) ;
+ virtual int decode_string(asn1::types::strtype &b) ;
+ // Choice
+ //
+ virtual void encode_choice(asn1::types::choice_type &b) ;
+ virtual int decode_choice(asn1::types::choice_type &b) ;
+
+ // Sequence
+ virtual void encode_sequence_preamble(asn1::types::sequence_type &b) ;
+ virtual void encode_sequence_epilogue(asn1::types::sequence_type &b) ;
+ void encode_sequence_preamble(const asn1::types::sequence_type &b) ;
+ void encode_sequence_epilogue(const asn1::types::sequence_type &b) ;
+ virtual int decode_sequence_preamble(asn1::types::sequence_type &b) ;
+ virtual int decode_sequence_epilogue(asn1::types::sequence_type &b) ;
+
+ // Any
+ //
+ virtual void encode_any(const asn1::types::any_type &b);
+ virtual int decode_any(asn1::types::any_type &b);
+ /**
+ * When reading ber, we need to be able to decode the length
+ */
+ long decode_length(unsigned char *buf, long *readed);
+ /**
+ * decode tag without cheking value
+ */
+ bool decode_tag( asn1::tag &t, int &len);
+
+ bool decode_header(const asn1::tag &tag,int &len,bool check_tag=true);
+
+ friend class asn1::codecBER;
+ protected:
+ /* deprecated */
+ void encode_header(const asn1::types::type &obj, int &len);
+ /* deprecated */
+ void encode_tag(const asn1::tag &obj,const int &len);
+ /* encode simple byte */
+ void encode_byte(unsigned char c);
+
+ unsigned char decode_byte();
+
+};
+
+// End namesape codecs
+}
+
+/**
+ * @brief This class is responsible for all BER encoding
+ * and decoding.
+ *
+ */
+ class codecBER : public codec
+ {
+ protected:
+ codecBER(const codecBER &c) {};
+ public:
+ codecBER() {}
+
+ template <class T>
+ void encode(streams::ber &ctx,const T &t) ;
+
+ /* New encoding .... deprecates the one in streams::ber*/
+ void encode_header(streams::ber &ctx, const asn1::types::type &obj, const size_t len);
+ /* New encoding that deprecates the one in ber class */
+ void encode_tag(streams::ber &ctx,const asn1::tag &obj,const size_t len);
+#if 0
+ /* Will this work ? I don't think it will. Need to think about it
+ * a bit more
+ */
+ size_t get_length(const asn1::types::type &obj) const;
+
+ template <class T>
+ size_t get_data_length(const T &t) const
+ { return 0; };
+#endif
+ template <class T>
+ int decode(streams::ber &ctx, T &t) ;
+ /* Special case for Sequence OF */
+ template <class T>
+ void encode(streams::ber &ctx,const asn1::Seq<T> &t)
+ {
+ typename asn1::Seq<T>::const_iterator mit = t.begin();
+ int dlen = t.get_data_length();
+ ctx.encode_header(t.tag(),dlen);
+ for (; mit != t.end() ; ++mit)
+ {
+ if (mit != t.begin())
+ encode(ctx,(*mit));
+ }
+ }
+ template <class T>
+ int decode(streams::ber &ctx,asn1::Seq<T> &t)
+ {
+ T element;
+ int ret;
+ int len = 0;
+ std::cout<<"TODO decode Seq<T>"<<std::endl;
+ if ( ! ctx.decode_header(t.tag(),len))
+ {
+ std::cerr<<"decode sequenceof failed wrong tag"<<std::endl;
+ return asn1::wrong_type;
+ }
+ do {
+ if ((ret = decode(ctx,element)) == asn1::ok)
+ {
+ t.push_back(element);
+// For debug purpose
+// std::cout<<"decode added 1 element "<<typeid(element).name()<<"Seq <T> size ="<<t.size()<<std::endl;
+ } else
+ {
+ break;
+ }
+ } while (ret == asn1::ok);
+ return asn1::ok;
+ }
+
+
+ /* handle optional types */
+ template <class T>
+ void encode(streams::ber &ctx,const asn1::intrusive_ptr<T> &t)
+ {
+ int len;
+ /* If it's a choice, several options are available ! do I create
+ * the object to check if it works or not ?
+ */
+ std::cout<<"codecBER::encode optional ! how do I do this ?"<<std::endl;
+ if (!t.is_nul())
+ {
+ encode(ctx,t.get());
+ }
+ }
+ template <class T>
+ int decode(streams::ber &ctx,asn1::intrusive_ptr<T> &t)
+ {
+ int len;
+ /* If it's a choice, several options are available ! do I create
+ * the object to check if it works or not ?
+ */
+ std::cout<<"codecBER::decode optional ! how do I do this ?"<<std::endl;
+ if (ctx.decode_header(t.tag(),len))
+ {
+ return decode(ctx,t.get());
+ } else
+ return asn1::wrong_tag;
+ }
+ // Need to provide implementation
+ // For base Types, INTEGER, BOOLEAN...
+#define ASN1_TYPE_CLS(PrimType,TagType,TagNum,Asn1Type) \
+ void encode_ber(streams::ber &ctx, const asn1::Asn1Type &t); \
+ int \
+ decode_ber(streams::ber &ctx, asn1::Asn1Type &t);
+
+ASN1_TYPE_CLS(asn1::prim::types::ObjectIdentifier,asn1::types::UNIVERSAL,6,ObjectIdentifier)
+
+#include "rtasn1/asn1_types.inc"
+
+
+ };
+
+/*
+ * encode / decode specialization declaration
+ */
+#define ASN1_TYPE_CLS(PrimType,TagType,TagNum,Asn1Type) \
+ template <> \
+ void codecBER::encode(streams::ber &ctx, const asn1::Asn1Type &t) \
+ ; \
+ template <> \
+ int \
+ codecBER::decode(streams::ber &ctx, asn1::Asn1Type &t) \
+ ;
+#include "rtasn1/asn1_types.inc"
+
+
+// End namespace ans1
+}
+
+#endif
--- /dev/null
+#include <iostream>
+#include <string>
+#include <typeinfo>
+#include <assert.h>
+#include "rtasn1/asn1.h"
+#include "rtasn1/asn1_codec.h"
+#include "rtasn1/asn1_context.h"
+#include "rtasn1/cjson/cJSON.h"
+
+#include "rtasn1/asn1_codec_jer.h"
+
+
+/* a lookup table which lets us quickly determine three things:
+ * VEC - valid escaped control char
+ * note. the solidus '/' may be escaped or not.
+ * IJC - invalid json char
+ * VHC - valid hex char
+ * NFP - needs further processing (from a string scanning perspective)
+ * NUC - needs utf8 checking when enabled (from a string scanning perspective)
+ */
+#define VEC 0x01
+#define IJC 0x02
+#define VHC 0x04
+#define NFP 0x08
+#define NUC 0x10
+
+static const char charLookupTable[256] =
+{
+ /*00*/ IJC , IJC , IJC , IJC , IJC , IJC , IJC , IJC ,
+ /*08*/ IJC , IJC , IJC , IJC , IJC , IJC , IJC , IJC ,
+ /*10*/ IJC , IJC , IJC , IJC , IJC , IJC , IJC , IJC ,
+ /*18*/ IJC , IJC , IJC , IJC , IJC , IJC , IJC , IJC ,
+
+ /*20*/ 0 , 0 , NFP|VEC|IJC, 0 , 0 , 0 , 0 , 0 ,
+ /*28*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , VEC ,
+ /*30*/ VHC , VHC , VHC , VHC , VHC , VHC , VHC , VHC ,
+ /*38*/ VHC , VHC , 0 , 0 , 0 , 0 , 0 , 0 ,
+
+ /*40*/ 0 , VHC , VHC , VHC , VHC , VHC , VHC , 0 ,
+ /*48*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+ /*50*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+ /*58*/ 0 , 0 , 0 , 0 , NFP|VEC|IJC, 0 , 0 , 0 ,
+
+ /*60*/ 0 , VHC , VEC|VHC, VHC , VHC , VHC , VEC|VHC, 0 ,
+ /*68*/ 0 , 0 , 0 , 0 , 0 , 0 , VEC , 0 ,
+ /*70*/ 0 , 0 , VEC , 0 , VEC , 0 , 0 , 0 ,
+ /*78*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+
+ NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
+ NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
+ NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
+ NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
+
+ NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
+ NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
+ NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
+ NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
+
+ NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
+ NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
+ NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
+ NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
+
+ NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
+ NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
+ NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
+ NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC
+};
+
+
+
+/*
+vim:et:sw=2:ts=2
+ */
+namespace asn1 {
+
+#define ASN1_TYPE_CLS(PrimType,TagType,TagNum,Asn1Type) \
+ template <> \
+ void codecJER::encode(streams::jer &ctx, const asn1::Asn1Type &t) \
+ { \
+ encode_jer(ctx,t); \
+ } \
+ template <> \
+ int \
+ codecJER::decode(streams::jer &ctx, asn1::Asn1Type &t) \
+ { \
+ return decode_jer(ctx,t); \
+ }
+#if 0
+/* comments for debuging purpose. */
+ std::cerr<<"codecJER::"<<__FUNCTION__<<" good "; \
+ std::cerr<<#Asn1Type<<std::endl; \
+ std::cerr<<"codecJER::"<<__FUNCTION__<<" good "; \
+ std::cerr<<#Asn1Type<<std::endl; \
+
+#endif
+#include "rtasn1/asn1_types.inc"
+
+template <>
+void codecJER::encode(streams::jer &ctx, const asn1::ObjectIdentifier &t)
+{
+ std::cerr<<"codecJER::"<<__FUNCTION__<<" good ";
+ std::cerr<<"asn1::ObjectIdentifier "<<std::endl;
+ //encode_jer(ctx,t);
+}
+template <>
+int
+codecJER::decode(streams::jer &ctx, asn1::ObjectIdentifier &t)
+{
+ std::cerr<<"codecJER::"<<__FUNCTION__<<" good ";
+ std::cerr<<"asn1::ObjectIdentifier"<<std::endl;
+ return asn1::ok;
+ //
+ //return decode_jer(ctx,t);
+}
+
+
+
+#define ASN1_CODEC_IMPL(Type,Encode,Decode) \
+void codecJER::encode_jer(streams::jer &ctx,const asn1::Type &t) \
+Encode \
+int codecJER::decode_jer(streams::jer &ctx,asn1::Type &t) \
+Decode
+
+ASN1_CODEC_IMPL(BOOLEAN,
+{
+ ctx.encode_boolean(t);
+},
+{
+ return ctx.decode_boolean(t);
+})
+ASN1_CODEC_IMPL(INTEGER,
+{
+ ctx.encode_integer(t);
+},
+{
+ return ctx.decode_integer(t);
+})
+ASN1_CODEC_IMPL(Int8,
+{
+ std::cout<<__FUNCTION__<<" Int8 TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(Int16,
+{
+ std::cout<<__FUNCTION__<<" Int16 TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(Int32,
+{
+ std::cout<<__FUNCTION__<<" Int32 TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(Int64,
+{
+ std::cout<<__FUNCTION__<<" Int64 TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(UInt8,
+{
+ std::cout<<__FUNCTION__<<" UInt 8 TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(UInt16,
+{
+ std::cout<<__FUNCTION__<<" UInt 16 TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+//
+ASN1_CODEC_IMPL(UInt32,
+{
+ std::cout<<__FUNCTION__<<" UInt 32 TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+//
+ASN1_CODEC_IMPL(UInt64,
+{
+ std::cout<<__FUNCTION__<<" UInt64 TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(BIT_STRING,
+{
+ ctx.encode_bitstring(t);
+},
+{
+ return ctx.decode_bitstring(t);
+})
+ASN1_CODEC_IMPL(OCTET_STRING,
+{
+ ctx.encode_octetstring(t);
+},
+{
+ return ctx.decode_octetstring(t);
+})
+ASN1_CODEC_IMPL(STRING,
+{
+ std::cout<<__FUNCTION__<<" STRING TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(Null,
+{
+ std::cout<<__FUNCTION__<<" NUll TODO"<<std::endl;
+ ctx.encode_null(t);
+},
+{
+ return asn1::ok;
+})
+#if 0
+ASN1_CODEC_IMPL(OBJECT_IDENTIFIER,
+{
+ std::cout<<__FUNCTION__<<" oid TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+#else
+ASN1_CODEC_IMPL(OBJECT_IDENTIFIER_NG,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+#endif
+ASN1_CODEC_IMPL(EXTERNAL,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(GeneralizedTime,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(UTCTime,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(REAL,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(ENUMERATED,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ std::cout<<__FUNCTION__<<" NOT SURE IF I should ENTER HERE! TODO"<<std::endl;
+ return asn1::wrong_type;
+})
+// typedef asn1::types::any_type ANY;
+ASN1_CODEC_IMPL(UTF8String,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(NumericString,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(PrintableString,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(TeletexString,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(VideotexString,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(IA5String,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(GraphicString,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(VisibleString,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(GeneralString,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(UniversalString,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(BMPString,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+
+
+
+namespace streams {
+
+bool
+jer::get_token(const char *s)
+{
+ size_t _len;
+ unsigned char *_buf;
+ size_t _curOff = m_bufOff;
+
+ if (json_lex(m_bufOff,&_buf,_len) == jer_tok_string)
+ {
+ if ( ! strncmp(s,(const char *)_buf,_len))
+ {
+ return true ;
+ } else
+ {
+ m_bufOff = _curOff;
+ return false;
+ }
+ } else
+ {
+ m_bufOff = _curOff;
+ return false;
+ }
+}
+
+bool
+jer::get_token(jer::jer_token tok)
+{
+ size_t _len = 0;
+ unsigned char *_buf = NULL;
+ size_t _curOff = m_bufOff;
+ int res;
+
+ if ((res = json_lex(m_bufOff,&_buf,_len)) == tok)
+ {
+ return true ;
+ } else
+ {
+ std::string s((const char * )_buf,_len);
+ m_bufOff = _curOff;
+ return false;
+ }
+}
+
+bool
+jer::get_token(std::string &s)
+{
+ size_t _len;
+ unsigned char *_buf;
+ size_t _curOff = m_bufOff;
+ int res;
+
+ if ((res = json_lex(m_bufOff,&_buf,_len)) == jer_tok_string)
+ {
+ s.assign((const char * )_buf,_len);
+ return true ;
+ } else
+ {
+ std::string s((const char * )_buf,_len);
+ m_bufOff = _curOff;
+ return false;
+ }
+}
+
+
+void jer::put_string(const std::string &s)
+{
+ if (s.size() > (m_size - m_bufOff))
+ {
+ std::cerr<<"jer::put_string Failed\n"<<std::endl;
+ } else {
+ strncpy((char *)(m_buffer+m_bufOff),(char *)s.c_str(),s.size());
+ m_bufOff += s.size();
+ }
+}
+
+/**
+ * @brief copy the message into the buffer. We need
+ * to return an error or realocate the buffer in cas
+ * of missing space.
+ */
+void jer::put_char(const unsigned char *_s,size_t len)
+{
+ if ( (m_bufOff + len) < get_size())
+ {
+ strncpy((char *)(m_buffer+m_bufOff),(char *)_s,len);
+ m_bufOff+=len;
+ } else
+ {
+ std::cerr<<"jer::put_char out of space.";
+ }
+}
+
+/**
+ * @brief copy the message into the buffer. We need
+ * to return an error or realocate the buffer in cas
+ * of missing space.
+ */
+void jer::put_char(const char *_s,size_t len)
+{
+ if ( m_bufOff + len < get_size())
+ {
+ strncpy((char *)(m_buffer+m_bufOff),(char *)_s,len);
+ m_bufOff+=len;
+ } else
+ {
+ std::cerr<<"jer::put_char out of space.";
+ }
+}
+
+const char *
+jer::error_to_string(int i) const
+{
+ switch (i)
+ {
+ default: ;
+ };
+ return "unknown";
+}
+
+const char *
+jer::tok2str(int tok) const
+{
+ switch (tok)
+ {
+ default: ;
+ };
+ return "unknown";
+}
+
+
+jer::jer(int sz) : asn1::context(sz)
+ , m_lineOff(0)
+ , m_charOff(0)
+ , m_bufOff(0)
+{
+ ASN1_BER_LOG_DEBUG("jer::jer %d ",sz);
+}
+
+jer::jer(unsigned char *buf,int sz)
+: asn1::context(buf,sz)
+ , m_lineOff(0)
+ , m_charOff(0)
+ , m_bufOff(0)
+{
+ ASN1_BER_LOG_DEBUG("jer::jer %d ",sz);
+}
+
+
+jer::jer(const jer &_codec) : asn1::context()
+ , m_lineOff(_codec.m_lineOff)
+ , m_charOff(_codec.m_charOff)
+ , m_bufOff(_codec.m_bufOff)
+{
+ ASN1_BER_LOG_DEBUG("jer::jer(const ber &_codec ) ");
+}
+
+
+// Null
+// 5
+void jer::encode_null(const asn1::Null &b)
+{
+ int len = 0;
+ put_char("null",4);
+ ASN1_BER_LOG_DEBUG("jer::encode Null tag=%d ",b.tag().byte());
+}
+
+int jer::decode_null(asn1::Null &b)
+{
+ int len = 0;
+ ASN1_BER_LOG_DEBUG("jer::decode Null ");
+
+ return asn1::ok;
+}
+
+
+// Bool
+//
+void jer::encode_boolean(const asn1::BOOLEAN &b)
+{
+ int len = 1;
+ ASN1_BER_LOG_DEBUG("jer::encode boolean tag=%d",b.tag().byte());
+ if (b == true)
+ {
+ put_char("true",4);
+ } else
+ put_char("false",5);
+}
+
+int jer::decode_boolean(asn1::BOOLEAN &b)
+{
+ size_t _len = 0;
+ unsigned char *_buf = NULL;
+ size_t _curOff = m_bufOff;
+ ASN1_BER_LOG_DEBUG("jer::decode boolean tag=%d",b.tag().byte());
+
+ if (json_lex(m_bufOff,&_buf,_len) == jer_tok_bool)
+ {
+ if ( ( _len == 4 ) && ! strncmp("true",(const char *)_buf,_len))
+ {
+ b = true;
+ } else if ( ( _len == 5 ) && ! strncmp("false",(const char *)_buf,_len))
+ {
+ b = false;
+ }
+ } else
+ {
+ m_bufOff = _curOff;
+ return false;
+ }
+ return asn1::ok;
+}
+
+
+// Integer
+//
+void jer::encode_integer(const asn1::types::type &b)
+{
+ int len = 0; size_t base = 10;
+ long tmp = 0; size_t count = 0;
+ long t = 0; long res = 0;
+ long long integer = 0;
+
+ if (const asn1::prim::types::Integer *i = dynamic_cast< const asn1::prim::types::Integer *>(&b))
+ {
+ integer = i->get_value();
+ } else if (const asn1::prim::types::UInt64 *i = dynamic_cast< const asn1::prim::types::UInt64 *>(&b))
+ {
+ integer = i->get_value();
+ }
+
+ char *ptr = (char *)buffer(); ptr+=m_bufOff;
+ tmp = integer;
+
+ if (tmp == 0)
+ count++;
+
+ while ((unsigned long)tmp > 0 )
+ {
+ tmp = tmp/base; count++;
+ }
+
+ if (m_bufOff + count > get_size())
+ {
+ std::cout<<"Issue with jer::encode_integer buffer overflow"<<std::endl;
+ return ;
+ }
+
+ ptr += count;
+ *ptr = '\0';
+ do
+ {
+ res = integer - base * (t = integer / base);
+ if (res < 10)
+ {
+ * --ptr = '0' + (char)res;
+ } else if ( res >= 10 && (res < 16 ))
+ {
+ * --ptr = 'A' - 10 + (char)res;
+ }
+ } while ((integer = t ) != 0);
+ m_bufOff += count;
+ ASN1_BER_LOG_DEBUG("jer::encode integer tag=%d value=%ld "
+ , b.tag().byte()
+ ,(long)integer
+ );
+}
+
+/**
+ * Decode Integer
+ */
+int jer::decode_integer(asn1::INTEGER &t)
+{
+ size_t len = 0;
+ unsigned char *buf = NULL;
+ int result = 0;
+ ASN1_BER_LOG_DEBUG("jer::decode integer tag=%d",t.tag().byte());
+ switch( json_lex(m_bufOff,&buf,len))
+ {
+ case jer_tok_integer:
+ {
+ std::string b((char *)buf,len);
+ t = atol(b.c_str());
+ }
+ break;
+ default:
+ std::cout<<"jer::decode_integer error"<<std::endl;
+ return asn1::wrong_type;
+ }
+ return asn1::ok;
+}
+
+
+int
+jer::decode_integer(asn1::UInt64 &t)
+{
+ size_t len = 0;
+ unsigned char *buf = NULL;
+ int result = 0;
+ ASN1_BER_LOG_DEBUG("jer::decode unsigned integer tag=%d",t.tag().byte());
+ switch( json_lex(m_bufOff,&buf,len))
+ {
+ case jer_tok_integer:
+ {
+ std::string b((char *)buf,len);
+ t = strtoul(b.c_str(),NULL,10);
+ }
+ break;
+ default:
+ std::cout<<"jer::decode_integer error"<<std::endl;
+ return asn1::wrong_type;
+ }
+ return asn1::ok;
+}
+
+
+// Bit String
+//
+void jer::encode_bitstring(const asn1::BIT_STRING &t)
+{
+ int len = t.size() + 1;
+ ASN1_BER_LOG_DEBUG("jer::encode bit string len=%d ",len);
+}
+
+int jer::decode_bitstring(asn1::BIT_STRING &t)
+{
+ ASN1_BER_LOG_DEBUG("jer::decode bit string tag=%d ",t.tag().byte());
+
+ return asn1::ok;
+}
+
+
+static char gAlpha[]= {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
+// Octet string
+//
+void jer::encode_octetstring(const asn1::OCTET_STRING &b)
+{
+ size_t len = (b.get_value()).size(); // Length
+ const char *ptr = (b.get_value()).c_str();
+ put_char("\"",1);
+ char *buf = (char *)buffer() + m_bufOff;
+ m_bufOff+=len*2;
+ //std::cerr<<"encode_octet_string:"<<len<<" "<<m_bufOff<<" "<<ptr<<std::endl;
+ ASN1_BER_LOG_DEBUG("jer::encode octet string tag=%d",b.tag().byte());
+ do
+ {
+ *buf++ = gAlpha[( (*ptr)>>4 ) & 0x0F];
+ *buf++ = gAlpha[( *ptr++ ) & 0x0F];
+ } while (--len);
+ put_char("\"",1);
+}
+
+int jer::decode_octetstring(asn1::OCTET_STRING &b_)
+{
+ int len = 0;
+ std::string field;
+ ASN1_BER_LOG_DEBUG("jer::decode octet string TODO ");
+ if (! get_token(field))
+ {
+ ASN1_BER_LOG_ERROR("jer::decode octerstring tag_id=%d no field",b_.tag().get_id());
+ return asn1::wrong_type;
+ }
+ std::string &result = b_.get_value().get_value();
+ result.resize(0,'\0');
+ for (std::string::iterator it = field.begin() ; it!= field.end()
+ ; ++it)
+ {
+ char c1 = *it; ++it;
+ char c2 = *it;
+ char r = ((c1 - '0')<<4 & 0xF0 ) | ((c2 - '0') & 0x0F );
+ result.push_back(r);
+
+ }
+ return asn1::ok;
+}
+
+void jer::encode_string(const asn1::types::type &b)
+{
+ int len = 0;
+ const asn1::prim::types::String &s = dynamic_cast< const asn1::prim::types::String &>(b);
+ len = s.get_value().size(); // Length
+ ASN1_BER_LOG_DEBUG( "jer::encode string tag=%d len=%d"
+ , b.tag().get_id()
+ , len
+ );
+ put_field(s.get_value().c_str(),len);
+}
+
+
+int jer::decode_string(asn1::types::type &b)
+{
+ int len = 0;
+ ASN1_BER_LOG_DEBUG("jer::decode string tag_id=%d",b.tag().get_id());
+ asn1::prim::types::String &s = dynamic_cast<asn1::prim::types::String &>(b);
+
+ return asn1::ok;
+}
+
+
+// Choice
+//
+void jer::encode_choice(asn1::types::choice_type &b)
+{
+ int len = 0;
+ ASN1_BER_LOG_DEBUG("jer::encode choice ");
+}
+
+int jer::decode_choice(asn1::types::choice_type &b)
+{
+ ASN1_BER_LOG_DEBUG("jer::decode choice ");
+ return asn1::ok;
+}
+
+
+// Sequence
+void jer::encode_sequence_preamble(asn1::types::sequence_type &b)
+{
+ int len = 0;
+ unsigned long pos = bytes();
+ unsigned char *bu = buffer();
+ ASN1_BER_LOG_DEBUG("jer::encode sequence preamble tag=%d",b.tag().byte());
+}
+void jer::encode_sequence_epilogue(asn1::types::sequence_type &b)
+{
+ ASN1_BER_LOG_DEBUG("jer::encode sequence epilogue tag=%d",b.tag().byte());
+}
+
+
+int jer::decode_sequence_preamble(asn1::types::sequence_type &b)
+{
+ if ( get_token(jer_tok_left_bracket))
+ {
+ return asn1::ok;
+ } else
+ return asn1::wrong_type;
+}
+
+int jer::decode_sequence_epilogue(asn1::types::sequence_type &b)
+{
+ if ( get_token(jer_tok_right_bracket))
+ {
+ return asn1::ok;
+ } else
+ return asn1::wrong_type;
+}
+
+
+//
+void jer::encode_header(const asn1::types::type &obj, int &len)
+{
+ asn1::tag t = obj.tag();
+ unsigned long pos = bytes();
+ unsigned char *b = buffer();
+
+ ASN1_BER_LOG_DEBUG("jer::encode_header code tag: cls=%d id=%d ",t.get_class(),t.get_id());
+ // Encode Tag, check the tag value ....
+}
+
+int jer::decode_tag(asn1::tag &t)
+{
+ int len;
+ return decode_header(t,len);
+}
+/**
+ *
+ */
+bool jer::decode_tag(asn1::tag &tag,int &len)
+{
+ return true;
+}
+
+bool jer::decode_header(const asn1::tag &tag,int &len)
+{
+ return true;
+}
+
+/* */
+#define STR_CHECK_EOF \
+if (offset >= jsonTextLen) { \
+ tok = jer_tok_eof; \
+ goto finish_string_lex; \
+}
+
+jer::jer_token
+jer::lex_string( const unsigned char * jsonText,
+ size_t jsonTextLen, size_t & offset)
+{
+ jer_token tok = jer_tok_error;
+ int hasEscapes = 0;
+
+ for (;;) {
+ unsigned char curChar;
+#if 0
+ /* now jump into a faster scanning routine to skip as much
+ * of the buffers as possible */
+ {
+ const unsigned char * p;
+ size_t len;
+
+ if ((lexer->bufInUse && yajl_buf_len(lexer->buf) &&
+ lexer->bufOff < yajl_buf_len(lexer->buf)))
+ {
+ p = ((const unsigned char *) yajl_buf_data(lexer->buf) +
+ (lexer->bufOff));
+ len = yajl_buf_len(lexer->buf) - lexer->bufOff;
+ lexer->bufOff += yajl_string_scan(p, len, lexer->validateUTF8);
+ }
+ else if (*offset < jsonTextLen)
+ {
+ p = jsonText + *offset;
+ len = jsonTextLen - *offset;
+ *offset += yajl_string_scan(p, len, lexer->validateUTF8);
+ }
+ }
+#endif
+ STR_CHECK_EOF;
+
+ curChar = readChar( jsonText, offset);
+
+ /* quote terminates */
+ if (curChar == '"') {
+ tok = jer_tok_string;
+ break;
+ }
+ /* backslash escapes a set of control chars, */
+ else if (curChar == '\\') {
+ hasEscapes = 1;
+ STR_CHECK_EOF;
+
+ /* special case \u */
+ curChar = readChar( jsonText, offset);
+ if (curChar == 'u') {
+ unsigned int i = 0;
+
+ for (i=0;i<4;i++) {
+ STR_CHECK_EOF;
+ curChar = readChar( jsonText, offset);
+ if (!(charLookupTable[curChar] & VHC)) {
+ /* back up to offending char */
+ unreadChar( offset);
+ m_error = jer_err_string_invalid_hex_char;
+ goto finish_string_lex;
+ }
+ }
+ } else if (!(charLookupTable[curChar] & VEC)) {
+ /* back up to offending char */
+ unreadChar(offset);
+ m_error = jer_err_string_invalid_escaped_char;
+ goto finish_string_lex;
+ }
+ }
+ /* when not validating UTF8 it's a simple table lookup to determine
+ * if the present character is invalid */
+ else if(charLookupTable[curChar] & IJC) {
+ /* back up to offending char */
+ unreadChar(offset);
+ m_error = jer_err_string_invalid_json_char;
+ goto finish_string_lex;
+ }
+#if 0
+ /* when in validate UTF8 mode we need to do some extra work */
+ else if (lexer->validateUTF8) {
+ yajl_tok t = yajl_lex_utf8_char(lexer, jsonText, jsonTextLen,
+ offset, curChar);
+
+ if (t == yajl_tok_eof) {
+ tok = yajl_tok_eof;
+ goto finish_string_lex;
+ } else if (t == yajl_tok_error) {
+ lexer->error = yajl_lex_string_invalid_utf8;
+ goto finish_string_lex;
+ }
+ }
+#endif
+ /* accept it, and move on */
+ }
+ finish_string_lex:
+ /* tell our buddy, the parser, wether he needs to process this string
+ * again */
+ if (hasEscapes && tok == jer_tok_string) {
+ tok = jer_tok_string_with_escapes;
+ }
+
+ return tok;
+ return jer_tok_error;
+}
+
+#define RETURN_IF_EOF if (offset >= jsonTextLen) return jer_tok_eof;
+jer::jer_token
+jer::lex_number( const unsigned char * jsonText,
+ size_t jsonTextLen, size_t & offset)
+{
+ unsigned char c;
+
+ jer_token tok = jer_tok_integer;
+
+ RETURN_IF_EOF;
+ c = readChar( jsonText, offset);
+
+ /* optional leading minus */
+ if (c == '-') {
+ RETURN_IF_EOF;
+ c = readChar( jsonText, offset);
+ }
+
+ /* a single zero, or a series of integers */
+ if (c == '0') {
+ RETURN_IF_EOF;
+ c = readChar( jsonText, offset);
+ } else if (c >= '1' && c <= '9') {
+ do {
+ RETURN_IF_EOF;
+ c = readChar( jsonText, offset);
+ } while (c >= '0' && c <= '9');
+ } else {
+ unreadChar( offset);
+ m_error = jer_err_missing_integer_after_minus;
+ return jer_tok_error;
+ }
+
+ /* optional fraction (indicates this is floating point) */
+ if (c == '.') {
+ int numRd = 0;
+
+ RETURN_IF_EOF;
+ c = readChar( jsonText, offset);
+
+ while (c >= '0' && c <= '9') {
+ numRd++;
+ RETURN_IF_EOF;
+ c = readChar( jsonText, offset);
+ }
+
+ if (!numRd) {
+ unreadChar( offset);
+ m_error = jer_err_missing_integer_after_decimal;
+ return jer_tok_error;
+ }
+ tok = jer_tok_double;
+ }
+
+ /* optional exponent (indicates this is floating point) */
+ if (c == 'e' || c == 'E') {
+ RETURN_IF_EOF;
+ c = readChar( jsonText, offset);
+
+ /* optional sign */
+ if (c == '+' || c == '-') {
+ RETURN_IF_EOF;
+ c = readChar( jsonText, offset);
+ }
+
+ if (c >= '0' && c <= '9') {
+ do {
+ RETURN_IF_EOF;
+ c = readChar( jsonText, offset);
+ } while (c >= '0' && c <= '9');
+ } else {
+ unreadChar( offset);
+ m_error = jer_err_missing_integer_after_exponent;
+ return jer_tok_error;
+ }
+ tok = jer_tok_double;
+ }
+
+ /* we always go "one too far" */
+ unreadChar( offset);
+
+ return tok;
+}
+
+jer::jer_token
+jer::lex_comment(const unsigned char * jsonText,
+ size_t jsonTextLen, size_t & offset)
+{
+ return jer_tok_error;
+}
+
+int
+jer::json_lex(size_t &offset,unsigned char **outBuf, size_t &outLen)
+{
+ unsigned char * jsonText = m_buffer;
+ size_t jsonTextLen = m_size;
+ size_t startOffset = offset;
+ int tok = jer_tok_error;
+ unsigned char c;
+
+ *outBuf = NULL;
+ outLen = 0;
+#if 1
+ for (;;) {
+ assert(offset <= jsonTextLen);
+
+ if (offset >= jsonTextLen) {
+ tok = jer_tok_eof;
+ goto lexed;
+ }
+
+ //c = readChar(lexer, jsonText, offset);
+ c = readChar();
+
+ switch (c) {
+ case '{':
+ tok = jer_tok_left_bracket;
+ goto lexed;
+ case '}':
+ tok = jer_tok_right_bracket;
+ goto lexed;
+ case '[':
+ tok = jer_tok_left_brace;
+ goto lexed;
+ case ']':
+ tok = jer_tok_right_brace;
+ goto lexed;
+ case ',':
+ tok = jer_tok_comma;
+ goto lexed;
+ case ':':
+ tok = jer_tok_colon;
+ goto lexed;
+ case '\t': case '\n': case '\v': case '\f': case '\r': case ' ':
+ startOffset++;
+ break;
+ case 't': {
+ const char * want = "rue";
+ do {
+ if (offset >= jsonTextLen) {
+ tok = jer_tok_eof;
+ goto lexed;
+ }
+ //c = readChar(lexer, jsonText, offset);
+ c = readChar();
+ if (c != *want) {
+ //unreadChar(lexer, offset);
+ unreadChar(offset);
+ m_error = jer_err_invalid_string;
+ tok = jer_tok_error;
+ goto lexed;
+ }
+ } while (*(++want));
+ tok = jer_tok_bool;
+ goto lexed;
+ }
+ case 'f': {
+ const char * want = "alse";
+ do {
+ if (offset >= jsonTextLen) {
+ tok = jer_tok_eof;
+ goto lexed;
+ }
+ //c = readChar(lexer, jsonText, offset);
+ c = readChar();
+ if (c != *want) {
+ //unreadChar(lexer, offset);
+ unreadChar(offset);
+ m_error = jer_err_invalid_string;
+ tok = jer_tok_error;
+ goto lexed;
+ }
+ } while (*(++want));
+ tok = jer_tok_bool;
+ goto lexed;
+ }
+ case 'n': {
+ const char * want = "ull";
+ do {
+ if (offset >= jsonTextLen) {
+ tok = jer_tok_eof;
+ goto lexed;
+ }
+ //c = readChar(lexer, jsonText, offset);
+ c = readChar();
+ if (c != *want) {
+ //unreadChar(lexer, offset);
+ unreadChar(offset);
+ m_error = jer_err_invalid_string;
+ tok = jer_tok_error;
+ goto lexed;
+ }
+ } while (*(++want));
+ tok = jer_tok_null;
+ goto lexed;
+ }
+ case '"': {
+ tok = lex_string( (const unsigned char *) jsonText,
+ jsonTextLen, offset);
+ goto lexed;
+ }
+ case '-':
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9': {
+ /* integer parsing wants to start from the beginning */
+ //unreadChar(lexer, offset);
+ unreadChar(offset);
+ tok = lex_number((const unsigned char *) jsonText,
+ jsonTextLen, offset);
+ goto lexed;
+ }
+ case '/':
+ /* hey, look, a probable comment! If comments are disabled
+ * it's an error. */
+ if (!m_allowComments) {
+ //unreadChar(lexer, offset);
+ unreadChar( offset);
+ m_error = jer_err_unallowed_comment;
+ tok = jer_tok_error;
+ goto lexed;
+ }
+ /* if comments are enabled, then we should try to lex
+ * the thing. possible outcomes are
+ * - successful lex (tok_comment, which means continue),
+ * - malformed comment opening (slash not followed by
+ * '*' or '/') (tok_error)
+ * - eof hit. (tok_eof) */
+ tok = lex_comment((const unsigned char *) jsonText,
+ jsonTextLen, offset);
+ if (tok == jer_tok_comment) {
+ /* "error" is silly, but that's the initial
+ * state of tok. guilty until proven innocent. */
+ tok = jer_tok_error;
+#if 0
+ yajl_buf_clear(lexer->buf);
+ bufInUse = 0;
+#endif
+ startOffset = offset;
+ break;
+ }
+ /* hit error or eof, bail */
+ goto lexed;
+ default:
+ m_error = jer_err_invalid_char;
+ tok = jer_tok_error;
+ goto lexed;
+ }
+ }
+
+
+ lexed:
+ /* need to append to buffer if the buffer is in use or
+ * if it's an EOF token */
+#if 0
+ if (tok == jer_tok_eof || lexer->bufInUse) {
+ if (!lexer->bufInUse) yajl_buf_clear(lexer->buf);
+ lexer->bufInUse = 1;
+ yajl_buf_append(lexer->buf, jsonText + startOffset, offset - startOffset);
+ lexer->bufOff = 0;
+
+ if (tok != jer_tok_eof) {
+ *outBuf = yajl_buf_data(lexer->buf);
+ *outLen = yajl_buf_len(lexer->buf);
+ lexer->bufInUse = 0;
+ }
+ } else
+#endif
+ if (tok != jer_tok_error) {
+ *outBuf = jsonText + startOffset;
+ outLen = offset - startOffset;
+ }
+
+ /* special case for strings. skip the quotes. */
+ if (tok == jer_tok_string || tok == jer_tok_string_with_escapes)
+ {
+ assert(outLen >= 2);
+ (*outBuf)++;
+ outLen -= 2;
+ }
+
+
+#ifdef YAJL_LEXER_DEBUG
+ if (tok == jer_tok_error) {
+ printf("lexical error: %s\n",
+ yajl_lex_error_to_string(yajl_lex_get_error(lexer)));
+ } else if (tok == jer_tok_eof) {
+ printf("EOF hit\n");
+ } else {
+ printf("lexed %s: '", tokToStr(tok));
+ fwrite(*outBuf, 1, *outLen, stdout);
+ printf("'\n");
+ }
+#endif
+#endif
+ return tok;
+}
+/**
+ * question the next token but don't move lexer forward
+ */
+int
+jer::json_lex_peek(size_t &offset,const unsigned char **outbuf, size_t &outlen)
+{
+ return 1;
+}
+
+
+/*
+ * vim:et:sw=2:ts=2
+ */
+/* end of namespace */
+}
+}
--- /dev/null
+#ifndef CODEC_JER_H
+#define CODEC_JER_H
+#include <iostream>
+
+#if defined(__GNUC__) && defined(DEBUG) & not(defined(ASN1_BER_LOG_DEBUG))
+#define ASN1_BER_LOG_DEBUG(fmt,args...) do {\
+ fprintf(stderr,fmt,##args);\
+ fprintf(stderr," (asn1.y : %d)\n",__LINE__);\
+} while (0)
+#elseif not(defined(ASN1_BER_LOG_DEBUG))
+ static inline void ASN1_BER_LOG_DEBUG(const char *fmt,...) {(void)fmt;};
+#endif
+
+namespace asn1 {
+class context;
+
+
+
+
+namespace streams {
+
+/**
+ * Should not be in codecs namespace.
+ * It's a jer context used by the jer codec.
+ */
+class jer : public asn1::context
+{
+ public:
+ enum jer_token {
+ jer_tok_bool
+ , jer_tok_colon
+ , jer_tok_comma
+ , jer_tok_eof
+ , jer_tok_error
+ , jer_tok_left_brace
+ , jer_tok_left_bracket
+ , jer_tok_null
+ , jer_tok_right_brace
+ , jer_tok_right_bracket
+ /* */
+ , jer_tok_integer
+ , jer_tok_double
+ , jer_tok_string
+ , jer_tok_string_with_escapes
+ , jer_tok_comment
+ };
+
+ enum jer_lex_error {
+ jer_err_ok = 0
+ ,jer_err_string_invalid_utf8
+ ,jer_err_string_invalid_escaped_char
+ ,jer_err_string_invalid_json_char
+ ,jer_err_string_invalid_hex_char
+ ,jer_err_invalid_string
+ ,jer_err_invalid_char
+ /* Missing error codes for numbers*/
+ ,jer_err_unallowed_comment
+ ,jer_err_missing_integer_after_minus
+ ,jer_err_missing_integer_after_decimal
+ ,jer_err_missing_integer_after_exponent
+ };
+
+ jer( int sz = 512) ;
+ jer(unsigned char *buf, int sz = 512) ;
+ jer(const jer &c) ;
+ ~jer() {}
+
+ virtual int decode_tag(asn1::tag &t) ;
+
+ // Null
+ // 5
+ virtual void encode_null(const asn1::Null &b) ;
+ virtual int decode_null(asn1::Null &b) ;
+
+ // Bool
+ //
+ virtual void encode_boolean(const asn1::BOOLEAN &b) ;
+ virtual int decode_boolean(asn1::BOOLEAN &b) ;
+
+ // Integer
+ //
+ virtual void encode_integer(const asn1::types::type &b) ;
+ virtual int decode_integer(asn1::INTEGER &b) ;
+ int decode_integer(asn1::UInt64 &b) ;
+
+ // Bit String
+ //
+ virtual void encode_bitstring(const asn1::BIT_STRING &b) ;
+ virtual int decode_bitstring(asn1::BIT_STRING &b) ;
+
+ // Octet string
+ //
+ virtual void encode_octetstring(const asn1::OCTET_STRING &b) ;
+ virtual int decode_octetstring(asn1::OCTET_STRING &b) ;
+
+ virtual void encode_string(const asn1::types::type &b) ;
+ virtual int decode_string(asn1::types::type &b) ;
+ // Choice
+ //
+ virtual void encode_choice(asn1::types::choice_type &b) ;
+ virtual int decode_choice(asn1::types::choice_type &b) ;
+
+ // Sequence
+ virtual void encode_sequence_preamble(asn1::types::sequence_type &b) ;
+ virtual void encode_sequence_epilogue(asn1::types::sequence_type &b) ;
+ virtual int decode_sequence_preamble(asn1::types::sequence_type &b) ;
+ virtual int decode_sequence_epilogue(asn1::types::sequence_type &b) ;
+
+ /**
+ * When reading jer, we need to be able to decode the length
+ */
+ bool decode_tag( asn1::tag &t, int &len);
+
+ bool decode_header(const asn1::tag &tag,int &len);
+ /**/
+ void put_string(const std::string &s);
+ /**/
+ void put_char(const unsigned char *s,size_t len);
+
+ void put_char(const char *s,size_t len);
+
+ /**
+ * retrieve token. If the lexer parses token
+ * return true or else return false and leave
+ * m_bufOff unchanged.
+ */
+ bool get_token(const char *);
+ bool get_token(jer_token tok);
+ bool get_token(std::string &s);
+
+ inline void put_field(const char *s,size_t len)
+ { put_char("\"",1); put_char(s,len); put_char("\"",1); };
+ /* json specifique functions code */
+ const char *error_to_string(int i) const;
+ /* get current offset into the most recently lexed json string */
+ inline size_t current_offset() const { return m_bufOff; };
+ /* number of char lexed */
+ inline size_t current_char() const { return m_charOff; };
+ /* number of lines lexed */
+ inline size_t current_line() const { return m_lineOff; };
+
+ friend std::ostream &operator<<(std::ostream &os,const jer &_jer)
+ {
+ os<<(char *)const_cast< jer &>(_jer).buffer(); return os;
+ }
+ protected:
+ /* To be reviewed */
+ inline unsigned char readChar()
+ {return (m_bufOff < get_size() ? *(m_buffer + m_bufOff++) : *m_buffer); };
+ /* To be reviewed */
+ inline unsigned char readChar(const unsigned char *c,size_t &offset)
+ {return c[offset++]; };
+
+ inline size_t unreadChar(size_t &off) { return (off>0)?off--:m_bufOff--; };
+ /**
+ * do i need encode_header for jer ?
+ */
+ void encode_header(const asn1::types::type &obj, int &len);
+
+ const char * tok2str(int tok) const;
+ /**
+ * analyse,lex buffer and return appropriate token
+ * this function can be invoked several times until eof.
+ */
+ int json_lex(size_t &offset,unsigned char **outbuf, size_t &outlen);
+ /**
+ * question the next token but don't move lexer forward
+ */
+ int json_lex_peek(size_t &offset,const unsigned char **outbuf, size_t &outlen);
+
+ jer_token lex_string(const unsigned char *,size_t,size_t &offset);
+
+ jer_token lex_number(const unsigned char *,size_t,size_t &offset);
+
+ jer_token lex_comment(const unsigned char *,size_t,size_t &offset);
+ /* Offset local variables */
+ size_t m_lineOff;
+ size_t m_charOff;
+ /** Current offset into lex buffer */
+ size_t m_bufOff;
+ bool m_allowComments;
+ // There is no way to get parent so may use a stack to push/pop parent element
+ jer_lex_error m_error;
+}; /* end jer class */
+
+} /* end streams namespace */
+
+/**
+ *
+ * How will codecJER look like ?
+ */
+
+ class codecJER : public codec
+ {
+ protected:
+
+ public:
+ codecJER() {}
+
+ template <class T>
+ void encode(streams::jer &ctx,const T &t) ;
+
+ template <class T>
+ int decode(streams::jer &ctx, T &t) ;
+
+ /* Special case for Sequence OF */
+ template <class T>
+ void encode(streams::jer &ctx,const asn1::Seq<T> &t)
+ {
+ typename asn1::Seq<T>::const_iterator mit = t.begin();
+ for (; mit != t.end() ; ++mit)
+ {
+ if (mit != t.begin())
+ ctx.put_char(", ",2);
+ encode(ctx,(*mit));
+ }
+ }
+
+ template <class T>
+ int decode(streams::jer &ctx,asn1::Seq<T> &t)
+ {
+ T element;
+ int ret;
+ if ( ! ctx.get_token(streams::jer::jer_tok_left_brace))
+ {
+
+ std::cerr<<"decode sequenceof non left brace aiee"<<std::endl;
+ return asn1::wrong_type;
+ }
+ do {
+ if ((ret = decode(ctx,element)) == asn1::ok)
+ {
+ t.push_back(element);
+// For debug purpose
+// std::cout<<"decode added 1 element "<<typeid(element).name()<<"Seq <T> size ="<<t.size()<<std::endl;
+ } else
+ {
+ break;
+ }
+ } while (ctx.get_token(streams::jer::jer_tok_comma));
+ if ( ! ctx.get_token(streams::jer::jer_tok_right_brace))
+ {
+ std::cerr<<"decode sequenceof non right brace aiee"<<std::endl;
+ return asn1::wrong_type;
+ }
+ return asn1::ok;
+ }
+
+ // Need to provide implementation
+ // For base Types, INTEGER, BOOLEAN...
+#define ASN1_TYPE_CLS(PrimType,TagType,TagNum,Asn1Type) \
+ void encode_jer(::asn1::streams::jer &ctx, const asn1::Asn1Type &t); \
+ int \
+ decode_jer(::asn1::streams::jer &ctx, asn1::Asn1Type &t);
+#include "rtasn1/asn1_types.inc"
+ }; /* end codecJER */
+
+/* encode / decode specialization declaration */
+#define ASN1_TYPE_CLS(PrimType,TagType,TagNum,Asn1Type) \
+ template <> \
+ void codecJER::encode(streams::jer &ctx, const asn1::Asn1Type &t) \
+ ; \
+ template <> \
+ int \
+ codecJER::decode(streams::jer &ctx, asn1::Asn1Type &t) \
+ ;
+#include "rtasn1/asn1_types.inc"
+
+
+}
+
+#endif
+/*
+ * vim: et sw=2 ts=2 :
+ */
--- /dev/null
+#include <iostream>
+#include <string>
+#include <typeinfo>
+#include "rtasn1/asn1.h"
+#include "rtasn1/asn1_codec.h"
+#include "rtasn1/asn1_context.h"
+
+#include "rtasn1/asn1_codec_oer.h"
+
+/*
+vim:et:sw=2:ts=2
+ */
+namespace asn1 {
+
+#define ASN1_TYPE_CLS(PrimType,TagType,TagNum,Asn1Type) \
+ template <> \
+ void codecOER::encode(streams::oer &ctx, const asn1::Asn1Type &t) \
+ { std::cerr<<"codecOER::"<<__FUNCTION__<<" good "; \
+ std::cerr<<#Asn1Type<<std::endl; \
+ encode_oer(ctx,t);\
+ } \
+ template <> \
+ int \
+ codecOER::decode(streams::oer &ctx, asn1::Asn1Type &t) \
+ { std::cerr<<"codecOER::"<<__FUNCTION__<<" good "; \
+ std::cerr<<#Asn1Type<<std::endl;\
+ return decode_oer(ctx,t);\
+ }
+#include "rtasn1/asn1_types.inc"
+
+
+#define ASN1_CODEC_IMPL(Type,Encode,Decode) \
+void codecOER::encode_oer(streams::oer &ctx,const asn1::Type &t) \
+Encode \
+int codecOER::decode_oer(streams::oer &ctx,asn1::Type &t) \
+Decode
+
+ASN1_CODEC_IMPL(BOOLEAN,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(INTEGER,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(Int8,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(Int16,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(Int32,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(UInt8,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(UInt16,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(UInt32,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(BIT_STRING,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(OCTET_STRING,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(STRING,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(Null,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+#if 0
+ASN1_CODEC_IMPL(OBJECT_IDENTIFIER,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+#else
+ASN1_CODEC_IMPL(OBJECT_IDENTIFIER_NG,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+
+#endif
+ASN1_CODEC_IMPL(EXTERNAL,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(GeneralizedTime,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(UTCTime,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(REAL,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(ENUMERATED,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+// typedef asn1::types::any_type ANY;
+ASN1_CODEC_IMPL(UTF8String,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(NumericString,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(PrintableString,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(TeletexString,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(VideotexString,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(IA5String,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(GraphicString,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(VisibleString,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(GeneralString,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(UniversalString,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+ASN1_CODEC_IMPL(BMPString,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return asn1::ok;
+})
+
+
+
+namespace streams {
+
+
+
+oer::oer(int sz) : asn1::context(sz)
+{
+ ASN1_BER_LOG_DEBUG("oer::oer %d ",sz);
+}
+
+oer::oer(const oer &_codec) : asn1::context()
+{
+ ASN1_BER_LOG_DEBUG("oer::oer(const ber &_codec ) ");
+}
+
+
+// Null
+// 5
+void oer::encode_null(const asn1::Null &b)
+{
+ int len = 0;
+ ASN1_BER_LOG_DEBUG("oer::encode Null tag=%d ",b.tag().byte());
+}
+
+int oer::decode_null(asn1::Null &b)
+{
+ int len = 0;
+ ASN1_BER_LOG_DEBUG("oer::decode Null ");
+
+ return asn1::ok;
+}
+
+
+// Bool
+//
+void oer::encode_boolean(const asn1::BOOLEAN &b)
+{
+ int len = 1;
+ ASN1_BER_LOG_DEBUG("oer::encode boolean tag=%d",b.tag().byte());
+}
+
+int oer::decode_boolean(asn1::BOOLEAN &b)
+{
+ int len = 0;
+ ASN1_BER_LOG_DEBUG("oer::decode boolean tag=%d",b.tag().byte());
+ return asn1::ok;
+}
+
+
+// Integer
+//
+void oer::encode_integer(const asn1::types::type &b)
+{
+ int len = 0;
+
+ const asn1::prim::types::Integer &i = dynamic_cast< const asn1::prim::types::Integer &>(b);
+ long integer = i.get_value();
+ int intsize = 4;
+ long mask = 0x1FF <<23; // Shift 8 *3 - 1 ? 0xFF800000
+
+ ASN1_BER_LOG_DEBUG("oer::encode integer tag=%d value=%ld intsize=%d decale =%d",b.tag().byte(),(long)i.get_value(),(int)intsize,(intsize<<3));
+
+}
+
+/**
+ * Decode Integer
+ */
+int oer::decode_integer(asn1::INTEGER &t)
+{
+ int len = 0;
+ int result = 0;
+
+ ASN1_BER_LOG_DEBUG("oer::decode integer tag=%d",t.tag().byte());
+ return asn1::ok;
+}
+
+
+// Bit String
+//
+void oer::encode_bitstring(const asn1::BIT_STRING &t)
+{
+ int len = t.size() + 1;
+ ASN1_BER_LOG_DEBUG("oer::encode bit string len=%d ",len);
+}
+
+int oer::decode_bitstring(asn1::BIT_STRING &t)
+{
+ ASN1_BER_LOG_DEBUG("oer::decode bit string tag=%d ",t.tag().byte());
+ return asn1::ok;
+}
+
+
+// Octet string
+//
+void oer::encode_octetstring(const asn1::OCTET_STRING &b)
+{
+ int len = 0;
+ ASN1_BER_LOG_DEBUG("oer::encode octet string tag=%d",b.tag().byte());
+}
+
+int oer::decode_octetstring(asn1::OCTET_STRING &b_)
+{
+ int len = 0;
+ ASN1_BER_LOG_DEBUG("oer::decode octet string TODO ");
+ return asn1::ok;
+}
+
+void oer::encode_string(const asn1::types::type &b)
+{
+ int len = 0;
+ ASN1_BER_LOG_DEBUG("oer::encode string tag=%d",b.tag().get_id());
+ const asn1::prim::types::String &s = dynamic_cast< const asn1::prim::types::String &>(b);
+ len = ((std::string)s.get_value()).size(); // Length
+ //encode_header(b.type::tag(),len);
+
+ unsigned long pos = bytes();
+ unsigned char *buf = buffer();
+
+}
+
+
+int oer::decode_string(asn1::types::type &b)
+{
+ int len = 0;
+ ASN1_BER_LOG_DEBUG("oer::decode string tag_id=%d",b.tag().get_id());
+ asn1::prim::types::String &s = dynamic_cast<asn1::prim::types::String &>(b);
+
+ return asn1::ok;
+}
+
+
+// Choice
+//
+void oer::encode_choice(asn1::types::choice_type &b)
+{
+ int len = 0;
+ ASN1_BER_LOG_DEBUG("oer::encode choice ");
+}
+
+int oer::decode_choice(asn1::types::choice_type &b)
+{
+ ASN1_BER_LOG_DEBUG("oer::decode choice ");
+ return asn1::ok;
+}
+
+
+// Sequence
+void oer::encode_sequence_preamble(asn1::types::sequence_type &b)
+{
+ int len = 0;
+ unsigned long pos = bytes();
+ unsigned char *bu = buffer();
+ ASN1_BER_LOG_DEBUG("oer::encode sequence preamble tag=%d",b.tag().byte());
+}
+void oer::encode_sequence_epilogue(asn1::types::sequence_type &b)
+{
+ ASN1_BER_LOG_DEBUG("oer::encode sequence epilogue tag=%d",b.tag().byte());
+}
+
+
+int oer::decode_sequence_preamble(asn1::types::sequence_type &b)
+{
+ int len;
+ std::string n = typeid(b).name();
+ ASN1_BER_LOG_DEBUG("oer::decode sequence preable %s",n.c_str());
+
+ //return b.decode_preamble_ber(*this);
+ return asn1::ok;
+}
+
+int oer::decode_sequence_epilogue(asn1::types::sequence_type &b)
+{
+ //return b.decode_epilogue_ber(*this);
+ return asn1::ok;
+}
+
+
+//
+void oer::encode_header(const asn1::types::type &obj, int &len)
+{
+ asn1::tag t = obj.tag();
+ unsigned long pos = bytes();
+ unsigned char *b = buffer();
+
+ ASN1_BER_LOG_DEBUG("oer::encode_header code tag: cls=%d id=%d ",t.get_class(),t.get_id());
+ // Encode Tag, check the tag value ....
+}
+
+
+bool oer::decode_header(const asn1::tag &tag,int &len)
+{
+ return true;
+}
+
+
+
+/*
+ * vim:et:sw=2:ts=2
+ */
+/* end of namespace */
+}
+}
--- /dev/null
+#ifndef CODEC_OER_H
+#define CODEC_OER_H
+#include <iostream>
+
+#if defined(__GNUC__) && defined(DEBUG) & not(defined(ASN1_BER_LOG_DEBUG))
+#define ASN1_BER_LOG_DEBUG(fmt,args...) do {\
+ fprintf(stderr,fmt,##args);\
+ fprintf(stderr," (asn1.y : %d)\n",__LINE__);\
+} while (0)
+#elseif not(defined(ASN1_BER_LOG_DEBUG))
+ static inline void ASN1_BER_LOG_DEBUG(const char *fmt,...) {(void)fmt;};
+#endif
+
+namespace asn1 {
+class context;
+
+
+
+
+namespace streams {
+//#define DEBUG
+/**
+ *
+ */
+
+class oer : public asn1::context
+{
+ public:
+ oer( int sz = 512) ;
+ oer(const oer &c) ;
+ ~oer() {}
+
+ // Null
+ // 5
+ virtual void encode_null(const asn1::Null &b) ;
+ virtual int decode_null(asn1::Null &b) ;
+
+ // Bool
+ //
+ virtual void encode_boolean(const asn1::BOOLEAN &b) ;
+ virtual int decode_boolean(asn1::BOOLEAN &b) ;
+
+ // Integer
+ //
+ virtual void encode_integer(const asn1::types::type &b) ;
+ virtual int decode_integer(asn1::INTEGER &b) ;
+
+ // Bit String
+ //
+ virtual void encode_bitstring(const asn1::BIT_STRING &b) ;
+ virtual int decode_bitstring(asn1::BIT_STRING &b) ;
+
+ // Octet string
+ //
+ virtual void encode_octetstring(const asn1::OCTET_STRING &b) ;
+ virtual int decode_octetstring(asn1::OCTET_STRING &b) ;
+
+ virtual void encode_string(const asn1::types::type &b) ;
+ virtual int decode_string(asn1::types::type &b) ;
+ // Choice
+ //
+ virtual void encode_choice(asn1::types::choice_type &b) ;
+ virtual int decode_choice(asn1::types::choice_type &b) ;
+
+ // Sequence
+ virtual void encode_sequence_preamble(asn1::types::sequence_type &b) ;
+ virtual void encode_sequence_epilogue(asn1::types::sequence_type &b) ;
+ virtual int decode_sequence_preamble(asn1::types::sequence_type &b) ;
+ virtual int decode_sequence_epilogue(asn1::types::sequence_type &b) ;
+
+ /**
+ * When reading ber, we need to be able to decode the length
+ */
+ bool decode_tag( asn1::tag &t, int &len);
+
+ bool decode_header(const asn1::tag &tag,int &len);
+ protected:
+ void encode_header(const asn1::types::type &obj, int &len);
+ // There is no way to get parent so may use a stack to push/pop parent element
+};
+
+}
+
+/**
+ *
+ * How will codecBER look like ?
+ */
+
+ class codecOER : public codec
+ {
+ protected:
+
+ public:
+ codecOER() {}
+
+ template <class T>
+ void encode(streams::oer &ctx,const T &t) ;
+
+ template <class T>
+ int decode(streams::oer &ctx, T &t) ;
+ // Need to provide implementation
+ // For base Types, INTEGER, BOOLEAN...
+#define ASN1_TYPE_CLS(PrimType,TagType,TagNum,Asn1Type) \
+ void encode_oer(streams::oer &ctx, const asn1::Asn1Type &t); \
+ int \
+ decode_oer(streams::oer &ctx, asn1::Asn1Type &t);
+#include "rtasn1/asn1_types.inc"
+ };
+
+/* encode / decode specialization declaration */
+#define ASN1_TYPE_CLS(PrimType,TagType,TagNum,Asn1Type) \
+ template <> \
+ void codecOER::encode(streams::oer &ctx, const asn1::Asn1Type &t) \
+ ; \
+ template <> \
+ int \
+ codecOER::decode(streams::oer &ctx, asn1::Asn1Type &t) \
+ ;
+#include "rtasn1/asn1_types.inc"
+
+
+}
+
+#endif
+/*
+ * vim: et sw=2 ts=2 :
+ */
--- /dev/null
+#include <iostream>
+#include <string>
+#include <typeinfo>
+#include "rtasn1/asn1.h"
+#include "rtasn1/asn1_codec.h"
+#include "rtasn1/asn1_context.h"
+
+#include "rtasn1/asn1_codec_per.h"
+
+/*
+vim:et:sw=2:ts=2
+ */
+namespace asn1 {
+
+#define ASN1_TYPE_CLS(PrimType,TagType,TagNum,Asn1Type) \
+ template <> \
+ void codecPER::encode(codecs::per &ctx, const asn1::Asn1Type &t) \
+ { std::cerr<<"codecPER::"<<__FUNCTION__<<" good "; \
+ std::cerr<<#Asn1Type<<std::endl; \
+ encode_per(ctx,t);\
+ } \
+ template <> \
+ asn1::Asn1Type & \
+ codecPER::decode(codecs::per &ctx, asn1::Asn1Type &t) \
+ { std::cerr<<"codecPER::"<<__FUNCTION__<<" good "; \
+ std::cerr<<#Asn1Type<<std::endl;\
+ return decode_per(ctx,t);\
+ }
+#include "rtasn1/asn1_types.inc"
+
+
+#define ASN1_CODEC_IMPL(Type,Encode,Decode) \
+void codecPER::encode_per(codecs::per &ctx,const asn1::Type &t) \
+Encode \
+asn1::Type &codecPER::decode_per(codecs::per &ctx,asn1::Type &t) \
+Decode
+
+ASN1_CODEC_IMPL(BOOLEAN,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return t;
+})
+ASN1_CODEC_IMPL(INTEGER,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return t;
+})
+ASN1_CODEC_IMPL(Int8,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return t;
+})
+ASN1_CODEC_IMPL(Int16,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return t;
+})
+ASN1_CODEC_IMPL(Int32,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return t;
+})
+//
+ASN1_CODEC_IMPL(Int64,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return t;
+})
+ASN1_CODEC_IMPL(UInt8,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return t;
+})
+ASN1_CODEC_IMPL(UInt16,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return t;
+})
+ASN1_CODEC_IMPL(UInt32,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return t;
+})
+ASN1_CODEC_IMPL(UInt64,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return t;
+})
+ASN1_CODEC_IMPL(BIT_STRING,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return t;
+})
+ASN1_CODEC_IMPL(OCTET_STRING,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return t;
+})
+ASN1_CODEC_IMPL(STRING,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return t;
+})
+ASN1_CODEC_IMPL(Null,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return t;
+})
+#if 0
+ASN1_CODEC_IMPL(OBJECT_IDENTIFIER,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return t;
+})
+#else
+ASN1_CODEC_IMPL(OBJECT_IDENTIFIER_NG,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return t;
+})
+#endif
+ASN1_CODEC_IMPL(EXTERNAL,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return t;
+})
+ASN1_CODEC_IMPL(GeneralizedTime,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return t;
+})
+ASN1_CODEC_IMPL(UTCTime,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return t;
+})
+ASN1_CODEC_IMPL(REAL,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return t;
+})
+ASN1_CODEC_IMPL(ENUMERATED,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return t;
+})
+// typedef asn1::types::any_type ANY;
+ASN1_CODEC_IMPL(UTF8String,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return t;
+})
+ASN1_CODEC_IMPL(NumericString,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return t;
+})
+ASN1_CODEC_IMPL(PrintableString,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return t;
+})
+ASN1_CODEC_IMPL(TeletexString,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return t;
+})
+ASN1_CODEC_IMPL(VideotexString,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return t;
+})
+ASN1_CODEC_IMPL(IA5String,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return t;
+})
+ASN1_CODEC_IMPL(GraphicString,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return t;
+})
+ASN1_CODEC_IMPL(VisibleString,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return t;
+})
+ASN1_CODEC_IMPL(GeneralString,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return t;
+})
+ASN1_CODEC_IMPL(UniversalString,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return t;
+})
+ASN1_CODEC_IMPL(BMPString,
+{
+ std::cout<<__FUNCTION__<<" TODO"<<std::endl;
+},
+{
+ return t;
+})
+
+
+
+namespace codecs {
+
+
+
+per::per(int sz) : asn1::context(sz)
+{
+ ASN1_BER_LOG_DEBUG("per::per %d ",sz);
+}
+
+per::per(const per &_codec) : asn1::context()
+{
+ ASN1_BER_LOG_DEBUG("per::per(const ber &_codec ) ");
+}
+
+
+// Null
+// 5
+void per::encode_null(const asn1::Null &b)
+{
+ int len = 0;
+ ASN1_BER_LOG_DEBUG("per::encode Null tag=%d ",b.tag().byte());
+}
+
+int per::decode_null(asn1::Null &b)
+{
+ int len = 0;
+ ASN1_BER_LOG_DEBUG("per::decode Null ");
+
+ return asn1::ok;
+}
+
+
+// Bool
+//
+void per::encode_boolean(const asn1::BOOLEAN &b)
+{
+ int len = 1;
+ ASN1_BER_LOG_DEBUG("per::encode boolean tag=%d",b.tag().byte());
+}
+
+int per::decode_boolean(asn1::BOOLEAN &b)
+{
+ int len = 0;
+ ASN1_BER_LOG_DEBUG("per::decode boolean tag=%d",b.tag().byte());
+ return asn1::ok;
+}
+
+
+// Integer
+//
+void per::encode_integer(const asn1::types::type &b)
+{
+ int len = 0;
+
+ const asn1::prim::types::Integer &i = dynamic_cast< const asn1::prim::types::Integer &>(b);
+ long integer = i.get_value();
+ int intsize = 4;
+ long mask = 0x1FF <<23; // Shift 8 *3 - 1 ? 0xFF800000
+
+ ASN1_BER_LOG_DEBUG("per::encode integer tag=%d value=%ld intsize=%d decale =%d",b.tag().byte(),(long)i.get_value(),(int)intsize,(intsize<<3));
+
+}
+
+/**
+ * Decode Integer
+ */
+int per::decode_integer(asn1::INTEGER &t)
+{
+ int len = 0;
+ int result = 0;
+
+ ASN1_BER_LOG_DEBUG("per::decode integer tag=%d",t.tag().byte());
+ return asn1::ok;
+}
+
+
+// Bit String
+//
+void per::encode_bitstring(const asn1::BIT_STRING &t)
+{
+ int len = t.size() + 1;
+ ASN1_BER_LOG_DEBUG("per::encode bit string len=%d ",len);
+}
+
+int per::decode_bitstring(asn1::BIT_STRING &t)
+{
+ ASN1_BER_LOG_DEBUG("per::decode bit string tag=%d ",t.tag().byte());
+ return asn1::ok;
+}
+
+
+// Octet string
+//
+void per::encode_octetstring(const asn1::OCTET_STRING &b)
+{
+ int len = 0;
+ ASN1_BER_LOG_DEBUG("per::encode octet string tag=%d",b.tag().byte());
+}
+
+int per::decode_octetstring(asn1::OCTET_STRING &b_)
+{
+ int len = 0;
+ ASN1_BER_LOG_DEBUG("per::decode octet string TODO ");
+ return asn1::ok;
+}
+
+void per::encode_string(const asn1::types::type &b)
+{
+ int len = 0;
+ ASN1_BER_LOG_DEBUG("per::encode string tag=%d",b.tag().get_id());
+ const asn1::prim::types::String &s = dynamic_cast< const asn1::prim::types::String &>(b);
+ len = ((std::string)s.get_value()).size(); // Length
+ //encode_header(b.type::tag(),len);
+
+ unsigned long pos = bytes();
+ unsigned char *buf = buffer();
+
+}
+
+
+int per::decode_string(asn1::types::type &b)
+{
+ int len = 0;
+ ASN1_BER_LOG_DEBUG("per::decode string tag_id=%d",b.tag().get_id());
+ asn1::prim::types::String &s = dynamic_cast<asn1::prim::types::String &>(b);
+
+ return asn1::ok;
+}
+
+
+// Choice
+//
+void per::encode_choice(asn1::types::choice_type &b)
+{
+ int len = 0;
+ ASN1_BER_LOG_DEBUG("per::encode choice ");
+}
+
+int per::decode_choice(asn1::types::choice_type &b)
+{
+ ASN1_BER_LOG_DEBUG("per::decode choice ");
+ return asn1::ok;
+}
+
+
+// Sequence
+void per::encode_sequence_preamble(asn1::types::sequence_type &b)
+{
+ int len = 0;
+ unsigned long pos = bytes();
+ unsigned char *bu = buffer();
+ ASN1_BER_LOG_DEBUG("per::encode sequence preamble tag=%d",b.tag().byte());
+}
+void per::encode_sequence_epilogue(asn1::types::sequence_type &b)
+{
+ ASN1_BER_LOG_DEBUG("per::encode sequence epilogue tag=%d",b.tag().byte());
+}
+
+
+int per::decode_sequence_preamble(asn1::types::sequence_type &b)
+{
+ int len;
+ std::string n = typeid(b).name();
+ ASN1_BER_LOG_DEBUG("per::decode sequence preable %s",n.c_str());
+
+ //return b.decode_preamble_ber(*this);
+ return asn1::ok;
+}
+
+int per::decode_sequence_epilogue(asn1::types::sequence_type &b)
+{
+ //return b.decode_epilogue_ber(*this);
+ return asn1::ok;
+}
+
+
+//
+void per::encode_header(const asn1::types::type &obj, int &len)
+{
+ asn1::tag t = obj.tag();
+ unsigned long pos = bytes();
+ unsigned char *b = buffer();
+
+ ASN1_BER_LOG_DEBUG("per::encode_header code tag: cls=%d id=%d ",t.get_class(),t.get_id());
+ // Encode Tag, check the tag value ....
+}
+
+bool per::decode_header(const asn1::tag &tag,int &len)
+{
+ return true;
+}
+
+
+
+/*
+ * vim:et:sw=2:ts=2
+ */
+/* end of namespace */
+}
+}
--- /dev/null
+#ifndef CODEC_PER_H
+#define CODEC_PER_H
+#include <iostream>
+
+#if defined(__GNUC__) && defined(DEBUG) & not(defined(ASN1_BER_LOG_DEBUG))
+#define ASN1_BER_LOG_DEBUG(fmt,args...) do {\
+ fprintf(stderr,fmt,##args);\
+ fprintf(stderr," (asn1.y : %d)\n",__LINE__);\
+} while (0)
+#elseif not(defined(ASN1_BER_LOG_DEBUG))
+ static inline void ASN1_BER_LOG_DEBUG(const char *fmt,...) {(void)fmt;};
+#endif
+
+namespace asn1 {
+class context;
+
+
+
+
+namespace codecs {
+//#define DEBUG
+/**
+ *
+ */
+
+class per : public asn1::context
+{
+ public:
+ per( int sz = 512) ;
+ per(const per &c) ;
+ ~per() {}
+
+ // Null
+ // 5
+ virtual void encode_null(const asn1::Null &b) ;
+ virtual int decode_null(asn1::Null &b) ;
+
+ // Bool
+ //
+ virtual void encode_boolean(const asn1::BOOLEAN &b) ;
+ virtual int decode_boolean(asn1::BOOLEAN &b) ;
+
+ // Integer
+ //
+ virtual void encode_integer(const asn1::types::type &b) ;
+ virtual int decode_integer(asn1::INTEGER &b) ;
+
+ // Bit String
+ //
+ virtual void encode_bitstring(const asn1::BIT_STRING &b) ;
+ virtual int decode_bitstring(asn1::BIT_STRING &b) ;
+
+ // Octet string
+ //
+ virtual void encode_octetstring(const asn1::OCTET_STRING &b) ;
+ virtual int decode_octetstring(asn1::OCTET_STRING &b) ;
+
+ virtual void encode_string(const asn1::types::type &b) ;
+ virtual int decode_string(asn1::types::type &b) ;
+ // Choice
+ //
+ virtual void encode_choice(asn1::types::choice_type &b) ;
+ virtual int decode_choice(asn1::types::choice_type &b) ;
+
+ // Sequence
+ virtual void encode_sequence_preamble(asn1::types::sequence_type &b) ;
+ virtual void encode_sequence_epilogue(asn1::types::sequence_type &b) ;
+ virtual int decode_sequence_preamble(asn1::types::sequence_type &b) ;
+ virtual int decode_sequence_epilogue(asn1::types::sequence_type &b) ;
+
+ /**
+ * When reading ber, we need to be able to decode the length
+ */
+
+ bool decode_header(const asn1::tag &tag,int &len);
+ protected:
+ void encode_header(const asn1::types::type &obj, int &len);
+ // There is no way to get parent so may use a stack to push/pop parent element
+};
+
+}
+
+/**
+ *
+ * How will codecPER look like ?
+ */
+
+ class codecPER : public codec
+ {
+ protected:
+
+ public:
+ codecPER() {}
+
+ template <class T>
+ void encode(codecs::per &ctx,const T &t) ;
+
+ template <class T>
+ T& decode(codecs::per &ctx, T &t) ;
+ // Need to provide implementation
+ // For base Types, INTEGER, BOOLEAN...
+#define ASN1_TYPE_CLS(PrimType,TagType,TagNum,Asn1Type) \
+ void encode_per(codecs::per &ctx, const asn1::Asn1Type &t); \
+ asn1::Asn1Type & \
+ decode_per(codecs::per &ctx, asn1::Asn1Type &t);
+#include "rtasn1/asn1_types.inc"
+ };
+
+/* encode / decode specialization declaration */
+#define ASN1_TYPE_CLS(PrimType,TagType,TagNum,Asn1Type) \
+ template <> \
+ void codecPER::encode(codecs::per &ctx, const asn1::Asn1Type &t) \
+ ; \
+ template <> \
+ asn1::Asn1Type & \
+ codecPER::decode(codecs::per &ctx, asn1::Asn1Type &t) \
+ ;
+#include "rtasn1/asn1_types.inc"
+
+
+}
+
+#endif
+/*
+ * vim: et sw=2 ts=2 :
+ */
--- /dev/null
+#cmakedefine HAVE_UNISTD_H
+#cmakedefine HAVE_STDLIB_H
+#cmakedefine HAVE_PTHREAD_H
+#cmakedefine HAVE_DIRECT_H
+#cmakedefine HAVE_STDINT_H
+/* system function check*/
+#cmakedefine HAVE_GETCWD
+#cmakedefine HAVE_MKDIR
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#ifdef HAVE_DIRECT_H
+#include <direct.h>
+#endif
--- /dev/null
+#include <iostream>
+#include <string>
+
+#include "rtasn1/asn1_errors.h"
+#include "asn1.h"
+#include "asn1_codec.h"
+#include "asn1_context.h"
+/*
+ * ** Translation Table as described in RFC1113
+ * */
+static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+/*
+ * ** Translation Table to decode (created by author)
+ * */
+static const char cd64[]="|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq";
+
+
+namespace asn1 {
+
+/**
+ * Default constructor
+ */
+context::context(size_t size) : m_bits(0),m_check_tag(true),m_managed(true)
+ , m_size(size)
+#ifdef WITH_CODEC
+ , asn1::context_base()
+#endif
+
+{
+ m_buffer = (unsigned char *)malloc(size);
+ memset(m_buffer,0x00,size);
+};
+
+context::context(unsigned char *b,size_t size) : m_bits(0),m_buffer(b),m_check_tag(true),m_managed(false)
+ , m_size(size)
+#ifdef WITH_CODEC
+ , asn1::context_base()
+#endif
+{
+};
+
+context::context(const context &c)
+#ifdef WITH_CODEC
+ : asn1::context_base()
+#endif
+{
+ ;
+}
+
+context::~context()
+{
+ if (types::debug_level> 6)
+ {
+ if (m_bits != 0)
+ {
+ std::cout<<" context::"<<__FUNCTION__<<" coded: "<<m_bits<<" bits "<<std::endl;
+ for (int i = 0 ; i< m_bits/ 8 ;i++)
+ {
+ printf("%02x ",m_buffer[i]);
+ if ( ( (i % 32) == 0 ) && ( i != 0))
+ std::cout<<std::endl;
+ }
+ std::cout<<std::endl;
+ }
+ }
+ if (m_managed)
+ free(m_buffer);
+}
+
+// Decode base 64 buffer and assign it internally for further
+// asn1 decoding
+void
+context::set_base64(const std::string &str)
+{
+ long size = str.size()/4 * 3 + 1;
+}
+
+// Encode the encoded buffer into asn1
+void
+context::get_base64(std::string &str)
+{
+ int count = 0;
+ unsigned char *p = buffer();
+ unsigned char *end = buffer()+bytes();
+
+ long size = ( (bytes() - 1) /3) * 4 + 4;
+
+ str.resize(size);
+ unsigned char *out = (unsigned char *)(const_cast<char *>(str.c_str()));
+ while (p < end)
+ {
+ if (p+3 < end) {
+ encode_base64_block(p,out,0);
+ p+=3; out+=4;
+ } else
+ {
+ encode_base64_block(p,out,end-p);
+ p+= (end-p);
+ }
+ }
+
+
+}
+
+void
+context::encode_base64_block(unsigned char *in,unsigned char *out,int len)
+{
+ out[0] = (unsigned char) cb64[ (int)(in[0] >> 2) ];
+ out[1] = (unsigned char) cb64[ (int)(((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4)) ];
+ out[2] = (unsigned char) (len > 1 ? cb64[ (int)(((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6)) ] : '=');
+ out[3] = (unsigned char) (len > 2 ? cb64[ (int)(in[2] & 0x3f) ] : '=');
+ ;
+}
+
+
+void
+context::decode_base64_block(unsigned char *in,unsigned char *out,int len)
+{
+ out[ 0 ] = (unsigned char ) (in[0] << 2 | in[1] >> 4);
+ out[ 1 ] = (unsigned char ) (in[1] << 4 | in[2] >> 2);
+ out[ 2 ] = (unsigned char ) (((in[2] << 6) & 0xc0) | in[3]);
+}
+
+}
--- /dev/null
+#ifndef ASN1_CONTEXT_H__
+#define ASN1_CONTEXT_H__
+#include <stdio.h>
+#include <iostream>
+# include <string.h>
+#if defined (__APPLE_CC__)
+# include <stdlib.h>
+#else
+# include "malloc.h"
+#endif
+#include "rtasn1/asn1.h"
+
+namespace asn1 {
+ namespace types {
+extern int debug_level;
+ }
+};
+
+namespace asn1 {
+
+/**
+ *
+ * Futur Abstract Class to decode/encode primitive types
+ *
+ */
+class context_base {
+
+ public:
+ context_base() {};
+
+ virtual int decode_tag(asn1::tag &t) = 0;
+ // Null
+ // 5
+ virtual void encode_null(const asn1::Null &b) = 0;
+ virtual int decode_null(asn1::Null &b) = 0;
+
+ // Bool
+ //
+ virtual void encode_boolean(const asn1::BOOLEAN &b) = 0;
+ virtual int decode_boolean(asn1::BOOLEAN &b) = 0;
+
+ // Integer
+ //
+ virtual void encode_integer(const asn1::types::type &b) = 0;
+ virtual int decode_integer(asn1::INTEGER &b) = 0;
+
+ // Bit String
+ //
+ virtual void encode_bitstring(const asn1::BIT_STRING &b) = 0;
+ virtual int decode_bitstring(asn1::BIT_STRING &b) = 0;
+
+ // Octet string
+ //
+ virtual void encode_octetstring(const asn1::OCTET_STRING &b) = 0;
+ virtual int decode_octetstring(asn1::OCTET_STRING &b) = 0;
+
+ virtual void encode_string(const asn1::types::strtype &b) = 0;
+ virtual int decode_string(asn1::types::strtype &b) = 0;
+
+ // Choice
+ //
+ virtual void encode_choice(asn1::types::choice_type &b) = 0;
+ virtual int decode_choice(asn1::types::choice_type &b) = 0;
+
+ // Sequence
+ //
+ virtual void encode_sequence_preamble(asn1::types::sequence_type &b) = 0;
+ virtual void encode_sequence_epilogue(asn1::types::sequence_type &b) = 0;
+ virtual int decode_sequence_preamble(asn1::types::sequence_type &b) = 0;
+ virtual int decode_sequence_epilogue(asn1::types::sequence_type &b) = 0;
+
+ // Any
+ //
+ virtual void encode_any(const asn1::types::any_type &b) = 0;
+ virtual int decode_any(asn1::types::any_type &b) = 0;
+
+ private:
+ context_base(const context_base &c) {};
+
+ protected:
+};
+
+
+#define WITH_CODEC
+/**
+ * context object provides an enviromnent to codec function for reading
+ * and writing data.
+ * It must be able to provide the position in the buffer, the number for
+ * bits written.
+ *
+ *
+ */
+class context
+#ifdef WITH_CODEC
+ : public ::asn1::context_base
+#endif
+{
+ private:
+ context(const context &c) ;
+ bool m_managed; // Flag that helps to decide wether the buffer shall be deleted or not.
+ public:
+
+ // Constructors
+ context(size_t size=512) ;
+
+ context(unsigned char *b,size_t size);
+
+
+ ~context() ;
+
+ // base 64 set and get for fast ws usage
+ void set_base64(const std::string &str);
+
+ void get_base64(std::string &str);
+ //
+ inline bool check_tag() const {return m_check_tag;};
+
+ inline void check_tag(bool _t) {m_check_tag = _t;};
+
+
+ inline void nb_bits( long b) {m_bits+=b;} ;
+
+ inline size_t get_size() const { return m_size; };
+
+ inline unsigned long nb_read_bits() {return m_bits;} ;
+ // This is something like get_position, set_position.
+ inline unsigned long bytes() {return m_bits / 8;};
+
+ void bytes(unsigned long l) { m_bits = l * 8;};
+
+ inline unsigned char * buffer() {return m_buffer;};
+
+ inline void reset() { m_bits = 0 ;} ;
+#ifdef WITH_CODEC
+ virtual int decode_tag(asn1::tag &t) {return true;};
+ // Null
+ // 5
+ virtual void encode_null(const asn1::Null &b) { ; };
+ virtual int decode_null(asn1::Null &b) { return false; };
+
+ // Bool
+ //
+ virtual void encode_boolean(const asn1::BOOLEAN &b) { ; };
+ virtual int decode_boolean(asn1::BOOLEAN &b) { return asn1::unknown; };
+
+ // Integer
+ //
+ virtual void encode_integer(const asn1::types::type &b) { ; };
+ virtual int decode_integer(asn1::INTEGER &b) { return asn1::unknown; };
+ virtual int decode_integer(asn1::UInt64 &b) { return asn1::unknown; };
+
+ // Bit String
+ //
+ virtual void encode_bitstring(const asn1::BIT_STRING &b) { ; };
+ virtual int decode_bitstring(asn1::BIT_STRING &b) { return asn1::unknown; };
+
+ // Octet string
+ //
+ virtual void encode_octetstring(const asn1::OCTET_STRING &b) { ; };
+ virtual int decode_octetstring(asn1::OCTET_STRING &b) { return asn1::unknown; };
+
+ virtual void encode_string(const asn1::types::strtype &b) {};
+ virtual int decode_string(asn1::types::strtype &b) {return asn1::unknown;};
+ // Choice
+ //
+ virtual void encode_choice(asn1::types::choice_type &b) { ; };
+ virtual int decode_choice(asn1::types::choice_type &b) { return asn1::unknown; };
+ // Sequence
+ //
+ virtual void encode_sequence_preamble(asn1::types::sequence_type &b) { ; };
+ virtual void encode_sequence_epilogue(asn1::types::sequence_type &b) { ; };
+ virtual int decode_sequence_preamble(asn1::types::sequence_type &b) { return asn1::unknown; };
+ virtual int decode_sequence_epilogue(asn1::types::sequence_type &b) { return asn1::unknown; };
+
+
+ // Any
+ //
+ virtual void encode_any(const asn1::types::any_type &b) {};
+ virtual int decode_any(asn1::types::any_type &b) {return asn1::unknown;};
+#endif
+ protected:
+ void encode_base64_block(unsigned char *in,unsigned char *out,int len);
+
+ void decode_base64_block(unsigned char *in,unsigned char *out,int len);
+
+ protected:
+ bool m_check_tag;
+ long m_bits;
+ unsigned char * m_buffer;
+ size_t m_size;
+};
+
+
+}
+
+/*
+vim:et:sw=2:ts=2:
+ */
+#endif
--- /dev/null
+#ifndef ASN1_DEBUG_H__
+#define ASN1_DEBUG_H__
+
+#ifndef GCC_VERSION
+#define GCC_VERSION (__GNUC__ *10000 \
+ + __GNUC_MINOR__ * 100 \
+ + __GNUC_PATCHLEVEL__ )
+#endif
+
+#if defined(__APPLE__) || (GCC_VERSION > 40800)
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#endif
+#if defined(_WIN32)
+# include <io.h>
+#endif
+
+
+namespace asn1 {
+ namespace types {
+ extern int debug_level;
+ }
+};
+
+#if defined(__GNUC__) && defined(DEBUG) && !defined(ASN1_BER_LOG_DEBUG)
+
+#define __MYFILE__ (strrchr(__FILE__,'/')?strrchr(__FILE__,'/')+1 : __FILE__)
+
+# define ASN1_BER_LOG_DEBUG(fmt,args...) do {\
+ if (::asn1::types::debug_level >= 7) \
+ { fprintf(stderr,fmt,##args);\
+ fprintf(stderr," (%s : %d)\n",__MYFILE__,__LINE__); \
+ } \
+} while (0);
+
+# define ASN1_BER_LOG_INFO(fmt,args...) do {\
+ if (::asn1::types::debug_level >= 3) \
+ { fprintf(stderr,fmt,##args);\
+ fprintf(stderr," (%s : %d)\n",__FILE__,__LINE__);\
+ } \
+} while (0);
+
+# define ASN1_BER_LOG_ERROR(fmt,args...) do {\
+ fprintf(stderr,fmt,##args);\
+ fprintf(stderr," (%s : %d)\n",__FILE__,__LINE__);\
+} while (0);
+
+#elif defined(_WIN32) || defined(_WINDOWS)
+
+#define __MYFILE__ (strrchr(__FILE__,'/')?strrchr(__FILE__,'/')+1 : __FILE__)
+
+# define ASN1_BER_LOG_DEBUG(fmt,...) do {\
+ if (::asn1::types::debug_level >= 7) \
+ { fprintf(stderr,fmt,__VA_ARGS__);\
+ fprintf(stderr," (%s : %d)\n",__MYFILE__,__LINE__); \
+ } \
+ } while (0);
+# define ASN1_BER_LOG_INFO(fmt,...) do {\
+ } while (0);
+# define ASN1_BER_LOG_ERROR(fmt,...) do {\
+ fprintf(stderr,fmt,__VA_ARGS__);\
+ fprintf(stderr," (%s : %d)\n",__FILE__,__LINE__);\
+ } while (0);
+#else
+// Not debug
+# if not(defined(ASN1_BER_LOG_DEBUG))
+# define ASN1_BER_LOG_DEBUG(fmt,...) \
+ do { } while (0);
+# else
+ static inline void ASN1_BER_LOG_DEBUG(const char *fmt,...)
+ {
+ (void)fmt;
+ };
+# endif
+
+#define ASN1_BER_LOG_INFO(fmt,args...) do {\
+ fprintf(stderr,fmt,##args);\
+ fprintf(stderr," (%s : %d)\n",__FILE__,__LINE__);\
+} while (0);
+
+# define ASN1_BER_LOG_ERROR(fmt,args...) do {\
+ fprintf(stderr,fmt,##args);\
+ fprintf(stderr," (%s : %d)\n",__FILE__,__LINE__);\
+} while (0);
+
+#endif
+
+#endif
--- /dev/null
+#ifndef ASN1_ERRORS_H__
+#define ASN1_ERRORS_H__
+
+/**
+ * Liste the errors that can occur during parsing
+ */
+
+namespace asn1 {
+
+enum errors {
+ ok = 0,
+ wrong_tag = 1,
+ wrong_type = 2,
+ wrong_length = 3,
+ constraint_size = 4,
+ incomplet = 5,
+ unknown = 6
+
+};
+
+};
+
+#endif
--- /dev/null
+#ifndef ASN1_ROSE_H__
+#define ASN1_ROSE_H__
+
+#include <typeinfo>
+#include <assert.h>
+namespace asn1 {
+
+
+// classes using intrusive pointers
+// must provide the folowing methodes
+//
+// add_ref
+// release
+//
+template <typename T>
+class intrusive_ptr
+{
+ public:
+ typedef T * pointer;
+ typedef T & reference;
+ intrusive_ptr(const asn1::tag &t = asn1::tag(0,0))
+ : m_ptr(NULL) , m_tag(t)
+ {
+// ASN1_BER_LOG_DEBUG("intrusive_ptr<>::construct tag= %d",m_tag.byte());
+ };
+
+ intrusive_ptr( T* h)
+ : m_ptr(h) ,m_tag(h->tag())
+ {if (m_ptr != NULL) m_ptr->add_ref();};
+
+ intrusive_ptr(const intrusive_ptr<T> & ht)
+ : m_tag(ht.m_tag) ,m_ptr(NULL)
+ {
+ ASN1_BER_LOG_DEBUG("intrusive_ptr<> copy tag= %d <- %d ht.m_ptr=%0lx"
+ , m_tag.byte()
+ , ht.m_tag.byte()
+ , (long)ht.m_ptr);
+ if (ht.m_ptr)
+ {
+ std::string name = typeid(*ht.m_ptr).name();
+ ASN1_BER_LOG_DEBUG("intrusive_ptr<> copied %s",name.c_str());
+ m_ptr = ht.m_ptr;
+ m_ptr->add_ref();
+ m_tag = ht.m_tag;
+ }
+ };
+
+ pointer clone()
+ {
+ T *tp = new T(m_tag);
+ return tp;
+ }
+ void set_tag(const asn1::tag &t) { m_tag =t;};
+ inline void create(asn1::tag t = asn1::tag(0,0))
+ {
+ if ( ! is_nul() )
+ m_ptr->release();
+ m_ptr = new T();
+ if (t.byte() > 0 )
+ {
+ m_ptr->set_tag(t);
+ } else {
+ // This does not work at all with csta_insigth !!
+ // m_ptr->set_tag(m_tag);
+ }
+ m_ptr->add_ref();
+ } ;
+
+ inline void release()
+ {
+ if (!is_nul() )
+ {
+ m_ptr->release();
+ m_ptr = NULL;
+ }
+ }
+ inline bool is_nul() const {return m_ptr == NULL;};
+
+ intrusive_ptr<T> & operator =(const intrusive_ptr<T> &ht)
+ {
+ if (m_ptr) m_ptr->release();
+ if (ht.m_ptr)
+ {
+ m_ptr = ht.m_ptr;
+ m_ptr->add_ref();
+ }
+ return *this;
+ };
+
+ virtual ~intrusive_ptr()
+ {
+ if (m_ptr)
+ m_ptr->release();
+ m_ptr = NULL;
+ };
+
+ const asn1::tag &tag() const
+ {
+ static asn1::tag t(0,0);
+ if (m_ptr)
+ m_ptr->tag();
+ return t;
+ }
+
+ bool primitive() const
+ {
+ if (m_ptr)
+ return m_ptr->primitive();
+ return false;
+ }
+
+ size_t get_length() const
+ {
+ if (m_ptr)
+ return m_ptr->get_length();
+ return 0;
+ }
+ void encode(asn1::context &ctx)
+ {
+ if (m_ptr)
+ m_ptr->encode(ctx);
+ }
+
+ int decode(asn1::context &ctx)
+ {
+ ASN1_BER_LOG_DEBUG("intrusive_ptr<>::decode DECODE m_ptr=%ld",(long)m_ptr);
+ if (m_ptr)
+ {
+ int ret = m_ptr->decode(ctx);
+ if ( ret != asn1::ok)
+ release();
+ return ret;
+ } else
+ {
+ std::string name;
+ if (m_tag.byte() > 0)
+ {
+ m_ptr = new T(m_tag);
+ } else
+ m_ptr = new T();
+ m_ptr->add_ref();
+ name = typeid(*m_ptr).name();
+
+ int ret = this->m_ptr->decode(ctx);
+ if ( ret != asn1::ok)
+ release();
+ return ret;
+ }
+ return asn1::unknown;
+ }
+ //
+ pointer operator *( ) { return m_ptr;};
+ const pointer operator *( ) const{ return m_ptr;};
+ // cast operator
+ operator T *( ) { return m_ptr;};
+
+ reference get()
+ { if (m_ptr == NULL ) create(m_tag); return *m_ptr; }
+
+ reference get() const
+ { if (m_ptr == NULL ) assert(0); return *m_ptr; }
+ //
+ T* operator ->() {return m_ptr;};
+ const T* operator ->() const {return m_ptr;};
+
+ friend std::ostream & operator<<(std::ostream &os,const intrusive_ptr<T> &t)
+ {
+ if (! t.is_nul())
+ {
+ os<<"OPT"<<(*t.m_ptr);
+ } else
+ os<<" null ";
+ return os;
+ }
+ protected:
+ pointer m_ptr;
+ asn1::tag m_tag;
+};
+
+
+
+ // Generic class for object handling.
+// Not yet clear about how this will work.
+struct Object {
+ public:
+ typedef asn1::intrusive_ptr<Object> ptr;
+
+ Object() : m_ref(0) {/*std::cout<<"Build Object"<<std::endl;*/};
+ Object(const Object &_o) { /*std::cout<<"Build Object"<<std::endl;*/};
+ virtual ~Object() { };
+
+ inline void add_ref() {m_ref++;}
+ inline void release() {if (--m_ref == 0) delete this;}
+
+ inline
+ Object &operator =(const Object &_o) {
+ std::cerr<<"Object operator = "<<typeid(_o).name()<<std::endl;
+ return *_o.clone();
+ };
+ // clone operation that will support covariant feature
+ virtual Object * clone() const {
+ std::cout<<"Object::clone()"<<std::endl;
+ return new Object(*this);
+ };
+
+ virtual void printf(std::ostream &os) const {};
+
+ virtual void encode(asn1::context &ctx)
+ { }
+
+ virtual int decode(asn1::context &ctx)
+ {
+ std::cout<<"Object::decode not good"<<std::endl;
+ return asn1::unknown;
+ };
+ // To be checked if it will work
+ template <typename T>
+ void to_type(T &_t)
+ {_t = dynamic_cast<T &>(*this); };
+
+ template <typename T>
+ void to_type(T *_t)
+ {_t = dynamic_cast<T *>(this); };
+ private:
+ int m_ref; // Ref counting
+};
+
+struct ObjectSetEntry
+{
+ ObjectSetEntry *m_next;
+ Object *m_object;
+};
+
+
+}
+/*
+vim:et:sw=2:ts=2:
+ */
+#endif
--- /dev/null
+#ifndef ASN1_TAG_H__
+#define ASN1_TAG_H__
+#include <iostream>
+namespace asn1
+{
+
+#define MAKE_TAG(CLS,C,ID ) ( (((CLS) & 0x03)<<6) |((C & 0x01)<<5) |((ID)&0x1F) )
+/* Don't use constructed info for tag comparisen */
+#define MAKE_LONG_TAG(CLS,C,ID ) ( (((CLS) & 0x03)) |((ID)<<2) )
+ /**
+ *
+ * The form below is the BER encoding.
+ * 8 7 6 5 4 3 2 1
+ * class | P/C | Tag Identifier
+ */
+struct tag
+{
+ public:
+ inline void set_constructed() { m_constructed = true;};
+
+ tag(int cls,int id,bool _c = false) : m_class(cls), m_id(id) ,m_constructed(_c) {};
+ tag(unsigned char c) : m_class(0),m_id(0),m_constructed(false) { byte(c);};
+ tag(const tag &_t) : m_class(_t.m_class), m_id(_t.m_id) ,m_constructed(_t.m_constructed) {};
+
+ inline int get_class() const {return m_class; };
+
+ inline int get_id() const {return m_id; };
+
+ inline long get_tag() const {return ((m_id<<2) | m_class); };
+
+ inline bool get_constructed() const {return m_constructed; };
+
+ bool operator ==(const tag & t) const
+ { return m_id == t.m_id && m_class == t.m_class;}
+
+ bool operator ==(long l) const
+ {
+ return (m_id == (l>>2)) && (m_class == (l & 0x03));
+ }
+
+ inline void byte(const unsigned char c) {
+ m_class = (0xC0 & c)>>6;
+ m_id = (0x1F & c);
+ m_constructed = ((0x20&c)>>5) > 0;
+ };
+
+ // Don't use this function to be able to process tag numbers > 30
+ inline unsigned char byte() const
+ { return MAKE_TAG(m_class,m_constructed,m_id); };
+ protected:
+ int m_class;
+ int m_id;
+ bool m_constructed;
+};
+
+}
+
+#endif
--- /dev/null
+#include <string>
+#include <typeinfo>
+#include "rtasn1/asn1.h"
+#include "rtasn1/asn1_errors.h"
+#include "asn1_types.h"
+#include "rtasn1/asn1_context.h"
+#include "rtasn1/asn1_codec_ber.h"
+#include <cassert>
+namespace asn1 {
+
+
+// Object Identifier
+std::ostream & operator << (std::ostream &os,const ObjectIdentifier &o)
+{
+ os<<"{"<<static_cast<const asn1::prim::types::ObjectIdentifier &>(o)<<"}";
+ return os;
+}
+
+} /* end namespace */
+/**
+ * REAL BEGIN
+ */
+namespace asn1 {
+namespace types {
+
+
+int debug_level = 1;
+
+// Local static functions
+// computes the number of bits required for the given number (positive)
+size_t count_bits(unsigned range)
+{
+ switch (range)
+ {
+ case 0 :
+ return sizeof(unsigned)*8;
+ case 1:
+ return 1;
+ }
+ size_t _bits = 0;
+ while (_bits < (sizeof(unsigned)*8) && range > (unsigned)(1 << _bits))
+ _bits++;
+ return _bits;
+}
+/* test */
+const tag gTags[] = {
+ tag(1,1)
+ , tag(2,0)
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// CLASS type implementation
+///////////////////////////////////////////////////////////////////////////////
+
+
+type::type(int c ,int tid)
+ : m_ref(0) , m_tag(c,tid)
+{
+}
+
+type::type(const asn1::tag &t)
+ : m_ref(0) , m_tag(t)
+{
+}
+
+type::type(const type &t)
+ : m_ref(0), m_tag(t.m_tag)
+{
+ ;
+}
+
+type::~type()
+{
+}
+#if 0
+ inline void add_ref() {m_ref++;}
+
+ inline void release() {if (--m_ref == 0) delete this;}
+#endif
+bool type::primitive() const
+{
+ return true;
+}
+#if 0
+int
+type::get_data_length() const
+{
+ return 0;
+}
+#endif
+void type::set_tag(const asn1::tag &t)
+{
+ if (!this->primitive())
+ {
+ m_tag = asn1::tag(t.get_class(),t.get_id(),true);
+ } else
+ m_tag = t;
+}
+
+type *
+type::clone()
+{
+ std::cerr<<"asn1::types::type::clone ERROR type here not good "<<std::endl;
+ return NULL;
+} // Needed for copy constructor choice
+
+
+// New encoding / decoding mechanism. I think codec is to bad
+void
+type::encode(asn1::context &ctx)
+{
+ std::cerr<<"types::encode(ctx) BIG Issue"<<std::endl;
+};
+
+int
+type::decode(asn1::context &ctx)
+{
+ std::cerr<<"types::decode(ctx) BIG Issue"<<std::endl;
+ return asn1::unknown;
+};
+
+const asn1::tag &
+type::tag() const
+{
+ static asn1::tag t = asn1::tag(0,0)/*(C,I)*/;
+ if (m_tag.byte() > 0)
+ {
+ return m_tag;
+ }
+ else
+ return t;
+}
+
+void
+type::printf(std::ostream &os) const
+{
+ os<<"type::printf TODO";
+}
+
+size_t
+type::get_length() const
+{
+ size_t len = 1;
+ if (m_tag.get_id() > 31)
+ len += (count_bits(m_tag.get_id())+6)/7;
+ // add data_len field
+ size_t data_len = get_data_length();
+ if (data_len < 128)
+ len+= 1;
+ else
+ len+= (count_bits(data_len)+7)/8 + 1;
+ // return tag + len + data_len
+ return len + data_len;
+}
+
+
+/**
+ * used by decode functions
+ *
+ */
+long length(unsigned char *buf, long *readed)
+{
+ long result = 0;
+ long nb_octet = *buf & 0x7f;
+ *readed = 1;
+ if ((*buf & 0x80) && (*buf & 0x7F)) {
+ // Long form number ...
+ *readed = (*buf & 0x7F) + 1;
+ buf++;
+ // ASN1_BER_LOG_DEBUG("ber::length nb_octet %d form :result = %ld readed=%ld buf-1=%02x buf=%02x",nb_octet,result,*readed,*(buf-1),*buf);
+ while (nb_octet-- ) {
+ result = (result<<8) | (*buf) ;
+ buf++;
+ }
+ ASN1_BER_LOG_DEBUG("asn1::types::length long form : value=%ld readed=%ld ",result,*readed);
+ return result;
+ } else if (!(*buf & 0x80) && (*buf & 0x7F)){
+ result = *buf & 0x7F;
+ // Short one byte
+ *readed = 1;
+ ASN1_BER_LOG_DEBUG("asn1::types::length short form :result=%ld readed=%ld",result,*readed);
+ return result;
+ } else if (*buf == 0) {
+ *readed = 1;
+ ASN1_BER_LOG_DEBUG("asn1::types::length: 0 ");
+ return 0;
+ }else {
+ // Indefinit form
+ std::cerr<<"asn1::types::length indefinit form not yet supported TO BE CODED"<<std::endl;
+ }
+ return 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// any_type implementation
+///////////////////////////////////////////////////////////////////////////////
+
+//
+//
+any_type::any_type(asn1::types::type *v )
+ : m_any(v)
+{
+}
+
+//
+//
+any_type::any_type(const asn1::types::type &v)
+ : m_any(NULL)
+{
+}
+
+//
+//
+any_type::~any_type()
+{
+}
+
+//
+//
+void
+any_type::encode(asn1::context &ctx)
+{
+ if (m_any )
+ m_any->encode(ctx);
+ ctx.encode_any(*this);
+}
+
+//
+//
+int
+any_type::decode(asn1::context &ctx)
+{
+ if (m_any )
+ return m_any->decode(ctx);
+ std::cerr<<"any_type::decode TOBE CODED"<<std::endl;
+ ctx.decode_any(*this);
+ return asn1::ok;
+}
+
+//
+//
+bool
+any_type::operator == (const any_type &_c) const
+{
+ std::cerr<<"any_type == TOBE CODED"<<std::endl;
+ return false;
+}
+
+//
+//
+const asn1::tag &
+any_type::tag() const
+{
+ if (m_any != NULL)
+ {
+ return m_any->tag();
+ } else
+ return m_tag;
+}
+
+} // end of namespace types
+
+///////////////////////////////////////////////////////////////////////////////
+// prim encode/decode specialized implementations
+///////////////////////////////////////////////////////////////////////////////
+
+// Boolean
+//
+static tag BOOLEAN_tag_list[] = {
+ tag(asn1::types::UNIVERSAL,1)
+};
+const asn1::types::descriptor asn1::BOOLEAN::_meta = {
+ BOOLEAN_tag_list
+ , 1
+ , NULL
+ , 0
+ , NULL
+ , 0
+};
+
+void BOOLEAN::encode(asn1::context &ctx)
+{
+ ctx.encode_boolean(*this);
+}
+
+
+int BOOLEAN::decode(asn1::context &ctx)
+{
+ return ctx.decode_boolean(*this);
+}
+
+
+// Integer
+static tag INTEGER_tag_list[] = {
+ tag(asn1::types::UNIVERSAL,2)
+};
+const asn1::types::descriptor asn1::INTEGER::_meta = {
+ INTEGER_tag_list
+ , 1
+ , NULL
+ , 0
+ , NULL
+ , 0
+};
+size_t INTEGER::get_data_length() const
+{
+ long value = m_Prim.get_value();
+ int shift = (sizeof(value)-1)*8-1;
+
+ // remove all sequences of nine 0's or 1's at the start of the value
+ while (shift > 0 && ((value >> shift)&0x1ff) == (value < 0 ? 0x1ff : 0))
+ shift -= 8;
+
+ return (shift+9)/8;
+}
+
+void INTEGER::encode(asn1::context &ctx)
+{
+ ctx.encode_integer(*this);
+}
+int INTEGER::decode(asn1::context &ctx)
+{
+ return ctx.decode_integer(*this);
+}
+
+// UInt64
+static tag UInt64_tag_list[] = {
+ tag(asn1::types::UNIVERSAL,2)
+};
+const asn1::types::descriptor asn1::UInt64::_meta = {
+ UInt64_tag_list
+ , 1
+ , NULL
+ , 0
+ , NULL
+ , 0
+};
+/**
+ * I have an issue when running tests on 64Bits architecture.
+ * For limits DWORD eg 0xFFFFFFFF the number of bytes is 5!
+ * I need to figure out what's wrong
+ * anyway, there is an issue. Both methods return the same value.
+ */
+size_t UInt64::get_data_length() const
+{
+#if 1
+ long long value = m_Prim.get_value();
+ int intsize = sizeof(value);
+ //int intsize = 4;
+ long long mask = ((long long)0x1FF << ((intsize -1 )*8 - 1)); // Shift 8 *3 - 1 ? 0xFF800000
+ std::cerr<<"value="<<value<<" intsize="<<intsize<<" mask="<<mask<<std::endl;
+ while ( ( ((value & mask) == 0) || ((value & mask) == mask))
+ && intsize > 1) {
+ intsize--;
+ value <<=8;
+ }
+ return intsize;
+#else
+ long long value = get_value();
+ long shift = (sizeof(value)-1)*8-1;
+
+ // remove all sequences of nine 0's or 1's at the start of the value
+ while (shift > 0 && ((value >> shift)&0x1ff) == (value < 0 ? 0x1ff : 0))
+ shift -= 8;
+
+ return (shift+9)/8;
+#endif
+}
+
+void UInt64::encode(asn1::context &ctx)
+{
+ ctx.encode_integer(*this);
+}
+
+int UInt64::decode(asn1::context &ctx)
+{
+ return ctx.decode_integer(*this);
+}
+
+
+// BitString
+static tag BIT_STRING_tag_list[] = {
+ tag(asn1::types::UNIVERSAL,3)
+};
+const asn1::types::descriptor asn1::BIT_STRING::_meta = {
+ BIT_STRING_tag_list
+ , 1
+ , NULL
+ , 0
+ , NULL
+ , 0
+};
+size_t BIT_STRING::get_data_length() const
+{
+ return size() + 1;
+}
+
+void BIT_STRING::encode(asn1::context &ctx)
+{
+ ctx.encode_bitstring(*this);
+}
+int BIT_STRING::decode(asn1::context &ctx)
+{
+ return ctx.decode_bitstring(*this);
+}
+
+// OCTET String
+static tag OCTET_STRING_tag_list[] = {
+ tag(asn1::types::UNIVERSAL,4)
+};
+const asn1::types::descriptor asn1::OCTET_STRING::_meta = {
+ OCTET_STRING_tag_list
+ , 1
+ , NULL
+ , 0
+ , NULL
+ , 0
+};
+size_t OCTET_STRING::get_data_length() const
+{
+ return get_value().size();
+}
+void OCTET_STRING::encode(asn1::context &ctx)
+{
+ ctx.encode_octetstring(*this);
+}
+int OCTET_STRING::decode(asn1::context &ctx)
+{
+ return ctx.decode_octetstring(*this);
+}
+
+// Null
+static tag Null_tag_list[] = {
+ tag(asn1::types::UNIVERSAL,5)
+};
+const asn1::types::descriptor asn1::Null::_meta = {
+ Null_tag_list
+ , 1
+ , NULL
+ , 0
+ , NULL
+ , 0
+};
+void Null::encode(asn1::context &ctx)
+{
+ ctx.encode_null(*this);
+}
+
+int Null::decode(asn1::context &ctx)
+{
+ return ctx.decode_null(*this);
+}
+
+//
+// OBJECT IDENTIFIER
+ObjectIdentifier::ObjectIdentifier(int len ,const char *buf)
+ : asn1::types::type(
+ asn1::tag(asn1::types::UNIVERSAL,6)
+ )
+ , asn1::prim::types::ObjectIdentifier(len,buf)
+{
+}
+
+ObjectIdentifier::ObjectIdentifier(const asn1::tag &t)
+ : asn1::types::type( t )
+ , asn1::prim::types::ObjectIdentifier()
+{
+}
+
+ObjectIdentifier &
+ObjectIdentifier::operator =(const ObjectIdentifier &c )
+{
+ if ( &c != this)
+ {
+ asn1::prim::types::ObjectIdentifier::operator=(c);
+ }
+ return *this;
+}
+
+
+bool ObjectIdentifier::operator ==(const ObjectIdentifier &o)
+{
+ return asn1::prim::types::ObjectIdentifier::operator ==(o);
+}
+
+void ObjectIdentifier::encode(asn1::context &ctx)
+{
+ unsigned long pos = ctx.bytes();
+ unsigned char *b = ctx.buffer();
+ asn1::tag &tg= const_cast<asn1::tag &>(this->tag());
+ b[pos] = tg.byte();
+ ctx.nb_bits(8);
+
+ ASN1_BER_LOG_DEBUG("OID encode size=%zu",m_len);
+ unsigned long ipos = pos;
+ b[++pos] = m_len;
+ for (int it = 0 ; it < m_len ;it++)
+ {
+ b[++pos] = m_oid[it];
+ }
+ ctx.nb_bits((m_len + 1)<<3);
+}
+
+int ObjectIdentifier::decode(asn1::context &ctx)
+{
+ unsigned long pos = ctx.bytes();
+ unsigned char *b = ctx.buffer();
+ asn1::tag tg(0,0);
+ tg.byte(b[pos]);
+ pos++;
+ long nb = 0;
+ if (tg.get_id() == this->tag().get_id() )
+ {
+ m_len = types::length(&b[pos],&nb);
+ ASN1_BER_LOG_DEBUG("OID decode len=%ld nb=%ld",m_len,nb);
+ ctx.nb_bits((m_len<<3)+ (nb<<3)+8);
+ if (m_len > MAX_OID_LEN)
+ {
+ ASN1_BER_LOG_ERROR(" ObjectIdentifier::decode len_exceed max %ld",m_len);
+ }
+ memcpy(m_oid,&b[pos+nb],(m_len>MAX_OID_LEN)?MAX_OID_LEN:m_len);
+ } else
+ {
+ ASN1_BER_LOG_DEBUG("ObjectIdentifier::decode FAILED bad tag %d expected 6 check_tag=%d" ,tg.get_id(),ctx.check_tag());
+ return asn1::wrong_tag;
+ }
+ return asn1::ok;
+}
+
+
+// OBJECT IDENTIFIER_NG
+void OBJECT_IDENTIFIER_NG::encode(asn1::context &ctx)
+{
+ unsigned long pos = ctx.bytes();
+ unsigned char *b = ctx.buffer();
+ asn1::tag &tg= const_cast<asn1::tag &>(tag());
+ b[pos] = tg.byte();
+ ctx.nb_bits(8);
+
+ ASN1_BER_LOG_DEBUG("OID encode size=%zu",m_Prim.get_oid_length());
+ unsigned long ipos = pos;
+ b[++pos] = m_Prim.get_oid_length();
+ for (int it = 0 ; it < m_Prim.get_oid_length() ;it++)
+ {
+ b[++pos] = m_Prim.get_value()[it];
+ }
+ ctx.nb_bits((pos-ipos+1)<<3); // * 8
+}
+
+int OBJECT_IDENTIFIER_NG::decode(asn1::context &ctx)
+{
+ unsigned long pos = ctx.bytes();
+ unsigned char *b = ctx.buffer();
+ asn1::tag tg(0,0);
+ tg.byte(b[pos]);
+ pos++;
+ long nb = 0;
+ if (tg.get_id() == this->tag().get_id() )
+ {
+ int m_len = types::length(&b[pos],&nb);
+ ASN1_BER_LOG_DEBUG("OID decode len=%ld nb=%ld"
+ , m_Prim.get_oid_length(),nb);
+ ctx.nb_bits((m_Prim.get_oid_length()<<3) + (nb<<3) + 8);
+ m_Prim.from_string(m_len,(char *)&b[pos+nb]);
+ } else
+ {
+ ASN1_BER_LOG_DEBUG("DECODE OID FAILED bad tag %d expected 6 check_tag=%d" ,tg.get_id(),ctx.check_tag());
+ return asn1::wrong_tag;
+ }
+ return asn1::ok;
+}
+
+
+
+// Enumeration
+static tag ENUMERATED_tag_list[] = {
+ tag(asn1::types::UNIVERSAL,10)
+};
+const asn1::types::descriptor asn1::ENUMERATED::_meta = {
+ ENUMERATED_tag_list
+ , 1
+ , NULL
+ , 0
+ , NULL
+ , 0
+};
+size_t ENUMERATED::get_data_length() const
+{
+ return 1;
+}
+
+void ENUMERATED::encode(asn1::context &ctx)
+{
+ ASN1_BER_LOG_DEBUG("prim<0,10,Integer>(ENUMERARED)::encode tag=%d",tag().byte());
+ ctx.encode_integer(*this);
+}
+
+int ENUMERATED::decode(asn1::context &ctx)
+{
+ INTEGER i(this->tag());
+ ASN1_BER_LOG_DEBUG("prim<0,10,Integer>(ENUMERARED)::decode");
+ int ret = ctx.decode_integer(i);
+ if (ret == asn1::ok) {
+ ASN1_BER_LOG_DEBUG("prim<0,10,Integer>(ENUMERARED)::decode assign %ld to m_"
+ ,i.get_value().get_value());
+ m_Prim = i.get_value();
+ }
+ return ret;
+}
+#ifdef ASN1_TYPE_CLS
+#undef ASN1_TYPE_CLS
+#endif
+#define ASN1_TYPE_CLS(p,cls,tg,typ) \
+tag typ##_tag_list[] = { \
+ tag(cls,tg) \
+}; \
+const asn1::types::descriptor asn1::typ::_meta = { \
+ typ##_tag_list \
+ , 1 \
+ , NULL \
+ , 0 \
+ , NULL \
+ , 0 \
+}; \
+typ &typ::operator =(const char *s) \
+{ \
+ m_Prim = std::string(s); \
+ return *this; \
+} \
+size_t typ::get_data_length() const \
+ { return get_value().size() ; } \
+void typ::encode(asn1::context &ctx) \
+{ \
+ ctx.encode_string(*this); \
+} \
+int typ::decode(asn1::context &ctx) \
+{ \
+ return ctx.decode_string(*this); \
+}
+
+ASN1_TYPE_CLS(asn1::prim::types::String,asn1::types::UNIVERSAL,12,UTF8String)
+// tag 13 is RELATIVE_OID
+ASN1_TYPE_CLS(asn1::prim::types::String,asn1::types::UNIVERSAL,18,NumericString)
+ASN1_TYPE_CLS(asn1::prim::types::String,asn1::types::UNIVERSAL,19,PrintableString)
+ASN1_TYPE_CLS(asn1::prim::types::String,asn1::types::UNIVERSAL,20,TeletexString)
+ASN1_TYPE_CLS(asn1::prim::types::String,asn1::types::UNIVERSAL,21,VideotexString)
+ASN1_TYPE_CLS(asn1::prim::types::String,asn1::types::UNIVERSAL,22,IA5String)
+ASN1_TYPE_CLS(asn1::prim::types::String,asn1::types::UNIVERSAL,25,GraphicString)
+ASN1_TYPE_CLS(asn1::prim::types::String,asn1::types::UNIVERSAL,26,VisibleString)
+ASN1_TYPE_CLS(asn1::prim::types::String,asn1::types::UNIVERSAL,27,GeneralString)
+ASN1_TYPE_CLS(asn1::prim::types::String,asn1::types::UNIVERSAL,29,UniversalString)
+ASN1_TYPE_CLS(asn1::prim::types::String,asn1::types::UNIVERSAL,30,BMPString)
+
+// GeneralizedTime
+static tag GeneralizedTime_tag_list[] = {
+ tag(asn1::types::UNIVERSAL,24)
+};
+const asn1::types::descriptor asn1::GeneralizedTime::_meta = {
+ GeneralizedTime_tag_list
+ , 1
+ , NULL
+ , 0
+ , NULL
+ , 0
+};
+void GeneralizedTime::encode(asn1::context &ctx)
+{
+ //ctx.encode_octetstring(*this);
+}
+int GeneralizedTime::decode(asn1::context &ctx)
+{
+ return asn1::wrong_tag;
+ //return ctx.decode_string(*this);
+}
+
+// UTCTime
+static tag UTCTime_tag_list[] = {
+ tag(asn1::types::UNIVERSAL,23)
+};
+const asn1::types::descriptor asn1::UTCTime::_meta = {
+ UTCTime_tag_list
+ , 1
+ , NULL
+ , 0
+ , NULL
+ , 0
+};
+void UTCTime::encode(asn1::context &ctx)
+{
+ //ctx.encode_octetstring(*this);
+}
+int UTCTime::decode(asn1::context &ctx)
+{
+ return asn1::wrong_tag;
+ //return ctx.decode_string(*this);
+}
+
+
+// Null
+void EXTERNAL::encode(asn1::context &ctx)
+{
+ ASN1_BER_LOG_DEBUG("EXTERNAL::encode TODO");
+}
+
+int EXTERNAL::decode(asn1::context &ctx)
+{
+ ASN1_BER_LOG_DEBUG("EXTERNAL::decode TODO");
+ return asn1::wrong_tag;
+}
+///////////////////////////////////////////////////////////////////////////////
+// prim codec specialized implementations
+///////////////////////////////////////////////////////////////////////////////
+
+
+// REAL;
+static tag REAL_tag_list[] = {
+ tag(asn1::types::UNIVERSAL,9)
+};
+const asn1::types::descriptor asn1::REAL::_meta = {
+ REAL_tag_list
+ , 1
+ , NULL
+ , 0
+ , NULL
+ , 0
+};
+void REAL::encode(asn1::context &ctx)
+{
+ ASN1_BER_LOG_DEBUG("REAL::encode TODO");
+
+}
+
+int REAL::decode(asn1::context &ctx)
+{
+ ASN1_BER_LOG_DEBUG("REAL::decode TODO");
+ return asn1::ok;
+}
+
+//
+//ENUMERATED;
+namespace types {
+
+//////////////////////////////////////////////////////////////////
+
+/**
+ *
+ */
+choice_type::choice_type( unsigned int k
+ , const asn1::tag &t
+ , const descriptor *_d
+ )
+ : m_kind(k), m_choice(NULL)
+ , asn1::types::type(t)
+ , m_desc(_d)
+{
+// ASN1_BER_LOG_DEBUG("choice_type(%p)::choice_type(%d) ",this,m_kind );
+}
+
+choice_type::choice_type(const asn1::tag &t,const descriptor *_d)
+ : m_kind(t.get_tag()), m_choice(NULL),asn1::types::type(t)
+ , m_desc(_d)
+{
+// ASN1_BER_LOG_DEBUG("choice_type::choice_type(%d) ",m_kind );
+}
+
+choice_type::choice_type(const choice_type &t) : m_kind(t.m_kind)
+ , asn1::types::type(t)
+ , m_choice(NULL)
+ , m_desc(t.m_desc)
+{
+ ASN1_BER_LOG_DEBUG("choice_type::choice_type(const choice_type &) t.m_choice=%p m_kind=%d tag=%ld"
+ ,t.m_choice,t.m_kind,t.m_tag.get_tag() );
+ if (this == &t)
+ {
+ return;
+ }
+ if (t.m_choice)
+ {
+ m_tag = t.m_tag;
+ m_choice = t.m_choice->clone();
+ } else
+ {
+ m_tag = t.m_tag;
+ m_choice = NULL;
+ }
+
+}
+
+/**
+ *
+ */
+bool choice_type::get_object()
+{
+ return this->create_object();
+
+}
+
+
+size_t choice_type::get_data_length() const
+{
+ if (m_choice)
+ return m_choice->get_data_length();
+ assert(0 && " choice_type::get_data_length nothing selected") ;
+ return 0;
+}
+
+// Get the current member. NULL if not found
+member_desc *
+choice_type::get_member() const
+{
+ int _count = 0;
+ assert((m_desc != NULL) && "mdesc should always be initialized not NULL.");
+ for ( ; _count < m_desc->m_t2elcount ; _count++)
+ {
+ if (m_tag.get_tag() == m_desc->m_t2el[_count].m_tag )
+ {
+ return &m_desc->m_members[m_desc->m_t2el[_count].m_elidx];
+ }
+ }
+ return NULL;
+}
+
+bool choice_type::check_create()
+{
+ ASN1_BER_LOG_DEBUG("choice_type(%p)::check_create kind=%d tag=%ld",this,m_kind,m_tag.get_tag() );
+ if (m_choice != NULL)
+ return true;
+ if ( create_object() )
+ {
+ member_desc *m = get_member() ;
+ if (m && ( m->m_tmode == 1) )
+ {
+ ASN1_BER_LOG_DEBUG("choice_type(%p)::check_create kind=%d tag=%ld EXPLICIT No tag propagation"
+ ,this,m_kind,m_tag.get_tag() );
+ return true;
+ }
+ if (m_tag.byte() != 0)
+ {
+ m_choice->set_tag(m_tag);
+ }
+ return true;
+ }
+ std::cerr<<"choice_type::check_create "<<this<<" failed"<<std::endl;
+ return false;
+}
+/**
+ *
+ */
+choice_type & choice_type::operator =(const choice_type &c)
+{
+#ifdef DEBUG
+ std::string name = typeid(*this).name();
+ std::string nc = typeid(c).name();
+ ASN1_BER_LOG_DEBUG("choice_type::operator = of %s %s",name.c_str(),nc.c_str() );
+#endif
+ if (this != &c)
+ {
+ if (m_choice) {
+ delete m_choice;
+ m_choice = NULL;
+ }
+ if (c.m_choice)
+ {
+ m_tag = c.m_tag;
+ m_kind = c.m_kind;
+ m_choice = c.m_choice->clone();
+ std::string x = typeid(*m_choice).name();
+ std::string xo = typeid(*c.m_choice).name();
+ ASN1_BER_LOG_DEBUG("choice_type::operator = kind=%d tg=%d m_choice %s = %s"
+ ,m_kind
+ ,m_tag.byte()
+ ,x.c_str()
+ ,xo.c_str());
+ } else
+ {
+#ifdef DEBUG
+ ASN1_BER_LOG_DEBUG("choice_type::operator = c.m_choice is nul for %s",name.c_str() );
+#endif
+ }
+ } else
+ {
+#ifdef DEBUG
+ ASN1_BER_LOG_DEBUG("choice_type::operator = copy to myself go awayof %s",name.c_str() );
+#endif
+ }
+ return *this;
+}
+
+/**
+ *
+ */
+bool choice_type::operator == (const choice_type &_c) const
+{
+#ifdef DEBUG
+ std::string name = typeid(*this).name();
+ ASN1_BER_LOG_DEBUG("choice_type::operator == %s",name.c_str() );
+#endif
+ return false;
+}
+
+/**
+ *
+ */
+choice_type::~choice_type() {
+// ASN1_BER_LOG_DEBUG("choice_type::~choice_type delete %d",m_kind);
+ if (m_choice)
+ delete m_choice;
+}
+
+/**
+ *
+ */
+bool choice_type::primitive() const
+{
+ if (m_choice)
+ return m_choice->primitive();
+ return true;
+}
+const asn1::tag &choice_type::tag() const
+{
+ if (m_choice)
+ return m_choice->tag();
+ return type::tag();
+}
+
+void
+choice_type::set_tag(const asn1::tag &t)
+{
+ ASN1_BER_LOG_DEBUG("choice_type(%p)::set_tag kind=%d class=%d id=%d"
+ , this
+ , m_kind
+ , t.get_class()
+ , t.get_id() );
+ if (m_choice)
+ delete m_choice;
+ m_choice = NULL;
+ // Is this always correct ? Most of the time. Don't remove
+ // Until you come out with a better idea
+ m_kind = t.get_tag( ) ;
+ asn1::types::type::set_tag(t);
+ if (this->create_object() )
+ {
+ member_desc *m = get_member() ;
+ if (m && ( m->m_tmode == 1) )
+ {
+ ASN1_BER_LOG_DEBUG( "choice_type(%p)::set_tag EXPLICIT dont' propagate"
+ , this
+ );
+ return ;
+ }
+ m_choice->set_tag(t);
+ }
+}
+// New way
+void choice_type::encode(asn1::context &ctx)
+{
+ ASN1_BER_LOG_DEBUG("choice_type::encode delegate to ctx " );
+ ctx.encode_choice(*this);
+}
+
+int choice_type::decode(asn1::context &ctx)
+{
+ std::string name = typeid(*this).name();
+ std::string name1;
+ if ( m_choice != NULL)
+ {
+ name1 = typeid(*m_choice).name();
+ delete m_choice ;
+ m_choice = NULL;
+ } else
+ name1 = "NULL";
+ ASN1_BER_LOG_DEBUG("choice_type::decode %s m_choice is %s (deleted) delegate to ctx",name.c_str(),name1.c_str() );
+ if ( m_choice && (dynamic_cast<choice_type *>(m_choice) == NULL))
+ {
+ ASN1_BER_LOG_DEBUG("choice_type::decode %s delegate to ctx NOT A CHOICE ",name.c_str() );
+ return m_choice->decode(ctx);
+ }
+ return ctx.decode_choice(*this);
+}
+
+ // New way specific for ber
+void choice_type::encode_ber(asn1::streams::ber &ctx)
+{
+ unsigned long m_pos = ctx.bytes();
+ unsigned char *m_buffer = ctx.buffer();
+ if (m_choice)
+ m_choice->encode(ctx);
+ m_buffer[m_pos++] = this->tag().byte();
+}
+
+int choice_type::decode_ber(asn1::streams::ber &ctx)
+{
+ asn1::tag t(0,0);
+ std::string name = typeid(*this).name();
+ unsigned long m_pos = ctx.bytes();
+ unsigned char *m_buffer = ctx.buffer();
+ int len = 0;
+ ASN1_BER_LOG_DEBUG("choice_type::decode_ber %s stream tag = %d"
+ , name.c_str()
+ , m_buffer[m_pos]
+ );
+
+ if (ctx.decode_tag(t,len) )
+ {
+ set_tag(t);
+ if (check_create())
+ {
+ std::string name = typeid(*this).name();
+ std::string name1 = typeid(*m_choice).name();
+ // Very ugly .... If m_choice is of type Choice
+ // It must be an explicit tag, Should be handled by parser
+ member_desc *m = get_member() ;
+ if (m && ( m->m_tmode == 1) )
+ {
+ std::cerr<<"choice_type::"<<__FUNCTION__<<" "<<name;
+ std::cerr<<" m_choice "<<name1<<" tag= "<<t.get_tag();
+ std::cerr<<" Still Buggy with EXPLICIT tag member "<<std::endl;
+ } else
+ ctx.bytes(m_pos);
+ //
+ int res = m_choice->decode(ctx);
+ if (res != asn1::ok)
+ {
+ ASN1_BER_LOG_ERROR("choice_type(%s)::decode_ber m_choice(%s)->decode failed tag = %d pos=%lu but tag was correct %d"
+ ,name.c_str()
+ ,name1.c_str()
+ ,t.byte()
+ , m_pos
+ , m_choice->tag().byte()
+ );
+ ctx.bytes(m_pos);
+ }
+ return res;
+ } else
+ {
+ ASN1_BER_LOG_ERROR("choice_type::decode_ber Failed %s tag=%d check create did not work",name.c_str(),t.byte() );
+ }
+ }
+ ctx.bytes(m_pos);
+ ASN1_BER_LOG_ERROR("choice_type::decode_ber Failed " );
+ return asn1::unknown;
+}
+
+void choice_type::printf(std::ostream &os) const
+{
+ if (m_choice)
+ {
+ member_desc *m = get_member() ;
+ os<<m->m_name<<" :";
+ m_choice->printf(os);
+ }
+}
+
+/**
+ * implement sequence
+ */
+sequence_type::sequence_type(const asn1::tag &t) : asn1::types::type(t)
+{
+}
+
+
+
+sequence_type::~sequence_type()
+{
+}
+
+
+sequence_type & sequence_type::operator = (const sequence_type &c)
+{
+ return *this;
+}
+
+
+bool
+sequence_type:: primitive() const
+{
+ return false;
+}
+
+
+const asn1::tag &sequence_type::tag() const
+{
+ ASN1_BER_LOG_DEBUG("sequence_type::tag return %d ",type::tag().byte() );
+ return type::tag();
+}
+
+size_t sequence_type::get_data_length() const
+{
+ assert (0) ;
+}
+ // New way
+void sequence_type::encode_preamble(asn1::context &ctx)
+{
+ m_pos = ctx.bytes();
+ m_buffer = ctx.buffer();
+ ctx.encode_sequence_preamble(*this);
+}
+
+void sequence_type::encode_preamble_ber(asn1::context &ctx)
+{
+ m_pos = ctx.bytes();
+ m_buffer = ctx.buffer();
+ m_buffer[m_pos++] = this->tag().byte();
+ ctx.nb_bits(16); // tag done
+}
+
+void sequence_type::encode_epilogue_ber(asn1::context &ctx)
+{
+ unsigned long len = ctx.bytes() - m_pos - 1;
+ m_buffer[m_pos] = len;
+}
+
+int sequence_type::decode_preamble_ber(asn1::streams::ber &ctx)
+{
+ return asn1::ok;
+}
+
+int sequence_type::decode_epilogue_ber(asn1::streams::ber &ctx)
+{
+ return asn1::ok;
+}
+
+/**
+ * Generic encoding decoding
+ */
+void sequence_type::encode_epilogue(asn1::context &ctx)
+{
+ ctx.encode_sequence_epilogue(*this);
+}
+
+
+int sequence_type::decode_preamble(asn1::context &ctx)
+{
+ int len;
+ m_pos = ctx.bytes();
+ m_buffer = ctx.buffer();
+ asn1::tag &tg= const_cast<asn1::tag &>(tag());
+ return ctx.decode_sequence_preamble(*this);
+}
+
+int sequence_type::decode_epilogue(asn1::context &ctx)
+{
+ unsigned long len = ctx.bytes() - m_pos - 1;
+ return ctx.decode_sequence_epilogue(*this);
+}
+
+
+void sequence_type::encode(asn1::context &ctx)
+{
+ encode_preamble(ctx);
+}
+
+int sequence_type::decode(asn1::context &ctx)
+{
+ return decode_preamble(ctx);
+}
+
+
+
+// End of namespace types
+}
+
+
+};
--- /dev/null
+#ifndef ASN1_TYPES_H__
+#define ASN1_TYPES_H__
+#include <iostream>
+#include <list>
+
+#include "rtasn1/asn1_errors.h"
+
+#define MEMBER_OFFSET(cls,mbr) ((ptrdiff_t)&(((cls *)0)->mbr) - (ptrdiff_t)((cls *)0))
+
+namespace asn1
+{
+ class context;
+ class codecJER;
+ class codecBER;
+ class codecOER;
+}
+
+namespace asn1 {
+
+/* basic types that will be used by codecs, and so on */
+typedef unsigned char byte; /* 8 bits data */
+typedef unsigned short word; /* 16 bits data */
+
+
+namespace types {
+
+//int debug_level;
+
+typedef enum {
+ UNIVERSAL,
+ APPLICATION,
+ CONTEXT_SPECIFIC,
+ PRIVATE
+} tag_class;
+
+
+/**
+ * The descriptors below are provided for choice because I was unable to
+ * come up with code that would work properly due to implicit / explicit
+ * tagging.
+ * I might considerer using this structures for set and sequence as well.
+ */
+struct member_desc;
+struct tag2member_desc;
+enum type_flags {
+ TF_NONE ,
+ TF_POINTER = 0x01,
+ TF_SHARED_POINTER = 0x02,
+ TF_OPEN_TYPE = 0x04
+};
+struct descriptor {
+ tag *m_tags;
+ unsigned int m_tagcount;
+ /**
+ * For Sequence, Set and Choice
+ */
+ struct member_desc *m_members; /* array of member descriptors */
+ int m_elcount; /* number of elements in struct */
+ struct tag2member_desc *m_t2el; /* */
+ long m_t2elcount; /* number of elements in t2el arr */
+};
+
+
+struct member_desc {
+ enum type_flags m_flags;
+ long m_tmode; /* tag mode EXPLICIT(1) or IMPLICIT(-1) */
+ long m_tag; /* tag value id<<2 |class */
+ int m_member_offser; /* Member offset */
+ long m_midx; /* member index is structure */
+ struct descriptor *m_type; /* member type descriptor */
+ const char *m_name; /* member str name for display */
+};
+
+/**
+ * Most of the time m_kind == m_tag
+ */
+struct tag2member_desc {
+ long m_tag; /* tag of the element */
+ long m_kind; /* This is a bit confusing.. */
+ int m_elidx; /* element index for the tag */
+};
+
+/**
+ *
+ */
+enum constraint_type {
+ un_constrained = 0
+ , partial_constrained
+ , fixed_constrained
+ , extendable_constrained
+};
+
+struct constraint_desc {
+ constraint_type m_t;
+ long m_l;
+ long m_u;
+};
+
+/** Functions
+ * - length will go
+ * - count_bits will be used to compute the length of an integer
+ *
+ */
+long length(unsigned char *buf, long *_read);
+
+size_t count_bits(unsigned int val);
+
+/**
+ * @brief top class for asn1 types.
+ */
+class type
+{
+ protected:
+ type(const type &t) ;
+
+ public:
+ type(int c = 0,int tid=0) ;
+
+ type(const asn1::tag &t) ;
+
+ virtual ~type() ;
+ // For the intrusive pointer managment
+ inline void add_ref()
+ {m_ref++;}
+
+ inline void release()
+ {if (--m_ref == 0) delete this;}
+
+ virtual bool primitive() const ;
+ // Return length of encoded type tag + len + data
+ size_t get_length() const;
+ // return only data length. Can'e declare
+ // as pure virtual because og object and objectclass templates
+ virtual size_t get_data_length() const
+ { return 0;}
+ virtual void set_tag(const asn1::tag &t) ;
+
+
+ // Needed for copy constructor choice
+ virtual type *clone() ;
+
+ // encoding / decoding mechanism.
+
+ virtual void encode(asn1::context &ctx) ;
+
+ virtual int decode(asn1::context &ctx) ;
+
+ virtual bool equal(const type &c)
+ {
+ std::cerr<<"type::equal should not be called"<<std::endl;
+ return false;
+ };
+ virtual const asn1::tag &tag() const ;
+
+ virtual void printf(std::ostream &os) const ;
+ friend std::ostream &operator <<(std::ostream &os, const type &s)
+ {
+ os<<" asn1::type ";
+ return os;
+ };
+ protected:
+ asn1::tag m_tag;
+ private:
+ int m_ref;
+};
+
+
+/**
+ * Temporary class to be removed
+ * once completely moved code to codecBER
+ */
+class strtype : public asn1::types::type
+{
+ public:
+ strtype(int a,int b) : asn1::types::type(a,b) {}
+ strtype(const asn1::tag &t) : asn1::types::type(t) {}
+
+ virtual asn1::prim::types::String & get_prim() = 0;
+ const asn1::prim::types::String & get_prim() const
+ { return const_cast<strtype *>(this)->get_prim(); };
+};
+
+/**
+ * container The fact that is a template and contains a
+ * vector is not really how it should be.
+ * Constructed types are sequences, choice, and any. This type
+ * should only be used for user interfaces.
+ */
+template <typename T>
+class container : public asn1::types::type
+{
+ public:
+ typedef T prim_type;
+ typedef T type;
+ typedef typename std::vector<T> items;
+ typedef typename std::vector<T>::iterator iterator;
+ typedef typename std::vector<T>::const_iterator const_iterator;
+
+ inline container(const asn1::tag &t)
+ : asn1::types::type(t)
+ {
+#if 0
+ std::cerr<<"container::container(t="<<(int)t.byte()<<")\n";
+ std::cerr<<"Liste size="<<m_.size()<<std::endl;
+#endif
+ };
+
+ inline container(const container<T> &c)
+ {
+ std::cout<<"cp :"<<c.m_.size()<<std::endl;
+ m_ = c.m_;
+ }
+
+ inline container(const T &c)
+ {
+ m_.push_back(c);
+ }
+
+ inline void operator=(const container<T> &c)
+ {
+#if 0
+ std::cout<<"container::cp copy " <<c.m_.size()<<std::endl;
+#endif
+ m_ = c.m_;
+ }
+
+ inline void operator=(const T&c) {
+ m_.push_back(c);
+ }
+
+ inline iterator begin()
+ {
+ return m_.begin();
+ };
+ inline const_iterator begin() const
+ {
+ return m_.begin();
+ };
+
+ inline iterator end()
+ {
+ return m_.end();}
+ ;
+ inline const_iterator end() const
+ {
+ return m_.end();}
+ ;
+
+ inline void push_back(T &t) {
+ m_.push_back(t);
+ };
+
+ virtual bool primitive() const
+ { return false; };
+
+ /**/
+ virtual const asn1::tag &tag() const
+ {
+ // std::cerr<<"container::tag\n";
+ static asn1::tag t = asn1::tag(0,0);
+ if (this->m_tag.byte() != 0)
+ {
+ return m_tag;
+ }
+ else
+ return t;
+ };
+
+ size_t size() const
+ {
+ return m_.size();
+ }
+ void resize(size_t t)
+ {
+ m_.resize(t);
+ }
+ void printf(std::ostream &os) const
+ {
+ int count = 0;
+ const_iterator mit = begin();
+ os << " container "<<std::endl;
+ for (;
+ mit != end();
+ ++mit)
+ {
+ std::streamsize indent = os.precision() + 2;
+ os<<std::setw(indent+2)<<"["<<count++<<"] "<<std::setprecision(indent);
+ os<<(*mit);
+ //(*mit).printf(os);
+ os<<"\n";
+ os<<std::setprecision(indent-2);
+ }
+ }
+ protected:
+ items m_;
+};
+
+/**
+ * @brief any is a container class more precisely a variat
+ * object. It represents ASN1 type.
+ * -> The constructor should use a tag and build the
+ * appropriate object according to the tag.
+ */
+class any_type : public asn1::types::type
+{
+ protected:
+ asn1::types::type *m_any;
+ public:
+ any_type(asn1::types::type *v = NULL);
+
+ any_type(const asn1::types::type &v);
+
+ ~any_type();
+ // Cast operator
+ // operator T() {return *m_any;}
+ // const T* operator *() {return m_any;}
+ virtual size_t get_data_length() const
+ { return 0 ; }
+
+ virtual void encode(asn1::context &ctx) ;
+
+ virtual int decode(asn1::context &ctx) ;
+
+ bool operator == (const any_type &_c) const ;
+
+ virtual const asn1::tag &tag() const ;
+
+ friend std::ostream &operator <<(std::ostream &os, const any_type &s)
+ {
+ //os<<" tag("<<C<<","<<I<<"){"<<(asn1::prim::types::Integer)s<<"}";
+ os<<" ANY Not ";
+ return os;
+ };
+};
+
+/**
+ *
+ *
+ */
+class choice_type : public asn1::types::type
+{
+ protected:
+ const descriptor *m_desc;
+ // copy constructor
+ choice_type(const choice_type &c) ;
+ public:
+ choice_type( unsigned int kind
+ , const asn1::tag &t = asn1::tag(0,0)
+ , const descriptor *_d = NULL
+ );
+ choice_type( const asn1::tag &t = asn1::tag(0,0)
+ , const descriptor *_d = NULL
+ );
+
+
+ virtual ~choice_type();
+
+ choice_type & operator = (const choice_type &c);
+
+ choice_type &get_value() { return *this; };
+ const choice_type &get_value() const { return *this; };
+
+ virtual choice_type *clone()
+ {
+ ASN1_BER_LOG_ERROR("choice_type::clone should never be called");
+ return NULL;
+ //return new choice_type(*this);
+ }
+ //
+ //
+ virtual bool create_object() = 0;
+ // check if m_choice != NULL if not create
+ bool check_create() ;
+
+ virtual void set_tag(const asn1::tag &t);
+
+ inline unsigned int get_kind() const { return m_kind;} ;
+
+ virtual bool primitive() const ;
+
+ bool operator == (const choice_type &_c) const;
+
+ virtual const asn1::tag &tag() const ;
+
+ virtual size_t get_data_length() const ;
+ // New way
+ virtual void encode(asn1::context &ctx) ;
+ virtual int decode(asn1::context &ctx) ;
+ // New way specific for ber .. Does not work !!!
+ virtual void encode_ber(asn1::streams::ber &ctx) ;
+
+ virtual int decode_ber(asn1::streams::ber &ctx) ;
+
+ virtual void printf(std::ostream &os) const ;
+
+ friend class ::asn1::codecJER;
+ friend class ::asn1::codecBER;
+
+ protected:
+ bool get_object();
+ // Get the current member. NULL if not found
+ member_desc *get_member() const;
+ // Attributes
+ asn1::types::type *m_choice;
+ unsigned int m_kind;
+};
+
+/**
+ *
+ *
+ */
+class sequence_type : public asn1::types::type
+{
+ // copy constructor
+ //sequence_type(const sequence_type &c);
+ public:
+ sequence_type(const asn1::tag &t = asn1::tag(0,16,true));
+
+ virtual ~sequence_type();
+
+ sequence_type & operator = (const sequence_type &c);
+
+ sequence_type &get_value() { return *this; };
+ const sequence_type &get_value() const { return *this; };
+
+ virtual bool primitive() const ;
+
+ virtual const asn1::tag &tag() const ;
+
+ virtual size_t get_data_length() const;
+
+ // New way
+ virtual void encode(asn1::context &ctx) ;
+ virtual int decode(asn1::context &ctx) ;
+
+ virtual void encode_preamble(asn1::context &ctx);
+ virtual void encode_epilogue(asn1::context &ctx);
+ virtual int decode_preamble(asn1::context &ctx);
+ virtual int decode_epilogue(asn1::context &ctx);
+ // May be specific functions here BER / PER / XER / OT
+ virtual void encode_preamble_ber(asn1::context &ctx);
+ virtual void encode_epilogue_ber(asn1::context &ctx);
+
+ virtual int decode_preamble_ber(asn1::streams::ber &ctx);
+ virtual int decode_epilogue_ber(asn1::streams::ber &ctx);
+
+ protected:
+ unsigned char * m_buffer;
+ unsigned long m_pos;
+};
+
+/* end of namespace types */
+}
+
+
+// class asn1t : public asn1::types::prim<typ> {
+/* In namespace asn1 */
+#define ASN1_TYPE_CLS_GEN(parent,typ,cls,tg,asn1t) \
+ class asn1t : \
+ public asn1::types::parent { \
+ protected: \
+ typ m_Prim; \
+ public: \
+ typedef typ prim_type; \
+ typedef typ* prim_type_pointer; \
+ typedef typ& prim_type_reference; \
+ typedef const typ& prim_type_const_reference;\
+ ~asn1t() {} \
+ asn1t(const asn1::tag &t = asn1::tag(cls,tg)) \
+ : asn1::types::parent(t) \
+ {}; \
+ asn1t(const asn1t &v) \
+ : m_Prim(v.m_Prim) , asn1::types::parent(v.m_tag) \
+ { } ; \
+ inline asn1t(const typ &c) \
+ : asn1::types::parent(asn1::tag(cls,tg)) \
+ , m_Prim(c) \
+ { }; \
+ inline asn1t(const typ::prim_type &c) \
+ : asn1::types::parent(asn1::tag(cls,tg)) \
+ , m_Prim(c) \
+ { }; \
+ \
+ prim_type get_value() const \
+ { \
+ return m_Prim; \
+ } \
+ prim_type_reference get_value() \
+ { \
+ return m_Prim; \
+ } \
+ prim_type::prim_type get_sys_value() const \
+ { \
+ return m_Prim.get_value(); \
+ } \
+ virtual asn1t *clone() \
+ { \
+ return new asn1t(*this); \
+ }; /* Needed for copy constructor choice */ \
+ /** */ \
+ bool equal(const asn1::types::type &t) \
+ { \
+ const asn1t *c = dynamic_cast<const asn1t *>(&t); \
+ std::cerr<<"prim::equal "<<c<<std::endl; \
+ if (c) \
+ { \
+ return m_Prim == c->get_value(); \
+ } else \
+ return false ; \
+ } \
+ /** */ \
+ inline asn1t &operator =(const asn1t &t) \
+ { \
+ m_Prim = t.m_Prim; return *this; \
+ }; \
+ \
+ virtual const asn1::tag &tag() const \
+ { \
+ static asn1::tag t = asn1::tag(cls,tg); \
+ if (m_tag.byte() > 0) \
+ { \
+ return m_tag; \
+ } else return t; \
+ }; \
+ \
+ /** Will be new way */ \
+ virtual void encode(asn1::context &ctx); \
+ \
+ virtual int decode(asn1::context &ctx); \
+ \
+ virtual void printf(std::ostream &os) const \
+ {os<<*this;}; \
+ \
+ friend std::ostream &operator <<(std::ostream &os, const asn1t &s)\
+ { \
+ os<<" tag("<<cls<<","<<tg<<"){"; \
+ os<<(s.m_Prim);os<<"}"; \
+ return os; \
+ }; \
+ static const types::descriptor _meta;
+
+
+/* Class completion macro mainly for missing ctors like long, int ... */
+#define ASN1_TYPE_CLS_ADD_BOOLEAN(parent,typ,cls,tg) \
+ inline BOOLEAN(const bool c) \
+ : asn1::types::parent(asn1::tag(cls,tg)) \
+ , m_Prim(c) \
+ { }; \
+ inline BOOLEAN &operator =(const bool m) \
+ { m_Prim =m; return *this; } \
+ inline bool operator ==(const bool m) const \
+ { return m_Prim ==(m); } \
+ inline bool operator ==(const BOOLEAN &m) const \
+ { return m_Prim == m.m_Prim; } \
+ virtual size_t get_data_length() const \
+ { return 1 ; }
+
+#define ASN1_TYPE_CLS_ADD_INTEGER(parent,typ,cls,tg) \
+ inline INTEGER(const int c) \
+ : asn1::types::parent(asn1::tag(cls,tg)) \
+ , m_Prim(c) \
+ { }; \
+ virtual size_t get_data_length() const; \
+ inline INTEGER &operator =(const int m) \
+ { m_Prim = m; return *this; } \
+ inline bool operator==(const INTEGER &o) const \
+ { return m_Prim == o.m_Prim; }; \
+ inline bool operator==(const long o) const \
+ { return m_Prim == o; }; \
+
+#define ASN1_TYPE_CLS_ADD_Int8(parent,typ,cls,tg) \
+ virtual size_t get_data_length() const \
+ { return 1 ; }
+#define ASN1_TYPE_CLS_ADD_Int16(parent,typ,cls,tg) \
+ virtual size_t get_data_length() const \
+ { return 2 ; }
+#define ASN1_TYPE_CLS_ADD_Int32(parent,typ,cls,tg) \
+ virtual size_t get_data_length() const \
+ { return 4 ; }
+#define ASN1_TYPE_CLS_ADD_Int64(parent,typ,cls,tg) \
+ virtual size_t get_data_length() const \
+ { return 8 ; }
+#define ASN1_TYPE_CLS_ADD_UInt8(parent,typ,cls,tg) \
+ virtual size_t get_data_length() const \
+ { return 1 ; }
+#define ASN1_TYPE_CLS_ADD_UInt16(parent,typ,cls,tg) \
+ virtual size_t get_data_length() const \
+ { return 2 ; }
+#define ASN1_TYPE_CLS_ADD_UInt32(parent,typ,cls,tg) \
+ virtual size_t get_data_length() const \
+ { return 4 ; }
+#define ASN1_TYPE_CLS_ADD_UInt64(parent,typ,cls,tg) \
+ inline UInt64(const unsigned long c) \
+ : asn1::types::parent(asn1::tag(cls,tg)) \
+ , m_Prim(c) \
+ { }; \
+ virtual size_t get_data_length() const; \
+ inline UInt64 &operator =(const typ::prim_type m) \
+ { m_Prim = m; return *this; } \
+ inline bool operator==(const UInt64 &o) const \
+ { return m_Prim == o.m_Prim; }; \
+ inline bool operator==(const typ::prim_type m) const \
+ { return m_Prim == m; }; \
+
+#define ASN1_TYPE_CLS_ADD_BIT_STRING(parent,typ,cls,tg) \
+ virtual size_t get_data_length() const; \
+ size_t size() const { return m_Prim.size();} \
+ inline size_t get_nb_bits() const \
+ { return m_Prim.get_nb_bits();} \
+ inline void set_nb_bits(int i) \
+ { return m_Prim.set_nb_bits(i);} \
+ typ::const_reference operator[](int idx) const \
+ { return m_Prim[idx]; } \
+ typ::reference operator[](int idx) \
+ { return m_Prim[idx]; } \
+ inline bool operator==(const BIT_STRING &o) const \
+ { return m_Prim == o.m_Prim; }; \
+
+#define ASN1_TYPE_CLS_ADD_OCTET_STRING(parent,typ,cls,tg) \
+ inline OCTET_STRING(const char *c) \
+ : asn1::types::parent(asn1::tag(cls,tg)) \
+ , m_Prim(c) \
+ { }; \
+ virtual size_t get_data_length() const; \
+ inline bool operator==(OCTET_STRING &o) const \
+ { return m_Prim == o.m_Prim; }; \
+
+#define ASN1_TYPE_CLS_ADD_STRING(parent,typ,cls,tg) \
+ inline STRING(const char *c) \
+ : asn1::types::parent(asn1::tag(cls,tg)) \
+ , m_Prim(c) \
+ { }; \
+ inline bool operator==(STRING &o) const \
+ { return m_Prim == o.m_Prim; }; \
+ virtual size_t get_data_length() const \
+ { return 0 ; }
+#define ASN1_TYPE_CLS_ADD_Null(parent,typ,cls,tg) \
+ virtual size_t get_data_length() const \
+ { return 0 ; } \
+ inline bool operator==(Null &o) const \
+ { return true; }; \
+
+#define ASN1_TYPE_CLS_ADD_EXTERNAL(parent,typ,cls,tg) \
+ virtual size_t get_data_length() const \
+ { return 0 ; }
+#define ASN1_TYPE_CLS_ADD_GeneralizedTime(parent,typ,cls,tg) \
+ virtual size_t get_data_length() const \
+ { return 0 ; } \
+ inline bool operator ==(const GeneralizedTime &m) const \
+ { return m_Prim == m.m_Prim; } \
+
+#define ASN1_TYPE_CLS_ADD_UTCTime(parent,typ,cls,tg) \
+ virtual size_t get_data_length() const \
+ { return 0 ; } \
+ inline bool operator ==(const UTCTime &m) const \
+ { return m_Prim == m.m_Prim; } \
+
+#define ASN1_TYPE_CLS_ADD_REAL(parent,typ,cls,tg) \
+ inline REAL(const double c) \
+ : asn1::types::parent(asn1::tag(cls,tg)) \
+ , m_Prim(c) \
+ { }; \
+ inline REAL &operator =(const double m) \
+ { m_Prim == m; return *this; } \
+ inline bool operator ==(const REAL &m) const \
+ { return m_Prim == m.m_Prim; } \
+ virtual size_t get_data_length() const \
+ { return 0 ; }
+
+#define ASN1_TYPE_CLS_ADD_ENUMERATED(parent,typ,cls,tg) \
+ friend class ::asn1::codecJER; \
+ virtual size_t get_data_length() const; \
+
+#define ASN1_TYPE_CLS_ADD_UTF8String(parent,typ,cls,tg) \
+ inline UTF8String(const char *c) \
+ : asn1::types::parent(asn1::tag(cls,tg)) \
+ , m_Prim(c) \
+ { }; \
+ UTF8String &operator =(const char *s); \
+ inline bool operator ==(const UTF8String &m) const \
+ { return m_Prim == m.m_Prim; } \
+ virtual size_t get_data_length() const; \
+ virtual asn1::prim::types::String & get_prim() \
+ { return m_Prim;};
+
+#define ASN1_TYPE_CLS_ADD_NumericString(parent,typ,cls,tg)\
+ inline NumericString(const char *c) \
+ : asn1::types::parent(asn1::tag(cls,tg)) \
+ , m_Prim(c) \
+ { }; \
+ NumericString &operator =(const char *s); \
+ inline bool operator ==(const NumericString &m) const \
+ { return m_Prim == m.m_Prim; } \
+ virtual size_t get_data_length() const; \
+ virtual asn1::prim::types::String & get_prim() \
+ { return m_Prim;};
+
+#define ASN1_TYPE_CLS_ADD_PrintableString(parent,typ,cls,tg) \
+ inline PrintableString(const char *c) \
+ : asn1::types::parent(asn1::tag(cls,tg)) \
+ , m_Prim(c) \
+ { }; \
+ PrintableString &operator =(const char *s); \
+ inline bool operator ==(const PrintableString &m) const \
+ { return m_Prim == m.m_Prim; } \
+ virtual size_t get_data_length() const; \
+ virtual asn1::prim::types::String & get_prim() \
+ { return m_Prim;};
+
+#define ASN1_TYPE_CLS_ADD_TeletexString(parent,typ,cls,tg) \
+ inline TeletexString(const char *c) \
+ : asn1::types::parent(asn1::tag(cls,tg)) \
+ , m_Prim(c) \
+ { }; \
+ TeletexString &operator =(const char *s); \
+ inline bool operator ==(const TeletexString &m) const \
+ { return m_Prim == m.m_Prim; } \
+ virtual size_t get_data_length() const; \
+ virtual asn1::prim::types::String & get_prim() \
+ { return m_Prim;};
+
+#define ASN1_TYPE_CLS_ADD_VideotexString(parent,typ,cls,tg) \
+ inline VideotexString(const char *c) \
+ : asn1::types::parent(asn1::tag(cls,tg)) \
+ , m_Prim(c) \
+ { }; \
+ VideotexString &operator =(const char *s); \
+ virtual size_t get_data_length() const; \
+ virtual asn1::prim::types::String & get_prim() \
+ { return m_Prim;};
+
+#define ASN1_TYPE_CLS_ADD_IA5String(parent,typ,cls,tg) \
+ inline IA5String(const char *c) \
+ : asn1::types::parent(asn1::tag(cls,tg)) \
+ , m_Prim(c) \
+ { }; \
+ IA5String &operator =(const char *s); \
+ virtual size_t get_data_length() const; \
+ inline bool operator==(IA5String &o) const \
+ { return m_Prim == o.m_Prim; }; \
+ virtual asn1::prim::types::String & get_prim() \
+ { return m_Prim;};
+
+#define ASN1_TYPE_CLS_ADD_GraphicString(parent,typ,cls,tg) \
+ inline GraphicString(const char *c) \
+ : asn1::types::parent(asn1::tag(cls,tg)) \
+ , m_Prim(c) \
+ { }; \
+ GraphicString &operator =(const char *s); \
+ virtual size_t get_data_length() const; \
+ inline bool operator==(const GraphicString &o) const \
+ { return m_Prim == o.m_Prim; }; \
+ virtual asn1::prim::types::String & get_prim() \
+ { return m_Prim;};
+
+#define ASN1_TYPE_CLS_ADD_VisibleString(parent,typ,cls,tg) \
+ inline VisibleString(const char *c) \
+ : asn1::types::parent(asn1::tag(cls,tg)) \
+ , m_Prim(c) \
+ { }; \
+ VisibleString &operator =(const char *s); \
+ virtual size_t get_data_length() const; \
+ virtual asn1::prim::types::String & get_prim() \
+ { return m_Prim;};
+
+#define ASN1_TYPE_CLS_ADD_GeneralString(parent,typ,cls,tg) \
+ inline GeneralString(const char *c) \
+ : asn1::types::parent(asn1::tag(cls,tg)) \
+ , m_Prim(c) \
+ { }; \
+ GeneralString &operator =(const char *s); \
+ virtual size_t get_data_length() const; \
+ virtual asn1::prim::types::String & get_prim() \
+ { return m_Prim;};
+
+#define ASN1_TYPE_CLS_ADD_UniversalString(parent,typ,cls,tg) \
+ inline UniversalString(const char *c) \
+ : asn1::types::parent(asn1::tag(cls,tg)) \
+ , m_Prim(c) \
+ { }; \
+ UniversalString &operator =(const char *s); \
+ inline bool operator ==(const UniversalString &m) const \
+ { return m_Prim == m.m_Prim; } \
+ virtual size_t get_data_length() const; \
+ virtual asn1::prim::types::String & get_prim() \
+ { return m_Prim;};
+
+#define ASN1_TYPE_CLS_ADD_BMPString(parent,typ,cls,tg) \
+ inline BMPString(const char *c) \
+ : asn1::types::parent(asn1::tag(cls,tg)) \
+ , m_Prim(c) \
+ { }; \
+ BMPString &operator =(const char *s); \
+ inline bool operator ==(const BMPString &m) const \
+ { return m_Prim == m.m_Prim; } \
+ virtual size_t get_data_length() const; \
+ virtual asn1::prim::types::String & get_prim() \
+ { return m_Prim;};
+
+#define ASN1_TYPE_CLS_ADD_OBJECT_IDENTIFIER_NG(parent,typ,cls,tg) \
+ inline void from_arc(size_t len, const long *m) \
+ { m_Prim.from_arc(len,m); } \
+ inline bool operator ==(const OBJECT_IDENTIFIER_NG &m) const \
+ { return m_Prim == m.m_Prim; } \
+ inline bool operator !=(const OBJECT_IDENTIFIER_NG &m) const \
+ { return ! (m_Prim == m.m_Prim); } \
+ virtual size_t get_data_length() const \
+ { return 0 ; }
+
+#define ASN1_TYPE_CLS(parent,typ,cls,tg,asn1t) \
+ ASN1_TYPE_CLS_GEN(parent,typ,cls,tg,asn1t) \
+ ASN1_TYPE_CLS_ADD_##asn1t(parent,typ,cls,tg) };
+
+
+/**/
+ASN1_TYPE_CLS(type,asn1::prim::types::Boolean,asn1::types::UNIVERSAL,1,BOOLEAN)
+ASN1_TYPE_CLS(type,asn1::prim::types::Integer,asn1::types::UNIVERSAL,2,INTEGER)
+ASN1_TYPE_CLS(type,asn1::prim::types::Int8,asn1::types::UNIVERSAL,2,Int8)
+ASN1_TYPE_CLS(type,asn1::prim::types::Int16,asn1::types::UNIVERSAL,2,Int16)
+ASN1_TYPE_CLS(type,asn1::prim::types::Int32,asn1::types::UNIVERSAL,2,Int32)
+ASN1_TYPE_CLS(type,asn1::prim::types::Int64,asn1::types::UNIVERSAL,2,Int64)
+ASN1_TYPE_CLS(type,asn1::prim::types::UInt8,asn1::types::UNIVERSAL,2,UInt8)
+ASN1_TYPE_CLS(type,asn1::prim::types::UInt16,asn1::types::UNIVERSAL,2,UInt16)
+ASN1_TYPE_CLS(type,asn1::prim::types::UInt32,asn1::types::UNIVERSAL,2,UInt32)
+ASN1_TYPE_CLS(type,asn1::prim::types::UInt64,asn1::types::UNIVERSAL,2,UInt64)
+ASN1_TYPE_CLS(type,asn1::prim::types::BitString,asn1::types::UNIVERSAL,3,BIT_STRING)
+ASN1_TYPE_CLS(type,asn1::prim::types::String,asn1::types::UNIVERSAL,4,OCTET_STRING)
+ASN1_TYPE_CLS(type,asn1::prim::types::String,asn1::types::UNIVERSAL,4,STRING)
+ASN1_TYPE_CLS(type,asn1::prim::types::Integer,asn1::types::UNIVERSAL,5,Null)
+ //ASN1_TYPE_CLS(type,asn1::prim::types::Integer,asn1::types::UNIVERSAL,6,OBJECT_IDENTIFIER)
+ASN1_TYPE_CLS(type,asn1::prim::types::String,asn1::types::UNIVERSAL,8,EXTERNAL)
+ASN1_TYPE_CLS(type,asn1::prim::types::UTCTime,asn1::types::UNIVERSAL,24,GeneralizedTime)
+ASN1_TYPE_CLS(type,asn1::prim::types::UTCTime,asn1::types::UNIVERSAL,23,UTCTime)
+ASN1_TYPE_CLS(type,asn1::prim::types::Real,asn1::types::UNIVERSAL,9,REAL)
+ASN1_TYPE_CLS(type,asn1::prim::types::Integer,asn1::types::UNIVERSAL,10,ENUMERATED)
+
+ typedef asn1::types::any_type ANY;
+ASN1_TYPE_CLS(strtype,asn1::prim::types::String,asn1::types::UNIVERSAL,12,UTF8String)
+ASN1_TYPE_CLS(strtype,asn1::prim::types::String,asn1::types::UNIVERSAL,18,NumericString)
+ASN1_TYPE_CLS(strtype,asn1::prim::types::String,asn1::types::UNIVERSAL,19,PrintableString)
+ASN1_TYPE_CLS(strtype,asn1::prim::types::String,asn1::types::UNIVERSAL,20,TeletexString)
+ASN1_TYPE_CLS(strtype,asn1::prim::types::String,asn1::types::UNIVERSAL,21,VideotexString)
+ASN1_TYPE_CLS(strtype,asn1::prim::types::String,asn1::types::UNIVERSAL,22,IA5String)
+ASN1_TYPE_CLS(strtype,asn1::prim::types::String,asn1::types::UNIVERSAL,25,GraphicString)
+ASN1_TYPE_CLS(strtype,asn1::prim::types::String,asn1::types::UNIVERSAL,26,VisibleString)
+ASN1_TYPE_CLS(strtype,asn1::prim::types::String,asn1::types::UNIVERSAL,27,GeneralString)
+ASN1_TYPE_CLS(strtype,asn1::prim::types::String,asn1::types::UNIVERSAL,29,UniversalString)
+ASN1_TYPE_CLS(strtype,asn1::prim::types::String,asn1::types::UNIVERSAL,30,BMPString)
+ASN1_TYPE_CLS(type,asn1::prim::types::ObjectIdentifier,asn1::types::UNIVERSAL,6,OBJECT_IDENTIFIER_NG)
+#undef ASN1_TYPE_CLS
+
+ class ObjectIdentifier;
+
+ std::ostream & operator <<(std::ostream &os, const ObjectIdentifier &s);
+
+ /**
+ * ASN1 ObjectIdentifier
+ */
+ class ObjectIdentifier : public asn1::prim::types::ObjectIdentifier
+ , public asn1::types::type
+ {
+ public:
+
+ ObjectIdentifier(int len = 0,const char *buf = NULL) ;
+
+ ObjectIdentifier(const asn1::tag &t) ;
+
+ ObjectIdentifier(const ObjectIdentifier &c)
+ : asn1::types::type(c.tag())
+ , asn1::prim::types::ObjectIdentifier(c)
+ { };
+ // What is this for ?
+ ObjectIdentifier(const ObjectIdentifier &c,int v)
+ : asn1::types::type(c.tag())
+ , asn1::prim::types::ObjectIdentifier(c)
+ { };
+
+ ObjectIdentifier &operator =(const ObjectIdentifier &c) ;
+
+ ObjectIdentifier *clone()
+ { return new ObjectIdentifier(*this); };
+
+ virtual size_t get_data_length() const
+ { return 0 ; }
+
+ bool operator ==(const ObjectIdentifier &o) ;
+
+ virtual void encode(asn1::context &ctx);
+
+ virtual int decode(asn1::context &ctx);
+
+ inline size_t size() {return m_len;}
+
+ virtual ~ObjectIdentifier() {};
+
+ virtual void printf(std::ostream &os) const {os<<*this;};
+
+ friend std::ostream &operator << (std::ostream &os,const ObjectIdentifier &o) ;
+ };
+
+ typedef ObjectIdentifier OBJECT_IDENTIFIER;
+
+ /**
+ *
+ *
+ */
+ template <typename T>
+ class Seq : public asn1::types::container<T>
+ {
+ public:
+ typedef typename asn1::types::container<T>::iterator iterator;
+ typedef typename asn1::types::container<T>::const_iterator const_iterator ;
+
+ Seq(const asn1::tag &t = asn1::tag(asn1::types::UNIVERSAL,16,true))
+ : asn1::types::container<T>(t)
+ {
+// std::cerr<<"Seq<T>::Seq<T>(t="<<(int)t.byte()<<")\n";
+ };
+ Seq(const Seq<T> &c) :
+ asn1::types::container<T>(asn1::tag(c.tag()))
+ {
+// std::cerr<<"Seq<T>::Seq<T> m_="<<this->m_.size()<<" c:"<<c.m_.size()<<std::endl;
+ this->m_ = c.m_;
+// std::cerr<<" After:"<<this->m_.size()<<std::endl;
+ };
+ Seq(const T &c) :
+ asn1::types::container<T>(asn1::tag(asn1::types::UNIVERSAL,16,true))
+ {
+// std::cerr<<"Seq:: copy base :"<<this->m_.size()<<std::endl;
+ this->m_.push_back(c);
+ };
+
+ inline Seq<T> &operator=(const Seq<T> &c)
+ {
+ if (this != &c)
+ {
+ this->m_ = c.m_;
+ }
+ return *this;
+ }
+
+ Seq<T> &get_value()
+ {
+ return *this;
+ }
+
+ const Seq<T> &get_value() const
+ {
+ return *this;
+ }
+
+ virtual Seq<T> *clone()
+ {
+ return new Seq<T>(*this);
+ }
+
+ bool operator ==(const Seq<T> &o) const
+ {
+ std::cerr<<"TODO implement Seq<T> =="<<std::endl;
+ return false;
+ }
+
+ virtual size_t get_data_length() const
+ { return 0 ; }
+
+ inline void push_back(T &t)
+ {
+ this->::asn1::types::container<T>::push_back(t);
+ };
+
+ inline iterator begin()
+ { return this->::asn1::types::container<T>::begin(); };
+
+ inline const_iterator begin() const
+ { return this->::asn1::types::container<T>::begin(); };
+
+ inline iterator end()
+ { return this->::asn1::types::container<T>::end(); };
+
+ inline const_iterator end() const
+ { return this->::asn1::types::container<T>::end(); };
+
+ inline T operator [](int i)
+ { return this->m_[i]; };
+
+ virtual ~Seq() ;
+
+ virtual void encode(asn1::context &ctx);
+ virtual int decode(asn1::context &ctx);
+
+ friend std::ostream &operator <<(std::ostream &os,const Seq<T> &t)
+ {
+ int count = 0;
+ typename ::asn1::types::container<T>::const_iterator mit=
+ const_cast<Seq<T> &>(t).begin();
+ os << "SEQUENCE OF"<<std::endl;
+ for (;
+ mit != const_cast<Seq<T> &>(t).end();
+ ++mit)
+ {
+ std::streamsize indent = os.precision() + 2;
+ os<<std::setw(indent+2)<<"["<<count++<<"] "<<std::setprecision(indent)<<(*mit)<<"\n";
+ os<<std::setprecision(indent-2);
+ }
+ return os;
+ };
+ };
+
+
+ template <typename T>
+ class Set : public asn1::types::container<T>
+ {
+ public:
+ typedef typename asn1::types::container<T>::iterator iterator;
+ typedef typename asn1::types::container<T>::const_iterator const_iterator ;
+ Set(const asn1::tag &t = asn1::tag(asn1::types::UNIVERSAL,17,true))
+ : asn1::types::container<T>(t)
+ {};
+
+ virtual ~Set() {};
+
+ Set(const Set<T> &c) :
+ asn1::types::container<T>(asn1::tag(c.tag()))
+ {
+ this->m_ = c.m_;
+ }
+ inline Set<T> &operator=(const Set<T> &c)
+ {
+ this->m_ = c.m_;
+ return *this;
+ }
+ virtual Set<T> *clone()
+ {
+ return new Set<T>(*this);
+ }
+
+ virtual size_t get_data_length() const
+ { return 0 ; }
+
+ Set<T> &get_value() { return *this; }
+
+ const Set<T> &get_value() const { return *this; }
+
+ Set(const T &c) :
+ asn1::types::container<T>(asn1::tag(asn1::types::UNIVERSAL,17))
+ {
+ this->m_.push_back(c);
+ }
+
+ bool operator ==(const Set<T> &o) const
+ {
+ std::cerr<<"TODO implement Seq<T> =="<<std::endl;
+ return false;
+ }
+
+ inline iterator begin()
+ { return this->::asn1::types::container<T>::begin(); };
+
+ inline const_iterator begin() const
+ { return this->::asn1::types::container<T>::begin(); }
+
+ inline iterator end()
+ { return this->::asn1::types::container<T>::end(); };
+
+ inline const_iterator end() const
+ { return this->::asn1::types::container<T>::end(); };
+
+ virtual const asn1::tag &tag() const
+ {
+ return this->::asn1::types::container<T>::tag();
+ };
+
+ virtual void encode(asn1::context &ctx);
+
+ virtual int decode(asn1::context &ctx);
+
+ inline T operator [](int i) {return this->m_[i];};
+
+ friend std::ostream &operator <<(std::ostream &os,const Set<T> &t)
+ {
+ int count = 0;
+ typename ::asn1::types::container<T>::const_iterator mit=
+ const_cast<Set<T> &>(t).begin();
+ for (;
+ mit != const_cast<Set<T> &>(t).end();
+ ++mit)
+ os<<"SET OF ["<<count++<<"]"<< (*mit)<<"\n";
+ return os;
+ };
+ };
+
+
+}
+
+/*
+ * vim: et sw=2 ts=2 list:
+ */
+#endif
--- /dev/null
+
+namespace asn1 {
+
+namespace types {
+
+
+// End of namespace types
+}
+
+/**
+ * Seq Template definition
+ */
+template <typename T>
+Seq<T>::~Seq() {
+ this->m_.erase(this->m_.begin(),this->m_.end());
+// ASN1_BER_LOG_DEBUG("Seq::~Seq SEQUENCE OF %s [size=%zu]",typeid(T).name(),this->m_.size());
+
+};
+
+template<typename T>
+void Seq<T>::encode(asn1::context &ctx)
+{
+ iterator mit;
+ unsigned long pos = ctx.bytes();
+ unsigned char *b = ctx.buffer();
+ ASN1_BER_LOG_DEBUG("Seq<T>::encode SEQUENCE-OF %s %s",typeid(T).name(),__FUNCTION__);
+ asn1::tag t_(0,16,true);
+ b[pos] = t_.byte() | 0x20;
+ ctx.nb_bits(16);
+ for (mit = begin();
+ mit != end();
+ ++mit)
+ {
+ ASN1_BER_LOG_DEBUG("Seq<T>::encode call encode on item ");
+ (*mit).T::encode(ctx);
+ }
+ b[pos+1]= ctx.bytes()-pos-2;
+}
+
+template<typename T>
+int Seq<T>::decode(asn1::context &ctx)
+{
+ int ret = asn1::ok;
+ unsigned long pos = ctx.bytes();
+ unsigned char *b = ctx.buffer();
+ long llen = 0;
+ long i = 0;
+ long nb = 1; // I need to find a way to get the length
+ ASN1_BER_LOG_DEBUG("Seq<T>::decode SEQUENCE-OF %s check_tag:%d b[pos]=%d b[pos+1]=%d b[pos+2]=%d",typeid(T).name(),ctx.check_tag(),b[pos],
+ static_cast<int>(static_cast<unsigned char>(b[pos+1])),
+ static_cast<int>(static_cast<unsigned char>(b[pos+2])));
+ long len = asn1::types::length(&b[pos+1],&nb);
+ ctx.nb_bits(((nb)<<3)+8);
+ if (len == 0 )
+ {
+ return 0;
+ }
+ do {
+ T element;
+ //ret = this->m_.back().decode(ctx);
+ ret = element.decode(ctx);
+ if (ret != asn1::ok)
+ break;
+ this->m_.resize(nb);
+ //this->m_.push_back(element);
+ this->m_[i++] = element;
+ nb++;
+ llen = ctx.bytes();
+ } while ((llen-(long)pos) < len);
+
+ if ((this->m_.size() == 0))
+ { // Failed decoding ....
+ ctx.nb_bits(-1*(((nb)<<3)+8));
+ }
+ ASN1_BER_LOG_DEBUG("Seq<T>::decode SEQUENCE-OF %s %s GOT %lu END",typeid(T).name(),__FUNCTION__,this->m_.size());
+ return ret;
+}
+
+/**
+ *
+ */
+/**
+ * Set Template definition
+ */
+template<typename T>
+void Set<T>::encode(asn1::context &ctx)
+{
+ iterator mit;
+ unsigned long pos = ctx.bytes();
+ unsigned char *b = ctx.buffer();
+ ASN1_BER_LOG_DEBUG("Set<T>::encode SET-OF %s %s",typeid(T).name(),__FUNCTION__);
+ asn1::tag t_(0,17,true);
+ b[pos] = t_.byte() | 0x20;
+ ctx.nb_bits(16);
+ for (mit = begin();
+ mit != end();
+ ++mit)
+ {
+ ASN1_BER_LOG_DEBUG("Set<T>::encode call encode on item ");
+ (*mit).encode(ctx);
+ }
+ b[pos+1]= ctx.bytes()-pos-2;
+}
+
+template<typename T>
+int Set<T>::decode(asn1::context &ctx)
+{
+ int ret = asn1::ok;
+ unsigned long pos = ctx.bytes();
+ unsigned char *b = ctx.buffer();
+ long llen = 0;
+ long i = 0;
+ long nb = 1; // I need to find a way to get the length
+ ASN1_BER_LOG_DEBUG("Set<T>::decode SET-OF %s check_tag:%d b[pos]=%d b[pos+1]=%d b[pos+2]=%d",typeid(T).name(),ctx.check_tag(),b[pos],
+ static_cast<int>(static_cast<unsigned char>(b[pos+1])),
+ static_cast<int>(static_cast<unsigned char>(b[pos+2])));
+ long len = asn1::types::length(&b[pos+1],&nb);
+ ctx.nb_bits(((nb)<<3)+8);
+ if (len == 0 )
+ {
+ return 0;
+ }
+ do {
+ T element;
+ //ret = this->m_.back().decode(ctx);
+ ret = element.decode(ctx);
+ if (ret != asn1::ok)
+ break;
+ this->m_.resize(nb);
+ //this->m_.push_back(element);
+ this->m_[i++] = element;
+ nb++;
+ llen = ctx.bytes();
+ } while ((llen-pos) < len);
+
+ if ((this->m_.size() == 0))
+ { // Failed decoding ....
+ ctx.nb_bits(-1*(((nb)<<3)+8));
+ }
+ ASN1_BER_LOG_DEBUG("Set<T>::decode SET-OF %s %s GOT %lu END"
+ ,typeid(T).name()
+ ,__FUNCTION__
+ ,this->m_.size());
+ return ret;
+}
+
+
+}
--- /dev/null
+#ifndef ASN1_TYPE_CLS
+# define ASN1_TYPE_CLS(PrimType,TagType,TagNum,Asn1Type)
+#endif
+
+ASN1_TYPE_CLS(asn1::prim::types::Boolean,asn1::types::UNIVERSAL,1,BOOLEAN)
+ASN1_TYPE_CLS(asn1::prim::types::Integer,asn1::types::UNIVERSAL,2,INTEGER)
+ASN1_TYPE_CLS(asn1::prim::types::Int8,asn1::types::UNIVERSAL,2,Int8)
+ASN1_TYPE_CLS(asn1::prim::types::Int16,asn1::types::UNIVERSAL,2,Int16)
+ASN1_TYPE_CLS(asn1::prim::types::Int32,asn1::types::UNIVERSAL,2,Int32)
+ASN1_TYPE_CLS(asn1::prim::types::Int64,asn1::types::UNIVERSAL,2,Int64)
+ASN1_TYPE_CLS(asn1::prim::types::UInt8,asn1::types::UNIVERSAL,2,UInt8)
+ASN1_TYPE_CLS(asn1::prim::types::UInt16,asn1::types::UNIVERSAL,2,UInt16)
+ASN1_TYPE_CLS(asn1::prim::types::UInt32,asn1::types::UNIVERSAL,2,UInt32)
+ASN1_TYPE_CLS(asn1::prim::types::UInt64,asn1::types::UNIVERSAL,2,UInt64)
+ASN1_TYPE_CLS(asn1::prim::types::BitString,asn1::types::UNIVERSAL,3,BIT_STRING)
+ASN1_TYPE_CLS(asn1::prim::types::String,asn1::types::UNIVERSAL,4,OCTET_STRING)
+ASN1_TYPE_CLS(asn1::prim::types::String,asn1::types::UNIVERSAL,4,STRING)
+ASN1_TYPE_CLS(asn1::prim::types::Integer,asn1::types::UNIVERSAL,5,Null)
+// ASN1_TYPE_CLS(asn1::prim::types::Integer,asn1::types::UNIVERSAL,6,OBJECT_IDENTIFIER)
+ASN1_TYPE_CLS(asn1::prim::types::ObjectIdentifier,asn1::types::UNIVERSAL,6,OBJECT_IDENTIFIER_NG)
+ASN1_TYPE_CLS(asn1::prim::types::String,asn1::types::UNIVERSAL,8,EXTERNAL)
+ASN1_TYPE_CLS(asn1::prim::types::UTCTime,asn1::types::UNIVERSAL,24,GeneralizedTime)
+ASN1_TYPE_CLS(asn1::prim::types::UTCTime,asn1::types::UNIVERSAL,23,UTCTime)
+ASN1_TYPE_CLS(asn1::prim::types::Real,asn1::types::UNIVERSAL,9,REAL)
+ASN1_TYPE_CLS(asn1::prim::types::Integer,asn1::types::UNIVERSAL,10,ENUMERATED)
+// typedef asn1::types::any_type ANY;
+ASN1_TYPE_CLS(asn1::prim::types::String,asn1::types::UNIVERSAL,12,UTF8String)
+ASN1_TYPE_CLS(asn1::prim::types::String,asn1::types::UNIVERSAL,18,NumericString)
+ASN1_TYPE_CLS(asn1::prim::types::String,asn1::types::UNIVERSAL,19,PrintableString)
+ASN1_TYPE_CLS(asn1::prim::types::String,asn1::types::UNIVERSAL,20,TeletexString)
+ASN1_TYPE_CLS(asn1::prim::types::String,asn1::types::UNIVERSAL,21,VideotexString)
+ASN1_TYPE_CLS(asn1::prim::types::String,asn1::types::UNIVERSAL,22,IA5String)
+ASN1_TYPE_CLS(asn1::prim::types::String,asn1::types::UNIVERSAL,25,GraphicString)
+ASN1_TYPE_CLS(asn1::prim::types::String,asn1::types::UNIVERSAL,26,VisibleString)
+ASN1_TYPE_CLS(asn1::prim::types::String,asn1::types::UNIVERSAL,27,GeneralString)
+ASN1_TYPE_CLS(asn1::prim::types::String,asn1::types::UNIVERSAL,29,UniversalString)
+ASN1_TYPE_CLS(asn1::prim::types::String,asn1::types::UNIVERSAL,30,BMPString)
+
+#undef ASN1_TYPE_CLS
--- /dev/null
+ Copyright (c) 2009 Dave Gamble
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+
--- /dev/null
+/*
+ Copyright (c) 2009 Dave Gamble
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+*/
+
+Welcome to cJSON.
+
+cJSON aims to be the dumbest possible parser that you can get your job done with.
+It's a single file of C, and a single header file.
+
+JSON is described best here: http://www.json.org/
+It's like XML, but fat-free. You use it to move data around, store things, or just
+generally represent your program's state.
+
+
+First up, how do I build?
+Add cJSON.c to your project, and put cJSON.h somewhere in the header search path.
+For example, to build the test app:
+
+gcc cJSON.c test.c -o test -lm
+./test
+
+
+As a library, cJSON exists to take away as much legwork as it can, but not get in your way.
+As a point of pragmatism (i.e. ignoring the truth), I'm going to say that you can use it
+in one of two modes: Auto and Manual. Let's have a quick run-through.
+
+
+I lifted some JSON from this page: http://www.json.org/fatfree.html
+That page inspired me to write cJSON, which is a parser that tries to share the same
+philosophy as JSON itself. Simple, dumb, out of the way.
+
+Some JSON:
+{
+ "name": "Jack (\"Bee\") Nimble",
+ "format": {
+ "type": "rect",
+ "width": 1920,
+ "height": 1080,
+ "interlace": false,
+ "frame rate": 24
+ }
+}
+
+Assume that you got this from a file, a webserver, or magic JSON elves, whatever,
+you have a char * to it. Everything is a cJSON struct.
+Get it parsed:
+ cJSON *root = cJSON_Parse(my_json_string);
+
+This is an object. We're in C. We don't have objects. But we do have structs.
+What's the framerate?
+
+ cJSON *format = cJSON_GetObjectItem(root,"format");
+ int framerate = cJSON_GetObjectItem(format,"frame rate")->valueint;
+
+
+Want to change the framerate?
+ cJSON_GetObjectItem(format,"frame rate")->valueint=25;
+
+Back to disk?
+ char *rendered=cJSON_Print(root);
+
+Finished? Delete the root (this takes care of everything else).
+ cJSON_Delete(root);
+
+That's AUTO mode. If you're going to use Auto mode, you really ought to check pointers
+before you dereference them. If you want to see how you'd build this struct in code?
+ cJSON *root,*fmt;
+ root=cJSON_CreateObject();
+ cJSON_AddItemToObject(root, "name", cJSON_CreateString("Jack (\"Bee\") Nimble"));
+ cJSON_AddItemToObject(root, "format", fmt=cJSON_CreateObject());
+ cJSON_AddStringToObject(fmt,"type", "rect");
+ cJSON_AddNumberToObject(fmt,"width", 1920);
+ cJSON_AddNumberToObject(fmt,"height", 1080);
+ cJSON_AddFalseToObject (fmt,"interlace");
+ cJSON_AddNumberToObject(fmt,"frame rate", 24);
+
+Hopefully we can agree that's not a lot of code? There's no overhead, no unnecessary setup.
+Look at test.c for a bunch of nice examples, mostly all ripped off the json.org site, and
+a few from elsewhere.
+
+What about manual mode? First up you need some detail.
+Let's cover how the cJSON objects represent the JSON data.
+cJSON doesn't distinguish arrays from objects in handling; just type.
+Each cJSON has, potentially, a child, siblings, value, a name.
+
+The root object has: Object Type and a Child
+The Child has name "name", with value "Jack ("Bee") Nimble", and a sibling:
+Sibling has type Object, name "format", and a child.
+That child has type String, name "type", value "rect", and a sibling:
+Sibling has type Number, name "width", value 1920, and a sibling:
+Sibling has type Number, name "height", value 1080, and a sibling:
+Sibling hs type False, name "interlace", and a sibling:
+Sibling has type Number, name "frame rate", value 24
+
+Here's the structure:
+typedef struct cJSON {
+ struct cJSON *next,*prev;
+ struct cJSON *child;
+
+ int type;
+
+ char *valuestring;
+ int valueint;
+ double valuedouble;
+
+ char *string;
+} cJSON;
+
+By default all values are 0 unless set by virtue of being meaningful.
+
+next/prev is a doubly linked list of siblings. next takes you to your sibling,
+prev takes you back from your sibling to you.
+Only objects and arrays have a "child", and it's the head of the doubly linked list.
+A "child" entry will have prev==0, but next potentially points on. The last sibling has next=0.
+The type expresses Null/True/False/Number/String/Array/Object, all of which are #defined in
+cJSON.h
+
+A Number has valueint and valuedouble. If you're expecting an int, read valueint, if not read
+valuedouble.
+
+Any entry which is in the linked list which is the child of an object will have a "string"
+which is the "name" of the entry. When I said "name" in the above example, that's "string".
+"string" is the JSON name for the 'variable name' if you will.
+
+Now you can trivially walk the lists, recursively, and parse as you please.
+You can invoke cJSON_Parse to get cJSON to parse for you, and then you can take
+the root object, and traverse the structure (which is, formally, an N-tree),
+and tokenise as you please. If you wanted to build a callback style parser, this is how
+you'd do it (just an example, since these things are very specific):
+
+void parse_and_callback(cJSON *item,const char *prefix)
+{
+ while (item)
+ {
+ char *newprefix=malloc(strlen(prefix)+strlen(item->name)+2);
+ sprintf(newprefix,"%s/%s",prefix,item->name);
+ int dorecurse=callback(newprefix, item->type, item);
+ if (item->child && dorecurse) parse_and_callback(item->child,newprefix);
+ item=item->next;
+ free(newprefix);
+ }
+}
+
+The prefix process will build you a separated list, to simplify your callback handling.
+The 'dorecurse' flag would let the callback decide to handle sub-arrays on it's own, or
+let you invoke it per-item. For the item above, your callback might look like this:
+
+int callback(const char *name,int type,cJSON *item)
+{
+ if (!strcmp(name,"name")) { /* populate name */ }
+ else if (!strcmp(name,"format/type") { /* handle "rect" */ }
+ else if (!strcmp(name,"format/width") { /* 800 */ }
+ else if (!strcmp(name,"format/height") { /* 600 */ }
+ else if (!strcmp(name,"format/interlace") { /* false */ }
+ else if (!strcmp(name,"format/frame rate") { /* 24 */ }
+ return 1;
+}
+
+Alternatively, you might like to parse iteratively.
+You'd use:
+
+void parse_object(cJSON *item)
+{
+ int i; for (i=0;i<cJSON_GetArraySize(item);i++)
+ {
+ cJSON *subitem=cJSON_GetArrayItem(item,i);
+ // handle subitem.
+ }
+}
+
+Or, for PROPER manual mode:
+
+void parse_object(cJSON *item)
+{
+ cJSON *subitem=item->child;
+ while (subitem)
+ {
+ // handle subitem
+ if (subitem->child) parse_object(subitem->child);
+
+ subitem=subitem->next;
+ }
+}
+
+Of course, this should look familiar, since this is just a stripped-down version
+of the callback-parser.
+
+This should cover most uses you'll find for parsing. The rest should be possible
+to infer.. and if in doubt, read the source! There's not a lot of it! ;)
+
+
+In terms of constructing JSON data, the example code above is the right way to do it.
+You can, of course, hand your sub-objects to other functions to populate.
+Also, if you find a use for it, you can manually build the objects.
+For instance, suppose you wanted to build an array of objects?
+
+cJSON *objects[24];
+
+cJSON *Create_array_of_anything(cJSON **items,int num)
+{
+ int i;cJSON *prev, *root=cJSON_CreateArray();
+ for (i=0;i<24;i++)
+ {
+ if (!i) root->child=objects[i];
+ else prev->next=objects[i], objects[i]->prev=prev;
+ prev=objects[i];
+ }
+ return root;
+}
+
+and simply: Create_array_of_anything(objects,24);
+
+cJSON doesn't make any assumptions about what order you create things in.
+You can attach the objects, as above, and later add children to each
+of those objects.
+
+As soon as you call cJSON_Print, it renders the structure to text.
+
+
+
+The test.c code shows how to handle a bunch of typical cases. If you uncomment
+the code, it'll load, parse and print a bunch of test files, also from json.org,
+which are more complex than I'd care to try and stash into a const char array[].
+
+
+Enjoy cJSON!
+
+
+- Dave Gamble, Aug 2009
--- /dev/null
+/*
+ Copyright (c) 2009 Dave Gamble
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+*/
+
+/* cJSON */
+/* JSON parser in C. */
+
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
+#include <float.h>
+#include <limits.h>
+#include <ctype.h>
+#include "cJSON.h"
+
+static const char *ep;
+
+const char *cJSON_GetErrorPtr(void) {return ep;}
+
+static int cJSON_strcasecmp(const char *s1,const char *s2)
+{
+ if (!s1) return (s1==s2)?0:1;if (!s2) return 1;
+ for(; tolower(*s1) == tolower(*s2); ++s1, ++s2) if(*s1 == 0) return 0;
+ return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2);
+}
+
+static void *(*cJSON_malloc)(size_t sz) = malloc;
+static void (*cJSON_free)(void *ptr) = free;
+
+static char* cJSON_strdup(const char* str)
+{
+ size_t len;
+ char* copy;
+
+ len = strlen(str) + 1;
+ if (!(copy = (char*)cJSON_malloc(len))) return 0;
+ memcpy(copy,str,len);
+ return copy;
+}
+
+void cJSON_InitHooks(cJSON_Hooks* hooks)
+{
+ if (!hooks) { /* Reset hooks */
+ cJSON_malloc = malloc;
+ cJSON_free = free;
+ return;
+ }
+
+ cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc;
+ cJSON_free = (hooks->free_fn)?hooks->free_fn:free;
+}
+
+/* Internal constructor. */
+static cJSON *cJSON_New_Item(void)
+{
+ cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));
+ if (node) memset(node,0,sizeof(cJSON));
+ return node;
+}
+
+/* Delete a cJSON structure. */
+void cJSON_Delete(cJSON *c)
+{
+ cJSON *next;
+ while (c)
+ {
+ next=c->next;
+ if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child);
+ if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring);
+ if (c->string) cJSON_free(c->string);
+ cJSON_free(c);
+ c=next;
+ }
+}
+
+/* Parse the input text to generate a number, and populate the result into item. */
+static const char *parse_number(cJSON *item,const char *num)
+{
+ double n=0,sign=1,scale=0;int subscale=0,signsubscale=1;
+
+ if (*num=='-') sign=-1,num++; /* Has sign? */
+ if (*num=='0') num++; /* is zero */
+ if (*num>='1' && *num<='9') do n=(n*10.0)+(*num++ -'0'); while (*num>='0' && *num<='9'); /* Number? */
+ if (*num=='.' && num[1]>='0' && num[1]<='9') {num++; do n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');} /* Fractional part? */
+ if (*num=='e' || *num=='E') /* Exponent? */
+ { num++;if (*num=='+') num++; else if (*num=='-') signsubscale=-1,num++; /* With sign? */
+ while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0'); /* Number? */
+ }
+
+ n=sign*n*pow(10.0,(scale+subscale*signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */
+
+ item->valuedouble=n;
+ item->valueint=(int)n;
+ item->type=cJSON_Number;
+ return num;
+}
+
+/* Render the number nicely from the given item into a string. */
+static char *print_number(cJSON *item)
+{
+ char *str;
+ double d=item->valuedouble;
+ if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN)
+ {
+ str=(char*)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */
+ if (str) sprintf(str,"%d",item->valueint);
+ }
+ else
+ {
+ str=(char*)cJSON_malloc(64); /* This is a nice tradeoff. */
+ if (str)
+ {
+ if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60)sprintf(str,"%.0f",d);
+ else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%e",d);
+ else sprintf(str,"%f",d);
+ }
+ }
+ return str;
+}
+
+static unsigned parse_hex4(const char *str)
+{
+ unsigned h=0;
+ if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
+ h=h<<4;str++;
+ if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
+ h=h<<4;str++;
+ if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
+ h=h<<4;str++;
+ if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
+ return h;
+}
+
+/* Parse the input text into an unescaped cstring, and populate item. */
+static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+static const char *parse_string(cJSON *item,const char *str)
+{
+ const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2;
+ if (*str!='\"') {ep=str;return 0;} /* not a string! */
+
+ while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */
+
+ out=(char*)cJSON_malloc(len+1); /* This is how long we need for the string, roughly. */
+ if (!out) return 0;
+
+ ptr=str+1;ptr2=out;
+ while (*ptr!='\"' && *ptr)
+ {
+ if (*ptr!='\\') *ptr2++=*ptr++;
+ else
+ {
+ ptr++;
+ switch (*ptr)
+ {
+ case 'b': *ptr2++='\b'; break;
+ case 'f': *ptr2++='\f'; break;
+ case 'n': *ptr2++='\n'; break;
+ case 'r': *ptr2++='\r'; break;
+ case 't': *ptr2++='\t'; break;
+ case 'u': /* transcode utf16 to utf8. */
+ uc=parse_hex4(ptr+1);ptr+=4; /* get the unicode char. */
+
+ if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0) break; /* check for invalid. */
+
+ if (uc>=0xD800 && uc<=0xDBFF) /* UTF16 surrogate pairs. */
+ {
+ if (ptr[1]!='\\' || ptr[2]!='u') break; /* missing second-half of surrogate. */
+ uc2=parse_hex4(ptr+3);ptr+=6;
+ if (uc2<0xDC00 || uc2>0xDFFF) break; /* invalid second-half of surrogate. */
+ uc=0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF));
+ }
+
+ len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len;
+
+ switch (len) {
+ case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
+ case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
+ case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
+ case 1: *--ptr2 =(uc | firstByteMark[len]);
+ }
+ ptr2+=len;
+ break;
+ default: *ptr2++=*ptr; break;
+ }
+ ptr++;
+ }
+ }
+ *ptr2=0;
+ if (*ptr=='\"') ptr++;
+ item->valuestring=out;
+ item->type=cJSON_String;
+ return ptr;
+}
+
+/* Render the cstring provided to an escaped version that can be printed. */
+static char *print_string_ptr(const char *str)
+{
+ const char *ptr;char *ptr2,*out;int len=0;unsigned char token;
+
+ if (!str) return cJSON_strdup("");
+ ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;}
+
+ out=(char*)cJSON_malloc(len+3);
+ if (!out) return 0;
+
+ ptr2=out;ptr=str;
+ *ptr2++='\"';
+ while (*ptr)
+ {
+ if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++;
+ else
+ {
+ *ptr2++='\\';
+ switch (token=*ptr++)
+ {
+ case '\\': *ptr2++='\\'; break;
+ case '\"': *ptr2++='\"'; break;
+ case '\b': *ptr2++='b'; break;
+ case '\f': *ptr2++='f'; break;
+ case '\n': *ptr2++='n'; break;
+ case '\r': *ptr2++='r'; break;
+ case '\t': *ptr2++='t'; break;
+ default: sprintf(ptr2,"u%04x",token);ptr2+=5; break; /* escape and print */
+ }
+ }
+ }
+ *ptr2++='\"';*ptr2++=0;
+ return out;
+}
+/* Invote print_string_ptr (which is useful) on an item. */
+static char *print_string(cJSON *item) {return print_string_ptr(item->valuestring);}
+
+/* Predeclare these prototypes. */
+static const char *parse_value(cJSON *item,const char *value);
+static char *print_value(cJSON *item,int depth,int fmt);
+static const char *parse_array(cJSON *item,const char *value);
+static char *print_array(cJSON *item,int depth,int fmt);
+static const char *parse_object(cJSON *item,const char *value);
+static char *print_object(cJSON *item,int depth,int fmt);
+
+/* Utility to jump whitespace and cr/lf */
+static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=32) in++; return in;}
+
+/* Parse an object - create a new root, and populate. */
+cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated)
+{
+ const char *end=0;
+ cJSON *c=cJSON_New_Item();
+ ep=0;
+ if (!c) return 0; /* memory fail */
+
+ end=parse_value(c,skip(value));
+ if (!end) {cJSON_Delete(c);return 0;} /* parse failure. ep is set. */
+
+ /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */
+ if (require_null_terminated) {end=skip(end);if (*end) {cJSON_Delete(c);ep=end;return 0;}}
+ if (return_parse_end) *return_parse_end=end;
+ return c;
+}
+/* Default options for cJSON_Parse */
+cJSON *cJSON_Parse(const char *value) {return cJSON_ParseWithOpts(value,0,0);}
+
+/* Render a cJSON item/entity/structure to text. */
+char *cJSON_Print(cJSON *item) {return print_value(item,0,1);}
+char *cJSON_PrintUnformatted(cJSON *item) {return print_value(item,0,0);}
+
+/* Parser core - when encountering text, process appropriately. */
+static const char *parse_value(cJSON *item,const char *value)
+{
+ if (!value) return 0; /* Fail on null. */
+ if (!strncmp(value,"null",4)) { item->type=cJSON_NULL; return value+4; }
+ if (!strncmp(value,"false",5)) { item->type=cJSON_False; return value+5; }
+ if (!strncmp(value,"true",4)) { item->type=cJSON_True; item->valueint=1; return value+4; }
+ if (*value=='\"') { return parse_string(item,value); }
+ if (*value=='-' || (*value>='0' && *value<='9')) { return parse_number(item,value); }
+ if (*value=='[') { return parse_array(item,value); }
+ if (*value=='{') { return parse_object(item,value); }
+
+ ep=value;return 0; /* failure. */
+}
+
+/* Render a value to text. */
+static char *print_value(cJSON *item,int depth,int fmt)
+{
+ char *out=0;
+ if (!item) return 0;
+ switch ((item->type)&255)
+ {
+ case cJSON_NULL: out=cJSON_strdup("null"); break;
+ case cJSON_False: out=cJSON_strdup("false");break;
+ case cJSON_True: out=cJSON_strdup("true"); break;
+ case cJSON_Number: out=print_number(item);break;
+ case cJSON_String: out=print_string(item);break;
+ case cJSON_Array: out=print_array(item,depth,fmt);break;
+ case cJSON_Object: out=print_object(item,depth,fmt);break;
+ }
+ return out;
+}
+
+/* Build an array from input text. */
+static const char *parse_array(cJSON *item,const char *value)
+{
+ cJSON *child;
+ if (*value!='[') {ep=value;return 0;} /* not an array! */
+
+ item->type=cJSON_Array;
+ value=skip(value+1);
+ if (*value==']') return value+1; /* empty array. */
+
+ item->child=child=cJSON_New_Item();
+ if (!item->child) return 0; /* memory fail */
+ value=skip(parse_value(child,skip(value))); /* skip any spacing, get the value. */
+ if (!value) return 0;
+
+ while (*value==',')
+ {
+ cJSON *new_item;
+ if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
+ child->next=new_item;new_item->prev=child;child=new_item;
+ value=skip(parse_value(child,skip(value+1)));
+ if (!value) return 0; /* memory fail */
+ }
+
+ if (*value==']') return value+1; /* end of array */
+ ep=value;return 0; /* malformed. */
+}
+
+/* Render an array to text */
+static char *print_array(cJSON *item,int depth,int fmt)
+{
+ char **entries;
+ char *out=0,*ptr,*ret;int len=5;
+ cJSON *child=item->child;
+ int numentries=0,i=0,fail=0;
+
+ /* How many entries in the array? */
+ while (child) numentries++,child=child->next;
+ /* Explicitly handle numentries==0 */
+ if (!numentries)
+ {
+ out=(char*)cJSON_malloc(3);
+ if (out) strcpy(out,"[]");
+ return out;
+ }
+ /* Allocate an array to hold the values for each */
+ entries=(char**)cJSON_malloc(numentries*sizeof(char*));
+ if (!entries) return 0;
+ memset(entries,0,numentries*sizeof(char*));
+ /* Retrieve all the results: */
+ child=item->child;
+ while (child && !fail)
+ {
+ ret=print_value(child,depth+1,fmt);
+ entries[i++]=ret;
+ if (ret) len+=strlen(ret)+2+(fmt?1:0); else fail=1;
+ child=child->next;
+ }
+
+ /* If we didn't fail, try to malloc the output string */
+ if (!fail) out=(char*)cJSON_malloc(len);
+ /* If that fails, we fail. */
+ if (!out) fail=1;
+
+ /* Handle failure. */
+ if (fail)
+ {
+ for (i=0;i<numentries;i++) if (entries[i]) cJSON_free(entries[i]);
+ cJSON_free(entries);
+ return 0;
+ }
+
+ /* Compose the output array. */
+ *out='[';
+ ptr=out+1;*ptr=0;
+ for (i=0;i<numentries;i++)
+ {
+ strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
+ if (i!=numentries-1) {*ptr++=',';if(fmt)*ptr++=' ';*ptr=0;}
+ cJSON_free(entries[i]);
+ }
+ cJSON_free(entries);
+ *ptr++=']';*ptr++=0;
+ return out;
+}
+
+/* Build an object from the text. */
+static const char *parse_object(cJSON *item,const char *value)
+{
+ cJSON *child;
+ if (*value!='{') {ep=value;return 0;} /* not an object! */
+
+ item->type=cJSON_Object;
+ value=skip(value+1);
+ if (*value=='}') return value+1; /* empty array. */
+
+ item->child=child=cJSON_New_Item();
+ if (!item->child) return 0;
+ value=skip(parse_string(child,skip(value)));
+ if (!value) return 0;
+ child->string=child->valuestring;child->valuestring=0;
+ if (*value!=':') {ep=value;return 0;} /* fail! */
+ value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
+ if (!value) return 0;
+
+ while (*value==',')
+ {
+ cJSON *new_item;
+ if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
+ child->next=new_item;new_item->prev=child;child=new_item;
+ value=skip(parse_string(child,skip(value+1)));
+ if (!value) return 0;
+ child->string=child->valuestring;child->valuestring=0;
+ if (*value!=':') {ep=value;return 0;} /* fail! */
+ value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
+ if (!value) return 0;
+ }
+
+ if (*value=='}') return value+1; /* end of array */
+ ep=value;return 0; /* malformed. */
+}
+
+/* Render an object to text. */
+static char *print_object(cJSON *item,int depth,int fmt)
+{
+ char **entries=0,**names=0;
+ char *out=0,*ptr,*ret,*str;int len=7,i=0,j;
+ cJSON *child=item->child;
+ int numentries=0,fail=0;
+ /* Count the number of entries. */
+ while (child) numentries++,child=child->next;
+ /* Explicitly handle empty object case */
+ if (!numentries)
+ {
+ out=(char*)cJSON_malloc(fmt?depth+4:3);
+ if (!out) return 0;
+ ptr=out;*ptr++='{';
+ if (fmt) {*ptr++='\n';for (i=0;i<depth-1;i++) *ptr++='\t';}
+ *ptr++='}';*ptr++=0;
+ return out;
+ }
+ /* Allocate space for the names and the objects */
+ entries=(char**)cJSON_malloc(numentries*sizeof(char*));
+ if (!entries) return 0;
+ names=(char**)cJSON_malloc(numentries*sizeof(char*));
+ if (!names) {cJSON_free(entries);return 0;}
+ memset(entries,0,sizeof(char*)*numentries);
+ memset(names,0,sizeof(char*)*numentries);
+
+ /* Collect all the results into our arrays: */
+ child=item->child;depth++;if (fmt) len+=depth;
+ while (child)
+ {
+ names[i]=str=print_string_ptr(child->string);
+ entries[i++]=ret=print_value(child,depth,fmt);
+ if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1;
+ child=child->next;
+ }
+
+ /* Try to allocate the output string */
+ if (!fail) out=(char*)cJSON_malloc(len);
+ if (!out) fail=1;
+
+ /* Handle failure */
+ if (fail)
+ {
+ for (i=0;i<numentries;i++) {if (names[i]) cJSON_free(names[i]);if (entries[i]) cJSON_free(entries[i]);}
+ cJSON_free(names);cJSON_free(entries);
+ return 0;
+ }
+
+ /* Compose the output: */
+ *out='{';ptr=out+1;if (fmt)*ptr++='\n';*ptr=0;
+ for (i=0;i<numentries;i++)
+ {
+ if (fmt) for (j=0;j<depth;j++) *ptr++='\t';
+ strcpy(ptr,names[i]);ptr+=strlen(names[i]);
+ *ptr++=':';if (fmt) *ptr++='\t';
+ strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
+ if (i!=numentries-1) *ptr++=',';
+ if (fmt) *ptr++='\n';*ptr=0;
+ cJSON_free(names[i]);cJSON_free(entries[i]);
+ }
+
+ cJSON_free(names);cJSON_free(entries);
+ if (fmt) for (i=0;i<depth-1;i++) *ptr++='\t';
+ *ptr++='}';*ptr++=0;
+ return out;
+}
+
+/* Get Array size/item / object item. */
+int cJSON_GetArraySize(cJSON *array) {cJSON *c=array->child;int i=0;while(c)i++,c=c->next;return i;}
+cJSON *cJSON_GetArrayItem(cJSON *array,int item) {cJSON *c=array->child; while (c && item>0) item--,c=c->next; return c;}
+cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;}
+
+/* Utility for array list handling. */
+static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;}
+/* Utility for handling references. */
+static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();if (!ref) return 0;memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;}
+
+/* Add item to array/object. */
+void cJSON_AddItemToArray(cJSON *array, cJSON *item) {cJSON *c=array->child;if (!item) return; if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}}
+void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item) {if (!item) return; if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);}
+void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) {cJSON_AddItemToArray(array,create_reference(item));}
+void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item) {cJSON_AddItemToObject(object,string,create_reference(item));}
+
+cJSON *cJSON_DetachItemFromArray(cJSON *array,int which) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0;
+ if (c->prev) c->prev->next=c->next;if (c->next) c->next->prev=c->prev;if (c==array->child) array->child=c->next;c->prev=c->next=0;return c;}
+void cJSON_DeleteItemFromArray(cJSON *array,int which) {cJSON_Delete(cJSON_DetachItemFromArray(array,which));}
+cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;}
+void cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));}
+
+/* Replace array/object items with new ones. */
+void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return;
+ newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem;
+ if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);}
+void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}}
+
+/* Create basic types: */
+cJSON *cJSON_CreateNull(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;}
+cJSON *cJSON_CreateTrue(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;}
+cJSON *cJSON_CreateFalse(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;}
+cJSON *cJSON_CreateBool(int b) {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;}
+cJSON *cJSON_CreateNumber(double num) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;}return item;}
+cJSON *cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;}
+cJSON *cJSON_CreateArray(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;}
+cJSON *cJSON_CreateObject(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;}
+
+/* Create Arrays: */
+cJSON *cJSON_CreateIntArray(const int *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
+cJSON *cJSON_CreateFloatArray(const float *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
+cJSON *cJSON_CreateDoubleArray(const double *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
+cJSON *cJSON_CreateStringArray(const char **strings,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateString(strings[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
+
+/* Duplication */
+cJSON *cJSON_Duplicate(cJSON *item,int recurse)
+{
+ cJSON *newitem,*cptr,*nptr=0,*newchild;
+ /* Bail on bad ptr */
+ if (!item) return 0;
+ /* Create new item */
+ newitem=cJSON_New_Item();
+ if (!newitem) return 0;
+ /* Copy over all vars */
+ newitem->type=item->type&(~cJSON_IsReference),newitem->valueint=item->valueint,newitem->valuedouble=item->valuedouble;
+ if (item->valuestring) {newitem->valuestring=cJSON_strdup(item->valuestring); if (!newitem->valuestring) {cJSON_Delete(newitem);return 0;}}
+ if (item->string) {newitem->string=cJSON_strdup(item->string); if (!newitem->string) {cJSON_Delete(newitem);return 0;}}
+ /* If non-recursive, then we're done! */
+ if (!recurse) return newitem;
+ /* Walk the ->next chain for the child. */
+ cptr=item->child;
+ while (cptr)
+ {
+ newchild=cJSON_Duplicate(cptr,1); /* Duplicate (with recurse) each item in the ->next chain */
+ if (!newchild) {cJSON_Delete(newitem);return 0;}
+ if (nptr) {nptr->next=newchild,newchild->prev=nptr;nptr=newchild;} /* If newitem->child already set, then crosswire ->prev and ->next and move on */
+ else {newitem->child=newchild;nptr=newchild;} /* Set newitem->child and move to it */
+ cptr=cptr->next;
+ }
+ return newitem;
+}
+
+void cJSON_Minify(char *json)
+{
+ char *into=json;
+ while (*json)
+ {
+ if (*json==' ') json++;
+ else if (*json=='\t') json++; // Whitespace characters.
+ else if (*json=='\r') json++;
+ else if (*json=='\n') json++;
+ else if (*json=='/' && json[1]=='/') while (*json && *json!='\n') json++; // double-slash comments, to end of line.
+ else if (*json=='/' && json[1]=='*') {while (*json && !(*json=='*' && json[1]=='/')) json++;json+=2;} // multiline comments.
+ else if (*json=='\"'){*into++=*json++;while (*json && *json!='\"'){if (*json=='\\') *into++=*json++;*into++=*json++;}*into++=*json++;} // string literals, which are \" sensitive.
+ else *into++=*json++; // All other characters.
+ }
+ *into=0; // and null-terminate.
+}
\ No newline at end of file
--- /dev/null
+/*
+ Copyright (c) 2009 Dave Gamble
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+*/
+
+#ifndef cJSON__h
+#define cJSON__h
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* cJSON Types: */
+#define cJSON_False 0
+#define cJSON_True 1
+#define cJSON_NULL 2
+#define cJSON_Number 3
+#define cJSON_String 4
+#define cJSON_Array 5
+#define cJSON_Object 6
+
+#define cJSON_IsReference 256
+
+/* The cJSON structure: */
+typedef struct cJSON {
+ struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
+ struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
+
+ int type; /* The type of the item, as above. */
+
+ char *valuestring; /* The item's string, if type==cJSON_String */
+ int valueint; /* The item's number, if type==cJSON_Number */
+ double valuedouble; /* The item's number, if type==cJSON_Number */
+
+ char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
+} cJSON;
+
+typedef struct cJSON_Hooks {
+ void *(*malloc_fn)(size_t sz);
+ void (*free_fn)(void *ptr);
+} cJSON_Hooks;
+
+/* Supply malloc, realloc and free functions to cJSON */
+extern void cJSON_InitHooks(cJSON_Hooks* hooks);
+
+
+/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */
+extern cJSON *cJSON_Parse(const char *value);
+/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */
+extern char *cJSON_Print(cJSON *item);
+/* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */
+extern char *cJSON_PrintUnformatted(cJSON *item);
+/* Delete a cJSON entity and all subentities. */
+extern void cJSON_Delete(cJSON *c);
+
+/* Returns the number of items in an array (or object). */
+extern int cJSON_GetArraySize(cJSON *array);
+/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
+extern cJSON *cJSON_GetArrayItem(cJSON *array,int item);
+/* Get item "string" from object. Case insensitive. */
+extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
+
+/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
+extern const char *cJSON_GetErrorPtr(void);
+
+/* These calls create a cJSON item of the appropriate type. */
+extern cJSON *cJSON_CreateNull(void);
+extern cJSON *cJSON_CreateTrue(void);
+extern cJSON *cJSON_CreateFalse(void);
+extern cJSON *cJSON_CreateBool(int b);
+extern cJSON *cJSON_CreateNumber(double num);
+extern cJSON *cJSON_CreateString(const char *string);
+extern cJSON *cJSON_CreateArray(void);
+extern cJSON *cJSON_CreateObject(void);
+
+/* These utilities create an Array of count items. */
+extern cJSON *cJSON_CreateIntArray(const int *numbers,int count);
+extern cJSON *cJSON_CreateFloatArray(const float *numbers,int count);
+extern cJSON *cJSON_CreateDoubleArray(const double *numbers,int count);
+extern cJSON *cJSON_CreateStringArray(const char **strings,int count);
+
+/* Append item to the specified array/object. */
+extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);
+extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);
+/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
+extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
+extern void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item);
+
+/* Remove/Detatch items from Arrays/Objects. */
+extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which);
+extern void cJSON_DeleteItemFromArray(cJSON *array,int which);
+extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string);
+extern void cJSON_DeleteItemFromObject(cJSON *object,const char *string);
+
+/* Update array items. */
+extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem);
+extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
+
+/* Duplicate a cJSON item */
+extern cJSON *cJSON_Duplicate(cJSON *item,int recurse);
+/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
+need to be released. With recurse!=0, it will duplicate any children connected to the item.
+The item->next and ->prev pointers are always zero on return from Duplicate. */
+
+/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
+extern cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated);
+
+extern void cJSON_Minify(char *json);
+
+/* Macros for creating things quickly. */
+#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
+#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
+#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
+#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
+#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
+#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
+
+/* When assigning an integer value, it needs to be propagated to valuedouble too. */
+#define cJSON_SetIntValue(object,val) ((object)?(object)->valueint=(object)->valuedouble=(val):(val))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null
+/*
+ Copyright (c) 2009 Dave Gamble
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "cJSON.h"
+
+/* Parse text to JSON, then render back to text, and print! */
+void doit(char *text)
+{
+ char *out;cJSON *json;
+
+ json=cJSON_Parse(text);
+ if (!json) {printf("Error before: [%s]\n",cJSON_GetErrorPtr());}
+ else
+ {
+ out=cJSON_Print(json);
+ cJSON_Delete(json);
+ printf("%s\n",out);
+ free(out);
+ }
+}
+
+/* Read a file, parse, render back, etc. */
+void dofile(char *filename)
+{
+ FILE *f=fopen(filename,"rb");fseek(f,0,SEEK_END);long len=ftell(f);fseek(f,0,SEEK_SET);
+ char *data=(char*)malloc(len+1);fread(data,1,len,f);fclose(f);
+ doit(data);
+ free(data);
+}
+
+/* Used by some code below as an example datatype. */
+struct record {const char *precision;double lat,lon;const char *address,*city,*state,*zip,*country; };
+
+/* Create a bunch of objects as demonstration. */
+void create_objects()
+{
+ cJSON *root,*fmt,*img,*thm,*fld;char *out;int i; /* declare a few. */
+
+ /* Here we construct some JSON standards, from the JSON site. */
+
+ /* Our "Video" datatype: */
+ root=cJSON_CreateObject();
+ cJSON_AddItemToObject(root, "name", cJSON_CreateString("Jack (\"Bee\") Nimble"));
+ cJSON_AddItemToObject(root, "format", fmt=cJSON_CreateObject());
+ cJSON_AddStringToObject(fmt,"type", "rect");
+ cJSON_AddNumberToObject(fmt,"width", 1920);
+ cJSON_AddNumberToObject(fmt,"height", 1080);
+ cJSON_AddFalseToObject (fmt,"interlace");
+ cJSON_AddNumberToObject(fmt,"frame rate", 24);
+
+ out=cJSON_Print(root); cJSON_Delete(root); printf("%s\n",out); free(out); /* Print to text, Delete the cJSON, print it, release the string. */
+
+ /* Our "days of the week" array: */
+ const char *strings[7]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
+ root=cJSON_CreateStringArray(strings,7);
+
+ out=cJSON_Print(root); cJSON_Delete(root); printf("%s\n",out); free(out);
+
+ /* Our matrix: */
+ int numbers[3][3]={{0,-1,0},{1,0,0},{0,0,1}};
+ root=cJSON_CreateArray();
+ for (i=0;i<3;i++) cJSON_AddItemToArray(root,cJSON_CreateIntArray(numbers[i],3));
+
+/* cJSON_ReplaceItemInArray(root,1,cJSON_CreateString("Replacement")); */
+
+ out=cJSON_Print(root); cJSON_Delete(root); printf("%s\n",out); free(out);
+
+
+ /* Our "gallery" item: */
+ int ids[4]={116,943,234,38793};
+ root=cJSON_CreateObject();
+ cJSON_AddItemToObject(root, "Image", img=cJSON_CreateObject());
+ cJSON_AddNumberToObject(img,"Width",800);
+ cJSON_AddNumberToObject(img,"Height",600);
+ cJSON_AddStringToObject(img,"Title","View from 15th Floor");
+ cJSON_AddItemToObject(img, "Thumbnail", thm=cJSON_CreateObject());
+ cJSON_AddStringToObject(thm, "Url", "http:/*www.example.com/image/481989943");
+ cJSON_AddNumberToObject(thm,"Height",125);
+ cJSON_AddStringToObject(thm,"Width","100");
+ cJSON_AddItemToObject(img,"IDs", cJSON_CreateIntArray(ids,4));
+
+ out=cJSON_Print(root); cJSON_Delete(root); printf("%s\n",out); free(out);
+
+ /* Our array of "records": */
+ struct record fields[2]={
+ {"zip",37.7668,-1.223959e+2,"","SAN FRANCISCO","CA","94107","US"},
+ {"zip",37.371991,-1.22026e+2,"","SUNNYVALE","CA","94085","US"}};
+
+ root=cJSON_CreateArray();
+ for (i=0;i<2;i++)
+ {
+ cJSON_AddItemToArray(root,fld=cJSON_CreateObject());
+ cJSON_AddStringToObject(fld, "precision", fields[i].precision);
+ cJSON_AddNumberToObject(fld, "Latitude", fields[i].lat);
+ cJSON_AddNumberToObject(fld, "Longitude", fields[i].lon);
+ cJSON_AddStringToObject(fld, "Address", fields[i].address);
+ cJSON_AddStringToObject(fld, "City", fields[i].city);
+ cJSON_AddStringToObject(fld, "State", fields[i].state);
+ cJSON_AddStringToObject(fld, "Zip", fields[i].zip);
+ cJSON_AddStringToObject(fld, "Country", fields[i].country);
+ }
+
+/* cJSON_ReplaceItemInObject(cJSON_GetArrayItem(root,1),"City",cJSON_CreateIntArray(ids,4)); */
+
+ out=cJSON_Print(root); cJSON_Delete(root); printf("%s\n",out); free(out);
+
+}
+
+int main (int argc, const char * argv[]) {
+ /* a bunch of json: */
+ char text1[]="{\n\"name\": \"Jack (\\\"Bee\\\") Nimble\", \n\"format\": {\"type\": \"rect\", \n\"width\": 1920, \n\"height\": 1080, \n\"interlace\": false,\"frame rate\": 24\n}\n}";
+ char text2[]="[\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"]";
+ char text3[]="[\n [0, -1, 0],\n [1, 0, 0],\n [0, 0, 1]\n ]\n";
+ char text4[]="{\n \"Image\": {\n \"Width\": 800,\n \"Height\": 600,\n \"Title\": \"View from 15th Floor\",\n \"Thumbnail\": {\n \"Url\": \"http:/*www.example.com/image/481989943\",\n \"Height\": 125,\n \"Width\": \"100\"\n },\n \"IDs\": [116, 943, 234, 38793]\n }\n }";
+ char text5[]="[\n {\n \"precision\": \"zip\",\n \"Latitude\": 37.7668,\n \"Longitude\": -122.3959,\n \"Address\": \"\",\n \"City\": \"SAN FRANCISCO\",\n \"State\": \"CA\",\n \"Zip\": \"94107\",\n \"Country\": \"US\"\n },\n {\n \"precision\": \"zip\",\n \"Latitude\": 37.371991,\n \"Longitude\": -122.026020,\n \"Address\": \"\",\n \"City\": \"SUNNYVALE\",\n \"State\": \"CA\",\n \"Zip\": \"94085\",\n \"Country\": \"US\"\n }\n ]";
+
+ /* Process each json textblock by parsing, then rebuilding: */
+ doit(text1);
+ doit(text2);
+ doit(text3);
+ doit(text4);
+ doit(text5);
+
+ /* Parse standard testfiles: */
+/* dofile("../../tests/test1"); */
+/* dofile("../../tests/test2"); */
+/* dofile("../../tests/test3"); */
+/* dofile("../../tests/test4"); */
+/* dofile("../../tests/test5"); */
+
+ /* Now some samplecode for building objects concisely: */
+ create_objects();
+
+ return 0;
+}
--- /dev/null
+{
+ "glossary": {
+ "title": "example glossary",
+ "GlossDiv": {
+ "title": "S",
+ "GlossList": {
+ "GlossEntry": {
+ "ID": "SGML",
+ "SortAs": "SGML",
+ "GlossTerm": "Standard Generalized Markup Language",
+ "Acronym": "SGML",
+ "Abbrev": "ISO 8879:1986",
+ "GlossDef": {
+ "para": "A meta-markup language, used to create markup languages such as DocBook.",
+ "GlossSeeAlso": ["GML", "XML"]
+ },
+ "GlossSee": "markup"
+ }
+ }
+ }
+ }
+}
--- /dev/null
+{"menu": {
+ "id": "file",
+ "value": "File",
+ "popup": {
+ "menuitem": [
+ {"value": "New", "onclick": "CreateNewDoc()"},
+ {"value": "Open", "onclick": "OpenDoc()"},
+ {"value": "Close", "onclick": "CloseDoc()"}
+ ]
+ }
+}}
--- /dev/null
+{"widget": {
+ "debug": "on",
+ "window": {
+ "title": "Sample Konfabulator Widget",
+ "name": "main_window",
+ "width": 500,
+ "height": 500
+ },
+ "image": {
+ "src": "Images/Sun.png",
+ "name": "sun1",
+ "hOffset": 250,
+ "vOffset": 250,
+ "alignment": "center"
+ },
+ "text": {
+ "data": "Click Here",
+ "size": 36,
+ "style": "bold",
+ "name": "text1",
+ "hOffset": 250,
+ "vOffset": 100,
+ "alignment": "center",
+ "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;"
+ }
+}}
\ No newline at end of file
--- /dev/null
+{"web-app": {
+ "servlet": [
+ {
+ "servlet-name": "cofaxCDS",
+ "servlet-class": "org.cofax.cds.CDSServlet",
+ "init-param": {
+ "configGlossary:installationAt": "Philadelphia, PA",
+ "configGlossary:adminEmail": "ksm@pobox.com",
+ "configGlossary:poweredBy": "Cofax",
+ "configGlossary:poweredByIcon": "/images/cofax.gif",
+ "configGlossary:staticPath": "/content/static",
+ "templateProcessorClass": "org.cofax.WysiwygTemplate",
+ "templateLoaderClass": "org.cofax.FilesTemplateLoader",
+ "templatePath": "templates",
+ "templateOverridePath": "",
+ "defaultListTemplate": "listTemplate.htm",
+ "defaultFileTemplate": "articleTemplate.htm",
+ "useJSP": false,
+ "jspListTemplate": "listTemplate.jsp",
+ "jspFileTemplate": "articleTemplate.jsp",
+ "cachePackageTagsTrack": 200,
+ "cachePackageTagsStore": 200,
+ "cachePackageTagsRefresh": 60,
+ "cacheTemplatesTrack": 100,
+ "cacheTemplatesStore": 50,
+ "cacheTemplatesRefresh": 15,
+ "cachePagesTrack": 200,
+ "cachePagesStore": 100,
+ "cachePagesRefresh": 10,
+ "cachePagesDirtyRead": 10,
+ "searchEngineListTemplate": "forSearchEnginesList.htm",
+ "searchEngineFileTemplate": "forSearchEngines.htm",
+ "searchEngineRobotsDb": "WEB-INF/robots.db",
+ "useDataStore": true,
+ "dataStoreClass": "org.cofax.SqlDataStore",
+ "redirectionClass": "org.cofax.SqlRedirection",
+ "dataStoreName": "cofax",
+ "dataStoreDriver": "com.microsoft.jdbc.sqlserver.SQLServerDriver",
+ "dataStoreUrl": "jdbc:microsoft:sqlserver://LOCALHOST:1433;DatabaseName=goon",
+ "dataStoreUser": "sa",
+ "dataStorePassword": "dataStoreTestQuery",
+ "dataStoreTestQuery": "SET NOCOUNT ON;select test='test';",
+ "dataStoreLogFile": "/usr/local/tomcat/logs/datastore.log",
+ "dataStoreInitConns": 10,
+ "dataStoreMaxConns": 100,
+ "dataStoreConnUsageLimit": 100,
+ "dataStoreLogLevel": "debug",
+ "maxUrlLength": 500}},
+ {
+ "servlet-name": "cofaxEmail",
+ "servlet-class": "org.cofax.cds.EmailServlet",
+ "init-param": {
+ "mailHost": "mail1",
+ "mailHostOverride": "mail2"}},
+ {
+ "servlet-name": "cofaxAdmin",
+ "servlet-class": "org.cofax.cds.AdminServlet"},
+
+ {
+ "servlet-name": "fileServlet",
+ "servlet-class": "org.cofax.cds.FileServlet"},
+ {
+ "servlet-name": "cofaxTools",
+ "servlet-class": "org.cofax.cms.CofaxToolsServlet",
+ "init-param": {
+ "templatePath": "toolstemplates/",
+ "log": 1,
+ "logLocation": "/usr/local/tomcat/logs/CofaxTools.log",
+ "logMaxSize": "",
+ "dataLog": 1,
+ "dataLogLocation": "/usr/local/tomcat/logs/dataLog.log",
+ "dataLogMaxSize": "",
+ "removePageCache": "/content/admin/remove?cache=pages&id=",
+ "removeTemplateCache": "/content/admin/remove?cache=templates&id=",
+ "fileTransferFolder": "/usr/local/tomcat/webapps/content/fileTransferFolder",
+ "lookInContext": 1,
+ "adminGroupID": 4,
+ "betaServer": true}}],
+ "servlet-mapping": {
+ "cofaxCDS": "/",
+ "cofaxEmail": "/cofaxutil/aemail/*",
+ "cofaxAdmin": "/admin/*",
+ "fileServlet": "/static/*",
+ "cofaxTools": "/tools/*"},
+
+ "taglib": {
+ "taglib-uri": "cofax.tld",
+ "taglib-location": "/WEB-INF/tlds/cofax.tld"}}}
\ No newline at end of file
--- /dev/null
+{"menu": {
+ "header": "SVG Viewer",
+ "items": [
+ {"id": "Open"},
+ {"id": "OpenNew", "label": "Open New"},
+ null,
+ {"id": "ZoomIn", "label": "Zoom In"},
+ {"id": "ZoomOut", "label": "Zoom Out"},
+ {"id": "OriginalView", "label": "Original View"},
+ null,
+ {"id": "Quality"},
+ {"id": "Pause"},
+ {"id": "Mute"},
+ null,
+ {"id": "Find", "label": "Find..."},
+ {"id": "FindAgain", "label": "Find Again"},
+ {"id": "Copy"},
+ {"id": "CopyAgain", "label": "Copy Again"},
+ {"id": "CopySVG", "label": "Copy SVG"},
+ {"id": "ViewSVG", "label": "View SVG"},
+ {"id": "ViewSource", "label": "View Source"},
+ {"id": "SaveAs", "label": "Save As"},
+ null,
+ {"id": "Help"},
+ {"id": "About", "label": "About Adobe CVG Viewer..."}
+ ]
+}}
--- /dev/null
+
+ADD_LIBRARY(asn1cpp
+ prim_oid.cpp)
+
+#
+# Install stull
+#
+
+IF(APPLE)
+ INSTALL(TARGETS asn1cpp
+ COMPONENT RuntimeLibraries
+ LIBRARY DESTINATION Smartasn1.app/Contents/lib/
+ ARCHIVE DESTINATION Smartasn1.app/Contents/lib/
+ )
+ELSE(APPLE)
+ INSTALL(TARGETS asn1cpp
+ COMPONENT RuntimeLibraries
+ LIBRARY DESTINATION lib/
+ ARCHIVE DESTINATION lib/
+ )
+ENDIF(APPLE)
--- /dev/null
+#ifndef PRIM_GENERALIZEDTIME_H
+#define PRIM_GENERALIZEDTIME_H
+
+namespace ans1 {
+namespace prim {
+namespace types {
+
+
+class GeneralizedTime {
+ public:
+ inline GeneralizedTime(int len,const char *v) : m_len(len),m_(v) {};
+ inline GeneralizedTime(const GeneralizedTime &oid) {}
+ inline ~GeneralizedTime() {}
+
+ inline bool operator==(const GeneralizedTime &o) { return true;};
+
+ protected:
+ int m_len;
+ const char *m_;
+
+};
+
+}
+}
+}
+#endif
--- /dev/null
+#ifndef PRIM_UTCTIME_H
+#define PRIM_UTCTIME_H
+
+namespace ans1 {
+namespace prim {
+namespace types {
+
+
+class UTCTime {
+ public:
+ inline UTCTime(int len,const char *v) : m_len(len),m_(v) {};
+ inline UTCTime(const UTCTime &oid) {}
+ inline ~UTCTime() {}
+
+ inline bool operator==(const UTCTime &o) {return true;};
+
+ protected:
+ int m_len;
+ const char *m_;
+
+};
+
+}
+}
+}
+#endif
+
--- /dev/null
+
+#include <iostream>
+#include <vector>
+#include <assert.h>
+#include <string.h>
+#include "rtasn1/prim_types.h"
+#include "rtasn1/cpp/prim_oid.h"
+
+#define GEN_LOG_DEBUG
+
+#define MIN(a,b) (((a)< (b))?(a):(b))
+
+namespace asn1 {
+namespace prim {
+namespace types {
+
+/**
+ * Default constructor
+ */
+ObjectIdentifier::ObjectIdentifier(long len,const char *buf)
+ : m_len(len)
+{
+ memset(m_oid,0x00,MAX_OID_LEN);
+ m_ = m_oid;
+ assert(len < MAX_OID_LEN);
+ memcpy(m_,buf,MIN(len,MAX_OID_LEN));
+}
+
+ObjectIdentifier::ObjectIdentifier(const char *v)
+{
+ memset(m_oid,0x00,MAX_OID_LEN);
+ m_ = m_oid;
+ size_t len = strlen(v);
+ assert(len < MAX_OID_LEN);
+ memcpy(m_,v,MIN(len,MAX_OID_LEN));
+}
+
+// Compare
+bool ObjectIdentifier::operator ==(const ObjectIdentifier &o) const
+{
+ return ( m_len == o.m_len ) && !strncmp(m_oid,o.m_oid,m_len);
+}
+// Copy constructor
+ObjectIdentifier::ObjectIdentifier(const ObjectIdentifier &oid)
+{
+ if (oid.m_len > MAX_OID_LEN)
+ {
+ std::cerr<<"ObjectIdentifier::ObjectIdentifier MAX_OID_LEN exeeded "<<oid.m_len<<std::endl;
+ }
+ assert(oid.m_len < MAX_OID_LEN);
+ memset(m_oid,0x00,MAX_OID_LEN);
+ m_ = m_oid;
+ m_len = oid.m_len;
+ memcpy(m_oid,oid.m_oid,MIN(oid.m_len,MAX_OID_LEN));
+}
+
+// Build string from ... 3 {1,3,5}
+ObjectIdentifier::ObjectIdentifier(long len,const long *arcs)
+{
+ from_arc(len,arcs);
+}
+
+
+// Copy operator
+ObjectIdentifier &ObjectIdentifier::operator =(const ObjectIdentifier &oid)
+{
+ assert(oid.m_len < MAX_OID_LEN);
+#if 0
+ std::cerr<<"ObjectIdentifier::= len="<<oid.m_len<<std::endl;
+#endif
+ m_len = oid.m_len;
+ m_ = m_oid;
+ memcpy(m_oid,oid.m_oid,MIN(oid.m_len,MAX_OID_LEN));
+ return *this;
+}
+
+/**
+ * This is only valid for OID where we use 7 bits for each octet.
+ */
+void ObjectIdentifier::encode_integer(long value)
+{
+ long integer = value;
+ long intsize = 4;
+ long mask = 0x1FF <<23; // Shift 8 *3 - 1 ? 0xFF800000
+ while ( (((integer & mask) == 0) || ((integer & mask) == mask))
+ && (intsize > 1)) {
+ intsize--;
+ integer <<=8;
+ }
+ mask = (0x7f << ((intsize-1)*7));
+ long decal = (intsize -1)*7;
+
+ while ((value & mask ) != 0)
+ {
+ long treat = ((value & mask)>>decal);
+ m_oid[m_len++] = (( treat & 0x7F) |0x80 );
+ value<<=7;
+ intsize--;
+ }
+ if (intsize)
+ m_oid[m_len++] = 0;
+ m_oid[m_len -1 ] = m_oid[m_len - 1] & 0x7F;
+ //m_oid[m_len ] = m_oid[m_len ] & 0x7F;
+}
+
+void
+ObjectIdentifier::from_string(long len,const char *arcs)
+{
+ memset(m_oid,0x00,MAX_OID_LEN);
+ m_len = len;
+ assert(len < MAX_OID_LEN);
+ memcpy(m_oid,arcs,MIN(len,MAX_OID_LEN));
+}
+
+void
+ObjectIdentifier::from_arc(long len,const long *arcs)
+{
+ long * pos = &m_len;
+ int first2 = 0;
+ *pos = 0;
+ assert(len < MAX_OID_LEN);
+ for ( int i = 0 ; i < len; i++)
+ {
+ long l = arcs[i];
+ if (i == 0)
+ {
+ first2 = 40 * arcs[i];
+ } else if (i == 1)
+ {
+ first2 = first2 + arcs[i];
+ m_oid[*pos] = first2;
+ (*pos)++;
+ } else
+ {
+ encode_integer(l);
+ }
+
+ }
+ assert(m_len < MAX_OID_LEN);
+}
+
+void
+ObjectIdentifier::to_arc(array_type &a)
+{
+ char *buf = const_cast<char *>(m_oid);
+ if (m_len)
+ {
+ for (int i = 0 ; i < m_len ; i++)
+ {
+ if (i == 0 )
+ {
+ long byte = buf[i] / 40;
+ a.push_back(byte);
+ byte = buf[i] % 40;
+ a.push_back(byte);
+
+ } else if (buf[i] & 0x80 ) {
+ long res = 0;
+ while ((buf[i] & 0x80))
+ {
+ res = (res<<7) | (buf[i++] &0x7F);
+ }
+ res = (res<<7) | (buf[i] &0x7F);
+ a.push_back(res);
+ } else
+ {
+ long l = buf[i];
+ a.push_back(l);
+ }
+ }
+ }
+}
+
+// Compare
+std::ostream & operator <<(std::ostream &os,const ObjectIdentifier &oid )
+{
+ char *buf = const_cast<char *>(oid.m_oid);
+
+ if (oid.m_len)
+ {
+ for (int i = 0 ; (i < oid.m_len) && (i<MAX_OID_LEN); i++)
+ {
+ if (i == 0 )
+ {
+ long byte = buf[i] / 40;
+ //this->m_.push_back((T)byte);
+ os<<byte;
+ byte = buf[i] % 40;
+ os<<"."<<byte;
+
+ } else if (buf[i] & 0x80 ) {
+ long res = 0;
+ while ((buf[i] & 0x80))
+ {
+ res = (res<<7) | (buf[i++] &0x7F);
+ }
+ res = (res<<7) | (buf[i] &0x7F);
+ os<<"."<<res;
+ } else
+ {
+ long l = buf[i];
+ os<<"."<<l;
+ }
+ }
+ } else
+ {
+ os<<"{}";
+ }
+ return os;
+}
+
+//END
+}
+}
+}
--- /dev/null
+#ifndef PRIM_OID_H
+#define PRIM_OID_H
+
+#include <vector>
+
+namespace asn1 {
+namespace prim {
+namespace types {
+#define MAX_OID_LEN 48
+/**
+ * ObjectIdentifier type
+ * Only store the encoded form.
+ * Decode the encoded form from display
+ */
+class ObjectIdentifier : public asn1::prim::types::prim< char *>
+{
+ public:
+ typedef std::vector<long> array_type;
+ typedef array_type::iterator iterator;
+
+ // Build from encoded ObjectIdentidier
+ ObjectIdentifier(long len=0,const char *v=NULL);
+ // Build from encoded ObjectIdentidier
+ ObjectIdentifier(const char *v);
+
+ // Build string from ... 3 {1,3,5}
+ ObjectIdentifier(long len,const long *arcs);
+
+ ObjectIdentifier(const ObjectIdentifier &oid);
+
+ inline ~ObjectIdentifier() {}
+ // Build oid string from arcs
+ void from_arc(long len,const long *arcs);
+ //
+ void from_string(long len,const char *arcs);
+
+ void to_arc(array_type &result);
+ // Copy operator
+ ObjectIdentifier &operator=(const ObjectIdentifier &oid);
+ // Compare
+ bool operator==(const ObjectIdentifier &oid) const;
+
+ inline long get_oid_length() const { return m_len;}
+ friend std::ostream & operator <<(std::ostream &os,const ObjectIdentifier &oid );
+ protected:
+ void encode_integer(long l);
+ protected:
+ char m_oid[MAX_OID_LEN] ; // Encoded Oid
+ long m_len;
+};
+
+std::ostream & operator <<(std::ostream &os,ObjectIdentifier &oid );
+
+}
+}
+}
+#endif
--- /dev/null
+#ifndef JER_TOKEN
+#define JER_TOKEN(id,str)
+#endif
+JER_TOKEN(bool,"bool")
+JER_TOKEN(colon,"colon")
+JER_TOKEN(comma,"comma")
+JER_TOKEN(eof,"eof")
+JER_TOKEN(error,"error")
+JER_TOKEN(left_brace,"lbrace")
+JER_TOKEN(left_bracket,"lbracket")
+JER_TOKEN(null,"null")
+JER_TOKEN(integer,"integer")
+JER_TOKEN(double,"double")
+JER_TOKEN(right_brace,"rbrace")
+JER_TOKEN(right_bracket,"rbracket")
+JER_TOKEN(string,"string")
+JER_TOKEN(string_with_escapes,"string_with_escapes")
+JER_TOKEN(comment,"comment")
+#undef JER_TOKEN
--- /dev/null
+#include <iostream>
+#include <string>
+#include <stdio.h>
+#include "rtasn1/asn1_config.h"
+#include "prim_types.h"
+
+#if 0
+#include "rtasn1/cpp/prim_oid.h"
+#include "rtasn1/cpp/prim_UTCTime.h"
+#include "rtasn1/cpp/prim_GeneralizedTime.h"
+#endif
+
+//#define NOTEMPLATE
+namespace asn1 {
+namespace prim {
+namespace types {
+
+template <typename C> struct prim;
+
+template <>
+std::ostream &operator << <bool>(std::ostream &os,const prim<bool> &_p)
+{
+ bool b = _p.get_value();
+ os<<"bool("<<std::hex<<b<<std::dec<<") ";
+ return os;
+}
+
+
+
+template <>
+std::ostream &operator << <std::string>(std::ostream &os,const prim<std::string> &_p)
+{
+ os<<" string (";
+
+ for (int i = 0 ; i < _p.m_.size(); i++)
+ {
+ char tmp[10];
+ sprintf(tmp,"%02x",(unsigned char )_p.m_[i]);
+ os<<tmp<<" ";
+ }
+
+ os<<std::dec<<") ";
+ return os;
+}
+
+std::ostream &operator << (std::ostream &os,const String &_p)
+{
+ os<<(const prim<std::string> &)(_p);
+ return os;
+}
+
+
+
+//
+#ifndef HAVE_STDINT_H
+template <>
+std::ostream & operator << <long>(std::ostream &os,const arithm_prim<long> &_p )
+{
+ os<<" long("<<_p.m_<<") ";
+ return os;
+};
+#endif
+template <>
+std::ostream & operator << <unsigned char>(std::ostream &os,const arithm_prim<unsigned char> &_p )
+{
+ os<<" UI8("<<static_cast<int>(_p.m_)<<") ";
+ return os;
+};
+
+template <>
+std::ostream & operator << <unsigned short>(std::ostream &os,const arithm_prim<unsigned short> &_p )
+{
+ os<<" UI16("<<_p.m_<<") ";
+ return os;
+};
+
+#ifdef HAVE_STDINT_H
+template <>
+std::ostream & operator << <uint32_t>(std::ostream &os,const arithm_prim<uint32_t> &_p )
+#else
+template <>
+std::ostream & operator << <unsigned int>(std::ostream &os,const arithm_prim<unsigned int> &_p )
+#endif
+{
+ os<<" UI32("<<_p.m_<<") ";
+ return os;
+};
+
+#ifdef HAVE_STDINT_H
+/* int64_t is long ??? */
+template <>
+std::ostream & operator << <int64_t>(std::ostream &os,const arithm_prim<int64_t> &_p )
+#else
+template <>
+std::ostream & operator << <long long>(std::ostream &os,const arithm_prim<long long> &_p )
+#endif
+{
+ os<<" I64("<<_p.m_<<") ";
+ return os;
+};
+
+
+
+#ifdef HAVE_STDINT_H
+template <>
+std::ostream & operator << <uint64_t>(std::ostream &os,const arithm_prim<uint64_t> &_p )
+#else
+template <>
+std::ostream & operator << <unsigned long long>(std::ostream &os,const arithm_prim<unsigned long long> &_p )
+#endif
+{
+ os<<" UI64("<<_p.m_<<") ";
+ return os;
+};
+
+
+
+template <>
+std::ostream & operator << <double>(std::ostream &os,const arithm_prim<double> &_p )
+{
+ os<<" <dbl("<<_p.m_<<") ";
+ return os;
+};
+
+
+std::ostream & operator <<(std::ostream &os,const asn1::prim::types::UTCTime &_p )
+{
+ std::string str = _p.toString();
+ os<<"Time ("<<str<<") ";
+ return os;
+}
+
+}
+}
+}
--- /dev/null
+#ifndef ASN1_PTYPES_H__
+#define ASN1_PTYPES_H__
+#include <iostream>
+#include <iomanip>
+#include <vector>
+#include <string>
+#include "rtasn1/cpp/prim_UTCTime.h"
+#include "rtasn1/cpp/prim_GeneralizedTime.h"
+
+//#define NOTEMPLATE
+namespace asn1 {
+namespace prim {
+namespace types {
+
+template <typename C> struct prim;
+
+template <typename C>
+std::ostream &operator <<(std::ostream &os,const prim<C> &t);
+
+
+/**
+ *
+ */
+template <typename C>
+struct prim {
+
+ protected:
+ public:
+ typedef C prim_type;
+ typedef C* prim_pointer;
+ typedef C& prim_type_reference;
+ typedef const C & prim_type_const_reference;
+
+ inline prim() : m_() {};
+ inline prim(const C &c) : m_(c) {}
+ inline prim(const prim<C> &v) : m_(v.m_) {};
+ inline ~prim() {};
+ // Copy assignement
+ inline prim<C> &operator =(const prim<C> &v) {m_ = v.m_; return *this;};
+ inline prim<C> &operator=(const C c) { m_ = c; return *this;}
+ //
+ inline bool operator==(const prim<C> &c) const { return m_ == c.m_;}
+ //
+ inline bool operator!=(const prim<C> &c) { return ! operator==(c);}
+ inline bool operator==(const C &c) const { return m_ == c;}
+ inline bool operator!=(const C &c) const { return m_ != c;}
+ //inline operator C() const {return m_;}
+ //template <typename X = C>
+ friend std::ostream & operator << <>(std::ostream &os,const prim<C> &_p );
+ // Better than cast
+ prim_type_reference get_value() { return m_;} ;
+ prim_type_const_reference get_value() const { return m_;} ;
+protected:
+ prim_type m_;
+};
+
+
+
+typedef prim<bool> Boolean;
+//typedef prim<std::string> String;
+
+/**
+ *
+ */
+class String : public prim<std::string>
+{
+ public:
+
+ String() {};
+ String(const String &t): prim<std::string>::prim(t.m_) {};
+ String(const std::string &t): prim<std::string>::prim(t) {};
+ String(const char *t): prim<std::string>::prim(t) {};
+ ~String() {};
+
+ inline void operator=(const std::string &c) { m_ = c;}
+
+ inline bool operator==(const String &c) const { return ! m_.compare(c.m_) ;}
+
+ inline const std::string toString(void) const {return this->m_;};
+ friend std::ostream & operator <<(std::ostream &os,const String &_p );
+
+ size_t size () const { return m_.size() ; }
+
+ const char *c_str() const { return m_.c_str() ; }
+};
+
+
+// Forward declation for array
+template <typename C> struct array ;
+template <typename C>
+std::ostream &operator <<(std::ostream &os,const array<C> &t);
+
+/**
+ *
+ */
+template <typename C>
+struct array {
+ public:
+ typedef C& reference;
+ typedef const C& const_reference;
+ typedef std::vector<C> type;
+ typedef typename std::vector<C>::iterator iterator;
+ typedef typename std::vector<C>::const_iterator const_iterator;
+
+ inline array(size_t sz = 0) :m_(sz)
+ {
+ //std::cout<<" build array "<<std::endl;
+ };
+ inline array(const array<C> &v) : m_(v.m_)
+ {
+ std::cout<<"array::array copy"<<std::endl;
+ };
+ inline array(const type &v) : m_(v)
+ {
+ std::cout<<"array::array(std::vector<C> &)"<<std::endl;
+ };
+ inline array(const C c)
+ {
+ std::cout<<" from c "<<std::endl;
+ m_.push_back(c);
+ }
+ inline array<C> &operator =(const array<C> &v) {m_ = v.m_;};
+ inline ~array() {};
+ inline iterator begin() {return m_.begin();};
+ inline const_iterator begin() const {return m_.begin();};
+ inline iterator end() {return m_.end();};
+ inline size_t size() const {return m_.size();};
+ //inline void operator=(const C c) { m_ = c;}
+ inline reference operator[](int c) {
+ if (m_.size() == 0)
+ {
+ m_.resize(c+1) ;
+ m_[c] = 0;
+ } else if (m_.size() <= c)
+ {
+ m_.resize(c+1);
+ m_[c] = 0;
+ }
+ return m_[c];
+ }
+ inline const_reference operator[](int c) const { return m_[c];}
+// inline bool operator==(const prim<C> &c) { m_ == c;}
+ inline void operator=(const C &c) { m_[0] = c;}
+ inline void operator=(const prim<C> &c) { m_ = c.m_;}
+ inline operator type () const {return m_;}
+
+ friend std::ostream & operator <<(std::ostream &os,const array<C> &_p )
+ {
+ typename std::vector<C>::const_iterator iter = _p.begin();
+ os<<" array [";os<<_p.size()<<"] ";
+ os<<std::setfill('0');
+ os<<std::setw(2);
+#if 1
+ for (; iter < _p.m_.end() ; ++iter) {
+ if (iter != _p.begin() )
+ os<<":";
+ os<<std::hex<<std::setfill('0')<<std::setw(2)<<(int)(*iter);
+ }
+ os<<std::dec;
+#endif
+ os<<std::setfill(' ');
+ return os;
+ };
+
+ protected:
+ type m_;
+};
+
+/**
+ *
+ */
+class UTCTime : public prim<std::string>
+{
+ public:
+
+ UTCTime() {};
+ UTCTime(const UTCTime &t): prim<std::string>::prim(t.m_) {};
+ UTCTime(const std::string &t): prim<std::string>::prim(t) {};
+ UTCTime(const char *t): prim<std::string>::prim(t) {};
+ ~UTCTime() {};
+
+ inline void operator=(const std::string &c) { m_ = c;}
+
+ inline const std::string toString(void) const {return this->m_;};
+ friend std::ostream & operator <<(std::ostream &os,const UTCTime &_p );
+
+
+};
+
+// Forward declaration for arith_prim streaming
+template <typename C> class arithm_prim;
+
+template <typename C>
+std::ostream &operator <<(std::ostream &os,const arithm_prim<C> &s);
+
+/**
+ *
+ */
+template <typename C>
+class arithm_prim : public prim<C>
+{
+ public:
+ inline arithm_prim() {};
+ inline arithm_prim(const arithm_prim<C> &v) : prim<C>(v) {};
+ inline ~arithm_prim() {};
+ inline arithm_prim(const C c) : prim<C>(c) {};
+
+ inline void operator = (const C c) {prim<C>::operator =(c);}
+ // Available in prim<C>
+ // inline bool operator ==(const arithm_prim<C> &c) { return this->m_ == (C)c.m_;};
+ // inline bool operator ==(const C c) { return prim<C>::operator ==(c);};
+ inline C operator +=(const C v) {return this->m_+=v;}
+ inline C operator -=(const C v) {return this->m_-=v;}
+ inline C operator *=(const C v) {return this->m_*=v;}
+ inline C operator /=(const C v) {return this->m_/=v;}
+#if 1
+ inline arithm_prim<C> &operator +=(const arithm_prim<C> &v)
+ { prim<C>::m_ += v.m_; return *this; }
+ inline arithm_prim<C> &operator -=(const arithm_prim<C> &v)
+ { prim<C>::m_ -= v.m_; return *this; }
+ inline arithm_prim<C> &operator *=(const arithm_prim<C> &v)
+ { prim<C>::m_ *= v.m_; return *this; }
+ inline arithm_prim<C> &operator /=(const arithm_prim<C> &v)
+ { prim<C>::m_ /= v.m_; return *this; }
+#endif
+
+ //inline C operator --(const C v) {return --this->m_;}
+ //inline C operator ++(const C v) {return ++this->m_;}
+ //
+ friend std::ostream &operator << <>(std::ostream &os,const arithm_prim<C> &_p);
+};
+
+/**
+ * Be aware the that what's below depends on the processor
+ * use it carefully.
+ * If stdint is available, I should use
+ *
+ */
+#ifdef HAVE_STDINT_H
+
+typedef arithm_prim<uint8_t> UInt8;
+typedef arithm_prim<uint16_t> UInt16;
+typedef arithm_prim<uint32_t> UInt32;
+typedef arithm_prim<uint64_t> UInt64;
+
+typedef arithm_prim<int8_t> Int8;
+typedef arithm_prim<int16_t> Int16;
+typedef arithm_prim<int32_t> Int32;
+typedef arithm_prim<int64_t> Int64;
+
+typedef arithm_prim<int64_t> Integer;
+#else
+typedef arithm_prim<long> Integer;
+typedef arithm_prim<unsigned char> UInt8;
+typedef arithm_prim<unsigned short> UInt16;
+typedef arithm_prim<unsigned int> UInt32;
+typedef arithm_prim<unsigned long long> UInt64;
+
+typedef arithm_prim<char> Int8;
+typedef arithm_prim<short> Int16;
+typedef arithm_prim<int> Int32;
+typedef arithm_prim<long long> Int64;
+#endif
+
+typedef arithm_prim<double> Real;
+
+
+std::ostream & operator <<(std::ostream &os,const asn1::prim::types::UTCTime &_p );
+/**
+ * BIT STRING ....
+ * -> I use a template in order to be able to specify
+ * several size of bit strings (8, 16 , 32, and above)
+ */
+class bs_prim : public prim<std::vector<unsigned char> >
+{
+ public:
+ typedef unsigned char C;
+
+ typedef std::vector<C> prim_type;
+ typedef prim_type * prim_pointer;
+ typedef prim_type & prim_type_reference;
+ typedef const prim_type & prim_type_const_reference;
+ /* There is an inconsitency */
+ typedef C* pointer;
+ typedef C& reference;
+ typedef const C& const_reference;
+ typedef std::vector<C> type;
+ typedef type & type_reference;
+ typedef std::vector<C>::iterator iterator;
+ typedef std::vector<C> ::const_iterator const_iterator;
+
+ bs_prim(size_t sz = 0)
+ : prim<std::vector<unsigned char> >()
+ {
+ }
+ bs_prim(const prim_type &c)
+ : prim<std::vector<unsigned char> >(c)
+ {
+ }
+
+ bs_prim(const bs_prim &_bs)
+ : prim<std::vector<unsigned char> >(_bs.get_value())
+ , m_NbBits(_bs.m_NbBits)
+ {
+ }
+
+ ~bs_prim()
+ {
+ }
+#if 0
+ void set_data(const char *)
+ {
+ }
+
+ void set_data(const std::string &_v)
+ {
+ m_NbBits = _v.size() << 3;
+ }
+#endif
+ //
+ inline size_t size() const
+ {
+ return this->m_.size();
+ }
+ //
+ void set_nb_bits( size_t _nb)
+ {
+ m_NbBits = _nb;
+ this->m_.resize(_nb/8+1);
+ };
+
+ //
+ inline size_t get_nb_bits() const
+ {
+ return m_NbBits;
+ };
+
+ //
+ void set_bit(int _bit)
+ {
+ int a,b;
+ unsigned char val = 1;
+ a = _bit / 8;
+ b = _bit % 8;
+ val = 1<<b;
+ this->m_[a] = this->m_[a] | val;
+ };
+
+ //
+ void clear_bit(int _bit)
+ {
+ int a,b;
+ unsigned char val = 1;
+ a = _bit / 8;
+ b = _bit % 8;
+ val = 1<<b;
+ this->m_[a] = this->m_[a] & ~val;
+ };
+
+ //
+ inline bool get_bit(int _bit) const
+ {
+ int a,b;
+ unsigned char val = 1;
+ a = _bit / 8;
+ b = _bit % 8;
+ val = 1<<b;
+ return (this->m_[a] & val)>0;
+ };
+
+ //
+ const_reference operator[](size_t c) const
+ {
+ return this->m_[c];
+ }
+ //
+ reference operator[](size_t c)
+ {
+ if (this->m_.size() <= c)
+ {
+ this->m_.resize(c+1);
+ this->m_[c] = 0;
+ m_NbBits = c << 3;
+ }
+ return this->m_[c];
+ }
+
+ //
+ iterator begin()
+ { return this->m_.begin() ; }
+ //
+ const_iterator begin() const
+ { return this->m_.begin() ; }
+ //
+ iterator end()
+ { return this->m_.end() ; }
+ //
+ const_iterator end() const
+ { return this->m_.end() ; }
+
+
+ friend std::ostream & operator <<(std::ostream &os,const bs_prim &_p )
+ {
+ size_t count = 0;
+ //const_iterator iter = _p.end();
+ const_iterator iter = _p.begin(); iter+=_p.m_NbBits/8 - 1 ;
+ os<<" bs[";os<<_p.size()<<"] ("<<_p.m_NbBits<<")";
+ //os<<std::setfill('0');
+ //os<<std::setw(2);
+ if (! _p.size())
+ {
+ return os;
+ }
+ std::streamsize indent = os.precision() + 2;
+ os<<std::endl;
+ os<<std::setfill(' ');
+ os<<std::setw(indent+2);
+ for (; iter >= _p.m_.begin() ; --iter) {
+ if (iter != _p.end() )
+ os<<":";
+ os<<std::hex<<std::setfill('0')<<std::setw(2)<<(int)(*iter);
+ if ( ! (++count % 16))
+ {
+ os<<std::endl;
+ os<<std::setfill(' ');
+ os<<std::setw(indent+2);
+ }
+ }
+ os<<std::dec;
+ os<<std::setfill(' ');
+ os<<"\n"<<std::setw(indent)<<std::setprecision(indent-2);
+ return os;
+ };
+
+ protected:
+ size_t m_NbBits;
+};
+
+typedef bs_prim BitString;
+
+
+}
+}
+}
+
+#include "rtasn1/cpp/prim_oid.h"
+
+
+#endif
--- /dev/null
+PROJECT(test-lib)
+
+ADD_DEFINITIONS(-DASN1_ATTRIBUTE_OPTIONAL_AS_SHARED_POINTER)
+# WIN32 no CPPUNIT AVAILABLE
+IF(NOT WIN32)
+
+SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
+ "${rules_SOURCE_DIR}/")
+
+INCLUDE(${rules_SOURCE_DIR}/utils.cmake)
+
+#FIND_LIBRARY(CPPUNIT_LIBRARY cppunit PATHS "/usr/local/lib:/usr/lib:/Users/aeb/External/lib/:/Users/aeb/External/bin/")
+FIND_LIBRARY(DL_LIB ltdl "/lib:/usr/local/lib:/usr/lib")
+
+FIND_PACKAGE(CPPUNIT REQUIRED)
+INCLUDE_DIRECTORIES(${CPPUNIT_INCLUDE_DIRS})
+
+#FIND_PACKAGE(CppUnit PATHS "/usr/local/lib:/usr/lib:/Users/aeb/External/lib/:/Users/aeb/External/bin/")
+#FIND_PACKAGE(CppUnit)
+
+IF(CPPUNIT_FOUND)
+ MESSAGE("FOUND CCPUNIT")
+ INCLUDE_DIRECTORIES(${CPPUNIT_INCLUDE_DIRS})
+ELSE(CPPUNIT_FOUND)
+ INCLUDE_DIRECTORIES("/Users/aeb/External/include")
+ENDIF(CPPUNIT_FOUND)
+#EXEC_PROGRAM(cat ARGS ${CMAKE_CURRENT_SOURCE_DIR}/modules.txt OUTPUT_VARIABLE
+# CSTAMODULES)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+
+FILE(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/modules.txt TESTMODULES)
+
+
+
+
+MACRO(TESTCASE)
+ PARSE_ARGUMENTS(THIS_TC
+ "NAME;SOURCE"
+ "DEBUG"
+ ${ARGN}
+ )
+ STRING(REGEX REPLACE ".cpp" "_codec.cpp" CODEC ${THIS_TC_SOURCE})
+ STRING(REGEX REPLACE "-" "_" CODEC ${CODEC})
+ ADD_EXECUTABLE(${THIS_TC_NAME}
+ UNIT-${THIS_TC_SOURCE}
+ ${CMAKE_CURRENT_BINARY_DIR}/${THIS_TC_SOURCE}
+ ${CMAKE_CURRENT_BINARY_DIR}/${CODEC}
+ main_test.cpp
+ )
+ TARGET_LINK_LIBRARIES(${THIS_TC_NAME} asn1)
+ TARGET_LINK_LIBRARIES(${THIS_TC_NAME} ${CPPUNIT_LIBRARY} )
+ IF(NOT ${DL_LIB} STREQUAL DL_LIB-NOTFOUND)
+ MESSAGE("DL LIB contains: ${DL_LIB} and var ")
+ TARGET_LINK_LIBRARIES(${THIS_TC_NAME} ${DL_LIB} )
+ ENDIF(NOT ${DL_LIB} STREQUAL DL_LIB-NOTFOUND)
+ENDMACRO(TESTCASE)
+
+# Also add codec codec now
+FOREACH(ITEM ${TESTMODULES})
+ STRING(REGEX REPLACE "-" "_" HITEM ${ITEM})
+ SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/${HITEM}.h GENERATED)
+ SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/${HITEM}_codec.cpp GENERATED)
+ SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/${ITEM}.cpp GENERATED)
+ SET(TESTSRC ${TESTSRC} ${CMAKE_CURRENT_BINARY_DIR}/${ITEM}.cpp)
+ SET(TESTSRC ${TESTSRC} ${CMAKE_CURRENT_BINARY_DIR}/${HITEM}_codec.cpp)
+ # SET(UNITTESTSRC ${UNITTESTSRC} ${CMAKE_CURRENT_SOURCE_DIR}/UNIT-${ITEM}.cpp)
+ SET(TESTHDR ${TESTHDR} ${HITEM}.h)
+ENDFOREACH(ITEM)
+
+#
+# Start OPTIONAL has SHARED POINTER
+#
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/TEST-basic-types-optional.cpp COMPILE_FLAGS "-DASN1_ATTRIBUTE_OPTIONAL_AS_SHARED_POINTER")
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_SOURCE_DIR}/UNIT-TEST-basic-types-optional.cpp COMPILE_FLAGS "-DASN1_ATTRIBUTE_OPTIONAL_AS_SHARED_POINTER")
+
+FILE(GLOB UNITESTSRC ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
+MESSAGE("GLOBAL FILES: ${UNITESTSRC}")
+SET_DIRECTORY_PROPERTIES(PROPERTIES
+ ADDITIONAL_MAKE_CLEAN_FILES "${TESTSRC} ${TESTHDR}"
+ )
+
+
+# ${CMAKE_CURRENT_SOURCE_DIR}/../../../data-models/asn1/Remote-Operations-Information-Objects.asn1
+#
+#
+#
+#
+ADD_CUSTOM_COMMAND(
+ OUTPUT ${TESTSRC}
+ COMMAND cat
+ ${CMAKE_CURRENT_SOURCE_DIR}/source.asn1
+ ARGS | ${CMAKE_CURRENT_BINARY_DIR}/../asn1p -c ON -e ber -C true
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/../asn1p
+ COMMENT "Build test .h and .cpp"
+ )
+
+LIST(REMOVE_ITEM UNITESTSRC ${CMAKE_CURRENT_SOURCE_DIR}/main_asn1_type_sizes.cpp)
+
+ADD_EXECUTABLE(tests
+ # UNIT-TEST-ber-primary-types.cpp
+ ${TESTSRC}
+ ${UNITESTSRC}
+ # main_test.cpp
+ )
+# Size checks
+ADD_EXECUTABLE(asn1p_type_sizes
+ main_asn1_type_sizes.cpp
+)
+
+TARGET_LINK_LIBRARIES(asn1p_type_sizes asn1)
+
+TESTCASE(NAME test-choice SOURCE TEST-basic-types-choice.cpp)
+TESTCASE(NAME test-implicit SOURCE TEST-basic-types-implicit.cpp)
+TESTCASE(NAME test-bt SOURCE TEST-basic-types.cpp)
+TESTCASE(NAME test-explicit SOURCE TEST-basic-types-explicit.cpp)
+TESTCASE(NAME test-tagged SOURCE TEST-basic-types-tagged.cpp)
+TESTCASE(NAME test-private-choice SOURCE TEST-private-types-choice.cpp)
+#ADD_EXECUTABLE(tests-choice
+# UNIT-TEST-basic-types-choice.cpp
+# ${CMAKE_CURRENT_BINARY_DIR}/TEST-basic-types-choice.cpp
+# main_test.cpp
+# )
+
+TARGET_LINK_LIBRARIES(tests asn1)
+ADD_DEPENDENCIES(tests ${TESTSRC})
+
+TARGET_LINK_LIBRARIES(tests ${CPPUNIT_LIBRARY} )
+IF(NOT ${DL_LIB} STREQUAL DL_LIB-NOTFOUND)
+MESSAGE("DL LIB contains: ${DL_LIB} and var ")
+TARGET_LINK_LIBRARIES(tests ${DL_LIB} )
+ENDIF(NOT ${DL_LIB} STREQUAL DL_LIB-NOTFOUND)
+
+
+ENDIF(NOT WIN32)
--- /dev/null
+#include <cppunit/config/SourcePrefix.h>
+
+#include <fstream>
+#include <string.h>
+
+#include "rtasn1/asn1.h"
+#include "rtasn1/asn1_codec.h"
+#include "rtasn1/asn1_codec_ber.h"
+#include "UNIT-TEST-basic-types-choice.h"
+#include "TEST_basic_types_choice.h"
+
+using namespace asn1;
+using namespace TEST_basic_types_choice;
+
+CPPUNIT_TEST_SUITE_REGISTRATION( TC_TEST_basic_types_choice);
+
+
+void TC_TEST_basic_types_choice::setUp()
+{
+
+}
+
+void TC_TEST_basic_types_choice::encode_TEST_Choice_device()
+{
+ TEST_Choice c( TEST_Choice::typeof_device );
+ c.get_device() = 3;
+ c.encode(m_ctx);
+
+ const unsigned char seq[] = {0x02,0x01,0x03};
+ int result = memcmp(m_ctx.buffer(),seq,3);
+ m_ctx.reset();
+ CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_basic_types_choice::encode_TEST_Choice_name()
+{
+ TEST_Choice c( TEST_Choice::typeof_name ,asn1::tag(asn1::types::UNIVERSAL,22));
+ c.get_name() = "Jones";
+ c.encode(m_ctx);
+
+ const unsigned char seq[] = {0x16,0x05,0x4a,0x6f,0x6e,0x65,0x73};
+ CppUnit::Message message(std::string("Failed encode name Jones"));
+ int result = memcmp(m_ctx.buffer(),seq,7);
+ m_ctx.reset();
+ CPPUNIT_ASSERT(result==0);
+}
+
+
+void TC_TEST_basic_types_choice::encode_TEST_Choice_b1()
+{
+ asn1::streams::ber ctx;
+ TEST_Choice c( TEST_Choice::typeof_b1 ,asn1::tag(asn1::types::UNIVERSAL,1));
+ c.get_b1() = false;
+ //c.codec(ctx,c,asn1::CODEC_ENCODE);
+ c.encode(ctx);
+
+ const unsigned char seq[] = {0x01,0x01,0x00};
+ int result = memcmp(ctx.buffer(),seq,3);
+ CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_basic_types_choice::encode_TEST_Choice_ip4()
+{
+ asn1::streams::ber ctx;
+ TEST_Choice c( TEST_Choice::typeof_ip4 ,asn1::tag(asn1::types::UNIVERSAL,16));
+
+ c.get_ip4().address = asn1::prim::types::String("\x0A\x03\x10\x21");
+ c.get_ip4().portNumber.get() = INTEGER(asn1::prim::types::Integer(2));
+ //c.codec(ctx,c,asn1::CODEC_ENCODE);
+ c.encode(ctx);
+ //10 09 04 04 0a 03 10 21 02 01 02
+ //30 08 04 0a 03 10 21 02 01 02
+ const unsigned char seq[] = {0x30,0x09,0x04,0x04,0x0A,0x03,0X10,0x21,0x02,0x1,0x02};
+ int result = memcmp(ctx.buffer(),seq,11);
+ CPPUNIT_ASSERT(result==0);
+}
+
+
+void TC_TEST_basic_types_choice::encode_TEST_Choice1_deviceId()
+{
+ asn1::streams::ber ctx;
+ TEST_Choice1 c( TEST_Choice1::typeof_device ,asn1::tag(asn1::types::CONTEXT_SPECIFIC,0));
+ c.get_device() = 9;
+ //c.codec(ctx,c,asn1::CODEC_ENCODE);
+ c.encode(ctx);
+ const unsigned char seq[] = {0x80,0x01,0x09};
+ int result = memcmp(ctx.buffer(),seq,3);
+ CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_basic_types_choice::encode_TEST_Choice1_i2()
+{
+ asn1::streams::ber ctx;
+ TEST_Choice1 c( TEST_Choice1::typeof_i2,asn1::tag(asn1::types::CONTEXT_SPECIFIC,1) );
+ c.get_i2() = 16;
+ //c.codec(ctx,c,asn1::CODEC_ENCODE);
+ c.encode(ctx);
+ const unsigned char seq[] = {0x81,0x01,0x10};
+ int result = memcmp(ctx.buffer(),seq,3);
+ CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_basic_types_choice::encode_TEST_Choice1_b1()
+{
+ asn1::streams::ber ctx;
+ TEST_Choice1 c( TEST_Choice1::typeof_b1 , asn1::tag(asn1::types::CONTEXT_SPECIFIC,2));
+ c.get_b1() = true;
+ //c.codec(ctx,c,asn1::CODEC_ENCODE);
+ c.encode(ctx);
+ const unsigned char seq[] = {0x82,0x01,0xFF};
+ int result = memcmp(ctx.buffer(),seq,3);
+ CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_basic_types_choice::encode_TEST_Choice1_bs1()
+{
+ asn1::streams::ber ctx;
+ TEST_Choice1 c( TEST_Choice1::typeof_bs1,asn1::tag(asn1::types::CONTEXT_SPECIFIC,3) );
+ c.get_bs1()[0] = 0x02;
+ c.get_bs1().set_nb_bits(2);
+ //c.codec(ctx,c,asn1::CODEC_ENCODE);
+ c.encode(ctx);
+ const unsigned char seq[] = {0x83,0x02,0x06,0x80};
+ const unsigned char seq1[] = {0x83,0x07,0x04,0x0a,0x3B,0x5F,0x29,0x1c,0xd0};
+ int result = memcmp(ctx.buffer(),seq,4);
+ ctx.reset();
+ CPPUNIT_ASSERT(result==0);
+ c.get_bs1()[0] = 0xcd;
+ c.get_bs1()[1] = 0x91;
+ c.get_bs1()[2] = 0xf2;
+ c.get_bs1()[3] = 0xB5;
+ c.get_bs1()[4] = 0xA3;
+ c.get_bs1()[5] = 0x0;
+ c.get_bs1().set_nb_bits(44);
+ //c.codec(ctx,c,asn1::CODEC_ENCODE);
+ c.encode(ctx);
+ result = memcmp(ctx.buffer(),seq1,9);
+ CPPUNIT_ASSERT(result==0);
+
+}
+
+void TC_TEST_basic_types_choice::encode_TEST_Choice1_os1()
+{
+ asn1::streams::ber ctx;
+ TEST_Choice1 c( TEST_Choice1::typeof_os1, asn1::tag(asn1::types::CONTEXT_SPECIFIC,4) );
+
+ c.get_os1() = asn1::prim::types::String("1");
+ //c.codec(ctx,c,asn1::CODEC_ENCODE);
+ c.encode(ctx);
+ const unsigned char seq[] = {0x84,0x01,0x31};
+ int result = memcmp(ctx.buffer(),seq,3);
+ CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_basic_types_choice::encode_TEST_Choice1_nul()
+{
+ asn1::streams::ber ctx;
+ TEST_Choice1 c( TEST_Choice1::typeof_nul , asn1::tag(asn1::types::CONTEXT_SPECIFIC,5));
+ CPPUNIT_ASSERT(c.check_create());
+ //c.codec(ctx,c,asn1::CODEC_ENCODE);
+ c.encode(ctx);
+ const unsigned char seq[] = {0x85,0x00,0x0};
+ int result = memcmp(ctx.buffer(),seq,2);
+ CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_basic_types_choice::encode_TEST_ChoiceChoiceA()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x40,0x01,0x0b};
+ //ChoiceChoice c(ChoiceChoice::typeof_choicea, asn1::tag(asn1::types::APPLICATION,0) );
+ ChoiceChoice c(ChoiceChoice::typeof_choicea );
+ //ChoiceChoice c(asn1::tag(asn1::types::CONTEXT_SPECIFIC,0));
+ c.get_choicea().get_i() = 11;
+ c.encode(ctx);
+ int result = memcmp(ctx.buffer(),seq,3);
+ CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_basic_types_choice::encode_TEST_ChoiceChoiceB()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x81,0x01,0x0a};
+ ChoiceChoice c(asn1::tag(asn1::types::CONTEXT_SPECIFIC,1));
+ c.get_choiceb().get_ib() = 10;
+ //c.codec(ctx,c,asn1::CODEC_ENCODE);
+ c.encode(ctx);
+ int result = memcmp(ctx.buffer(),seq,3);
+ CPPUNIT_ASSERT(result==0);
+}
+//decode
+
+void TC_TEST_basic_types_choice::decode_TEST_Choice_device()
+{
+ asn1::streams::ber ctx;
+ TEST_Choice c;
+ const unsigned char seq[] = {0x02,0x01,0x07};
+ //c.get_device() = 3;
+ memcpy(ctx.buffer(),seq,3);
+ //c.codec(ctx,c,asn1::CODEC_DECODE);
+ c.decode(ctx);
+
+ CPPUNIT_ASSERT(c.get_kind() == TEST_Choice::typeof_device);
+ CPPUNIT_ASSERT(c.get_device()== 7);
+}
+void TC_TEST_basic_types_choice::decode_TEST_Choice_name()
+{
+ asn1::streams::ber ctx;
+ TEST_Choice c;
+ const unsigned char seq[] = {0x16,0x05,0x4a,0x6f,0x6e,0x65,0x73};
+
+// asn1::prim::types::String s("Jones");
+
+ memcpy(ctx.buffer(),seq,7);
+ //c.codec(ctx,c,asn1::CODEC_DECODE);
+ c.decode(ctx);
+
+ CPPUNIT_ASSERT(c.get_kind() == TEST_Choice::typeof_name);
+ //CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_basic_types_choice::decode_TEST_Choice1_deviceId()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x80,0x01,0x0D};
+ TEST_Choice1 c;
+
+ memcpy(ctx.buffer(),seq,3);
+ //c.codec(ctx,c,asn1::CODEC_DECODE);
+ c.decode(ctx);
+ CPPUNIT_ASSERT(c.get_device()==13);
+ CPPUNIT_ASSERT(5==5);
+}
+
+void TC_TEST_basic_types_choice::decode_TEST_Choice1_i2()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x81,0x01,0x0D};
+ //TEST_Choice1 c( TEST_Choice1::typeof_i2 );
+ TEST_Choice1 c( TEST_Choice1::typeof_i2,asn1::tag(asn1::types::CONTEXT_SPECIFIC,1) );
+ c.get_i2() = 14;
+ memcpy(ctx.buffer(),seq,3);
+ //c.codec(ctx,c,asn1::CODEC_DECODE);
+ c.decode(ctx);
+ CPPUNIT_ASSERT(c.get_i2()==13);
+}
+
+void TC_TEST_basic_types_choice::decode_TEST_Choice1_b1()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x82,0x01,0xFF};
+ TEST_Choice1 c( TEST_Choice1::typeof_i2,asn1::tag(asn1::types::CONTEXT_SPECIFIC,1) );
+ c.get_i2() = 14;
+ memcpy(ctx.buffer(),seq,3);
+ //c.codec(ctx,c,asn1::CODEC_DECODE);
+ c.decode(ctx);
+ CPPUNIT_ASSERT(c.get_kind() == TEST_Choice1::typeof_b1);
+ CPPUNIT_ASSERT(c.get_b1() == true);
+}
+
+void TC_TEST_basic_types_choice::decode_TEST_Choice1_bs1()
+{
+ asn1::streams::ber ctx;
+ //const unsigned char seq[] = {0x83,0x02,0x00,0x0D};
+ const unsigned char seq[] = {0x83,0x07,0x04,0x0a,0x3B,0x5F,0x29,0x1c,0xd0};
+ TEST_Choice1 c( TEST_Choice1::typeof_i2 );
+ memcpy(ctx.buffer(),seq,9);
+ //c.codec(ctx,c,asn1::CODEC_DECODE);
+ c.decode(ctx);
+ CPPUNIT_ASSERT(c.get_kind() == TEST_Choice1::typeof_bs1);
+ CPPUNIT_ASSERT(c.get_bs1()[0] == 0xcd);
+ CPPUNIT_ASSERT(c.get_bs1()[1] == 0x91);
+ CPPUNIT_ASSERT(c.get_bs1()[2] == 0xf2);
+ CPPUNIT_ASSERT(c.get_bs1()[3] == 0xb5);
+}
+
+void TC_TEST_basic_types_choice::decode_TEST_Choice1_os1()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x84,0x01,0x32};
+ TEST_Choice1 c( TEST_Choice1::typeof_i2,asn1::tag(asn1::types::CONTEXT_SPECIFIC,1) );
+ c.get_i2() = 14;
+ memcpy(ctx.buffer(),seq,3);
+ //c.codec(ctx,c,asn1::CODEC_DECODE);
+ c.decode(ctx);
+ CPPUNIT_ASSERT(c.get_kind() == TEST_Choice1::typeof_os1);
+ CPPUNIT_ASSERT(std::string("2").compare(c.get_os1().get_sys_value() ) == 0);
+}
+
+void TC_TEST_basic_types_choice::decode_TEST_Choice1_nul()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x85,0x00,0x00};
+ TEST_Choice1 c( TEST_Choice1::typeof_i2 );
+ memcpy(ctx.buffer(),seq,2);
+ //c.codec(ctx,c,asn1::CODEC_DECODE);
+ c.decode(ctx);
+ CPPUNIT_ASSERT(c.get_kind() == TEST_Choice1::typeof_nul);
+}
+
+void TC_TEST_basic_types_choice::decode_TEST_ChoiceChoiceA()
+{
+ asn1::streams::ber ctx;
+ //const unsigned char seq[] = {0x40,0x01,0x0b};
+ const unsigned char seq[] = {0x80,0x03,0x40,0x01,0x0b};
+ ChoiceChoice c( 0, asn1::tag(asn1::types::APPLICATION,0) );
+ memcpy(ctx.buffer(),seq,5);
+ c.decode(ctx);
+ CPPUNIT_ASSERT(c.get_choicea().get_i()== 11);
+}
+
+void TC_TEST_basic_types_choice::decode_TEST_ChoiceChoiceB()
+{
+ asn1::streams::ber ctx;
+ //const unsigned char seq[] = {0x81,0x01,0x0a};
+ const unsigned char seq[] = {0x81,0x03,0x81,0x01,0x0a};
+ ChoiceChoice c(asn1::tag(asn1::types::CONTEXT_SPECIFIC,1));
+ c.get_choiceb().get_ib() = 0;
+ memcpy(ctx.buffer(),seq,5);
+ //c.codec(ctx,c,asn1::CODEC_DECODE);
+ c.decode(ctx);
+ CPPUNIT_ASSERT(c.get_choiceb().get_ib() == 10);
+}
+
--- /dev/null
+#ifndef TESTCASE_SIMPLETYPE_H
+#define TESTCASE_SIMPLETYPE_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include "TEST_basic_types.h"
+
+
+class TC_TEST_basic_types_choice : public CPPUNIT_NS::TestFixture
+{
+ CPPUNIT_TEST_SUITE( TC_TEST_basic_types_choice );
+ CPPUNIT_TEST(encode_TEST_Choice_device);
+ CPPUNIT_TEST(encode_TEST_Choice_name);
+ CPPUNIT_TEST(encode_TEST_Choice_b1);
+ CPPUNIT_TEST(encode_TEST_Choice_ip4);
+ CPPUNIT_TEST(encode_TEST_Choice1_deviceId);
+ CPPUNIT_TEST(encode_TEST_Choice1_i2);
+ CPPUNIT_TEST(encode_TEST_Choice1_b1);
+ CPPUNIT_TEST(encode_TEST_Choice1_bs1);
+ CPPUNIT_TEST(encode_TEST_Choice1_os1);
+ CPPUNIT_TEST(encode_TEST_Choice1_nul);
+ CPPUNIT_TEST(encode_TEST_ChoiceChoiceA);
+ CPPUNIT_TEST(encode_TEST_ChoiceChoiceB);
+ CPPUNIT_TEST(decode_TEST_Choice_device);
+ CPPUNIT_TEST(decode_TEST_Choice_name);
+ CPPUNIT_TEST(decode_TEST_Choice1_deviceId);
+ CPPUNIT_TEST(decode_TEST_Choice1_i2);
+ CPPUNIT_TEST(decode_TEST_Choice1_b1);
+ CPPUNIT_TEST(decode_TEST_Choice1_bs1);
+ CPPUNIT_TEST(decode_TEST_Choice1_os1);
+ CPPUNIT_TEST(decode_TEST_Choice1_nul);
+ CPPUNIT_TEST(decode_TEST_ChoiceChoiceA);
+ CPPUNIT_TEST(decode_TEST_ChoiceChoiceB);
+
+
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ void setUp();
+ protected:
+
+ void encode_TEST_Choice_device();
+ void encode_TEST_Choice_name();
+ void encode_TEST_Choice_b1();
+ void encode_TEST_Choice_ip4();
+ void encode_TEST_Choice1_deviceId();
+ void encode_TEST_Choice1_i2();
+ void encode_TEST_Choice1_b1();
+ void encode_TEST_Choice1_bs1();
+ void encode_TEST_Choice1_os1();
+ void encode_TEST_Choice1_nul();
+ void encode_TEST_ChoiceChoiceA();
+ void encode_TEST_ChoiceChoiceB();
+ //
+ //
+ void decode_TEST_Choice_device();
+ void decode_TEST_Choice_name();
+ void decode_TEST_Choice1_deviceId();
+ void decode_TEST_Choice1_i2();
+ void decode_TEST_Choice1_b1();
+ void decode_TEST_Choice1_bs1();
+ void decode_TEST_Choice1_os1();
+ void decode_TEST_Choice1_nul();
+ void decode_TEST_ChoiceChoiceA();
+ void decode_TEST_ChoiceChoiceB();
+ protected:
+ asn1::streams::ber m_ctx;
+ asn1::codecBER m_codec;
+};
+
+#endif
--- /dev/null
+
+
+#include <cppunit/config/SourcePrefix.h>
+
+#include <fstream>
+#include <string.h>
+
+#include "rtasn1/asn1.h"
+#include "rtasn1/asn1_codec.h"
+#include "rtasn1/asn1_codec_ber.h"
+#include "TEST_basic_types_enum.h"
+#include "UNIT-TEST-basic-types-enum.h"
+
+CPPUNIT_TEST_SUITE_REGISTRATION( TC_TEST_basic_types_enum);
+
+using namespace TEST_basic_types_enum;
+
+void TC_TEST_basic_types_enum::setUp()
+{
+
+}
+
+void TC_TEST_basic_types_enum::encode_TEST_Enum()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x0a,0x01,0x02};
+ //S.m_value = TEST_Enum::two;
+ asn1::prim::types::Integer I(TEST_Enum::two);
+ TEST_Enum S;
+ //S = I;
+ S = TEST_Enum::two;
+ //S.codec(ctx,S,asn1::CODEC_ENCODE);
+ S.encode(ctx);
+ int result = memcmp(ctx.buffer(),seq,3);
+ CPPUNIT_ASSERT(result == 0);
+}
+void TC_TEST_basic_types_enum::encode_TEST_SeqEnum()
+{
+ const unsigned char seq[] = {0x31,0x05,0x02,0x01,0x06,0x05,0x00};
+ asn1::streams::ber ctx;
+ TEST_SeqEnum S;
+ S.enum1 = TEST_Enum::one ;
+ //S.codec(ctx,S,asn1::CODEC_ENCODE);
+ S.encode(ctx);
+ int result = memcmp(ctx.buffer(),seq,7);
+// CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_basic_types_enum::decode_TEST_Enum()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x0a,0x01,0x01};
+ TEST_Enum S;
+ memcpy(ctx.buffer(),seq,3);
+ //S.codec(ctx,S,asn1::CODEC_DECODE);
+ S.decode(ctx);
+ CPPUNIT_ASSERT( S == TEST_Enum::one);
+}
+
+void TC_TEST_basic_types_enum::decode_TEST_SeqEnum()
+{
+ asn1::streams::ber ctx;
+ asn1::INTEGER i(asn1::prim::types::Integer(10)),i2(asn1::prim::types::Integer(12));
+}
+
--- /dev/null
+#ifndef TESTCASE_SIMPLETYPE_H
+#define TESTCASE_SIMPLETYPE_H
+
+#include <cppunit/extensions/HelperMacros.h>
+
+#include "rtasn1/asn1.h"
+#include "rtasn1/asn1_codec.h"
+#include "rtasn1/asn1_codec_ber.h"
+#include "UNIT-TEST-basic-types-enum.h"
+
+class TC_TEST_basic_types_enum : public CPPUNIT_NS::TestFixture
+{
+ CPPUNIT_TEST_SUITE( TC_TEST_basic_types_enum );
+ CPPUNIT_TEST(encode_TEST_Enum);
+ CPPUNIT_TEST(encode_TEST_SeqEnum);
+ CPPUNIT_TEST(decode_TEST_Enum);
+ CPPUNIT_TEST(decode_TEST_SeqEnum);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ void setUp();
+ protected:
+
+ void encode_TEST_Enum();
+ void encode_TEST_SeqEnum();
+ void decode_TEST_Enum();
+ void decode_TEST_SeqEnum();
+ protected:
+ asn1::streams::ber m_ctx;
+ asn1::codecBER m_codec;
+};
+
+#endif
--- /dev/null
+#include <cppunit/config/SourcePrefix.h>
+
+#include <fstream>
+#include <string.h>
+
+#include "rtasn1/asn1.h"
+#include "rtasn1/asn1_codec.h"
+#include "rtasn1/asn1_codec_ber.h"
+#include "UNIT-TEST-basic-types-explicit.h"
+#include "TEST_basic_types_explicit.h"
+#include "TEST_basic_types_explicit_codec.hpp"
+
+using namespace asn1;
+using namespace TEST_basic_types_explicit;
+
+CPPUNIT_TEST_SUITE_REGISTRATION( TC_TEST_basic_types_explicit);
+
+
+void TC_TEST_basic_types_explicit::setUp()
+{
+
+}
+
+void TC_TEST_basic_types_explicit::encode_Test()
+{
+ asn1::streams::ber ctx;
+ Test i;
+ i.get_value() = 5;
+
+ //i.codec(ctx,i,asn1::CODEC_ENCODE);
+ i.encode(ctx);
+ const unsigned char seq[] = {0x60,0x03,0x02,0x01,0x05};
+ int result = memcmp(ctx.buffer(),seq,5);
+ CPPUNIT_ASSERT(result==0);
+}
+
+
+void TC_TEST_basic_types_explicit::encode_O_String()
+{
+ const unsigned char seq[] = {0x61,0x06,0x04,0x04,0x64,0x65,0x64,0x65};
+ asn1::streams::ber ctx;
+ std::string dede("dede");
+ O_String q;
+ q.get_value() = dede;
+ q.encode(ctx);
+ int result = memcmp(ctx.buffer(),seq,8);
+ CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_basic_types_explicit::encode_B_String()
+{
+ const unsigned char seq[] = { 0x62,0x04,0x03,0x02,0x00,0x55 };
+ asn1::streams::ber ctx;
+ B_String q;
+ q[0]=0x55;
+ q.set_nb_bits(8);
+ //m_codec.encode(ctx,q);
+ q.encode(ctx);
+ int result = memcmp(ctx.buffer(),seq,6);
+ CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_basic_types_explicit::encode_Bool_String()
+{
+ const unsigned char seq[] = { 0x63,0x03,0x01,0x01,0xFF };
+ asn1::streams::ber ctx;
+ Bool_String q;
+ q .get_value() = true;
+ q.encode(ctx);
+ int result = memcmp(ctx.buffer(),seq,5);
+ CPPUNIT_ASSERT(result==0);
+}
+
+/**
+ *
+ */
+void TC_TEST_basic_types_explicit::decode_Test()
+{
+ asn1::streams::ber ctx;
+ Test q;
+ const unsigned char seq[] = {0x60,0x03,0x02,0x01,0x09};
+
+ memcpy(ctx.buffer(),seq,5);
+ int r = q.decode(ctx);
+
+ CPPUNIT_ASSERT(r == asn1::ok);
+ CPPUNIT_ASSERT(q.get_value() == 9);
+}
+
+void TC_TEST_basic_types_explicit::decode_O_String()
+{
+ asn1::streams::ber ctx;
+ O_String q;
+ const unsigned char seq[] = {0x61,0x06,0x04,0x04,0x64,0x65,0x64,0x65};
+
+ memcpy(ctx.buffer(),seq,8);
+ int r = q.decode(ctx);
+
+ CPPUNIT_ASSERT(r == asn1::ok);
+}
+
+void TC_TEST_basic_types_explicit::decode_B_String()
+{
+ asn1::streams::ber ctx;
+ B_String q;
+ //const unsigned char seq[] = { 0x62,0x07,0x30,0x05,0x0a,0x01,0x01,0x16,0x00 };
+ const unsigned char seq[] = { 0x62,0x04,0x03,0x02,0x00,0x51 };
+
+ memcpy(ctx.buffer(),seq,6);
+ int r = q.decode(ctx);
+
+ CPPUNIT_ASSERT(r == asn1::ok);
+ CPPUNIT_ASSERT(q[0] == 0x51);
+}
+
+void TC_TEST_basic_types_explicit::decode_Bool_String()
+{
+ asn1::streams::ber ctx;
+ Bool_String q;
+ const unsigned char seq[] = { 0x63,0x03,0x01,0x01,0x00 };
+
+ memcpy(ctx.buffer(),seq,5);
+ int r = q.decode(ctx);
+
+ CPPUNIT_ASSERT(r == asn1::ok);
+}
--- /dev/null
+#ifndef TESTCASE_IMPLICITTYPE_H
+#define TESTCASE_IMPLICITTYPE_H
+
+#include <cppunit/extensions/HelperMacros.h>
+
+#include "rtasn1/asn1.h"
+#include "rtasn1/asn1_codec.h"
+#include "rtasn1/asn1_codec_ber.h"
+#include "TEST_basic_types_explicit.h"
+
+class TC_TEST_basic_types_explicit : public CPPUNIT_NS::TestFixture
+{
+ CPPUNIT_TEST_SUITE( TC_TEST_basic_types_explicit );
+ CPPUNIT_TEST(encode_Test);
+ CPPUNIT_TEST(encode_O_String);
+ CPPUNIT_TEST(encode_B_String);
+ CPPUNIT_TEST(encode_Bool_String);
+ // Decoding
+ CPPUNIT_TEST(decode_Test);
+ CPPUNIT_TEST(decode_O_String);
+ CPPUNIT_TEST(decode_B_String);
+ CPPUNIT_TEST(decode_Bool_String);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ void setUp();
+ protected:
+
+ void encode_Test();
+ void encode_O_String();
+ void encode_B_String();
+ void encode_Bool_String();
+
+ void decode_Test();
+ void decode_O_String();
+ void decode_B_String();
+ void decode_Bool_String();
+ protected:
+ asn1::streams::ber m_ctx;
+ asn1::codecBER m_codec;
+};
+
+#endif
--- /dev/null
+#include <cppunit/config/SourcePrefix.h>
+
+#include <fstream>
+#include <string.h>
+
+#include "rtasn1/asn1.h"
+#include "rtasn1/asn1_codec.h"
+#include "rtasn1/asn1_codec_ber.h"
+#include "UNIT-TEST-basic-types-implicit.h"
+#include "TEST_basic_types_implicit.h"
+
+using namespace asn1;
+using namespace TEST_basic_types_implicit;
+
+CPPUNIT_TEST_SUITE_REGISTRATION( TC_TEST_basic_types_implicit);
+
+
+void TC_TEST_basic_types_implicit::setUp()
+{
+
+}
+
+void TC_TEST_basic_types_implicit::encode_Ti()
+{
+ asn1::streams::ber ctx;
+ Ti i;
+ i.get_value() = 5;
+
+ //i.codec(ctx,i,asn1::CODEC_ENCODE);
+ i.encode(ctx);
+ const unsigned char seq[] = {0x88,0x01,0x05};
+ int result = memcmp(ctx.buffer(),seq,3);
+ CPPUNIT_ASSERT(result==0);
+}
+
+
+void TC_TEST_basic_types_implicit::encode_query_device()
+{
+ const unsigned char seq[] = { 0xa2,0x07,0x30,0x05,0x0a,0x01,0x01,0x16,0x00 };
+ asn1::streams::ber ctx;
+ ListForwardParameters_type lfp;
+ lfp.forwardingType = 1;
+ QueryDeviceResult q( QueryDeviceResult::typeof_deviceInformation,asn1::tag(2,0,true) );
+ q.get_deviceInformation().set_tag(asn1::tag(2,2));
+ q.get_deviceInformation().get_forward().push_back(lfp);;
+ //q.codec(ctx,q,asn1::CODEC_ENCODE);
+ q.encode(ctx);
+
+ int result = memcmp(ctx.buffer(),seq,9);
+ CPPUNIT_ASSERT(result==0);
+}
+
+/**
+ *
+ */
+void TC_TEST_basic_types_implicit::decode_Ti()
+{
+ asn1::streams::ber ctx;
+ Ti q;
+ const unsigned char seq[] = { 0x88,0x01,0x0a};
+
+ memcpy(ctx.buffer(),seq,3);
+ int r = q.decode(ctx);
+
+ CPPUNIT_ASSERT(r == asn1::ok);
+ CPPUNIT_ASSERT(q.get_value() == 10);
+}
+
+void TC_TEST_basic_types_implicit::decode_query_device()
+{
+ asn1::streams::ber ctx;
+ QueryDeviceResult q( QueryDeviceResult::typeof_deviceInformation );
+ const unsigned char seq[] = { 0xa1,0x07,0x30,0x05,0x0a,0x01,0x01,0x16,0x00 };
+
+ memcpy(ctx.buffer(),seq,9);
+ int r = q.decode(ctx);
+
+ CPPUNIT_ASSERT(r == asn1::ok);
+}
+
--- /dev/null
+#ifndef TESTCASE_IMPLICITTYPE_H
+#define TESTCASE_IMPLICITTYPE_H
+
+#include <cppunit/extensions/HelperMacros.h>
+
+#include "rtasn1/asn1.h"
+#include "rtasn1/asn1_codec.h"
+#include "rtasn1/asn1_codec_ber.h"
+#include "TEST_basic_types_implicit.h"
+
+class TC_TEST_basic_types_implicit : public CPPUNIT_NS::TestFixture
+{
+ CPPUNIT_TEST_SUITE( TC_TEST_basic_types_implicit );
+ CPPUNIT_TEST(encode_Ti);
+ CPPUNIT_TEST(encode_query_device);
+ // Decoding
+ CPPUNIT_TEST(decode_Ti);
+ CPPUNIT_TEST(decode_query_device);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ void setUp();
+ protected:
+
+ void encode_Ti();
+ void encode_query_device();
+
+ void decode_Ti();
+ void decode_query_device();
+ protected:
+ asn1::streams::ber m_ctx;
+ asn1::codecBER m_codec;
+};
+
+#endif
--- /dev/null
+#include <cppunit/config/SourcePrefix.h>
+#include <string.h>
+#include <fstream>
+#define MAIN
+#include "rtasn1/asn1.h"
+#include "rtasn1/asn1_codec.h"
+#include "rtasn1/asn1_codec_ber.h"
+#include "TEST_basic_types_optional.h"
+#include "UNIT-TEST-basic-types-optional.h"
+
+CPPUNIT_TEST_SUITE_REGISTRATION( TC_TEST_basic_types_optional);
+
+using namespace TEST_basic_types_optional;
+
+/**
+ *
+ */
+void TC_TEST_basic_types_optional::setUp()
+{
+
+}
+/**
+ requestID INTEGER,
+ extention Extention OPTIONAL
+ */
+void TC_TEST_basic_types_optional::encode_Request()
+{
+ asn1::INTEGER i(asn1::prim::types::Integer(4));
+ Request r;
+ r.requestID = i;
+
+ asn1::streams::ber ctx;
+ unsigned char *table = ctx.buffer();
+
+ r.encode(ctx);
+
+ //ctx.nb_bits(-1*ctx.nb_read_bits());
+
+ //r.codec(ctx,str,CODEC_ENCODE);
+
+ CPPUNIT_ASSERT( (ctx.nb_read_bits() / 8) == 5);
+}
+
+/**
+ *
+ */
+void TC_TEST_basic_types_optional::decode_Request()
+{
+ const unsigned char seq[] = {0x30,0x03,0x02,0x01,0x04};
+ Request r;
+ asn1::streams::ber ctx;
+
+ memcpy(ctx.buffer(),seq,5);
+
+ r.decode(ctx);
+
+ CPPUNIT_ASSERT(r.requestID==4);
+}
+
+/**
+ *
+ */
+void TC_TEST_basic_types_optional::encode_ReqDefaultInt()
+{
+ const unsigned char seq[] = {0x30,0x02,0x05,0x00};
+ ReqDefaultInt r;
+ //r.extID = i;
+
+ asn1::streams::ber ctx;
+ unsigned char *table = ctx.buffer();
+
+ r.encode(ctx);
+
+ CPPUNIT_ASSERT( (ctx.nb_read_bits() / 8) == 4);
+
+ CPPUNIT_ASSERT( memcmp(ctx.buffer(),seq,4) == 0);
+
+}
+
+/**
+ *
+ */
+void TC_TEST_basic_types_optional::encode_ReqDefaultIntOther()
+{
+ const unsigned char seq[] = {0x30,0x05,0x02,0x01,0x03,0x05,0x00};
+ ReqDefaultInt r;
+ // Why should an attribute with a default value be tagged as shared ptr ?
+ //r.extID = asn1::intrusive_ptr<INTEGER>(new INTEGER(3));
+ r.extID = 3;
+ r.bit_mask.set(ReqDefaultInt::extID_present);
+ asn1::streams::ber ctx;
+ unsigned char *table = ctx.buffer();
+
+ r.encode(ctx);
+
+ CPPUNIT_ASSERT( (ctx.nb_read_bits() / 8) == 7);
+
+ CPPUNIT_ASSERT( memcmp(ctx.buffer(),seq,7) == 0);
+
+}
+
+
+/**
+ *
+ */
+void TC_TEST_basic_types_optional::encode_ReqDefaultBool()
+{
+ ReqDefaultBool r;
+ //r.extID = i;
+
+ asn1::streams::ber ctx;
+ unsigned char *table = ctx.buffer();
+
+ r.encode(ctx);
+
+ CPPUNIT_ASSERT( (ctx.nb_read_bits() / 8) == 4);
+}
+
+/**
+ *
+ */
+void TC_TEST_basic_types_optional::encode_ReqDefaultBoolOther()
+{
+ const unsigned char seq[] = {0x30,0x05,0x01,0x01,0x00,0x05,0x00};
+ ReqDefaultBool r;
+ //r.extID = i;
+ //r.extID = asn1::intrusive_ptr<BOOLEAN>(new BOOLEAN(false));
+ r.extID = true;
+ r.bit_mask.set(ReqDefaultBool::extID_present);
+ asn1::streams::ber ctx;
+ unsigned char *table = ctx.buffer();
+
+ r.encode(ctx);
+
+ CPPUNIT_ASSERT( (ctx.nb_read_bits() / 8) == 7);
+}
+
+/**
+ *
+ */
+void TC_TEST_basic_types_optional::encode_ReqDefaultString()
+{
+ ReqDefaultString r;
+ //r.extID = i;
+
+ asn1::streams::ber ctx;
+ unsigned char *table = ctx.buffer();
+
+ r.encode(ctx);
+
+ CPPUNIT_ASSERT( (ctx.nb_read_bits() / 8) == 4);
+}
+
+/**
+ *
+ */
+void TC_TEST_basic_types_optional::encode_ReqDefaultStringOther()
+{
+ const unsigned char seq[] = {0x30,0x08,0x16,0x04,0x64,0x65,0x64,0x65,0x05,0x00};
+ ReqDefaultString r;
+ //r.extID = i;
+ asn1::prim::types::String ps = std::string("dede");
+ //r.extID = asn1::intrusive_ptr<IA5String>(new IA5String());
+ (r.extID) = ps;
+ r.bit_mask.set(ReqDefaultString::extID_present);
+ asn1::streams::ber ctx;
+ unsigned char *table = ctx.buffer();
+
+ r.encode(ctx);
+
+ CPPUNIT_ASSERT( (ctx.nb_read_bits() / 8) == 10);
+}
+
+
+/**
+ *
+ */
+void TC_TEST_basic_types_optional::encode_ReqOptInt()
+{
+ const unsigned char seq[] = {0x30,0x02,0x05,0x00};
+ const unsigned char seqopt[] = {0x30,0x03,0x02,0x01,0x04};
+ ReqOptInt r;
+ asn1::intrusive_ptr<INTEGER> i( new INTEGER(asn1::prim::types::Integer(3)));
+ asn1::streams::ber ctx;
+ unsigned char *table = ctx.buffer();
+
+ r.encode(ctx);
+
+ CPPUNIT_ASSERT( (ctx.nb_read_bits() / 8) == 4);
+ // Set the optional value
+ ctx.reset();
+
+ r.extID = i;
+ r.encode(ctx);
+
+ CPPUNIT_ASSERT( (ctx.nb_read_bits() / 8) == 7);
+}
+
+/**
+ *
+ */
+void TC_TEST_basic_types_optional::encode_ReqOptBool()
+{
+ ReqOptBool r;
+ asn1::streams::ber ctx;
+ unsigned char *table = ctx.buffer();
+
+ r.encode(ctx);
+
+ CPPUNIT_ASSERT( (ctx.nb_read_bits() / 8) == 4);
+}
+
+/**
+ *
+ */
+void TC_TEST_basic_types_optional::encode_ReqOptString()
+{
+ ReqOptString r;
+ asn1::streams::ber ctx;
+ unsigned char *table = ctx.buffer();
+
+ r.encode(ctx);
+
+ CPPUNIT_ASSERT( (ctx.nb_read_bits() / 8) == 4) ;
+}
+
+
+/**
+Extension ::= SEQUENCE {
+ extID INTEGER DEFAULT 2,
+ data OCTET STRING,
+ bits BitSTR DEFAULT {bit1} ,
+ boolean BOOLEAN DEFAULT TRUE,
+ toto BitSTR DEFAULT {}
+}
+*/
+
+
+/**
+ *
+ */
+void TC_TEST_basic_types_optional::encode_Extension()
+{
+ const unsigned char seq[] = {0x30,0x02,0x04,0x00};
+ Extension e;
+
+ asn1::streams::ber ctx;
+ unsigned char *table = ctx.buffer();
+
+ e.encode(ctx);
+ CPPUNIT_ASSERT((ctx.nb_read_bits()/8) == 4);
+}
+
+/**
+ *
+ */
+void TC_TEST_basic_types_optional::encode_ExtensionOther()
+{
+ // 30 08 02 01 04 04 00 01 01 00
+ Extension e;
+ e.extID = 4;
+ e.bit_mask.set(Extension::extID_present);
+ e.boolean = false;
+ e.bit_mask.set(Extension::boolean_present);
+ asn1::streams::ber ctx;
+ unsigned char *table = ctx.buffer();
+
+ e.encode(ctx);
+ CPPUNIT_ASSERT((ctx.nb_read_bits()/8) == 10);
+}
+
+
+/**
+ *
+ */
+void TC_TEST_basic_types_optional::decode_Extension()
+{
+ const unsigned char seq[] = { 0x30,0x08,0x02,0x01,0x04,0x04,0x00,0x01,0x01,0x00 };
+ Extension e;
+
+ asn1::streams::ber ctx;
+ unsigned char *table = ctx.buffer();
+
+ memcpy(ctx.buffer(),seq,10);
+ e.decode(ctx);
+ CPPUNIT_ASSERT(e.boolean == false);
+ CPPUNIT_ASSERT(e.extID == 4);
+}
+
+void TC_TEST_basic_types_optional::decode_ReqDefaultInt()
+{
+ const unsigned char seq[] = {0x30,0x02,0x05,0x00};
+ const unsigned char seqopt[] = {0x30,0x03,0x02,0x01,0x04,0x05,0x00};
+ ReqDefaultInt r;
+ asn1::streams::ber ctx;
+ unsigned char *table = ctx.buffer();
+
+ memcpy(ctx.buffer(),seq,4);
+ r.decode(ctx);
+
+ CPPUNIT_ASSERT( r.extID == 2);
+ // Set the optional value
+ ctx.reset();
+ memcpy(ctx.buffer(),seqopt,7);
+
+ r.decode(ctx);
+
+ CPPUNIT_ASSERT(r.extID == 4 );
+}
+/**
+ *
+ */
+void TC_TEST_basic_types_optional::decode_ReqDefaultBool()
+{
+ const unsigned char seq[] = {0x30,0x02,0x05,0x00};
+ const unsigned char seqopt[] = {0x30,0x03,0x01,0x01,0x04,0x05,0x00};
+ ReqDefaultBool r;
+ asn1::streams::ber ctx;
+ unsigned char *table = ctx.buffer();
+
+ memcpy(ctx.buffer(),seq,4);
+ r.decode(ctx);
+
+ //CPPUNIT_ASSERT( r.extID.is_nul() == true);
+ CPPUNIT_ASSERT( r.extID == false);
+ // Set the optional value
+ ctx.reset();
+ memcpy(ctx.buffer(),seqopt,7);
+
+ r.decode(ctx);
+
+ //CPPUNIT_ASSERT( r.extID.is_nul() == false);
+ CPPUNIT_ASSERT(r.extID == true );
+}
+
+/**
+ *
+ */
+void TC_TEST_basic_types_optional::decode_ReqDefaultString()
+{
+ const unsigned char seq[] = {0x30,0x02,0x05,0x00};
+ const unsigned char seqopt[] = {0x30,0x06,0x16,0x02,0x30,0x31,0x05,0x00};
+ ReqDefaultString r;
+ asn1::streams::ber ctx;
+ unsigned char *table = ctx.buffer();
+
+ memcpy(ctx.buffer(),seq,4);
+ r.decode(ctx);
+
+ CPPUNIT_ASSERT(std::string("james").compare(r.extID.get_sys_value()) == 0 );
+ // Set the optional value
+ ctx.reset();
+ memcpy(ctx.buffer(),seqopt,8);
+
+ r.decode(ctx);
+
+ CPPUNIT_ASSERT(std::string("01").compare(r.extID.get_sys_value()) == 0 );
+}
+
+/**
+ *
+ */
+void TC_TEST_basic_types_optional::decode_ReqOptInt()
+{
+ const unsigned char seq[] = {0x30,0x02,0x05,0x00};
+ const unsigned char seqopt[] = {0x30,0x03,0x02,0x01,0x04,0x05,0x00};
+ ReqOptInt r;
+ asn1::streams::ber ctx;
+ unsigned char *table = ctx.buffer();
+
+ memcpy(ctx.buffer(),seq,4);
+ r.decode(ctx);
+
+ CPPUNIT_ASSERT( r.extID.is_nul() == true);
+ // Set the optional value
+ ctx.reset();
+ memcpy(ctx.buffer(),seqopt,7);
+
+ r.decode(ctx);
+
+ CPPUNIT_ASSERT(**(r.extID) == 4 );
+}
+/**
+ *
+ */
+void TC_TEST_basic_types_optional::decode_ReqOptBool()
+{
+ const unsigned char seq[] = {0x30,0x02,0x05,0x00};
+ const unsigned char seqopt[] = {0x30,0x03,0x01,0x01,0x04,0x05,0x00};
+ ReqOptBool r;
+ asn1::streams::ber ctx;
+ unsigned char *table = ctx.buffer();
+
+ memcpy(ctx.buffer(),seq,4);
+ r.decode(ctx);
+
+ CPPUNIT_ASSERT( r.extID.is_nul() == true);
+ // Set the optional value
+ ctx.reset();
+ memcpy(ctx.buffer(),seqopt,7);
+
+ r.decode(ctx);
+
+ CPPUNIT_ASSERT( r.extID.is_nul() == false);
+ CPPUNIT_ASSERT(**(r.extID) == true );
+}
+
+/**
+ *
+ */
+void TC_TEST_basic_types_optional::decode_ReqOptString()
+{
+ const unsigned char seq[] = {0x30,0x02,0x05,0x00};
+ const unsigned char seqopt[] = {0x30,0x06,0x16,0x02,0x30,0x31,0x05,0x00};
+ ReqOptString r;
+ asn1::streams::ber ctx;
+ unsigned char *table = ctx.buffer();
+
+ memcpy(ctx.buffer(),seq,4);
+ r.decode(ctx);
+
+ CPPUNIT_ASSERT( r.extID.is_nul() == true);
+ // Set the optional value
+ ctx.reset();
+ memcpy(ctx.buffer(),seqopt,8);
+
+ r.decode(ctx);
+
+ CPPUNIT_ASSERT( r.extID.is_nul() == false);
+ CPPUNIT_ASSERT(std::string("01").compare(r.extID->get_sys_value()) == 0 );
+}
+
--- /dev/null
+#ifndef TESTCASE_BTYPE_OPT_H
+#define TESTCASE_BTYPE_OPT_H
+
+#include <cppunit/extensions/HelperMacros.h>
+
+
+class TC_TEST_basic_types_optional : public CPPUNIT_NS::TestFixture
+{
+ CPPUNIT_TEST_SUITE( TC_TEST_basic_types_optional );
+ CPPUNIT_TEST(encode_Request);
+ CPPUNIT_TEST(encode_ReqDefaultInt);
+ CPPUNIT_TEST(encode_ReqDefaultIntOther);
+ CPPUNIT_TEST(encode_ReqDefaultBool);
+ CPPUNIT_TEST(encode_ReqDefaultBoolOther);
+ CPPUNIT_TEST(encode_ReqDefaultString);
+ CPPUNIT_TEST(encode_ReqDefaultStringOther);
+ CPPUNIT_TEST(encode_Extension);
+ CPPUNIT_TEST(encode_ExtensionOther);
+ CPPUNIT_TEST(encode_ReqOptInt);
+ CPPUNIT_TEST(encode_ReqOptBool);
+ CPPUNIT_TEST(encode_ReqOptString);
+
+ CPPUNIT_TEST(decode_Request);
+ CPPUNIT_TEST(decode_Extension);
+ CPPUNIT_TEST(decode_ReqDefaultInt);
+ CPPUNIT_TEST(decode_ReqDefaultBool);
+ CPPUNIT_TEST(decode_ReqDefaultString);
+ CPPUNIT_TEST(decode_ReqOptInt);
+ CPPUNIT_TEST(decode_ReqOptBool);
+ CPPUNIT_TEST(decode_ReqOptString);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ void setUp();
+ protected:
+
+ void encode_Request();
+ void encode_ReqDefaultInt();
+ void encode_ReqDefaultIntOther();
+ void encode_ReqDefaultBool();
+ void encode_ReqDefaultBoolOther();
+ void encode_ReqDefaultString();
+ void encode_ReqDefaultStringOther();
+ void encode_Extension();
+ void encode_ExtensionOther();
+ void encode_ReqOptInt();
+ void encode_ReqOptBool();
+ void encode_ReqOptString();
+
+ void decode_Request();
+ void decode_Extension();
+ void decode_ReqDefaultInt();
+ void decode_ReqDefaultBool();
+ void decode_ReqDefaultString();
+ void decode_ReqOptInt();
+ void decode_ReqOptBool();
+ void decode_ReqOptString();
+ protected:
+ asn1::streams::ber m_ctx;
+ asn1::codecBER m_codec;
+};
+
+#endif
--- /dev/null
+#include <cppunit/config/SourcePrefix.h>
+
+#include <fstream>
+#include <string.h>
+
+#include "rtasn1/asn1.h"
+#include "rtasn1/asn1_codec.h"
+#include "rtasn1/asn1_codec_ber.h"
+#include "TEST_basic_types_sequence.h"
+#include "UNIT-TEST-basic-types-sequence.h"
+
+CPPUNIT_TEST_SUITE_REGISTRATION( TC_TEST_basic_types_sequence);
+
+using namespace TEST_basic_types_sequence;
+
+void TC_TEST_basic_types_sequence::setUp()
+{
+
+}
+
+void TC_TEST_basic_types_sequence::decode_Sequence()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x30,0x05,0x02,0x01,0x05,0x05,0x00};
+ unsigned char *table = ctx.buffer();
+ memcpy(table,seq,7);
+ TEST_Sequence S;
+ S.decode(ctx);
+ CPPUNIT_ASSERT(S.device==5);
+}
+void TC_TEST_basic_types_sequence::decode_ImplicitSequence()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x30,0x07,0x80,0x02,0x61,0x62,0x82,0x1,0x63};
+ unsigned char *table = ctx.buffer();
+ memcpy(table,seq,9);
+ TEST_Implicit_Sequence S;
+ S.decode(ctx);
+ CPPUNIT_ASSERT(std::string("ab").compare(S.s1.get_sys_value())==0);
+}
+void TC_TEST_basic_types_sequence::decode_IntegerList()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = { 0x30, 0x06, 0x02, 0x01, 0x0a, 0x02, 0x01, 0x0c};
+ unsigned char *table = ctx.buffer();
+ memcpy(table,seq,8);
+ Seq<asn1::INTEGER> S;
+ S.decode(ctx);
+ CPPUNIT_ASSERT(S[0]==10);
+}
+
+void TC_TEST_basic_types_sequence::encode_Sequence()
+{
+ const unsigned char seq[] = {0x30,0x05,0x02,0x01,0x06,0x05,0x00};
+ asn1::streams::ber ctx;
+ TEST_Sequence S;
+ S.device = 6;
+ S.encode(ctx);
+ int result = memcmp(ctx.buffer(),seq,7);
+ CPPUNIT_ASSERT(result==0);
+}
+void TC_TEST_basic_types_sequence::encode_ImplicitSequence()
+{
+ asn1::streams::ber ctx;
+ TEST_Implicit_Sequence S;
+ IA5String s(asn1::prim::types::String("ab"));
+ S.s1 = s;
+ //S.s2.get() = "c";
+ S.s3.get() = "d";
+ //S.encode(ctx);
+ m_codec.encode(ctx,S);
+ unsigned char seq[] = {0x30, 0x07, 0x80, 0x02, 0x61, 0x62, 0x82, 0x01,0x64 };
+ int result = memcmp(ctx.buffer(),seq,9);
+ CPPUNIT_ASSERT(result==0);
+}
+void TC_TEST_basic_types_sequence::encode_IntegerList()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = { 0x30, 0x06, 0x02, 0x01, 0x0a, 0x02, 0x01, 0x0c};
+ TEST_IntegerList S;
+ //Seq<asn1::INTEGER> S;
+ asn1::INTEGER i(10),i2(12);
+ S.push_back(i);
+ S.push_back(i2);
+ S.encode(ctx);
+ int result = memcmp(ctx.buffer(),seq,8);
+ CPPUNIT_ASSERT(result==0);
+}
--- /dev/null
+#ifndef TESTCASE_SIMPLETYPE_H
+#define TESTCASE_SIMPLETYPE_H
+
+#include <cppunit/extensions/HelperMacros.h>
+
+#include "rtasn1/asn1.h"
+#include "rtasn1/asn1_codec.h"
+#include "rtasn1/asn1_codec_ber.h"
+#include "UNIT-TEST-basic-types-sequence.h"
+
+class TC_TEST_basic_types_sequence : public CPPUNIT_NS::TestFixture
+{
+ CPPUNIT_TEST_SUITE( TC_TEST_basic_types_sequence );
+
+ CPPUNIT_TEST(encode_IntegerList);
+ CPPUNIT_TEST(encode_Sequence);
+ CPPUNIT_TEST(encode_ImplicitSequence);
+ CPPUNIT_TEST(decode_IntegerList);
+ CPPUNIT_TEST(decode_Sequence);
+ CPPUNIT_TEST(decode_ImplicitSequence);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ void setUp();
+ protected:
+
+ void decode_Sequence();
+ void decode_IntegerList();
+ void decode_ImplicitSequence();
+
+ void encode_IntegerList();
+ void encode_ImplicitSequence();
+ void encode_Sequence();
+ protected:
+ asn1::streams::ber m_ctx;
+ asn1::codecBER m_codec;
+};
+
+#endif
--- /dev/null
+
+
+#include <cppunit/config/SourcePrefix.h>
+
+#include <fstream>
+#include <string.h>
+
+#include "rtasn1/asn1.h"
+#include "rtasn1/asn1_codec.h"
+#include "rtasn1/asn1_codec_ber.h"
+#include "TEST_basic_types_set.h"
+#include "UNIT-TEST-basic-types-set.h"
+
+CPPUNIT_TEST_SUITE_REGISTRATION( TC_TEST_basic_types_set);
+
+using namespace TEST_basic_types_set;
+
+void TC_TEST_basic_types_set::setUp()
+{
+
+}
+
+void TC_TEST_basic_types_set::encode_Set()
+{
+ const unsigned char seq[] = {0x31,0x05,0x02,0x01,0x06,0x05,0x00};
+ asn1::streams::ber ctx;
+ TEST_Set S;
+ S.device = 6;
+ S.encode(ctx);
+ int result = memcmp(ctx.buffer(),seq,7);
+ CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_basic_types_set::encode_SetOfInt()
+{
+ const unsigned char seq[] = {0x31,0x06,0x02,0x01,0x05,0x02,0x01,0x04};
+ asn1::streams::ber ctx;
+ TEST_SetOfInt S;
+ Int i;
+ i = 5;
+ S.push_back(i);
+ i = 4;
+ S.push_back(i);
+ S.encode(ctx);
+ int result = memcmp(ctx.buffer(),seq,8);
+
+ CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_basic_types_set::encode_ImplicitSequence()
+{
+ asn1::streams::ber ctx;
+ // TEST_Implicit_Sequence S;
+ IA5String s(asn1::prim::types::String("ab"));
+}
+
+void TC_TEST_basic_types_set::encode_IntegerList()
+{
+ asn1::streams::ber ctx;
+ asn1::INTEGER i(10),i2(12);
+}
+
+/**
+ * Decode Stuff
+ */
+
+void TC_TEST_basic_types_set::decode_Set()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x31,0x05,0x02,0x01,0x05,0x05,0x00};
+ unsigned char *table = ctx.buffer();
+ memcpy(table,seq,7);
+ TEST_Set S;
+ S.decode(ctx);
+ CPPUNIT_ASSERT(S.device==5);
+}
+
+void TC_TEST_basic_types_set::decode_SetOfInt()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x31,0x06,0x02,0x01,0x03,0x02,0x01,0x08};
+ unsigned char *table = ctx.buffer();
+ memcpy(table,seq,8);
+ TEST_SetOfInt S;
+ S.decode(ctx);
+ CPPUNIT_ASSERT(S.size() == 2);
+}
+
+
--- /dev/null
+#ifndef TESTCASE_SIMPLETYPE_H
+#define TESTCASE_SIMPLETYPE_H
+
+#include <cppunit/extensions/HelperMacros.h>
+
+#include "rtasn1/asn1.h"
+#include "rtasn1/asn1_codec.h"
+#include "rtasn1/asn1_codec_ber.h"
+#include "UNIT-TEST-basic-types-set.h"
+
+class TC_TEST_basic_types_set : public CPPUNIT_NS::TestFixture
+{
+ CPPUNIT_TEST_SUITE( TC_TEST_basic_types_set );
+ CPPUNIT_TEST(encode_Set);
+ CPPUNIT_TEST(encode_SetOfInt);
+ CPPUNIT_TEST(encode_IntegerList);
+ CPPUNIT_TEST(encode_ImplicitSequence);
+
+ CPPUNIT_TEST(decode_Set);
+ CPPUNIT_TEST(decode_SetOfInt);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ void setUp();
+ protected:
+
+ void encode_Set();
+ void encode_IntegerList();
+ void encode_ImplicitSequence();
+ void encode_SetOfInt();
+
+ void decode_Set();
+ void decode_SetOfInt();
+ protected:
+ asn1::streams::ber m_ctx;
+ asn1::codecBER m_codec;
+};
+
+#endif
--- /dev/null
+
+
+#include <cppunit/config/SourcePrefix.h>
+
+#include <fstream>
+#include <string.h>
+
+#include "rtasn1/asn1.h"
+#include "rtasn1/asn1_codec.h"
+#include "rtasn1/asn1_codec_ber.h"
+#include "TEST_basic_types_tagged.h"
+#include "UNIT-TEST-basic-types-tagged.h"
+
+CPPUNIT_TEST_SUITE_REGISTRATION( TC_TEST_basic_types_tagged);
+
+using namespace TEST_basic_types_tagged;
+
+void TC_TEST_basic_types_tagged::setUp()
+{
+
+}
+
+void TC_TEST_basic_types_tagged::encode_TaggedInteger()
+{
+ asn1::streams::ber ctx;
+// const unsigned char seq[] = {0x43,0x03,0x02,0x01,0x03};
+ // Explicit tagging is constructed
+ const unsigned char seq[] = {0x63,0x03,0x02,0x01,0x03};
+ Int S;
+ asn1::prim::types::Integer i = 3;
+ S = i;
+ S.encode(ctx);
+ int result = memcmp(ctx.buffer(),seq,5);
+ CPPUNIT_ASSERT(result == 0);
+}
+
+void TC_TEST_basic_types_tagged::encode_TaggedSeq()
+{
+ const unsigned char seq[] = {0x62,0x07,0x30,0x05,0x02,0x01,0x06,0x05,0x00};
+ asn1::streams::ber ctx;
+ SeqE S;
+ asn1::prim::types::Integer i = 6;
+ S.one = i;
+ S.encode(ctx);
+ int result = memcmp(ctx.buffer(),seq,9);
+ CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_basic_types_tagged::encode_TaggedSeqE1()
+{
+ // Explicit tagging is construted
+ const unsigned char seq[] = {0x64,0x09,0x30,0x07,0x63,0x03,0x02,0x01,0x0A,0x05,0x00};
+ asn1::streams::ber ctx;
+ SeqE1 S;
+ asn1::prim::types::Integer i = 10;
+ S.one = i;
+ //S.codec(ctx,S,asn1::CODEC_ENCODE);
+ S.encode(ctx);
+ int result = memcmp(ctx.buffer(),seq,11);
+ CPPUNIT_ASSERT(result==0);
+}
+
+
+void TC_TEST_basic_types_tagged::encode_TaggedSeqI()
+{
+ const unsigned char seq[] = {0x65,0x05,0x55,0x01,0x06,0x56,0x00};
+ asn1::streams::ber ctx;
+ SeqI S;
+ asn1::prim::types::Integer i = 6;
+ S.one = i;
+ //S.codec(ctx,S,asn1::CODEC_ENCODE);
+ S.encode(ctx);
+ int result = memcmp(ctx.buffer(),seq,7);
+ CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_basic_types_tagged::encode_TaggedInSeq()
+{
+ //const unsigned char seq[] = {0x30,0x0a,0xa0,0x03,0x02,0x01,0x06,0x43,0x03,0x02,0x01,0x09};
+ // Explicit is constructed
+ // 30 06 a0 03 02 01 06 63 03 43 01 09
+ const unsigned char seq[] = {0x30,0x0a,0xa0,0x03,0x02,0x01,0x06,0x63,0x03,0x02,0x01,0x09};
+ asn1::streams::ber ctx;
+ InSeq S;
+ asn1::prim::types::Integer i = 6;
+ S.one = i;
+ Int nu; i= 9;
+ nu = i;
+ S.nu = nu;
+ //S.encode(ctx);
+ m_codec.encode(ctx,S);
+ int result = memcmp(ctx.buffer(),seq,12);
+ CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_basic_types_tagged::encode_TaggedChoice()
+{
+ //const unsigned char seq[] = {0xa2,0x09,0x30,0x07,0x83,0x03,0x02,0x01,0x06,0x05,0x00};
+ const unsigned char seq[] = {0x64,0x03,0x40,0x01,0x06};
+ asn1::streams::ber ctx;
+ Choice S(Choice::typeof_one);
+ asn1::prim::types::Integer i = 6;
+ S.get_one() = i;
+ //S.kind_ = Choice::typeof_one;
+ //S.codec(ctx,S,asn1::CODEC_ENCODE);
+ S.encode(ctx);
+ int result = memcmp(ctx.buffer(),seq,5);
+ CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_basic_types_tagged::encode_TaggedChoiceSeqE()
+{
+ //const unsigned char seq[] = {0x62,0x07,0x30,0x05,0x02,0x01,0x06,0x05,0x00};
+ //const unsigned char seq[] = {0xa2,0x09,0x30,0x07,0x83,0x03,0x02,0x01,0x06,0x05,0x00};
+ const unsigned char seq[] = {0x64,0x09,0x62,0x07,0x30,0x05,0X02,0x01,0x6,0x05,0x00};
+ asn1::streams::ber ctx;
+ Choice S(Choice::typeof_seqe,asn1::tag(asn1::types::APPLICATION,2));
+ S.get_seqe().one = 6;
+ //S.kind_ = Choice::typeof_one;
+ //S.codec(ctx,S,asn1::CODEC_ENCODE);
+ S.encode(ctx);
+ int result = memcmp(ctx.buffer(),seq,5);
+ CPPUNIT_ASSERT(result==0);
+}
+
+
+void TC_TEST_basic_types_tagged::encode_TaggedSetE()
+{
+ // 64 07 30 05 02 01 06 05 00
+ const unsigned char seq[] = {0x64,0x07,0x31,0x05,0x02,0x01,0x06,0x05,0x00};
+ asn1::streams::ber ctx;
+ TSetE S;
+ asn1::prim::types::Integer i = 6;
+ S.one = i;
+ S.encode(ctx);
+ int result = memcmp(ctx.buffer(),seq,9);
+ CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_basic_types_tagged::encode_IntILT62()
+{
+ const unsigned char seq[] = {0x5F,0x3E,0x01,0x05};
+ asn1::streams::ber ctx;
+ IntILT62 I;
+ I = 5;
+ I.encode(ctx);
+ int result = memcmp(ctx.buffer(),seq,4);
+ CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_basic_types_tagged::encode_IntILT432()
+{
+ const unsigned char seq[] = {0x5F,0x83,0x30,0x01,0x05};
+ asn1::streams::ber ctx;
+ IntILT432 I;
+ I = 5;
+ I.encode(ctx);
+ int result = memcmp(ctx.buffer(),seq,5);
+ CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_basic_types_tagged::encode_IntELT72()
+{
+ // 7f 48 03 02 01 05
+ const unsigned char seq[] = {0x5F,0x83,0x30,0x01,0x05};
+ asn1::streams::ber ctx;
+ IntELT72 I;
+ I = 5;
+ //I.encode(ctx);
+ m_codec.encode(ctx,I);
+ int result = memcmp(ctx.buffer(),seq,5);
+ CPPUNIT_ASSERT(result==0);
+}
+
+
+
+
+
+#if 0
+void TC_TEST_basic_types_tagged::decode_TEST_SeqEnum()
+{
+ asn1::streams::ber ctx;
+ asn1::INTEGER i(10),i2(12);
+}
+
+#endif
+
+void TC_TEST_basic_types_tagged::decode_IntILT62()
+{
+ const unsigned char seq[] = {0x5F,0x3E,0x01,0x05};
+ asn1::streams::ber ctx;
+ IntILT62 I;
+ memcpy(ctx.buffer(),seq,4);
+ I.decode(ctx);
+ CPPUNIT_ASSERT(I.get_value()==5);
+}
+
+void TC_TEST_basic_types_tagged::decode_IntILT432()
+{
+ const unsigned char seq[] = {0x5F,0x83,0x30,0x01,0x0a};
+ asn1::streams::ber ctx;
+ IntILT432 I;
+ memcpy(ctx.buffer(),seq,5);
+ I.decode(ctx);
+ CPPUNIT_ASSERT(I.get_value()==10);
+}
+
+void TC_TEST_basic_types_tagged::decode_IntELT72()
+{
+}
+
+
+void TC_TEST_basic_types_tagged::decode_TaggedInteger()
+{
+ asn1::streams::ber ctx;
+ //const unsigned char seq[] = {0x43,0x03,0x02,0x01,0x07};
+ const unsigned char seq[] = {0x63,0x03,0x02,0x01,0x07};
+ Int S;
+ memcpy(ctx.buffer(),seq,5);
+ //S.codec(ctx,S,asn1::CODEC_DECODE);
+ S.decode(ctx);
+ CPPUNIT_ASSERT( S.get_value() == 7);
+}
+
+
+void TC_TEST_basic_types_tagged::decode_TaggedSeq()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x62,0x07,0x30,0x05,0x02,0x01,0x06,0x05,0x00};
+ SeqE S;
+ memcpy(ctx.buffer(),seq,9);
+ //S.codec(ctx,S,asn1::CODEC_DECODE);
+ S.decode(ctx);
+ CPPUNIT_ASSERT( S.one == 6);
+}
+void TC_TEST_basic_types_tagged::decode_TaggedSeqE1()
+{
+ asn1::streams::ber ctx;
+ //const unsigned char seq[] = {0x64,0x09,0x30,0x07,0x43,0x03,0x02,0x01,0x06,0x05,0x00};
+ const unsigned char seq[] = {0x64,0x09,0x30,0x07,0x63,0x03,0x02,0x01,0x06,0x05,0x00};
+ SeqE1 S;
+ memcpy(ctx.buffer(),seq,11);
+ S.decode(ctx);
+ CPPUNIT_ASSERT( S.one.get_value() == 6);
+}
+
+void TC_TEST_basic_types_tagged::decode_TaggedSeqI()
+{
+ const unsigned char seq[] = {0x65,0x05,0x55,0x01,0x06,0x56,0x00};
+ asn1::streams::ber ctx;
+ SeqI S;
+ memcpy(ctx.buffer(),seq,11);
+ S.decode(ctx);
+ int result = memcmp(ctx.buffer(),seq,7);
+ // CPPUNIT_ASSERT(result==0);
+ CPPUNIT_ASSERT( S.one.get_value() == 6);
+}
+
+
+void TC_TEST_basic_types_tagged::decode_TaggedInSeq()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x30,0x0a,0xa0,0x03,0x02,0x01,0x06,0x43,0x03,0x02,0x01,0x09};
+ InSeq S;
+ memcpy(ctx.buffer(),seq,12);
+ S.decode(ctx);
+ CPPUNIT_ASSERT( S.one.get_value() == 6);
+}
+
+void TC_TEST_basic_types_tagged::decode_TaggedChoice()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x64,0x03,0x40,0x01,0x06};
+ Choice S;
+ memcpy(ctx.buffer(),seq,5);
+ S.decode(ctx);
+ CPPUNIT_ASSERT( S.get_one() == 6);
+}
+
+void TC_TEST_basic_types_tagged::decode_TaggedSetE()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x64,0x07,0x31,0x05,0x02,0x01,0x06,0x05,0x00};
+ TSetE S;
+ memcpy(ctx.buffer(),seq,9);
+ S.decode(ctx);
+ CPPUNIT_ASSERT( S.one == 6);
+}
+
+
+
--- /dev/null
+#ifndef TESTCASE_SIMPLETYPE_H
+#define TESTCASE_SIMPLETYPE_H
+
+#include <cppunit/extensions/HelperMacros.h>
+
+#include "rtasn1/asn1.h"
+#include "rtasn1/asn1_codec.h"
+#include "rtasn1/asn1_codec_ber.h"
+#include "UNIT-TEST-basic-types-tagged.h"
+
+class TC_TEST_basic_types_tagged : public CPPUNIT_NS::TestFixture
+{
+ CPPUNIT_TEST_SUITE( TC_TEST_basic_types_tagged );
+ CPPUNIT_TEST(encode_TaggedInteger);
+ CPPUNIT_TEST(encode_TaggedSeq);
+ CPPUNIT_TEST(encode_TaggedSeqE1);
+ CPPUNIT_TEST(encode_TaggedSeqI);
+ CPPUNIT_TEST(encode_TaggedInSeq);
+ CPPUNIT_TEST(encode_TaggedChoice);
+ CPPUNIT_TEST(encode_TaggedChoiceSeqE);
+ CPPUNIT_TEST(encode_TaggedSetE);
+ CPPUNIT_TEST(encode_IntILT62);
+ CPPUNIT_TEST(encode_IntILT432);
+ CPPUNIT_TEST(encode_IntELT72);
+
+ CPPUNIT_TEST(decode_IntILT62);
+ CPPUNIT_TEST(decode_IntILT432);
+ CPPUNIT_TEST(decode_IntELT72);
+ CPPUNIT_TEST(decode_TaggedInteger);
+ CPPUNIT_TEST(decode_TaggedSeq);
+ CPPUNIT_TEST(decode_TaggedSeqE1);
+ CPPUNIT_TEST(decode_TaggedSeqI);
+ CPPUNIT_TEST(decode_TaggedInSeq);
+ CPPUNIT_TEST(decode_TaggedChoice);
+ CPPUNIT_TEST(decode_TaggedSetE);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ void setUp();
+ protected:
+
+ void encode_TaggedInteger();
+ void encode_TaggedSeq();
+ void encode_TaggedSeqE1();
+ void encode_TaggedSeqI();
+ void encode_TaggedInSeq();
+ void encode_TaggedChoice();
+ void encode_TaggedChoiceSeqE();
+ void encode_TaggedSetE();
+ void encode_IntILT62();
+ void encode_IntILT432();
+ void encode_IntELT72();
+
+ void decode_IntILT62();
+ void decode_IntILT432();
+ void decode_IntELT72();
+ void decode_TaggedInteger();
+ void decode_TaggedSeq();
+ void decode_TaggedSeqE1();
+ void decode_TaggedSeqI();
+ void decode_TaggedInSeq();
+ void decode_TaggedChoice();
+ void decode_TaggedSetE();
+#if 0
+ void encode_TaggedSeq();
+ void decode_TaggedSeq();
+ void decode_TEST_Enum();
+ void decode_TEST_SeqEnum();
+#endif
+ protected:
+ asn1::streams::ber m_ctx;
+ asn1::codecBER m_codec;
+};
+
+#endif
--- /dev/null
+#include <cppunit/config/SourcePrefix.h>
+#include <string.h>
+#include <fstream>
+#define MAIN
+#include "rtasn1/asn1.h"
+#include "rtasn1/asn1_codec.h"
+#include "rtasn1/asn1_codec_ber.h"
+#include "TEST_basic_types.h"
+#include "UNIT-TEST-basic-types.h"
+
+CPPUNIT_TEST_SUITE_REGISTRATION( TC_TEST_basic_types);
+
+using namespace TEST_basic_types;
+
+void TC_TEST_basic_types::setUp()
+{
+
+}
+
+void TC_TEST_basic_types::encode_Test()
+{
+ std::string s("Jones");
+ asn1::prim::types::String ps = s;
+ VisibleString os =ps;
+ VString1 vs1(os);
+ VString2 str;
+ str = vs1;
+
+ asn1::streams::ber ctx;
+ unsigned char *table = ctx.buffer();
+ table[0] = '\02'; table[1] = '\01';table[2] = '\05';
+ TEST_basic_types::Test test;
+ //asn1::streams::ber::codec(ctx,test,asn1::CODEC_DECODE);
+ //test.codec(ctx,test,asn1::CODEC_DECODE);
+ test.decode(ctx);
+ ctx.nb_bits(-1*ctx.nb_read_bits());
+ //str.codec(ctx,str,CODEC_ENCODE);
+ str.encode(ctx);
+ CPPUNIT_ASSERT(test.get_value()==5);
+}
+
+void TC_TEST_basic_types::encode_TestI()
+{
+ const unsigned char seq[] = {0x02,0x01,0x01};
+ TEST_basic_types::TestI i;
+ i = TEST_basic_types::TestI::one;
+
+ asn1::streams::ber ctx;
+
+ i.encode(ctx);
+
+ int result = memcmp(ctx.buffer(),seq,3);
+ CPPUNIT_ASSERT(result == 0);
+}
+
+
+void TC_TEST_basic_types::encode_VString1()
+{
+ asn1::streams::ber ctx;
+ asn1::prim::types::String s("Jones");
+ VString1 str;
+ str = s;
+ //str.codec(ctx,str,asn1::CODEC_ENCODE);
+ str.encode(ctx);
+
+ const unsigned char seq[] = {0x1a,0x05,0x4a,0x6f,0x6e,0x65,0x73};
+ int result = memcmp(ctx.buffer(),seq,7);
+ CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_basic_types::encode_VString2()
+{
+ asn1::streams::ber ctx;
+ asn1::prim::types::String s("Jones");
+ VString2 str;
+ str = VString1(s);
+ //codec<asn1::streams::ber>(ctx,str,asn1::CODEC_ENCODE);
+ //str.codec(ctx,str,asn1::CODEC_ENCODE);
+ str.encode(ctx);
+
+ const unsigned char seq[] = {0x43,0x05,0x4a,0x6f,0x6e,0x65,0x73};
+ int result = memcmp(ctx.buffer(),seq,7);
+ CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_basic_types::encode_VString3()
+{
+ asn1::streams::ber ctx;
+ asn1::prim::types::String s("Jones");
+ // (VString2(VString1((std::string("Jones")))));
+ VString2 str2;
+ str2 = VString1(s);
+ VString3 str;
+ str = str2;
+
+ //str.codec(ctx,str,asn1::CODEC_ENCODE);
+ str.encode(ctx);
+ const unsigned char seq[] = {0xa2,0x07,0x43,0x05,0x4a,0x6f,0x6e,0x65,0x73};
+ int result = memcmp(ctx.buffer(),seq,9);
+ CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_basic_types::encode_VString4()
+{
+ asn1::streams::ber ctx;
+ asn1::prim::types::String s("Jones");
+ //(VString3(VString2(VString1((std::string("Jones"))))));
+ VString2 str2;
+ str2 = VString1(s);
+ VString3 str3;
+ str3 = str2;
+ VString4 str;
+ str = str3;
+ //str = s; Fails during compilation
+ //str.codec(ctx,str,asn1::CODEC_ENCODE);
+ str.encode(ctx);
+
+ const unsigned char seq[] = {0x67,0x07,0x43,0x05,0x4a,0x6f,0x6e,0x65,0x73};
+ int result = memcmp(ctx.buffer(),seq,9);
+ CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_basic_types::encode_VString5()
+{
+ asn1::streams::ber ctx;
+ asn1::prim::types::String s("Jones");
+ VString5 str ;
+ VString2 str2;
+ VString1 str1(s);
+ str2 = str1;
+ str = str2;
+ //str.codec(ctx,str,asn1::CODEC_ENCODE);
+ str.encode(ctx);
+ const unsigned char seq[] = {0x82,0x05,0x4a,0x6f,0x6e,0x65,0x73};
+
+ int result = memcmp(ctx.buffer(),seq,7);
+ CPPUNIT_ASSERT(result==0);
+
+}
+
+void TC_TEST_basic_types::encode_BString()
+{
+ asn1::streams::ber ctx;
+ B_String str;
+ str[0]= 0x0a;
+ //str.codec(ctx,str,asn1::CODEC_ENCODE);
+ str.encode(ctx);
+
+ const unsigned char seq[] = {0x03,0x02,0x04,0xa0};
+ //int result = memcmp(ctx.buffer(),seq,4);
+ CPPUNIT_ASSERT_EQUAL((unsigned long)4,ctx.bytes());
+ CPPUNIT_ASSERT_EQUAL(0,memcmp(ctx.buffer(),seq,4));
+
+}
+
+// Decode string
+
+void TC_TEST_basic_types::decode_Test()
+{
+}
+
+void TC_TEST_basic_types::decode_TestI()
+{
+ const unsigned char seq[] = {0x02,0x01,0x02};
+ TEST_basic_types::TestI i;
+ asn1::streams::ber ctx;
+
+ memcpy(ctx.buffer(),seq,3);
+
+ i.decode(ctx);
+
+ CPPUNIT_ASSERT(i.get_value() == 2);
+}
+
+void TC_TEST_basic_types::decode_VString1()
+{
+ const unsigned char seq[] = {0x1a,0x05,0x4a,0x6f,0x6e,0x65,0x73};
+ asn1::streams::ber ctx;
+ memcpy(ctx.buffer(),seq,7);
+ VString1 str;
+ //str.codec(ctx,str,asn1::CODEC_DECODE);
+ str.decode(ctx);
+ CPPUNIT_ASSERT(std::string("Jones").compare(str.get_sys_value())==0);
+}
+void TC_TEST_basic_types::decode_VString2()
+{
+ const unsigned char seq[] = {0x43,0x05,0x4a,0x6f,0x6e,0x65,0x73};
+ asn1::streams::ber ctx;
+ memcpy(ctx.buffer(),seq,7);
+ VString2 str;
+ //str.codec(ctx,str,asn1::CODEC_DECODE);
+ str.decode(ctx);
+ CPPUNIT_ASSERT(std::string("Jones").compare(str.get_sys_value())==0);
+}
+void TC_TEST_basic_types::decode_VString3()
+{
+ const unsigned char seq[] = {0xa2,0x07,0x43,0x05,0x4a,0x6f,0x6e,0x65,0x73};
+ asn1::streams::ber ctx;
+ memcpy(ctx.buffer(),seq,9);
+ VString3 str;
+ //str.codec(ctx,str,asn1::CODEC_DECODE);
+ str.decode(ctx);
+ CPPUNIT_ASSERT(std::string("Jones").compare(str.get_sys_value())==0);
+}
+void TC_TEST_basic_types::decode_VString4()
+{
+ const unsigned char seq[] = {0x67,0x07,0x43,0x05,0x4a,0x6f,0x6e,0x65,0x73};
+ asn1::streams::ber ctx;
+ memcpy(ctx.buffer(),seq,9);
+ VString4 str;
+ //str.codec(ctx,str,asn1::CODEC_DECODE);
+ str.decode(ctx);
+ CPPUNIT_ASSERT(std::string("Jones").compare(str.get_sys_value())==0);
+}
+void TC_TEST_basic_types::decode_VString5()
+{
+ const unsigned char seq[] = {0x82,0x05,0x4a,0x6f,0x6e,0x65,0x73};
+ asn1::streams::ber ctx;
+ memcpy(ctx.buffer(),seq,7);
+ VString5 str;
+ //str.codec(ctx,str,asn1::CODEC_DECODE);
+ str.decode(ctx);
+ CPPUNIT_ASSERT(std::string("Jones").compare(str.get_sys_value())==0);
+}
+
+void TC_TEST_basic_types::decode_BString()
+{
+ const unsigned char seq[] = {0x03,0x02,0x04,0xa0};
+ asn1::streams::ber ctx;
+
+ B_String str;
+ memcpy(ctx.buffer(),seq,4);
+ //str.codec(ctx,str,asn1::CODEC_DECODE);
+ str.decode(ctx);
+ CPPUNIT_ASSERT(str[0]==0x0a);
+}
+
+/**
+ * OCTET STRING TESTS
+ */
+void TC_TEST_basic_types::ostring_equal()
+{
+ O_String a,b;
+ asn1::prim::types::String s("Jones");
+ a = s;
+ b = a;
+ CPPUNIT_ASSERT(a == b);
+ // b = std::string("toto");
+ //CPPUNIT_ASSERT(a != b);
+}
+
+void TC_TEST_basic_types::ostring_copy()
+{
+ O_String a,b;
+ a = std::string("toto");
+ b = a;
+ CPPUNIT_ASSERT(a == b);
+}
+
+/**
+ * OBJECT IDENTIFIER TESTS
+ */
+void TC_TEST_basic_types::oid_equal()
+{
+ TestOid a,b;
+ id_1 v;
+ a = id_1();
+ b = v;
+ std::cerr<<"ARRAY: a="<<a<<" b="<<b<<" v ="<<v<<std::endl;
+ CPPUNIT_ASSERT(a == b);
+}
+
+void TC_TEST_basic_types::oid_copy()
+{
+ TestOid a,b;
+ id_1 v;
+ a = id_1();
+ b = a;
+ CPPUNIT_ASSERT(a == b);
+}
--- /dev/null
+#ifndef TESTCASE_SIMPLETYPE_H
+#define TESTCASE_SIMPLETYPE_H
+
+#include <cppunit/extensions/HelperMacros.h>
+
+
+class TC_TEST_basic_types : public CPPUNIT_NS::TestFixture
+{
+ CPPUNIT_TEST_SUITE( TC_TEST_basic_types );
+ CPPUNIT_TEST(encode_Test);
+ CPPUNIT_TEST(encode_TestI);
+ CPPUNIT_TEST(encode_VString1);
+ CPPUNIT_TEST(encode_VString2);
+ CPPUNIT_TEST(encode_VString3);
+ CPPUNIT_TEST(encode_VString4);
+ CPPUNIT_TEST(encode_VString5);
+ CPPUNIT_TEST(encode_BString);
+
+ CPPUNIT_TEST(decode_Test);
+ CPPUNIT_TEST(decode_TestI);
+ CPPUNIT_TEST(decode_VString1);
+ CPPUNIT_TEST(decode_VString2);
+ CPPUNIT_TEST(decode_VString3);
+ CPPUNIT_TEST(decode_VString4);
+ CPPUNIT_TEST(decode_VString5);
+ CPPUNIT_TEST(decode_BString);
+
+ CPPUNIT_TEST(oid_equal);
+ CPPUNIT_TEST(oid_copy);
+
+ CPPUNIT_TEST(ostring_equal);
+ CPPUNIT_TEST(ostring_copy);
+
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ void setUp();
+ protected:
+
+ void encode_Test();
+ void encode_TestI();
+ void encode_VString1();
+ void encode_VString2();
+ void encode_VString3();
+ void encode_VString4();
+ void encode_VString5();
+ void encode_BString();
+
+ void decode_Test();
+ void decode_TestI();
+ void decode_VString1();
+ void decode_VString2();
+ void decode_VString3();
+ void decode_VString4();
+ void decode_VString5();
+ void decode_BString();
+
+ void oid_equal();
+ void oid_copy();
+
+ void ostring_equal();
+ void ostring_copy();
+ protected:
+ asn1::streams::ber m_ctx;
+ asn1::codecBER m_codec;
+};
+
+#endif
--- /dev/null
+#include <cppunit/config/SourcePrefix.h>
+#include <string.h>
+#include <fstream>
+#define MAIN
+#include "rtasn1/asn1.h"
+#include "rtasn1/asn1_codec.h"
+#include "rtasn1/asn1_codec_ber.h"
+#include "UNIT-TEST-ber-primary-types.h"
+#include "TEST_basic_types.h"
+
+CPPUNIT_TEST_SUITE_REGISTRATION( TC_TEST_primary_types);
+
+using namespace TEST_basic_types;
+
+void TC_TEST_primary_types::setUp()
+{
+
+}
+
+void TC_TEST_primary_types::encode_Null()
+{
+ const unsigned char seq[] = {0x05,0x00};
+ asn1::streams::ber ctx;
+ asn1::streams::ber ber;
+ Null i;
+ i.encode(ctx);
+ int result = memcmp(ctx.buffer(),seq,2);
+ CPPUNIT_ASSERT(result==0);
+
+ ber.encode_null(i);
+ result = memcmp(ber.buffer(),seq,2);
+ CPPUNIT_ASSERT(result==0);
+ ber.reset();
+ m_codec.encode(ber,i);
+ result = memcmp(ber.buffer(),seq,2);
+ CPPUNIT_ASSERT(result==0);
+
+ CPPUNIT_ASSERT(asn1::ok==m_codec.decode(ber,i));
+}
+
+void TC_TEST_primary_types::encode_Boolean()
+{
+ asn1::streams::ber ctx;
+ BOOLEAN b;
+ b = false;
+ b.encode(ctx);
+ ctx.reset();
+ CPPUNIT_ASSERT(( asn1::ok == m_codec.decode(ctx,b)) && ( b == false) );
+ ctx.reset(); b = true;
+ b.encode(ctx);
+ ctx.reset();
+ CPPUNIT_ASSERT(( asn1::ok == m_codec.decode(ctx,b)) && ( b == true) );
+
+}
+
+void TC_TEST_primary_types::encode_Integer()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x02,0x01,0x06};
+ const unsigned char iUByte[] = {0x02,0x01,0xFF}; // 255
+ const unsigned char iSByte[] = {0x02,0x01,0x81}; // -127
+ const unsigned char iUWord[] = {0x02,0x02,0xFF,0xFF};
+ const unsigned char iSWord[] = {0x02,0x01,0xFF,0xFF};
+ INTEGER i;
+ UInt64 ui64;
+ i = 6;
+ i.encode(ctx);
+ int result = memcmp(ctx.buffer(),seq,3);
+ CPPUNIT_ASSERT(result==0);
+ /* Check 255 */
+ i = 255 ; ctx.reset();
+ m_codec.encode(ctx,i); ctx.reset(); i = 0;
+ CPPUNIT_ASSERT(( asn1::ok == m_codec.decode(ctx,i)) && ( i == 255) );
+ /* Check 65536 */
+ i = 65536 ; ctx.reset();
+ m_codec.encode(ctx,i); ctx.reset(); i = 0;
+ CPPUNIT_ASSERT(( asn1::ok == m_codec.decode(ctx,i)) && ( i == 65536) );
+ /* Check Unsiged Dword*/
+ ui64 = 4294967295UL ; ctx.reset();
+ m_codec.encode(ctx,ui64); ctx.reset(); ui64 = 0UL;
+ CPPUNIT_ASSERT(( asn1::ok == m_codec.decode(ctx,ui64)) && ( ui64 == 4294967295UL) );
+ /* Check a negative value */
+ i = -127 ; ctx.reset();
+ m_codec.encode(ctx,i); ctx.reset(); i = 0;
+ CPPUNIT_ASSERT(( asn1::ok == m_codec.decode(ctx,i)) && ( i == -127) );
+}
+void TC_TEST_primary_types::encode_Integer1()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x02,0x02,0x00,0xb4};
+ INTEGER i;
+ i = 180;
+ i.encode(ctx);
+ int result = memcmp(ctx.buffer(),seq,4);
+ CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_primary_types::encode_Integer127()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x02,0x01,0x7F};
+ INTEGER i;
+ i = 127;
+ i.encode(ctx);
+ int result = memcmp(ctx.buffer(),seq,3);
+ CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_primary_types::encode_Integer128()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x02,0x02,0x00,0x80};
+ INTEGER i;
+ i = 128;
+ i.encode(ctx);
+ int result = memcmp(ctx.buffer(),seq,4);
+ CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_primary_types::encode_Integer256()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x02,0x02,0x01,0x00};
+ INTEGER i;
+ i = 256;
+ i.encode(ctx);
+ int result = memcmp(ctx.buffer(),seq,4);
+ CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_primary_types::encode_Integer_n128()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x02,0x01,0x80,0x34};
+ INTEGER i;
+ i = -128;
+ i.encode(ctx);
+ int result = memcmp(ctx.buffer(),seq,3);
+ CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_primary_types::encode_Integer_n129()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x02,0x02,0xFF,0x7F};
+ INTEGER i;
+ i = -129;
+ i.encode(ctx);
+ int result = memcmp(ctx.buffer(),seq,4);
+ CPPUNIT_ASSERT(result==0);
+}
+
+
+
+void TC_TEST_primary_types::encode_Integer235()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x02,0x02,0x00,0xeb};
+ INTEGER i;
+ i = 235;
+ i.encode(ctx);
+ int result = memcmp(ctx.buffer(),seq,4);
+ CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_primary_types::encode_Real()
+{
+ asn1::streams::ber ctx;
+ REAL i;
+ i = 4.5;
+ i.encode(ctx);
+ CPPUNIT_ASSERT(1==0);
+}
+
+void TC_TEST_primary_types::encode_BitString()
+{
+ asn1::streams::ber ctx;
+ BIT_STRING str;
+ str[0] = 0x10;
+ str.encode(ctx);
+}
+
+void TC_TEST_primary_types::encode_OctetString()
+{
+ asn1::streams::ber ctx;
+ OCTET_STRING s(std::string("Jones"));
+ s.encode(ctx);
+}
+
+void TC_TEST_primary_types::encode_UTF8String()
+{
+ const unsigned char seq[] = {0x0c,0x05,0x4a,0x6f,0x6e,0x65,0x73};
+ asn1::streams::ber ber;
+ UTF8String s( "Jones" );
+ ber.encode_string(s);
+
+ int result = memcmp(ber.buffer(),seq,7);
+ CPPUNIT_ASSERT(result==0);
+
+
+}
+
+void TC_TEST_primary_types::encode_PrintableString()
+{
+ const unsigned char seq[] = {0x13,0x05,0x4a,0x6f,0x6e,0x65,0x73};
+ asn1::streams::ber ber;
+ PrintableString s( "Jones" );
+ ber.encode_string(s);
+
+ int result = memcmp(ber.buffer(),seq,7);
+ CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_primary_types::encode_TeletexString()
+{
+ const unsigned char seq[] = {0x14,0x05,0x4a,0x6f,0x6e,0x65,0x73};
+ asn1::streams::ber ber;
+ TeletexString s( "Jones" );
+ ber.encode_string(s);
+
+ int result = memcmp(ber.buffer(),seq,7);
+ CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_primary_types::encode_VideotexString()
+{
+ const unsigned char seq[] = {0x15,0x05,0x4a,0x6f,0x6e,0x65,0x73};
+ asn1::streams::ber ber;
+ VideotexString s( "Jones" );
+ ber.encode_string(s);
+
+ int result = memcmp(ber.buffer(),seq,7);
+ CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_primary_types::encode_IA5String()
+{
+ const unsigned char seq[] = {0x16,0x05,0x4a,0x6f,0x6e,0x65,0x73};
+ asn1::streams::ber ber;
+ IA5String s( "Jones" );
+ ber.encode_string(s);
+
+ int result = memcmp(ber.buffer(),seq,7);
+ CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_primary_types::encode_GraphicString()
+{
+ const unsigned char seq[] = {0x19,0x05,0x4a,0x6f,0x6e,0x65,0x73};
+ asn1::streams::ber ber;
+ GraphicString s( "Jones" );
+ ber.encode_string(s);
+
+ int result = memcmp(ber.buffer(),seq,7);
+ CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_primary_types::encode_GeneralString()
+{
+ const unsigned char seq[] = {0x1b,0x05,0x4a,0x6f,0x6e,0x65,0x73};
+ asn1::streams::ber ber;
+ GeneralString s( "Jones" );
+ ber.encode_string(s);
+ int result = memcmp(ber.buffer(),seq,7);
+ CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_primary_types::encode_UniversalString()
+{
+ const unsigned char seq[] = {0x1d,0x05,0x4a,0x6f,0x6e,0x65,0x73};
+ asn1::streams::ber ber;
+ UniversalString s( "Jones" );
+ ber.encode_string(s);
+ int result = memcmp(ber.buffer(),seq,7);
+ CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_primary_types::encode_BMPString()
+{
+ const unsigned char seq[] = {0x1e,0x05,0x4a,0x6f,0x6e,0x65,0x73};
+ asn1::streams::ber ber;
+ BMPString s( "Jones" );
+ ber.encode_string(s);
+ int result = memcmp(ber.buffer(),seq,7);
+ CPPUNIT_ASSERT(result==0);
+}
+
+
+void TC_TEST_primary_types::encode_VisibleString()
+{
+ const unsigned char seq[] = {0x1a,0x05,0x4a,0x6f,0x6e,0x65,0x73};
+ asn1::streams::ber ctx;
+ asn1::streams::ber ber;
+ asn1::prim::types::String s("Jones");
+ VisibleString vs(s);
+ vs.encode(ctx);
+
+ ber.encode_string(vs);
+
+ int result = memcmp(ber.buffer(),seq,7);
+ CPPUNIT_ASSERT(result==0);
+
+ result = memcmp(ctx.buffer(),seq,7);
+ CPPUNIT_ASSERT(result==0);
+
+}
+
+
+void TC_TEST_primary_types::encode_NumericString()
+{
+ const unsigned char seq[] = {0x12,0x04,0x31,0x32,0x33,0x34};
+ asn1::streams::ber ctx;
+ asn1::streams::ber ber;
+ //std::string s("Jones");
+ NumericString vs("1234");
+ vs.encode(ctx);
+
+ ber.encode_string(vs);
+
+ int result = memcmp(ber.buffer(),seq,6);
+ CPPUNIT_ASSERT(result==0);
+
+ result = memcmp(ctx.buffer(),seq,6);
+ CPPUNIT_ASSERT(result==0);
+}
+
+void TC_TEST_primary_types::encode_Oid()
+{
+ long oi[] = {1,3,7};
+ const unsigned char seq[] = {0x06,0x02,0x2b,0x07};
+ // {1.3.128}
+ long oid128[] = {1,3,128};
+ const unsigned char seq128[] = {0x06,0x03,0x2b,0x81,0x00};
+
+ long lid_1[] = { 1, 3, 6, 1, 5, 5, 7};
+ // id_1;
+ asn1::streams::ber ctx;
+ OBJECT_IDENTIFIER_NG i ;
+ OBJECT_IDENTIFIER_NG i1 ;
+ i.from_arc(3,oi);
+ i.encode(ctx);
+ int result = memcmp(ctx.buffer(),seq,4);
+ CPPUNIT_ASSERT(result==0);
+ i1.from_arc(7,lid_1);
+ CPPUNIT_ASSERT(i != i1);
+ i.from_arc(3,oid128);
+ ctx.reset();
+ i.encode(ctx);
+ CPPUNIT_ASSERT_EQUAL(0,memcmp(ctx.buffer(),seq128,5));
+}
+// decoding ...
+//
+
+
+void TC_TEST_primary_types::decode_Null()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x05,0x00};
+ Null i;
+ memcpy(ctx.buffer(),seq,2);
+ i.decode(ctx);
+ CPPUNIT_ASSERT(ctx.nb_read_bits()==16);
+}
+
+void TC_TEST_primary_types::decode_Boolean()
+{
+ asn1::streams::ber ctx;
+ BOOLEAN b;
+ const unsigned char seq[] = {0x01,0x01,0xFF};
+ memcpy(ctx.buffer(),seq,3);
+ b.decode(ctx);
+ CPPUNIT_ASSERT(ctx.nb_read_bits()==24);
+ CPPUNIT_ASSERT(b==true);
+}
+
+void TC_TEST_primary_types::decode_Integer()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x02,0x01,0x0a};
+ INTEGER i;
+ memcpy(ctx.buffer(),seq,3);
+ i.decode(ctx);
+ CPPUNIT_ASSERT(i==10);
+}
+void TC_TEST_primary_types::decode_Integer1()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x02,0x02,0x00,0xb4};
+ INTEGER i;
+ memcpy(ctx.buffer(),seq,4);
+ i.decode(ctx);
+ CPPUNIT_ASSERT(i==180);
+}
+void TC_TEST_primary_types::decode_Integer127()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x02,0x01,0x7F,0x34};
+ INTEGER i;
+ memcpy(ctx.buffer(),seq,3);
+ i.decode(ctx);
+ CPPUNIT_ASSERT(i==127);
+}
+void TC_TEST_primary_types::decode_Integer128()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x02,0x02,0x00,0x80};
+ INTEGER i;
+ memcpy(ctx.buffer(),seq,4);
+ i.decode(ctx);
+ CPPUNIT_ASSERT(i==128);
+}
+void TC_TEST_primary_types::decode_Integer256()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x02,0x02,0x01,0x00};
+ INTEGER i;
+ memcpy(ctx.buffer(),seq,4);
+ i.decode(ctx);
+ CPPUNIT_ASSERT(i==256);
+}
+void TC_TEST_primary_types::decode_Integer_n128()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x02,0x01,0x80};
+ INTEGER i;
+ memcpy(ctx.buffer(),seq,3);
+ i.decode(ctx);
+ CPPUNIT_ASSERT(i== -128);
+}
+void TC_TEST_primary_types::decode_Integer_n129()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x02,0x02,0xFF,0x7F};
+ INTEGER i;
+ memcpy(ctx.buffer(),seq,4);
+ i.decode(ctx);
+ CPPUNIT_ASSERT(i== -129);
+}
+
+void TC_TEST_primary_types::decode_Integer235()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x02,0x02,0x00,0xeb};
+ INTEGER i;
+ memcpy(ctx.buffer(),seq,4);
+ i.decode(ctx);
+ CPPUNIT_ASSERT(i==235);
+}
+
+
+void TC_TEST_primary_types::decode_Real()
+{
+ asn1::streams::ber ctx;
+ REAL i;
+ //i.encode(ctx);
+ CPPUNIT_ASSERT(1==0);
+}
+
+void TC_TEST_primary_types::decode_BitString()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x03,0x07,0x04,0x0a,0x3B,0x5F,0x29,0x1c,0xd0};
+ BIT_STRING str;
+ memcpy(ctx.buffer(),seq,9);
+ str.decode(ctx);
+ std::cout<<" t[0]="<<std::hex<<(unsigned short)str[0]<<" "<<std::dec;
+ std::cout<<" t[1]="<<std::hex<<(unsigned short)str[1]<<" "<<std::dec;
+ std::cout<<" t[2]="<<std::hex<<(unsigned short)str[2]<<" "<<std::dec;
+ std::cout<<" t[3]="<<std::hex<<(unsigned short)str[3]<<" "<<std::dec;
+ std::cout<<" t[4]="<<std::hex<<(unsigned short)str[4]<<" "<<std::dec;
+ std::cout<<" t[5]="<<std::hex<<(unsigned short)str[5]<<" "<<std::dec;
+ CPPUNIT_ASSERT(str[0]==0xcd);
+}
+
+void TC_TEST_primary_types::decode_OctetString()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x04,0x05,0x4a,0x6f,0x6e,0x65,0x73};
+ OCTET_STRING s;
+
+ memcpy(ctx.buffer(),seq,7);
+ s.decode(ctx);
+
+ CPPUNIT_ASSERT(std::string("Jones").compare(s.get_sys_value())==0);
+}
+void TC_TEST_primary_types::decode_UTF8String()
+{
+}
+
+void TC_TEST_primary_types::decode_PrintableString()
+{
+}
+
+void TC_TEST_primary_types::decode_TeletexString()
+{
+}
+
+void TC_TEST_primary_types::decode_VideotexString()
+{
+}
+
+void TC_TEST_primary_types::decode_IA5String()
+{
+}
+
+void TC_TEST_primary_types::decode_GraphicString()
+{
+}
+
+void TC_TEST_primary_types::decode_GeneralString()
+{
+}
+
+void TC_TEST_primary_types::decode_UniversalString()
+{
+}
+
+void TC_TEST_primary_types::decode_BMPString()
+{
+}
+
+
+void TC_TEST_primary_types::decode_VisibleString()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x1a,0x05,0x4a,0x6f,0x6e,0x65,0x73};
+ asn1::prim::types::String s("Jones");
+ asn1::prim::types::String s1;
+ VisibleString vs;
+ memcpy(ctx.buffer(),seq,7);
+ vs.decode(ctx);
+ s1 = vs.get_value();
+ int result = s1.get_value().compare(s.get_value());
+ // int result = memcmp(ctx.buffer(),seq,7);
+ CPPUNIT_ASSERT(result==0);
+}
+
+
+void TC_TEST_primary_types::decode_NumericString()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x12,0x05,0x31,0x32,0x33,0x34,0x35};
+ NumericString vs;
+ memcpy(ctx.buffer(),seq,7);
+ vs.decode(ctx);
+ CPPUNIT_ASSERT(std::string("12345").compare(vs.get_sys_value())==0);
+}
+
+void TC_TEST_primary_types::decode_Oid()
+{
+ asn1::streams::ber ctx;
+ // { 2.100.}
+ const unsigned char seq[] = {0x06,0x03,0x81,0x34,0x03,0x65,0x73};
+ // {1.3.128}
+ const unsigned char seq128[] = {0x06,0x03,0x2b,0x81,0x00};
+ // { 1.3.36.3.3.1.2}
+ const unsigned char seq2[] = {0x06,0x06,0x2B,0x24,0x03,0x03,0x01,0x02};
+ OBJECT_IDENTIFIER i;
+ //
+ memcpy(ctx.buffer(),seq2,8);
+ i.decode(ctx);
+ asn1::prim::types::ObjectIdentifier::array_type a;
+ i.to_arc(a);
+ asn1::prim::types::ObjectIdentifier::iterator it = a.begin();
+ CPPUNIT_ASSERT((*it)== 1);
+ ++it;
+ CPPUNIT_ASSERT((*it)== 3);
+ // Check 128
+ ctx.reset();
+ memcpy(ctx.buffer(),seq128,5);
+ i.decode(ctx);
+ a.clear();
+ i.to_arc(a); it = a.begin(); ++it; ++it;
+ CPPUNIT_ASSERT_EQUAL((long)128,*it);
+}
--- /dev/null
+#ifndef TESTCASE_SIMPLETYPE_H
+#define TESTCASE_SIMPLETYPE_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include "rtasn1/asn1.h"
+
+
+class TC_TEST_primary_types : public CPPUNIT_NS::TestFixture
+{
+ CPPUNIT_TEST_SUITE( TC_TEST_primary_types );
+ CPPUNIT_TEST(encode_Null);
+ CPPUNIT_TEST(encode_Boolean);
+ CPPUNIT_TEST(encode_Integer);
+ CPPUNIT_TEST(encode_Integer1);
+ CPPUNIT_TEST(encode_Integer127);
+ CPPUNIT_TEST(encode_Integer128);
+ CPPUNIT_TEST(encode_Integer256);
+ CPPUNIT_TEST(encode_Integer_n128);
+ CPPUNIT_TEST(encode_Integer_n129);
+ CPPUNIT_TEST(encode_Integer235);
+ CPPUNIT_TEST(encode_Real);
+ CPPUNIT_TEST(encode_BitString);
+ CPPUNIT_TEST(encode_OctetString);
+ CPPUNIT_TEST(encode_UTF8String);
+ CPPUNIT_TEST(encode_NumericString);
+ CPPUNIT_TEST(encode_PrintableString);
+ CPPUNIT_TEST(encode_TeletexString);
+ CPPUNIT_TEST(encode_VideotexString);
+ CPPUNIT_TEST(encode_IA5String);
+ CPPUNIT_TEST(encode_GraphicString);
+ CPPUNIT_TEST(encode_VisibleString);
+ CPPUNIT_TEST(encode_GeneralString);
+ CPPUNIT_TEST(encode_UniversalString);
+ CPPUNIT_TEST(encode_BMPString);
+ CPPUNIT_TEST(encode_Oid);
+ CPPUNIT_TEST(decode_Null);
+ CPPUNIT_TEST(decode_Boolean);
+ CPPUNIT_TEST(decode_Integer);
+ CPPUNIT_TEST(decode_Integer1);
+ CPPUNIT_TEST(decode_Integer127);
+ CPPUNIT_TEST(decode_Integer128);
+ CPPUNIT_TEST(decode_Integer256);
+ CPPUNIT_TEST(decode_Integer_n128);
+ CPPUNIT_TEST(decode_Integer_n129);
+ CPPUNIT_TEST(decode_Integer235);
+ CPPUNIT_TEST(decode_Real);
+ CPPUNIT_TEST(decode_BitString);
+ CPPUNIT_TEST(decode_OctetString);
+
+ CPPUNIT_TEST(decode_UTF8String);
+ CPPUNIT_TEST(decode_NumericString);
+ CPPUNIT_TEST(decode_PrintableString);
+ CPPUNIT_TEST(decode_TeletexString);
+ CPPUNIT_TEST(decode_VideotexString);
+ CPPUNIT_TEST(decode_IA5String);
+ CPPUNIT_TEST(decode_GraphicString);
+ CPPUNIT_TEST(decode_VisibleString);
+ CPPUNIT_TEST(decode_GeneralString);
+ CPPUNIT_TEST(decode_UniversalString);
+ CPPUNIT_TEST(decode_BMPString);
+ CPPUNIT_TEST(decode_Oid);
+ CPPUNIT_TEST_SUITE_END();
+/**
+ typedef asn1::types::EXPLICIT<asn1::types::UNIVERSAL,12,OCTET_STRING> UTF8String;
+
+ typedef asn1::types::EXPLICIT<asn1::types::UNIVERSAL,18,OCTET_STRING> NumericString;
+ typedef asn1::types::EXPLICIT<asn1::types::UNIVERSAL,19,OCTET_STRING> PrintableString;
+ typedef asn1::types::EXPLICIT<asn1::types::UNIVERSAL,20,OCTET_STRING> TeletexString;
+ typedef asn1::types::EXPLICIT<asn1::types::UNIVERSAL,21,OCTET_STRING> VideotexString;
+ typedef asn1::types::EXPLICIT<asn1::types::UNIVERSAL,22,OCTET_STRING> IA5String;
+ typedef asn1::types::EXPLICIT<asn1::types::UNIVERSAL,25,OCTET_STRING> GraphicString;
+ typedef asn1::types::EXPLICIT<asn1::types::UNIVERSAL,26,OCTET_STRING> VisibleString;
+ typedef asn1::types::EXPLICIT<asn1::types::UNIVERSAL,27,OCTET_STRING> GeneralString;
+ typedef asn1::types::EXPLICIT<asn1::types::UNIVERSAL,29,OCTET_STRING> UniversalString;
+ typedef asn1::types::EXPLICIT<asn1::types::UNIVERSAL,30,OCTET_STRING> BMPString;
+*/
+
+ public:
+ void setUp();
+ protected:
+
+ void encode_Null();
+ void encode_Boolean();
+ void encode_Integer();
+ void encode_Integer1();
+ void encode_Integer127();
+ void encode_Integer128();
+ void encode_Integer256();
+ void encode_Integer_n128();
+ void encode_Integer_n129();
+ void encode_Integer235();
+ void encode_Real();
+ void encode_BitString();
+ void encode_OctetString();
+ void encode_UTF8String();
+ void encode_NumericString();
+ void encode_PrintableString();
+ void encode_TeletexString();
+ void encode_VideotexString();
+ void encode_IA5String();
+ void encode_GraphicString();
+ void encode_VisibleString();
+ void encode_GeneralString();
+ void encode_UniversalString();
+ void encode_BMPString();
+ void encode_Oid();
+
+ //decoging program
+ void decode_Null();
+ void decode_Boolean();
+ void decode_Integer();
+ void decode_Integer1();
+ void decode_Integer127();
+ void decode_Integer128();
+ void decode_Integer256();
+ void decode_Integer_n128();
+ void decode_Integer_n129();
+ void decode_Integer235();
+ void decode_Real();
+ void decode_BitString();
+ void decode_OctetString();
+ void decode_UTF8String();
+ void decode_NumericString();
+ void decode_PrintableString();
+ void decode_TeletexString();
+ void decode_VideotexString();
+ void decode_IA5String();
+ void decode_GraphicString();
+ void decode_VisibleString();
+ void decode_GeneralString();
+ void decode_UniversalString();
+ void decode_BMPString();
+ void decode_Oid();
+ protected:
+ asn1::codecBER m_codec;
+ asn1::streams::ber m_ctx;
+};
+
+#endif
--- /dev/null
+#include <cppunit/config/SourcePrefix.h>
+#include <string.h>
+#include <fstream>
+
+#include "rtasn1/asn1.h"
+#include "rtasn1/asn1_codec.h"
+#include "rtasn1/asn1_codec_ber.h"
+#include "UNIT-TEST-private-types-choice.h"
+
+CPPUNIT_TEST_SUITE_REGISTRATION( TC_TEST_private_types_choice);
+
+using namespace TEST_private_types_choice;
+
+void TC_TEST_private_types_choice::setUp()
+{
+
+}
+
+void TC_TEST_private_types_choice::encode_len()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x30,0x05,0x02,0x01,0x0b,0x05,0x00};
+ TEST_Sequence S;
+ S.device.set_tag(asn1::tag(asn1::types::UNIVERSAL,2));
+ S.device.get_len() = 11;
+ //S.codec(ctx,S,asn1::CODEC_ENCODE);
+ S.encode(ctx);
+
+ int result = memcmp(ctx.buffer(),seq,7);
+ CPPUNIT_ASSERT(result==0);
+}
+
+
+void TC_TEST_private_types_choice::encode_number()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x30,0x05,0x80,0x01,0x0d,0x05,0x00};
+ TEST_Sequence S;
+ //TEST_Sequence::device_t dev(TEST_Sequence::device_t::typeof_number,asn1::tag(asn1::types::CONTEXT_SPECIFIC,0));
+ TEST_Sequence_device dev(TEST_Sequence_device::typeof_number,asn1::tag(asn1::types::CONTEXT_SPECIFIC,0));
+ dev.get_number() = 13;
+ S.device.set_tag(asn1::tag(asn1::types::CONTEXT_SPECIFIC,0));
+ S.device = dev;
+ //S.codec(ctx,S,asn1::CODEC_ENCODE);
+ S.encode(ctx);
+
+ int result = memcmp(ctx.buffer(),seq,7);
+ CPPUNIT_ASSERT(result==0);
+}
+/**
+TEST-ChoiceCplx ::= CHOICE {
+ cseq SEQUENCE {
+ s1 INTEGER
+ },
+ cset SET {
+ s2 BOOLEAN,
+ s21 BOOLEAN
+ },
+ cchoice CHOICE {
+ s3 OCTET STRING,
+ s31 NULL
+ }
+}
+*/
+void TC_TEST_private_types_choice::encode_cseq()
+{
+ const unsigned char seq[] = {0xa1,0x05,0x30,0x03,0x02,0x01,0x09};
+ asn1::streams::ber ctx;
+ TEST_ChoiceCplx c(TEST_ChoiceCplx::typeof_cseq);
+
+ c.get_cseq().s1 = 9;
+ //c.codec(ctx,c,asn1::CODEC_ENCODE);
+ c.encode(ctx);
+
+ int result = memcmp(ctx.buffer(),seq,7);
+ CPPUNIT_ASSERT(result == 0);
+}
+
+void TC_TEST_private_types_choice::encode_cset()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0xa1,0x08,0x31,0x06,0x01,0x01,0xFF,0x01,0x1,0x00};
+ //TEST_ChoiceCplx c(TEST_ChoiceCplx::typeof_cset,asn1::tag(0,TEST_ChoiceCplx::typeof_cset));
+ TEST_ChoiceCplx c(TEST_ChoiceCplx::typeof_cset,asn1::tag(0,17));
+
+ c.get_cset().s2 = true;
+ c.get_cset().s21 = false;
+ //c.encode(ctx);
+ //c.codec(ctx,c,asn1::CODEC_ENCODE);
+ c.encode(ctx);
+
+ int result = memcmp(ctx.buffer(),seq,10);
+ CPPUNIT_ASSERT(result == 0);
+}
+
+void TC_TEST_private_types_choice::encode_cchoice()
+{
+ const unsigned char seq[] = {0xa1,0x04,0xa2,0x02,0x81,0x00};
+ //const unsigned char seq[] = {0xa1,0x02,0x81,0x00,0x00,0x00};
+ asn1::streams::ber ctx;
+ TEST_ChoiceCplx c(TEST_ChoiceCplx::typeof_cchoice,asn1::tag(2,2));
+
+ c.get_cchoice().get_s31();
+ c.encode(ctx);
+
+ int result = memcmp(ctx.buffer(),seq,6);
+ CPPUNIT_ASSERT(result == 0);
+}
+// decoding
+
+void TC_TEST_private_types_choice::decode_len()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x30,0x05,0x02,0x01,0x0d,0x05,0x00};
+ TEST_Sequence S;
+ memcpy(ctx.buffer(),seq,7);
+ //S.codec(ctx,S,asn1::CODEC_DECODE);
+ S.decode(ctx);
+
+ CPPUNIT_ASSERT(S.device.get_len()==13);
+}
+void TC_TEST_private_types_choice::decode_number()
+{
+ asn1::streams::ber ctx;
+ const unsigned char seq[] = {0x30,0x05,0x80,0x01,0x0d,0x05,0x00};
+ TEST_Sequence S;
+ memcpy(ctx.buffer(),seq,7);
+ //S.codec(ctx,S,asn1::CODEC_DECODE);
+ S.decode(ctx);
+
+ CPPUNIT_ASSERT(S.device.get_number()==13);
+}
+
+void TC_TEST_private_types_choice::decode_cseq()
+{
+ const unsigned char seq[] = {0xa1,0x05,0x30,0x03,0x02,0x01,0x08};
+ asn1::streams::ber ctx;
+ TEST_ChoiceCplx c(TEST_ChoiceCplx::typeof_cseq);
+
+ memcpy(ctx.buffer(),seq,7);
+ //c.codec(ctx,c,asn1::CODEC_DECODE);
+ c.decode(ctx);
+
+ CPPUNIT_ASSERT(c.get_cseq().s1 == 8);
+}
+void TC_TEST_private_types_choice::decode_cset()
+{
+ const unsigned char seq[] = {0xa1,0x08,0x31,0x06,0x01,0x01,0xFF,0x01,0x1,0x00};
+ asn1::streams::ber ctx;
+ TEST_ChoiceCplx c(TEST_ChoiceCplx::typeof_cseq);
+
+ memcpy(ctx.buffer(),seq,10);
+ //c.codec(ctx,c,asn1::CODEC_DECODE);
+ c.decode(ctx);
+
+ CPPUNIT_ASSERT( (c.get_cset().s21 == false) && (c.get_cset().s2 == true));
+}
+
+/**
+ *
+ */
+void TC_TEST_private_types_choice::decode_cchoice()
+{
+ const unsigned char seq[] = {0xa1,0x04,0xa2,0x02,0x81,0x00};
+ asn1::streams::ber ctx;
+ //TEST_ChoiceCplx c(TEST_ChoiceCplx::typeof_cchoice,asn1::tag(0,5));
+ TEST_ChoiceCplx c;
+
+ memcpy(ctx.buffer(),seq,6);
+ int res = c.decode(ctx);
+ std::cerr<<"Kind:"<<c.get_kind()<<std::endl;
+ CPPUNIT_ASSERT(res == asn1::ok);
+ CPPUNIT_ASSERT(c.get_kind() == TEST_ChoiceCplx::typeof_cchoice);
+ //CPPUNIT_ASSERT(0);
+}
--- /dev/null
+#ifndef TESTCASE_SIMPLETYPE_H
+#define TESTCASE_SIMPLETYPE_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include "TEST_private_types_choice.h"
+
+
+class TC_TEST_private_types_choice : public CPPUNIT_NS::TestFixture
+{
+ CPPUNIT_TEST_SUITE( TC_TEST_private_types_choice );
+ CPPUNIT_TEST(encode_len);
+ CPPUNIT_TEST(encode_number);
+ CPPUNIT_TEST(encode_cseq);
+ CPPUNIT_TEST(encode_cset);
+ CPPUNIT_TEST(encode_cchoice);
+ CPPUNIT_TEST(decode_len);
+ CPPUNIT_TEST(decode_number);
+ CPPUNIT_TEST(decode_cseq);
+ CPPUNIT_TEST(decode_cset);
+ CPPUNIT_TEST(decode_cchoice);
+
+
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ void setUp();
+ protected:
+
+ void encode_len();
+ void encode_number();
+ void encode_cseq();
+ void encode_cset();
+ void encode_cchoice();
+
+ void decode_len();
+ void decode_number();
+ void decode_cseq();
+ void decode_cset();
+ void decode_cchoice();
+ protected:
+ asn1::codecBER m_codec;
+ asn1::streams::ber m_ctx;
+};
+
+#endif
--- /dev/null
+#ifndef TESTCASE_SIMPLETYPE_H
+#define TESTCASE_SIMPLETYPE_H
+
+#include <cppunit/extensions/HelperMacros.h>
+
+#include "rtasn1/asn1.h"
+#include "rtasn1/asn1_codec.h"
+#include "rtasn1/asn1_codec_ber.h"
+#include "UNIT-TEST-type-parameter.h"
+
+class TC_TEST_type_parameter : public CPPUNIT_NS::TestFixture
+{
+ CPPUNIT_TEST_SUITE( TC_TEST_type_parameter );
+ CPPUNIT_TEST(encode_call);
+ CPPUNIT_TEST(decode_call);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ void setUp();
+ protected:
+
+ void encode_call();
+ void decode_call();
+ protected:
+ asn1::codecBER m_codec;
+ asn1::streams::ber m_ctx;
+};
+
+#endif
--- /dev/null
+#include <string.h>
+#include <fstream>
+//#define MAIN
+#include "rtasn1/asn1_config.h"
+#include "rtasn1/asn1.h"
+#include "rtasn1/asn1_codec.h"
+#include "rtasn1/asn1_codec_ber.h"
+#include "rtasn1/asn1_codec_jer.h"
+
+void test_codec()
+{
+ asn1::INTEGER i;
+ asn1::streams::ber ctx(500);
+ asn1::codecBER cb;
+
+ cb.encode(ctx,i);
+
+}
+
+void test_codec_jer()
+{
+ asn1::INTEGER i;
+ asn1::streams::jer ctx(500);
+ asn1::codecJER cb;
+
+ cb.encode(ctx,i);
+
+}
+
+
+/**
+ * The aim of this program is to display the
+ * size of all basic objects.
+ */
+int main(int argc,char **argv)
+{
+ asn1::Set<asn1::INTEGER> setof;
+ asn1::Seq<asn1::OCTET_STRING> seqof;
+
+ std::cout<<"Asn1p runtime library, size of type"<<std::endl;
+#define ASN1_TYPE_CLS(PrimType,TagType,TagNum,Asn1Type) \
+ std::cout<<"size of asn1::"<<#Asn1Type<<"\t = "<<sizeof(asn1::Asn1Type)<<std::endl;
+#include "rtasn1/asn1_types.inc"
+
+ std::cout<<"size of SET_OF(INTEGER)\t = "<<sizeof(setof)<<std::endl;
+ std::cout<<"size of SEQ_OF(OCTET_STRING)\t = "<<sizeof(seqof)<<std::endl;
+ test_codec();
+ test_codec_jer();
+
+ std::cout<<"size of prim Boolean \t = "<<sizeof(asn1::prim::types::Boolean)<<std::endl;
+ std::cout<<"size of prim Integer \t = "<<sizeof(asn1::prim::types::Integer)<<std::endl;
+ std::cout<<"size of prim UInt8 \t = "<<sizeof(asn1::prim::types::UInt8)<<std::endl;
+ std::cout<<"size of prim UInt16 \t = "<<sizeof(asn1::prim::types::UInt16)<<std::endl;
+ std::cout<<"size of prim UInt32 \t = "<<sizeof(asn1::prim::types::UInt32)<<std::endl;
+ std::cout<<"size of prim UInt64 \t = "<<sizeof(asn1::prim::types::UInt64)<<std::endl;
+ std::cout<<"size of prim String \t = "<<sizeof(asn1::prim::types::String)<<std::endl;
+ std::cout<<"size of prim BitString \t = "<<sizeof(asn1::prim::types::BitString)<<std::endl;
+}
+
+/**
+ * vim: et sw=2 ts=3:
+ */
--- /dev/null
+#include <iostream>
+
+#include <cppunit/BriefTestProgressListener.h>
+#include <cppunit/CompilerOutputter.h>
+#include <cppunit/XmlOutputter.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/TestResult.h>
+#include <cppunit/TestResultCollector.h>
+#include <cppunit/TestRunner.h>
+
+
+#include "rtasn1/asn1_config.h"
+#include "rtasn1/asn1.h"
+#include "rtasn1/asn1_codec.h"
+#include "rtasn1/asn1_codec_ber.h"
+
+int main(int argc,char **argv)
+{
+ asn1::types::debug_level = 9;
+
+ if ( (argc > 1) && strcmp(argv[1],"-r") == 0)
+ asn1::types::debug_level = 1;
+
+ // Create the event manager and test controller
+ CPPUNIT_NS::TestResult controller;
+
+ // Add a listener that colllects test result
+ CPPUNIT_NS::TestResultCollector result;
+ controller.addListener( &result );
+
+ // Add a listener that print dots as test run.
+ CPPUNIT_NS::BriefTestProgressListener progress;
+ controller.addListener( &progress );
+
+ // Add the top suite to the test runner
+ CPPUNIT_NS::TestRunner runner;
+ runner.addTest( CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest() );
+ runner.run( controller );
+
+ // Print test in a compiler compatible format.
+ CPPUNIT_NS::CompilerOutputter outputter( &result, CPPUNIT_NS::stdCOut() );
+ outputter.write();
+
+ // Test xml output
+ std::ofstream xmlFile("Asn1TestResults.xml");
+ CPPUNIT_NS::XmlOutputter xmlOutput(&result,xmlFile);
+ xmlOutput.write();
+ return result.wasSuccessful() ? 0 : 1;
+
+}
--- /dev/null
+TEST-basic-types
+TEST-basic-types-integer-limits
+TEST-basic-types-implicit
+TEST-basic-types-explicit
+TEST-basic-types-sequence
+TEST-basic-types-set
+TEST-basic-types-enum
+TEST-basic-types-choice
+TEST-private-types-choice
+TEST-basic-types-tagged
+TEST-basic-types-optional
--- /dev/null
+
+
+/**
+ * Should be initiliazed with an array of functions
+ * constrains,
+ * each type of the project has is pair of encoding/decoding function
+ */
+class PocCodecBER : public asn1::codecBER<PocCodecBER>
+{
+ public:
+ PocCodecBER();
+
+ void encode(asn1::context &ctx,const long l);
+
+ long &decode(asn1::context &ctx,long &l);
+
+
+};
+
+/*
+ * vim: et sw=2 ts=2 list:
+ */
--- /dev/null
+
+template <>
+asn1::codecBER<long>::encode(asn1::context &ctx,long l)
+{ static_cast<PocCodecBER *>(this)->encode(ctx,l); };
--- /dev/null
+--
+-- Test-basic-types
+--
+TEST-basic-types {iso(1) identified-organization(3) 1}
+DEFINITIONS ::=
+BEGIN
+Test::=INTEGER
+TestI ::=INTEGER { one(1), two(2) ,tree(3)}
+TestOid ::= OBJECT IDENTIFIER
+O-String::= OCTET STRING(SIZE(1..32))
+
+B-String ::= BIT STRING {
+ default(0),
+ one(1),
+ two(2)
+}
+
+VString1 ::= VisibleString
+
+VString2 ::= [APPLICATION 3] IMPLICIT VString1
+
+VString3 ::= [2] EXPLICIT VString2
+
+VString4 ::= [APPLICATION 7] IMPLICIT VString3
+
+VString5 ::= [2] IMPLICIT VString2
+
+id-1 OBJECT IDENTIFIER ::= { 1 3 6 1 5 5 7}
+id-2 OBJECT IDENTIFIER ::= { 1 3 }
+id-3 OBJECT IDENTIFIER ::= { 1 2 }
+END
+
+--
+-- Test-basic-types-integer-limits
+--
+TEST-basic-types-integer-limits {iso(1) identified-organization(3) 1 2}
+DEFINITIONS ::=
+BEGIN
+
+SByte ::=INTEGER(-127..128)
+UByte ::=INTEGER(0..255)
+
+SWord ::= INTEGER(-32767..3232768)
+UWord ::= INTEGER(0..65535)
+
+SDWord ::= INTEGER(-2147483647..2147483648)
+UDWord ::= INTEGER(0..4294967295)
+
+END
+
+
+--
+-- Test-basic-types-explicit
+--
+TEST-basic-values {iso(1) identified-organization(3) 2 }
+DEFINITIONS ::=
+BEGIN
+
+vi INTEGER ::= 8
+
+nul IA5String ::= { 0, 0}
+
+soh IA5String ::= { 0, 1}
+
+latinCapitalLetterA BMPString ::= {0,0,0,65}
+
+OpCode ::= CHOICE
+{
+ local INTEGER,
+ global OBJECT IDENTIFIER
+}
+
+gsr1 OpCode ::= local : 5
+
+gsr2 OpCode ::= global : { iso(1) 3}
+END
+
+--
+-- Test-basic-types-explicit
+--
+TEST-basic-types-explicit {iso(1) identified-organization(3) 3}
+DEFINITIONS ::=
+BEGIN
+Test::= [APPLICATION 0] EXPLICIT INTEGER
+
+O-String::= [APPLICATION 1] EXPLICIT OCTET STRING(SIZE(1..32))
+
+B-String::= [APPLICATION 2] EXPLICIT BIT STRING(SIZE(1..16))
+
+Bool-String::= [APPLICATION 3] EXPLICIT BOOLEAN
+END
+
+--
+-- Test-basic-types-implicit
+--
+TEST-basic-types-implicit {iso(1) identified-organization(3) 4}
+DEFINITIONS ::=
+BEGIN
+Test::=INTEGER
+
+Ti ::= [8] IMPLICIT INTEGER
+
+TEST-Seq::= SEQUENCE {
+ t1 INTEGER OPTIONAL,
+ t2 [0] IMPLICIT INTEGER OPTIONAL,
+ t3 [1] IMPLICIT INTEGER OPTIONAL
+}
+
+TEST-Choice::= CHOICE {
+ c1 [0] IMPLICIT INTEGER ,
+ c2 [1] IMPLICIT INTEGER ,
+ c3 [2] IMPLICIT INTEGER
+}
+
+
+
+TEST-IntegerList ::= SEQUENCE OF INTEGER
+
+NumberDigits ::= IA5String
+DeviceInfo ::= NULL
+AgentState ::= NULL
+CSTAPrivateData ::= BOOLEAN
+ForwardingType ::= ENUMERATED {
+ un(1)
+ , deux(2)
+}
+
+ListForwardParameters ::= SEQUENCE OF SEQUENCE
+ { forwardingType ForwardingType,
+ forwardDN NumberDigits }
+
+QueryDeviceInformation ::= CHOICE {
+ msgWaitingOn [0] IMPLICIT BOOLEAN,
+ doNotDisturbOn [1] IMPLICIT BOOLEAN,
+ forward [2] IMPLICIT ListForwardParameters,
+ lastDialedNumber [3] IMPLICIT NumberDigits,
+ deviceInfo [4] IMPLICIT DeviceInfo,
+ agentState [5] IMPLICIT AgentState }
+
+QueryDeviceResult ::= --snacc isPdu:"TRUE" -- CHOICE
+ { deviceInformation [0] QueryDeviceInformation,
+ [1] SEQUENCE
+ { deviceInfoBis QueryDeviceInformation,
+ extensions CSTAPrivateData OPTIONAL } }
+
+
+
+
+END
+
+--
+-- Test-basic-types-choice
+--
+TEST-basic-types-choice {iso(1) identified-organization(3) 5}
+DEFINITIONS ::=
+BEGIN
+
+IP4Address ::= SEQUENCE
+{
+ address OCTET STRING (SIZE(4)),
+ portNumber INTEGER(0..65535) OPTIONAL
+}
+
+TEST-Choice::=CHOICE {
+ device INTEGER,
+ name IA5String,
+ b1 BOOLEAN,
+ ip4 IP4Address
+}
+
+TEST-Choice1::=CHOICE {
+ device [0] IMPLICIT INTEGER,
+ i2 [1] IMPLICIT INTEGER,
+ b1 [2] IMPLICIT BOOLEAN,
+ bs1 [3] IMPLICIT BIT STRING,
+ os1 [4] IMPLICIT OCTET STRING,
+ nul [5] IMPLICIT NULL
+}
+-- application level tags
+ChoiceA ::= CHOICE {
+ i [APPLICATION 0] IMPLICIT INTEGER,
+ b [APPLICATION 1] IMPLICIT BOOLEAN
+}
+-- context specific tags
+ChoiceB ::= CHOICE {
+ ib [1] IMPLICIT INTEGER,
+ bb [2] IMPLICIT BOOLEAN
+}
+-- Simulate csta acse apdu...
+ChoiceChoice ::= CHOICE {
+ -- Tag is required for ChoiceA because the underlying type is a Choice as
+ -- well.
+ choicea [0] ChoiceA,
+ choiceb [1] ChoiceB
+}
+
+
+END
+
+--
+-- Test-basic-types-sequence
+--
+TEST-basic-types-sequence {iso(1) identified-organization(3) 6}
+DEFINITIONS ::=
+BEGIN
+
+TEST-Sequence::= SEQUENCE {
+ device INTEGER,
+ name NULL
+}
+
+TEST-SeqSeq ::= SEQUENCE {
+ ss1 SEQUENCE {
+ ss2 IA5String
+ }
+}
+
+TEST-Implicit-Sequence ::= SEQUENCE {
+ s1 [0] IMPLICIT IA5String,
+ s2 [1] IMPLICIT IA5String OPTIONAL,
+ s3 [2] IMPLICIT IA5String OPTIONAL
+
+}
+
+TEST-IntegerList ::= SEQUENCE OF INTEGER
+
+TEST-SeqOfSeq ::= SEQUENCE OF SEQUENCE {
+ device INTEGER,
+ present BOOLEAN
+}
+
+TEST-CplxSeq ::= SEQUENCE {
+ s1 VisibleString(SIZE(0..64)),
+ i1 [0] IMPLICIT SEQUENCE OF INTEGER OPTIONAL,
+ i2 [1] IMPLICIT SEQUENCE OF SEQUENCE {
+ b1 BOOLEAN,
+ n NULL
+ }
+}
+
+TEST-CplxSeqNm ::= SEQUENCE {
+ i2 [1] IMPLICIT SEQUENCE OF nmSeq SEQUENCE {
+ b1 BOOLEAN,
+ n NULL
+ }
+}
+
+END
+
+--
+-- TEST-basic-types-set
+--
+TEST-basic-types-set {iso(1) identified-organization(3) 7}
+DEFINITIONS ::=
+BEGIN
+
+TEST-Set::= SET {
+ device INTEGER,
+ name NULL
+}
+
+TEST-Set1 ::= SET {
+ device INTEGER,
+ devices SEQUENCE OF INTEGER,
+ deviceSet SET OF INTEGER
+}
+
+Int ::= INTEGER
+
+OString ::= OCTET STRING (SIZE(0..64))
+
+TEST-SetOfOString ::= SET OF OString
+
+TEST-SetOfInt ::= SET SIZE(1..4) OF Int
+
+END
+
+--
+-- TEST-basic-types-enum
+--
+TEST-basic-types-enum {iso(1) identified-organization(3) 8}
+DEFINITIONS ::=
+BEGIN
+
+TEST-Enum::= ENUMERATED {
+ null(0),
+ one(1),
+ two(2)
+}
+
+TEST-SeqEnum ::= SEQUENCE {
+ enum1 TEST-Enum,
+ enum2 ENUMERATED { no(0), yes(1)},
+ enum3 ENUMERATED {true } OPTIONAL
+}
+
+Presence ::= ENUMERATED {optional,conditional,mandatory}
+
+Criticality::= ENUMERATED {reject,ignore,notify}
+END
+
+--
+-- TEST-basic-types-tagged
+--
+TEST-basic-types-tagged {iso(1) identified-organization(3) 9}
+DEFINITIONS ::=
+BEGIN
+
+Int ::= [APPLICATION 3] INTEGER
+IntELT72 ::= [APPLICATION 72] INTEGER (0..255)
+
+SeqE ::= [APPLICATION 2] EXPLICIT SEQUENCE {
+ one INTEGER,
+ nu NULL
+}
+
+SeqE1 ::= [APPLICATION 4] EXPLICIT SEQUENCE {
+ one Int,
+ nu NULL
+}
+
+IntI ::= [APPLICATION 21] IMPLICIT INTEGER
+OctI ::= [APPLICATION 22] IMPLICIT OCTET STRING
+IntILT62 ::= [APPLICATION 62] IMPLICIT INTEGER
+IntILT432 ::= [APPLICATION 432] IMPLICIT INTEGER
+
+
+SeqI ::= [APPLICATION 5] IMPLICIT SEQUENCE {
+ one IntI,
+ two OctI
+}
+
+SeqI1 ::= [APPLICATION 6] IMPLICIT SEQUENCE {
+ one Int,
+ nu NULL
+}
+
+SeqP ::= [APPLICATION 5] SEQUENCE {
+ seq [APPLICATION 10] SEQUENCE {
+ one INTEGER,
+ two BOOLEAN
+ },
+ nu NULL
+}
+
+
+
+Choice ::= [APPLICATION 4] CHOICE {
+ one [APPLICATION 0] IMPLICIT INTEGER,
+ nu NULL,
+ seqe SeqE
+}
+
+InSeq ::= SEQUENCE {
+ one [0 ] INTEGER,
+ nu Int
+}
+
+TSetE ::= [APPLICATION 4] SET {
+ one INTEGER,
+ nu NULL
+}
+
+TSetI ::= [APPLICATION 6] IMPLICIT SET {
+ one INTEGER,
+ nu NULL
+}
+END
+
+
+
+--
+-- TEST-private-types-choice
+--
+TEST-private-types-choice {iso(1) identified-organization(3) 10}
+DEFINITIONS ::=
+BEGIN
+
+TEST-Sequence::= SEQUENCE {
+ device CHOICE {
+ len INTEGER,
+ number [0] IMPLICIT INTEGER
+ },
+ name NULL
+}
+
+TEST-SeqChoiceSeq ::= SEQUENCE {
+ v CHOICE {
+ s1 [0] IMPLICIT SEQUENCE {
+ name VisibleString,
+ n NULL
+ },
+ s2 [1] IMPLICIT SEQUENCE {
+ n NULL,
+ nm VisibleString
+ }
+ -- Does not work yet !!!!
+ ,
+ s3 [2] IMPLICIT SEQUENCE OF SEQUENCE {
+ p GraphicString,
+ pm VisibleString OPTIONAL
+ }
+ }
+}
+
+--
+-- Working on generator to support this case !!!!
+-- Main issue with CHOICE SET. SET does not handle private structure
+-- missing scope
+
+TEST-ChoiceCplx ::= [1] CHOICE {
+ cseq SEQUENCE {
+ s1 INTEGER
+ },
+ cset SET {
+ s2 BOOLEAN,
+ s21 BOOLEAN
+ },
+ cchoice [2] CHOICE {
+ s3 [0] IMPLICIT OCTET STRING,
+ s31 [1] IMPLICIT NULL
+ }
+}
+
+
+END
+
+TEST-private-types-seq-of {iso(1) identified-organization(3) 11}
+DEFINITIONS ::=
+BEGIN
+
+TEST-Sequence::= SEQUENCE {
+ device CHOICE {
+ len INTEGER,
+ number [0] IMPLICIT INTEGER
+ },
+ name NULL
+}
+
+TEST-SeqChoiceSeq ::= SEQUENCE {
+ v CHOICE {
+ s1 [0] IMPLICIT SEQUENCE {
+ name VisibleString,
+ n NULL
+ },
+ s2 [1] IMPLICIT SET OF CHOICE {
+ n NULL,
+ nm VisibleString
+ },
+ s3 [2] IMPLICIT SEQUENCE OF SEQUENCE {
+ p GraphicString,
+ pm VisibleString OPTIONAL
+ }
+ }
+
+
+}
+END
+
+
+--
+-- TEST-basic-types-selection
+--
+TEST-basic-types-selection {iso(1) identified-organization(3) 12}
+DEFINITIONS ::=
+BEGIN
+
+TEST-Selection::= SEQUENCE {
+ -- len nm < TEST-SeqSelectReference ,
+ number [0] IMPLICIT INTEGER,
+ name NULL
+}
+
+TEST-SeqSelectReference ::= CHOICE {
+ name VisibleString,
+ n NULL,
+ s2 [1] BOOLEAN,
+ nm VisibleString
+}
+
+
+END
+
+--
+-- Test optionnal
+--
+TEST-basic-types-optional {iso(1) identified-organization(3) 13}
+DEFINITIONS ::=
+BEGIN
+
+Request ::= SEQUENCE {
+ requestID INTEGER,
+ extention Extension OPTIONAL
+}
+
+ReqDefaultInt ::= SEQUENCE {
+ extID INTEGER DEFAULT 2,
+ nul NULL
+}
+
+ReqDefaultBool ::= SEQUENCE {
+ extID BOOLEAN DEFAULT FALSE,
+ nul NULL
+}
+-- Still bug
+ReqDefaultString ::= SEQUENCE {
+ extID IA5String DEFAULT "james" ,
+ nul NULL
+}
+
+ReqOptInt ::= SEQUENCE {
+ extID INTEGER OPTIONAL,
+ nul NULL
+}
+
+ReqOptBool ::= SEQUENCE {
+ extID BOOLEAN OPTIONAL,
+ nul NULL
+}
+
+ReqOptString ::= SEQUENCE {
+ extID IA5String OPTIONAL,
+ nul NULL
+}
+
+Extension ::= SEQUENCE {
+ extID INTEGER DEFAULT 2,
+ data OCTET STRING,
+ bits BitSTR DEFAULT {bit1} ,
+ boolean BOOLEAN DEFAULT TRUE,
+ toto BitSTR DEFAULT {}
+}
+
+BitSTR ::= BIT STRING {
+ nul(0),
+ bit1(1),
+ bit2(2),
+ bit3(3)
+}
+
+END
+
+
+--
+--- H323 needs parameterized support
+--
+
+--
+-- Simple parametered type
+--
+TEST-type-parameter {iso(1) identified-organization(3) 14}
+DEFINITIONS ::=
+BEGIN
+
+ Aa ::= INTEGER
+--TEST-PSeq{MyType}::= SEQUENCE {
+-- 2017/07/27 Still issue with otag. Suspect that
+-- reparenting does not work with parameterized types
+-- in this case.
+-- device CHOICE {
+-- type [0] MyType,
+-- number [1] IMPLICIT INTEGER
+-- },
+-- name NULL,
+-- simpler MyType
+-- }
+
+-- Call::=TEST-PSeq{INTEGER}
+MyType ::= INTEGER
+END
+
+--
+-- H323 actively uses extensible structures
+--
+TEST-type-extensible {iso(1) identified-organization(3) 15}
+DEFINITIONS ::=
+BEGIN
+
+TEST-ExtendSeq ::= SEQUENCE {
+ device SEQUENCE {
+ type MyType,
+ number [0] IMPLICIT INTEGER,
+ ...
+ },
+ name NULL,
+ ...
+}
+
+TEST-ExtendSeqE ::= SEQUENCE {
+ device SEQUENCE {
+ typeE MyType,
+ numberE [0] IMPLICIT INTEGER,
+ ...
+ },
+ nameE NULL,
+ ... ,
+ add1 BOOLEAN,
+ add2 INTEGER,
+ ...
+}
+
+
+TEST-ExtendChoice ::= CHOICE {
+ c1 INTEGER,
+ c2 SEQUENCE {
+ a1 INTEGER,
+ b1 BOOLEAN
+ },
+ ...
+}
+
+
+MyType ::= INTEGER
+END
+
+--
+-- basic type value constraint
+--
+TEST-basic-type-value-constraint {iso(1) identified-organization(3) 16}
+DEFINITIONS ::=
+BEGIN
+
+ Aa ::= INTEGER
+ Bb::= [1] INTEGER
+ Cc::= [2] INTEGER (0..6,...)
+ Dd::= [2] INTEGER (0..6,...,7)
+ Ee::= INTEGER (7..20)
+
+ Ff::= INTEGER {red(0), white(1), blue(2), green(3), purple(4)}
+ -- Value Assignements !!!!
+ a Aa ::= 3
+ b Bb::= 4
+ c Cc::= 5
+ d Dd::= 6
+ e Ee::= 7
+ f Ff::= green
+ g INTEGER ::= 10
+
+W ::= SEQUENCE {w1 Aa DEFAULT a}
+
+x Aa ::= a
+Y ::= Aa(1..a)
+
+END
+
+--
+-- CSTA needs ROS supports
+--
+
+--
+-- Ros definition
+--
+TEST-rose {iso (1) id(2)}
+DEFINITIONS ::=
+BEGIN
+
+OpCode ::= CHOICE
+{
+ local INTEGER,
+ global OBJECT IDENTIFIER
+}
+
+InvokeId ::= CHOICE {present INTEGER,
+ absent NULL
+}
+
+ERROR ::= CLASS
+{
+ &ErrorCode
+}
+
+OPERATION ::= CLASS
+{
+ &ArgumentType OPTIONAL,
+ &argumentTypeOptional BOOLEAN OPTIONAL,
+ &returnResult BOOLEAN DEFAULT TRUE,
+ &ResultType OPTIONAL,
+ &resultTypeOptional BOOLEAN OPTIONAL,
+ &Errors ERROR OPTIONAL,
+ &Linked OPERATION OPTIONAL,
+ &alwaysReturns BOOLEAN DEFAULT TRUE,
+ &operationCode OpCode UNIQUE OPTIONAL
+}
+WITH SYNTAX
+{
+ [ARGUMENT &ArgumentType [OPTIONAL &argumentTypeOptional]]
+ [RESULT &ResultType [OPTIONAL &resultTypeOptional]]
+ [RETURN RESULT &returnResult]
+ [ERRORS &Errors]
+ [LINKED &Linked]
+ [ALWAYS RESPONDS &alwaysReturns]
+ [CODE &operationCode]
+}
+
+ROS {InvokeId : IdSet , OPERATION : Invokable} ::= CHOICE {
+ invoke [1] Invoke{{IdSet},{Invokable}}
+}
+
+Invoke{InvokeId:InvokeIdSet,OPERATION:Operations,INTEGER:IntegerSet,INTEGER:integerValue} ::= SEQUENCE
+{
+ invokeId InvokeId(InvokeIdSet),
+ invokeI INTEGER(IntegerSet),
+ opcode OPERATION.&operationCode
+}
+END
+
+
+--
+-- Test ROS operation
+--
+TEST-rose-operation {iso (1) id(2) 2}
+DEFINITIONS ::=
+BEGIN
+--IMPORTS OPERATION FROM Remote-Operations-Information-Objects {iso (1)};
+
+InvokeId ::= CHOICE {present INTEGER,
+ absent NULL
+}
+
+Code ::= CHOICE
+{
+ local INTEGER,
+ global OBJECT IDENTIFIER
+}
+
+OpCode ::= CHOICE
+{
+ local INTEGER,
+ global OBJECT IDENTIFIER
+}
+
+Priority ::= INTEGER
+
+OPERATION ::= CLASS
+{
+ &ArgumentType OPTIONAL,
+ &argumentTypeOptional BOOLEAN OPTIONAL,
+ &returnResult BOOLEAN DEFAULT TRUE,
+ &ResultType OPTIONAL,
+ &resultTypeOptional BOOLEAN OPTIONAL,
+ &Errors ERROR OPTIONAL,
+ &Linked OPERATION OPTIONAL,
+ &alwaysReturns BOOLEAN DEFAULT TRUE,
+ &operationCode OpCode UNIQUE OPTIONAL
+}
+WITH SYNTAX
+{
+ [ARGUMENT &ArgumentType [OPTIONAL &argumentTypeOptional]]
+ [RESULT &ResultType [OPTIONAL &resultTypeOptional]]
+ [RETURN RESULT &returnResult]
+ [ERRORS &Errors]
+ [LINKED &Linked]
+ [ALWAYS RESPONDS &alwaysReturns]
+ [CODE &operationCode]
+}
+ERROR ::= CLASS
+{
+ &ParameterType OPTIONAL,
+ ¶meterTypeOptional BOOLEAN OPTIONAL,
+ &ErrorPriority Priority OPTIONAL,
+ &errorCode Code UNIQUE OPTIONAL
+}
+WITH SYNTAX
+{
+ [PARAMETER &ParameterType [OPTIONAL ¶meterTypeOptional]]
+ [PRIORITY &ErrorPriority]
+ [CODE &errorCode]
+}
+
+
+Invoke{InvokeId:InvokeIdSet,OPERATION:Operations,INTEGER:IntegerSet,INTEGER:integerValue} ::= SEQUENCE
+{
+ invokeId InvokeId(InvokeIdSet),
+ invokeI INTEGER(IntegerSet),
+ opcode OPERATION.&operationCode
+}
+
+eventReport OPERATION ::=
+{
+ ARGUMENT EventReportArgument
+ ALWAYS RESPONDS FALSE
+ CODE local:12
+}
+
+makeCall OPERATION ::=
+{
+ ARGUMENT MakeCallArgument
+ RESULT MakeCallResult
+ ERRORS {failures}
+ CODE local:13
+}
+
+
+EventReportArgument ::= SEQUENCE {
+ test INTEGER,
+ spec BOOLEAN
+}
+
+MakeCallArgument ::= SEQUENCE {
+ deviceID INTEGER
+}
+
+MakeCallResult ::= SEQUENCE {
+ ok BOOLEAN OPTIONAL
+}
+
+failures ERROR ::= {
+ PARAMETER LocalFailures
+ CODE local:1
+}
+
+LocalFailures ::=CHOICE {
+ num INTEGER
+}
+END
+
+--
+-- Test ValueSet
+--
+TEST-value-set {iso (1) id(2) 3}
+DEFINITIONS ::=
+BEGIN
+IMPORTS OPERATION FROM Remote-Operations-Information-Objects {iso (1) 2 2};
+
+ValueSet INTEGER ::= { 1 | 2 | 3 }
+
+ObjectValueSet OPERATION ::= { op1 | op2 | op3 }
+
+
+END
+
+
+--
+-- Test Container
+--
+TEST-container {iso (1) id(2) 4}
+DEFINITIONS ::=
+BEGIN
+IMPORTS OPERATION FROM Remote-Operations-Information-Objects {iso (1) 2 2};
+
+Counter ::= INTEGER(0..65535)
+
+TEST-CALL ::= CLASS {
+ &id Counter UNIQUE,
+ &Value
+} WITH SYNTAX {
+ ID &id
+ TYPE &Value
+}
+
+ValueSet INTEGER ::= { 1 | 2 | 3 }
+
+MySeq ::= SEQUENCE {
+ is INTEGER,
+ vals Proto-Container { {ObjectValueSet } },
+ -- vals Proto-Container ( { {ObjectValueSet } }),
+ ...
+}
+
+
+ObjectValueSet TEST-CALL ::= { {ID 1 TYPE INTEGER}| {ID 2 TYPE BOOLEAN} | { ID 3 TYPE Counter} }
+
+Proto-Container {TEST-CALL : CallSet } ::= SEQUENCE OF Proto-Field {{CallSet}}
+
+Proto-Field { TEST-CALL : CallSet } ::= SEQUENCE{
+ id TEST-CALL.&id ({CallSet}),
+ value TEST-CALL.&Value({CallSet}{@id})
+}
+
+END
+
+