esnacc-ng-1.8.1/000077500000000000000000000000001302010526100133455ustar00rootroot00000000000000esnacc-ng-1.8.1/.gitignore000066400000000000000000000010661302010526100153400ustar00rootroot00000000000000#*# *.a *.d *.gcno *.gcda *.ko *.la *.lo *.loT *.mod.c *.o *.obj *.exe *~ *.Tpo *.so *.tar.gz *.cdbs-config_list config.guess.cdbs-orig config.h config.h.in config.sub.cdbs-orig ylwrap /Makefile /Makefile.in /aclocal.m4 /compile /config.guess /config.h /config.h.in /config.log /config.status /config.sub /configure /configure-stamp /depcomp /distfiles /dist-docs /install-sh /libtool /manpage-check /missing /missing-distfiles /package.m4 /stamp-h1 /ltmain.sh /ar-lib /autom4te.cache /GPATH /GRTAGS /GTAGS /test-driver /rpm pr.ber test-suite.log *.info *-coverage/ esnacc-ng-1.8.1/.travis.yml000066400000000000000000000024431302010526100154610ustar00rootroot00000000000000language: c os: - linux - osx compiler: - gcc - clang env: global: # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created # via the "travis encrypt" command using the project repo's public key - secure: "GcsLxtnsY96G7Fnrd0q4hTHRn8SBKz/rZskrI/YwwuIsUT1WiCHU2sqklaq7eD+mbVndpN53dwRtrtRKK+U4rhFZN5Nwdpha6RDEppDJXS0IwXbBRVNzX6DQ/iMWjwj/oyKYshUIq6wsJUYcG67/9iMYX1J3BrVII6o1MHm4xPpVfkcOy4XmQrBD1IBaQY+TrcExnV86giJfLhJjeD/MvQ8MYGY4S1ET9y1uRfCj9r06d64aOVRsGYqyqgRB+qTS9bjC4t0C/xkCk90LXSLkGqQ95MoHGK4byD5uExWb6+Px4RW/Rad0gjbBOwlszLxTqdF23eeLpyhNFaWBlpVMKOyKpWl8m31/t1HPO74ytXCXNVhx2FRodHMZg3Bj1zOuJs8PSARiu038T53qUHeGDQLGY0Ph8T2JdvPAgNpV+y7lK5Owk/G6nUabnDLwsHHuNWTk2mk6dr2reoZOdQF+dvzS2RaHGATwThd3HIZ1rLZo0ZQg7olbf4WB8QZorjtTA4xCF3MLAGJl6iSrhCY6pmdPsnYldaOpGcoo+29sBdjZHvSBPg8iBmgzowKSRennUNy4WqIj0JSW8/6lk/WnZLLb0Mf50LGYEhdJPkjks2UPlvSkZwTfHLtcHB5RxEyxi5msKi33EG6osgf68CCj6enx1kFQ1TtxjrqIvllLtwM=" addons: apt: packages: - xsltproc coverity_scan: project: name: "orgcandman/esnacc-ng" description: "ASN.1 compiler to C/C++" notification_email: aconole@bytheb.org build_command_prepend: "./boot.sh && ./configure" build_command: "make" branch_pattern: coverity script: - ./boot.sh - ./configure - make - make distcheck esnacc-ng-1.8.1/CONDUCT.md000066400000000000000000000103461302010526100147720ustar00rootroot00000000000000esnacc-ng Code of Conduct ========================= The esnacc-ng project is made up of many thousands of users (knowingly and unknowingly), and worked on by a number of developers. These people fall all along the spectrum of professional to volunteer, and come from all over the world. Diversity is a great strength, and the esnacc-ng project is lucky to have a large and diverse set of contributors of all manner of technical strengths. However, when such a diverse group of people works together there are bound to be communication issues. To keep all communications useful and productive, it is important that we establish some ground rules for community participation. These rules apply to *everyone*. This list is not meant to be exhaustive or comprehensive enumeration of every action that is or isn't acceptable. The overriding rule is always, "be reasonable, and understand that a human is at the other end." This list applies to all of the esnacc-ng communcation mediums, be they IRC, mailing lists, git commit messages, code, code comments, bug database entries, and any other area where esnacc-ng folks are communicating. If you believe someone is violating the code of conduct, please report it immediately to conduct@esnacc.org. If you believe someone is in immediate physical danger, it is important that you contact law enforcement before involving the esnacc-ng community. Good Ideas ---------- * DO be friendly and patient. Not everyone is as familiar with the technologies. We were all new, once. * DO be welcoming and inclusive. We want to be a community that benefits from the old addage of diversity breeding strength. The more diverse our views, the more effective we can be. * DO be considerate. We all have rushing deadlines, and important features to provide. Our work builds on the work of others. And others work builds on our work. However, we will not succeed if we blindly push ahead with poorly planned or thought out features. We are all communicating in English, but it may not be our primary language. * DO be respectful. No two people can be in agreement 100% of the time. This is just a fact of human nature. It is NEVER acceptable to turn disagreement into personal attacks. It is important to remember that when people feel threatened or afraid they stop contributing. It is important that we always let people feel respected, and safe when dealing with members of the community. * DO be careful with words. ASN.1 is typically a tool for industry professionals. As such, we have a higher concentration of professionals who contribute. It is expected that all contributors behave "professionally" at all times. This does not mean that every idea or contribution will be desirable or should be accepted. It DOES mean that when an idea is a failing one, we calmly and respectfully explain such and move on. Insults, put downs, and other exclusionary behavior aren't acceptable. This includes, but is not limited to violent threats, offensive language directed at an individual, discriminatory jokes, sexually explicit material, violent material, unwelcome sexual attention, advocating any of the above behavior. Do not's -------- * DO NOT assume that the person on the other end speaks english natively. Words that might not make sense, and words which are inflammatory in one culture, are not so in another. If a particular word choice is not understandable, ask for clarification before assuming any offense was meant. * DO NOT insult or threaten any individual. Sometimes patches contain code which has a quite foul odor [1]. It is okay to tell someone that their code cannot be accepted for technical reasons. It is NEVER okay to personally insult someone because of their submission. * DO NOT post or publish materials "you wouldn't want your mother to see." This means if you be ashamed of your post if someone read it, you probably shouldn't post it. Questions --------- Don't hesitate to ask for any clarification of the above. The goal is to encourage additional participation in the development of esnacc-ng. This document was partially derived from the Django Code of Conduct [2]. 1: https://en.wikipedia.org/wiki/Code_smell 2: https://www.djangoproject.com/conduct/ esnacc-ng-1.8.1/CONTRIBUTING.md000066400000000000000000000143061302010526100156020ustar00rootroot00000000000000How to submit patches ===================== eSNACC has a development email list hosted at dev@lists.esnacc.org and the archives can be found at http://mail.esnacc.org/mailman/listinfo/dev Send patch changes as emails to the development mailing list; one patch per email, please. If you are using git, then `git format-patch` does most of the work described below for you. Before you start ---------------- Before you send patches, make sure that each patch makes sense. This means that your patch should: - Not break anything. The best way to check this is to make a clean build with your patch applied; run the various scripts included and ensure that nothing crashes. (This is a good first order test) - Make one concise, logical change. Avoid grouping lots of unrelated changes together. - Update any documentation when new features are added. Testing your patch is important. To that end, always run at least `make check` before submitting a patch. The best thing to do is use `./configure --enable-code-coverage` followed by `make check-code-coverage`, and ensure that the code you are posting has been tested. Email Subject ------------- The subject line of your email should be in the following format: `[TYPE /] FOO: ` - TYPE specifies the kind of change you are posting. The type "RFC" indicates a patch which is a "Request For Comments," and will never be applied to the tree. "PATCH" is the normal type of a changeset, which if accepted will be applied to the tree. - `/` indicates that this is the nth of a series of m changesets. It helps reviewers to read patches in the correct order. You may omit this prefix if you are sending only one changeset. - FOO should either be a broad area of esnacc (compiler, documentation, automake, etc.), or a specific file. - `` briefly describes the change. The subject, minus the `[TYPE /]` prefix, becomes the first line of the commit's change log message. Description ----------- The body of the email should start with a more thorough description of the change. This becomes the body of the commit message, following the subject. There is no need to duplicate the summary given in the subject. Please limit lines in the description to no more than 79 characters in width. The description should include: - The rationale for the change. - Design description and rationale (but this might be better added as code comments). - Testing that you performed (or testing that should be done but you could not for whatever reason). - Tags (see below). There is no need to describe what the patch actually changed, if the reader can see it for himself. Developer's Certificate of Origin --------------------------------- To help track the author of a patch as well as the submission chain, and be clear that the developer has authority to submit a patch for inclusion in Enhanced SNACC please sign off your work. The sign off certifies the following: Developer's Certificate of Origin 1.1 By making a contribution to this project, I certify that: (a) The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or (b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it. (d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved. Patch Signing Tags ------------------ The *Signed-off-by* tag indicates that you were directly involved in the generation of this patch, either by producing the code, or by influencing it heavily. Signing off on a change indicates that you take direct responsibility for that change. The *Acked-by* tag indicates that you acknowledge the change. It indicates that you have read the change, understood it, and believe it to be acceptable for inclusion in the development tree. Acknowledgement usually implies that you have done a cursory build with the patch. The *Reviewed-by* tag means is the same as the *Acked-by* but does not imply you have built the change. The *Tested-by* tag indicates anyone who has applied the code change to their tree, compiled with the change, and executed the functionality being manipulated. The *Reported-by* tag indicates a user that was responsible for reporting a bug in the code. Comments -------- If you want to include any comments in your email that should not be part of the commit's change log message, put them after the description, separated by a line that contains just `---`. It may be helpful to include a diffstat here for changes that touch multiple files. Patch ----- The patch should be in the body of the email following the description, separated by a blank line. Patches should be in `diff -up` format. We recommend that you use Git to produce your patches, in which case you should use the `-M -C` options to `git diff` (or other Git tools) if your patch renames or copies files. Quilt (http://savannah.nongnu.org/projects/quilt) might be useful if you do not want to use Git. Patches should be inline in the email message. Some email clients corrupt white space or wrap lines in patches. There are hints on how to configure many email clients to avoid this problem at: http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob_plain;f=Documentation/email-clients.txt If you cannot convince your email client not to mangle patches, then sending the patch as an attachment is a second choice. esnacc-ng-1.8.1/INSTALL.md000066400000000000000000000216331302010526100150020ustar00rootroot00000000000000How to install Enhanced Sample Neufeld ASN.1 C Compiler ======================================================= This document describes the process for building and installing the esnacc package, generically, on any system which has autotools support, and the appropriate C and C++ compilers. Build Requirements ------------------ To compile the software for the Enhanced Sample Neufeld ASN.1 C Compiler, you will need: - GNU Make - Supported C and C++ compilers * Clang * GCC 4.x and GCC 5.x * MSVC 2013 While esnacc may build with other C and C++ compilers, the ones listed above are tested more thoroughly. It is therefore recommended to use one of the compilers listed above. - flex, or lex - bison, or yacc If you are working from a Git tree or snapshot (instead of from a distribution tarball), or if you modify the esnacc build system you will also need the following software: - Autoconf version 2.63 or later. - Automake version 1.10 or later. - libtool version 2.4 or later. (Older versions might work too.) Building and Installing Enhanced Sample Neufeld ASN.1 C Compiler ================================================================ Once you have installed all the prerequisites listed above, you may follow the procedure below to build the configuration and build systems. Bootstrapping the sources ------------------------- This step is not needed if you have downloaded a released tarball. If you pulled the sources directly from the esnacc Git tree or got a Git tree snapshot, then run boot.sh in the top source directory to build the "configure" script. `% ./boot.sh` Configuring the Sources ----------------------- Configure the package by running the configure script. You can usually invoke configure without any arguments. For example: `% ./configure` By default all files are installed under /usr/local. esnacc also expects to place header files under /usr/local/include/c-lib/inc and /usr/local/include/cxx-lib/inc by default. If you want to install files under /usr instead (for example), then add options as shown below: `% ./configure --prefix=/usr` Note that distributions which ship esnacc will be using the various options to configure the various binary directories. By default, static libraries are built and linked against. If you want to use shared libraries instead: `% ./configure --enable-shared` To use a specific C compiler for compiling the esnacc software, also specify it on the configure command line, like so: `% ./configure CC=specific-c-compiler` To use a specific C++ compiler for compiling the esnacc software, specify it on the configure command line, like so: `% ./configure CXX=specific-cxx-compiler` These options may be combined, for example: `% ./configure CC=specific-c-compiler CXX=specific-cxx-compiler` To supply special flags to the C compiler, specify them as CFLAGS on the configure command line. If you want the default CFLAGS, which include "-g" to build debug symbols and "-O2" to enable optimizations, you must include them yourself. For example, to build with the default CFLAGS plus "-mssse3", you might run configure as follows: `% ./configure CFLAGS="-g -O2 -mssse3"` Similarly, to configure the C++ flags, customize the CXXFLAGS variable as follows: `% ./configure CXXFLAGS="-g -O2 -mssse3"` These variables may be combined, as with the CC and CXX variables. The configure script accepts a number of other options and honors additional environment variables. For a full list, invoke configure with the --help option. You can also run configure from a separate build directory. This is helpful if you want to build esnacc in more than one way from a single source directory, e.g. to try out both GCC and Clang compilers. Here is an example: `% mkdir _gcc && (cd _gcc && ../configure CC=gcc)` `% mkdir _clang && (cd _clang && ../configure CC=clang)` Building the Sources -------------------- 1. Run GNU make in the build directory, e.g.: `% make` or if GNU make is installed as "gmake": `% gmake` If you used a separate build directory, run make or gmake from that directory, e.g.: `% make -C _gcc` `% make -C _clang` Some versions of Clang and ccache are not completely compatible. If you see unusual warnings when you use both together, consider disabling ccache for use with Clang. 2. Consider running the testsuite. Refer to "Running the Testsuite" below, for instructions. 3. Become root by running "su" or another program. 4. Run "make install" to install the executables and manpages into the running system, by default under /usr/local. Packages ======== You can install the esnacc Debian package from Debian on Stretch and later releases: `apt-get install esnacc libesnacc-dev` All binary packages generated from esnacc source are listed here: https://tracker.debian.org/pkg/esnacc esnacc includes a Debian compatible rules set, which can be used to generate appropriate .deb files for installation on any Debian or Debian-derived system (such as Ubuntu). In order to build these packages, it is required that all prerequisites listed are installed. This can be done using the `apt-get` and `dpkg` utilities. For all builds, you must install at least the "cdbs," "build-essential," "dh-autoreconf," and "fakeroot" packages. This can be done, e.g. with: `apt-get install build-essential cdbs dh-autoreconf fakeroot` It is then necessary to install all of the packages listed in the Build-Depends line in the debian/control file. You can install these similarly e.g. with `apt-get install`. Check that you have installed all prerequisites by running `dpkg-checkbuilddeps` from the top-level of the esnacc directory. If everything is installed correctly, dpkg-checkbuilddeps will exit without printing an error message. If you are missing any dependencies, they will be listed. To build the packages, run `fakeroot debian/rules binary` from the top-level esnacc directory. This will do a build, including executing the targets of `make check`, and produce a number of .deb files in the parent directory. To install these built packages, use `dpkg -i`. Testsuites ========== This section describe esnacc's built-in support for various test suites. You must bootstrap, configure and build esnacc (steps are in "Building and Installing Enhanced Sample Neufeld ASN.1 C Compiler" above) before you run the tests described here. You do not need to install esnacc in order to run these test suites. You do not need supervisor privilege to run these test suites. Self-Tests ---------- esnacc includes a suite of self-tests. Before you submit patches upstream, we advise that you run the tests and ensure that they pass. If you add new features to esnacc, then adding tests for those features will ensure your features don't break as developers modify other areas. Refer to "Testsuites" above for prerequisites. To run all the unit tests in esnacc, one at a time: `make check` Continuous Integration with Travis-CI and AppVeyor -------------------------------------------------- A .travis.yml file is provided to automatically build esnacc with various build configurations and run the testsuite using travis-ci. Builds will be performed with gcc, and clang for linux, as well as Mac OS X. Additionally, an appveyor.yml file is provided to ensure builds under the Microsoft Windows operating system. The CI build is triggered via git push (regardless of the specific branch) or pull request against any esnacc GitHub repository that is linked to travis-ci. Instructions to setup travis-ci for your GitHub repository: 1. Go to http://travis-ci.org/ and sign in using your GitHub ID. 2. Go to the "Repositories" tab and enable the ovs repository. You may disable builds for pushes or pull requests. 3. In order to avoid forks sending build failures to the upstream mailing list, the notification email recipient is encrypted. If you want to receive email notification for build failures, replace the the encrypted string: 3.1) Install the travis-ci CLI (Requires ruby >=2.0): gem install travis 3.2) In your esnacc-ng repository: travis encrypt mylist@mydomain.org 3.3) Add/replace the notifications section in .travis.yml and fill in the secure string as returned by travis encrypt: notifications: email: recipients: - secure: "....." (You may remove/omit the notifications section to fall back to default notification behaviour which is to send an email directly to the author and committer of the failing commit. Note that the email is only sent if the author/committer have commit rights for the particular GitHub repository). 4. Pushing a commit to the repository which breaks the build or the testsuite will now trigger a email sent to mylist@mydomain.org Bugs ==== Please report bugs to [the esnacc github repository](https://github.com/esnacc/esnacc-ng). esnacc-ng-1.8.1/Makefile.am000066400000000000000000000063531302010526100154100ustar00rootroot00000000000000# Copyright (C) 2016, Aaron Conole # # Licensed under the GNU General Public License v2 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at: # # http://www.gnu.org/licenses/old-licenses/gpl-2.0.html # # Please note, this may NOT be relicensed under any version of the # GNU General Public License, other than the one specified. # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ACLOCAL_AMFLAGS = -I m4 AM_CFLAGS = -Wstrict-prototypes -Wall AM_CFLAGS += $(WARNING_FLAGS) ALL_LOCAL = BUILT_SOURCES = CLEANFILES = CLEAN_LOCAL = DISTCLEANFILES = TESTS = docs = \ README.md \ licenseq.txt \ INSTALL.md \ NEWS \ copying EXTRA_DIST = \ $(docs) \ .travis.yml \ scan_script.sh \ doc/PERCompilerRequirementsMatrix.doc \ doc/eSNACCManuals.zip bin_PROGRAMS = sbin_PROGRAMS = bin_SCRIPTS = DIST_HOOKS = dist_man_MANS = dist_pkgdata_DATA = dist_pkgdata_SCRIPTS = dist_sbin_SCRIPTS = dist_scripts_SCRIPTS = dist_scripts_DATA = INSTALL_DATA_LOCAL = UNINSTALL_LOCAL = man_MANS = MAN_FRAGMENTS = MAN_ROOTS = noinst_DATA = noinst_HEADERS = nobase_include_HEADERS = snacc.h policy.h lib_LTLIBRARIES = noinst_man_MANS = noinst_PROGRAMS = noinst_SCRIPTS = pkgdata_DATA = sbin_SCRIPTS = scripts_SCRIPTS = completion_SCRIPTS = scripts_DATA = SUFFIXES = check_DATA = check_SCRIPTS = pkgconfig_DATA = FLAKE8_PYFILES = check_PROGRAMS = all_lib_LDFLAGS = \ -version-info $(LT_VERSION_INTF) scriptsdir = $(pkgdatadir)/scripts completiondir = $(sysconfdir)/bash_completion.d pkgconfigdir = $(libdir)/pkgconfig @CODE_COVERAGE_RULES@ # This ensures that files added to EXTRA_DIST are always distributed, # even if they are inside an Automake if...endif conditional block that is # disabled by some particular "configure" run. For more information, see: # http://article.gmane.org/gmane.comp.sysutils.automake.general/10891 noinst_HEADERS += $(EXTRA_DIST) .asn1.c: compiler/esnacc -c -mo `dirname $@` $< .asn1.cpp: compiler/esnacc -C -mo `dirname $@` $< SUFFIXES += .in .in: $(AM_V_GEN)$(SED) \ -e 's,[@]VERSION[@],$(VERSION),g' \ -e 's,[@]localstatedir[@],$(localstatedir),g' \ -e 's,[@]pkgdatadir[@],$(pkgdatadir),g' \ -e 's,[@]sysconfdir[@],$(sysconfdir),g' \ -e 's,[@]bindir[@],$(bindir),g' \ -e 's,[@]sbindir[@],$(sbindir),g' \ -e 's,[@]abs_builddir[@],$(abs_builddir),g' \ -e 's,[@]abs_top_srcdir[@],$(abs_top_srcdir),g' \ -e 's,[@]prefix[@],$(prefix),g' \ -e 's,[@]exec_prefix[@],$(exec_prefix),g' \ -e 's,[@]libdir[@],$(libdir),g' \ -e 's,[@]includedir[@],$(includedir),g' \ $< > $@ include c-lib/automake.mk include cxx-lib/automake.mk include compiler/automake.mk include c-examples/automake.mk include cxx-examples/automake.mk # This file is excluded from distribution on releases. # include debian/automake.mk include redhat/automake.mk esnacc-ng-1.8.1/NEWS000066400000000000000000000141511302010526100140460ustar00rootroot000000000000001.8.1 ----- * Bugfixes 1.80 ---- * Restarting full eSnacc support with eSnacc NG * Converted to modern automake * All c++ libraries have been renamed to cxx * Fixed minbuf to follow the GenBuf abstraction * Fixed GenBuf prototype * Moved GenBuf macros to static inline functions * Added support for modern style CONTAINs/SIZEs * Fixed default value generation code for the C++ backend. * Added experimental AUTOMATIC tags support ======================================================================= main changes between versions 1.1 and 1.2: * ports to linux and alpha, which should make snacc both endianess and 64 bit clean. * to complement the destructors, T::T (const T&) and T &T::operator = (const T &) have been added to override the defaults supplied by the compiler. reason: simple pointer duplication may lead to unreferenced objects and to objects referenced more than once (on which the destructors delete may choke). * the files asn_useful.[hcC] and tbl.[ch] get regenerated automagically. since the compiler itself is compiled with it, a bootstapping version is included in the distribution. * the choice selector and all pointer members get initialized to get predictable behaviour from the destructors (C++ code only, the C code may still be broken!). * turned C++ inline functions into normal functions. this can reduce the size of .o files and executables dramatically! (the change was partially made by IBM ENC.) * the c++ lib compiles under gcc 2.6 (which has the bool type built-in). * GNU autoconf support added. * makefiles rewritten to provide the usual phony targets. * code duplication (4 config files, 3 c_libs) reduced. * C++ destructors added (partially contributed by IBM ENC). ======================================================================= Snacc Changes from version 1.0 to 1.1 Thanks to many bug reports from users of snacc 1.0, snacc 1.1 is more reliable. Most of the changes between 1.0 and 1.1 are listed in the "1.0-to-1.1-changes" file. Type tables are the biggest addition. The rest were mostly bug fixes. If you reported a bug and you don't see the fix, I either didn't have time or simply forgot. Sorry. See README.future for the status of snacc now that I have graduated. The remainder of this file contains descriptions of many of the fixes between version 1.0 and 1.1. I am sure there are fixes that are not documented here. ======================================================================= The GNU Library Public License (LGPL) has been punted. ======================================================================= Added table generation the compiler files: src/{ tbl.c tbl.h gen_tbls.c } ======================================================================= Added table libraries and tools files: tbl_include/* tbl_lib/* tbl_tools/* tbl_example/* ======================================================================= Re-aligned data structure for parse tree with code generated by newer version of snacc (yes, the parse tree was originally defined in ASN.1 - see asn1specs/asn1module.asn1) ======================================================================= defined T61String and ISO646String Tag codes. files: snacc/c_inlcude/asn_tag.h and snacc/c++_inlcude/asn_tag.h #define TT61STRING_TAG_CODE TELETEXSTRING_TAG_CODE #define ISO646STRING_TAG_CODE VISIBLESTRING_TAG_CODE ======================================================================= Named arcs in OBJECT IDENTIFER values no longer generate ASN.1 integers. e.g. test OBJECT IDENTIFIER ::={2 3 4 ds(5) 1} used to be equivalent to: ds INTEGER ::= 5 test OBJECT IDENTIFER ::= {2 3 4 ds 1} Snacc now ignores the name (ds in this case). Ideally the arc could be entered into an object identifier tree maintained by snacc. files: snacc/src/val_parser.c ======================================================================= Fixed bug in macro definition parsing that threw off the line number global. file: asn1.lex ======================================================================= Added file and line number information to import errors. A lineNo field was added to the ImportElmt and ImportModule data structures. The yacc code for the import elements & modules sets the lineNo values correctly. The error reporting code in line_types.c and line_values.c now prints the line number info. files: link_types.c link_values.c asn1module.h asn1.yacc ======================================================================= Added some line number info to multiply defined symbol error reports file: err_chk.c - uses importElmt line number info ======================================================================= Added line number info to export errors. ======================================================================= Added file and line number info to typing errors for OBJECT IDENTIFIER values. Also stopped errors that cascade from other OID values referencing a malformed oid value. file: normalize.c ======================================================================= Error messages will be printed for recursively defined OBJECT IDENTIIFER values. file: link_values.c ======================================================================= Fixed bug #20. ie Not grabbing EOC on tagged (by def or in parent) CHOICEs embedded in other SET, SEQ, CHOICE, SET OF or SEQ OF types. file: gen_c_dec.c ======================================================================= Fixed bug #21. ie Value linking problem when assigning a value to a choice with a named number from one of the choice's elmts. file: link_values.c, snacc_util.c (added routine "GetAllNamedElmts") ======================================================================= Fixed bug #22 - potentially not allocating enough space for a C++ field name conflict file: snacc/src/back_ends/c++_gen/cpp_types.c ======================================================================= Fixed nibble alloc bug. curr pointer could be incremened past end ptr which then caused problems with new allocs. file: c_lib/nibble_alloc.c tbl_lib/nibble_alloc.c ======================================================================= esnacc-ng-1.8.1/README.md000066400000000000000000000222531302010526100146300ustar00rootroot00000000000000Enhanced Sample Neufeld ASN C Compiler ======================================= Build Status ------------ [![Travis Build Status](https://travis-ci.org/esnacc/esnacc-ng.png)](https://travis-ci.org/esnacc/esnacc-ng) [![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/github/azsnacc/esnacc-ng?branch=master&svg=true)](https://ci.appveyor.com/api/projects/status/github/azsnacc/esnacc-ng?branch=master) What is eSNACC -------------- This package originally provided the C/yacc/lex source code for snacc, an ASN.1 to C or C++ compiler. Snacc is short for "Sample Neufeld Asn.1 to C Compiler" and ASN.1 stands for Abstract Syntax Notation One (CCITT X.208/ ISO 8824). See the COPYRIGHT file for copyright information. eSNACC is an enhanced version of the Sample Neufeld ASN C Compiler. It supports BER, DER, and PER rulesets for C and C++ code generation. There is experimental support for TCL. eSNACC takes ASN.1 code files, parses them, and outputs appropriate header and source files for inclusion in a larger project. eSNACC is licensed under two different liceses. The compiler itself is a GPLv2+ licensed software; the version maintained here will continue to be GPLv2, unless a compelling reason to switch presents itself. The runtime is a much less restrictive license - it is considered as Public Domain code. So if you wish to contribute, be sure that you understand any runtime changes you contribute MUST be public domain for inclusion into this distribution. Any compiler changes MUST be GPL, at least v2. Building eSNACC --------------- The following represents a very quick start guide to building the esnacc codebase. For more detailed instructions, see [INSTALL.md] First, run the './boot.sh' script, to generate the appropriate configure scripts. Next, run './configure' passing in the appropriate options. Finally, run 'make' to build. 'make install' will put the binaries and library data in the appropriate places. Note: release and debug versions use the same library names. If you want to be a debug version you must make sure you are working with a clean source tree. Same goes for building a release version after building a debug version. Running eSNACC -------------- Given an ASN.1 source file(s) esnacc can produce: 1. C routines for BER encoding, decoding, printing and freeing. 2. C++ routines for BER encoding, decoding, and printing. 3. A type table that can be used with C driver routines for BER encoding, decoding, printing and freeing. 4. if you are really lucky, a core dump! :) esnacc tries to produce reasonably efficient C or C++ routines and data structures to support BER encoding and decoding values of the given ASN.1 data structures. Printing routines for the decoded values are also generated. For C only, hierarchical freeing routines are generated (but are not recommended for efficiency reasons). When using the C or C++ (not table) options, esnacc creates the following C files for each ASN.1 source file (module): 1. .h file for the C/C++ translation of the ASN.1 data structure and prototypes for the generated routines. 2. .c/.cpp file for the C/C++ encode, decode, print and free routines. When using the table option, snacc produces a type table file (a BER encoding) that can later be loaded at runtime by the table driven encoding and decoding routines. FUTURE ENCHANCEMENTS -------------------- * Support for 1997 ASN.1 syntax * Change ANY tables so that each ASN.1 module is responsible for removing the ANYs they install in the table. PER FUTURE ENHANCEMENTS ----------------------- * PER 'C' code generation * Recognition and handling of extensibility CHANGE LOG ---------- New in 1.8: * After years of dust accumulating, eSNACC is re-maintained. New in 1.7: * Enchancements to C++ runtime: * Support of constraints checking for BER/PER * Added Asn-Relative-Oid's * Updated Asn-Oid to be inherited from Asn-Relative-Oid * Added Extensibility to the set/sequence/choice syntax (BER encoding/decoding only, PER is not yet supported) * asn::list has been changed to std::list (many changes) * non-optional set/sequence/choice elements are no longer generated as pointers * PER encode/decode capability for both aligned and unaligned variants (see PER beta notes below) * Enchancements to C runtime: * Added useful types * Added Asn-Relative-Oid's * Enhancements to compiler * eSNACC no longer supports un-named types (2002 syntax update) * added -b compiler option to turn on/off PER encoding/decoding function generation in set/sequence/choice (Note -- calling PEnc/PDec will still work, but will not produce correct encoding unless -b is used!!) New in EKMS PER Beta (Packed Encoding Rules): * Aligned and unaligned PER variants (C++ only) * Limited constraint checking and PER encoding for PER visible constraints * Supported * char Stringtypes * Integer * Octet String * Bit String * Sequence-of / Set-of (limited) * Currently Unsupported * wide char stringtypes * extensibility in constraints New in 1.6Beta: * Updated "C" library to automatically handle ANY load/unloads as buffers. * Added interpretation of ASN.1 integer constants as values in tag references for "C" and C++. * Added "--snacc namespace: " pre-processor feature for unique C++ ASn.1 module namespace references. * Updated SNACC document (in the ./SNACC/doc directory) to present DigitalNet updates/enhancements. * Updated c++-examples and c-examples to demontrate recent features. New in 1.5: * Updated "C" library to automatically handle ANY load/unloads as buffers. * Added interpretation of ASN.1 integer constants as values in tag references for "C" and C++. * Added "--snacc namespace: " pre-processor feature for unique C++ ASn.1 module namespace references. * Updated SNACC document (in the ./SNACC/doc directory) to present DigitalNet updates/enhancements. * Updated c++-examples and c-examples to demontrate recent features. New in 1.4: * rewrote makefiles to make build process easier and faster. * Enchancements to C++ runtime: * AsnInt changed to be so that it no longer inherits AsnOcts * AsnBits enchanced to construct BitStrings from binary strings. * Added AsnSetOf and AsnSeqOf templates. * Added Exception handling (see snaccexcept.h) * Moved BDecPdu to AsnType. So every type as access to it now. This was done to help reduce the number of symbols & methods the compiler generates. * Added useful types * Enchancements to C runtime: * Added useful types * Enhancements to compiler * Removed -u switch because useful types are now in the runtime library. * Added useful types as basic types. New in 1.3b4: * Generic table decoding routines with callback mechanism in tbl library * New tool "berdecode", decoding any BER data, can also use table file * New Tcl/Tk tool "asnwish", reads table files, access to grammar, en-/decoding * Fix for tag values > 2^14 * Fix for table-encoding tag values dividable by 128 * Small fix in AsnBits::GetBit to return TRUE (i.e., 1) instead of #bit in byte New in 1.3b3: * Added isPdu flag to tables * Added number range checks during parsing New in 1.3b2: * Small fix of C value string generation wrt char values >127 * Added (limited) size constraints, bitstring and enumeration names to tables New in 1.3b1: * Made snacc.h more C++-readable (credits to Steve Walker). * Improved dependency generation for stupid makedepends. * Corrected PeekTag to peek into buffer only as far as necessary. * Added installable error handler. * Fixed small glitch in idl-code generator (credits to Markku Savela). * Finally fixed cut-and-paste error in SEQUENCE OF parsing. New in 1.3a: * Continued porting C, C++, tbl to 64 bit, any endianness: Hash typedef, PeekTag algorithm used by tables. * Fixed cut-and-paste error in SEQUENCE OF parsing. * Added missing initialisation of exponent in asn-real.[Cc]. * Fixed tbl-free.c and some other table-related bugs. * Added casts and stuff for picky C++ compilers. * Incorporated all valid bug fixes from snacc-bugs. * Initial move of tcl stuff to tcl7.6/tk4.2/tree4.1. snacc ASN.1 Compiler Release 1.1 - (updated Jul 93) ----------------------------------------------------- See the latex or PostScript version of the documentation in the snacc/doc directory for indepth information on this tool. For a quick introduction, look at the examples in snacc/c_examples, snacc/c++_examples and snacc/tbl_example. Features of ASN.1 Supported --------------------------- - parses ASN.1 '90 (subtype notation etc.) - macro definitions do not generate syntax errors but are are not processed. (retained as string) - value notation is parsed and for OBJECT IDENTIFIERs, INTEGERs and BOOLEANS (any other value in { }'s is currently kept as a string) - handles multiple ASN.1 module compiling/linking (IMPORTS/EXPORTS) - some X.400 and SNMP macros are parsed - supports ";" separted type or value definitions in the ASN.1 source. This is useful when dealing with some macros that introduce parsing problems. Does not require the ";"'s though. - ANY DEFINED BY types are handled using the SNMP OBJECT-TYPE macro to define the identifier to type mapping. esnacc-ng-1.8.1/TODO.md000066400000000000000000000041531302010526100144370ustar00rootroot00000000000000eSNACC Project Ideas ==================== This file lists a number of items and ideas for enhancing eSNACC. Programming Project Ideas ========================= Each of these projects should result in one or more patches submitted to to the esnacc project (using the GitHub interface, for now). Fedora Spec File ---------------- One existed for snacc - just need to get it and update it for esnacc. eSNACC m4 automake rules ------------------------ It would be really good if there was an esnacc.m4 that would populate makefile entries with the appropriate rules and targets to build .asn1 files using esnacc. Hook up the Examples -------------------- This is an ongoing effort to fix up and re-enable the various c and c++ language examples. They are all there under c-examples and c++-examples. Steps for this task: 1. Ensure that all of the c-examples are compiling 2. Rename c++-examples to cxx-examples. 3. Hook up the c++ examples 4. (Stretch) Have the code generator generate "fuzz tests" or test code that can be exercised in a unit test to validate encoding, saving and decoding. Re-enable tcl support --------------------- During the conversion to esnacc, support for TCLSH interfaces was dropped, mostly due to testing compatibility reasons. This should be re-enabled so that esnacc can get feature parity again. Python, C#, golang, and JS backend ---------------------------------- eSNACC should really have backends for these (and other) popular languages. Minimally, BER support should go along with those languages, and if possible adding addtional encoding rule support should be done. This requires mostly copying existing boilerplate and modifying it... which really means Template Generation Engine -------------------------- It would be better to just refactor the back-end system to use template files for generation. That way, there's no need to even bother with additional specific backend code - just write new templates. This requires modifying the code emitting system to support a new template language and extending that language to be future capable, but it really is a better design overall. esnacc-ng-1.8.1/appveyor.yml000066400000000000000000000020241302010526100157330ustar00rootroot00000000000000version: 1.0.{build} branches: only: - master clone_folder: C:\esnacc-ng init: - ps: >- mkdir C:\pthreads-win32 $source = "ftp://sourceware.org/pub/pthreads-win32/pthreads-w32-2-9-1-release.zip" $destination = "C:\pthreads-win32\pthreads-win32.zip" Invoke-WebRequest $source -OutFile $destination cd C:\pthreads-win32 7z x C:\pthreads-win32\pthreads-win32.zip cd C:\esnacc-ng build_script: - '"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\VsDevCmd"' - C:\MinGW\msys\1.0\bin\bash -lc "echo \"C:/MinGW /mingw\" > /etc/fstab" - C:\MinGW\msys\1.0\bin\bash -lc "cp /c/pthreads-win32/Pre-built.2/dll/x86/*.dll /c/esnacc-ng/." - C:\MinGW\msys\1.0\bin\bash -lc "mv /bin/link.exe /bin/link_copy.exe" - C:\MinGW\msys\1.0\bin\bash -lc "cd /c/esnacc-ng && ./boot.sh" - C:\MinGW\msys\1.0\bin\bash -lc "cd /c/esnacc-ng && ./configure CC=build-aux/cccl CXX=build-aux/cccl LD=\"`which link`\" --with-pthread=C:/pthreads-win32/Pre-built.2" - C:\MinGW\msys\1.0\bin\bash -lc "cd /c/esnacc-ng && make " esnacc-ng-1.8.1/asn1specs/000077500000000000000000000000001302010526100152455ustar00rootroot00000000000000esnacc-ng-1.8.1/asn1specs/.gitignore000066400000000000000000000000401302010526100172270ustar00rootroot00000000000000.deps .dirstamp p-rec.c p-rec.h esnacc-ng-1.8.1/asn1specs/any.asn1000066400000000000000000000047051302010526100166260ustar00rootroot00000000000000-- file: asn1specs/any.asn1 -- -- this file is used in ../c{,++}-examples/any/ -- -- $Header: /baseline/SNACC/asn1specs/any.asn1,v 1.2 2003/12/17 19:05:02 gronej Exp $ -- $Log: any.asn1,v $ -- Revision 1.2 2003/12/17 19:05:02 gronej -- SNACC baseline merged with PER v1_7 tag -- -- Revision 1.1.2.1 2003/11/05 14:58:53 gronej -- working PER code merged with esnacc_1_6 -- -- Revision 1.1.1.1 2000/08/21 20:36:15 leonberp -- First CVS Version of SNACC. -- -- Revision 1.2 1997/02/16 20:25:20 rj -- check-in of a few cosmetic changes -- -- Revision 1.1 1994/08/31 22:44:44 rj -- first check-in. ANY-TEST DEFINITIONS ::= BEGIN -- -- use the SNMP OBJECT type to define the correlation between -- the identifying INTEGER/OBJECT IDENTIFIER -- and the ANY DEFINED BY type -- intId OBJECT-TYPE SYNTAX INTEGER ACCESS read-write STATUS mandatory ::= 1 boolId OBJECT-TYPE SYNTAX BOOLEAN ACCESS read-write STATUS mandatory ::= 2 octsId OBJECT-TYPE SYNTAX [PRIVATE 2] IMPLICIT OCTET STRING ACCESS read-write STATUS mandatory ::= 3 bitsId OBJECT-TYPE SYNTAX [PRIVATE 1] BIT STRING ACCESS read-write STATUS mandatory ::= 4 realId OBJECT-TYPE SYNTAX REAL ACCESS read-write STATUS mandatory ::= 5 -- -- note that the following OBJECT-TYPE OBJECT IDENTIFIER values -- reference the previous OBJECT-TYPE INTEGER values intOid OBJECT-TYPE SYNTAX INTEGER ACCESS read-write STATUS mandatory ::= { 0 1 2 3 4 intId} boolOid OBJECT-TYPE SYNTAX BOOLEAN ACCESS read-write STATUS mandatory ::= { 0 1 2 3 4 boolId} octsOid OBJECT-TYPE SYNTAX OCTET STRING ACCESS read-write STATUS mandatory ::= { 0 1 2 3 4 octsId} bitsOid OBJECT-TYPE SYNTAX BIT STRING ACCESS read-write STATUS mandatory ::= { 0 1 2 3 4 bitsId} realOid OBJECT-TYPE SYNTAX REAL ACCESS read-write STATUS mandatory ::= { 0 1 2 3 4 realId} -- this type tests both the INTEGER and OBJECT IDENTIFIER mapping AnyTestType ::= --snacc isPdu:"TRUE" -- SEQUENCE { intMap TSeq1, oidMap TSeq2 } TSeq1 ::= SEQUENCE OF AttrValue1 AttrValue1 ::= SEQUENCE { id INTEGER, ANY DEFINED BY id } TSeq2 ::= SEQUENCE OF AttrValue2 AttrValue2 ::= SEQUENCE { id OBJECT IDENTIFIER, ANY DEFINED BY id } END esnacc-ng-1.8.1/asn1specs/asn-useful.asn1000066400000000000000000000047741302010526100201270ustar00rootroot00000000000000ASN-USEFUL DEFINITIONS ::= BEGIN -- file: .../asn1specs/asn-useful.asn1 -- -- NOTE: every one of these types is marked as a PDU so the compiler -- will produce the encode and decode routines that -- enc/dec the top tag/len pairs, not just the content decoders. -- (only nec for re-generating the library files "asn_useful.[ch]"). -- The isPdu field does not affect how this module is linked -- with other modules during compilation. -- -- (type DEF comment directives immediately follow the "::=") -- -- MS 92 -- -- $Header: /baseline/SNACC/asn1specs/asn-useful.asn1,v 1.2 2003/12/17 19:05:02 gronej Exp $ -- $Log: asn-useful.asn1,v $ -- Revision 1.2 2003/12/17 19:05:02 gronej -- SNACC baseline merged with PER v1_7 tag -- -- Revision 1.1.2.1 2003/11/05 14:58:53 gronej -- working PER code merged with esnacc_1_6 -- -- Revision 1.1.1.1 2000/08/21 20:36:15 leonberp -- First CVS Version of SNACC. -- -- Revision 1.3 1995/07/24 15:12:35 rj -- useful.asn1 renamed to asn-useful.asn1 to accomodate to snacc's new file name generation scheme. -- -- Revision 1.2 1994/08/28 09:54:19 rj -- comment leader fixed. -- -- Revision 1.1 1994/08/28 09:51:15 rj -- first check-in. ObjectDescriptor ::= -- isPdu:"TRUE" -- [UNIVERSAL 7] IMPLICIT OCTET STRING VideotexString ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 21] IMPLICIT OCTET STRING GraphicString ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 25] IMPLICIT OCTET STRING VisibleString ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 26] IMPLICIT OCTET STRING ISO646String ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 26] IMPLICIT OCTET STRING GeneralString ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 27] IMPLICIT OCTET STRING UTCTime ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 23] IMPLICIT OCTET STRING GeneralizedTime ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 24] IMPLICIT OCTET STRING EXTERNAL ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 8] IMPLICIT SEQUENCE { direct-reference OBJECT IDENTIFIER OPTIONAL, indirect-reference INTEGER OPTIONAL, data-value-descriptor ObjectDescriptor OPTIONAL, encoding CHOICE { single-ASN1-type [0] OCTET STRING, -- should be ANY octet-aligned [1] IMPLICIT OCTET STRING, arbitrary [2] IMPLICIT BIT STRING } } END -- of ASN-USEFUL type definitions esnacc-ng-1.8.1/asn1specs/asn-usefulVDA.asn1000066400000000000000000000065471302010526100204620ustar00rootroot00000000000000ASN-USEFUL DEFINITIONS ::= BEGIN -- file: .../asn1specs/asn-useful.asn1 -- -- NOTE: every one of these types is marked as a PDU so the compiler -- will produce the encode and decode routines that -- enc/dec the top tag/len pairs, not just the content decoders. -- (only nec for re-generating the library files "asn_useful.[ch]"). -- The isPdu field does not affect how this module is linked -- with other modules during compilation. -- -- (type DEF comment directives immediately follow the "::=") -- -- MS 92 -- -- $Header: /baseline/SNACC/asn1specs/asn-usefulVDA.asn1,v 1.2 2003/12/17 19:05:03 gronej Exp $ -- $Log: asn-usefulVDA.asn1,v $ -- Revision 1.2 2003/12/17 19:05:03 gronej -- SNACC baseline merged with PER v1_7 tag -- -- Revision 1.1.2.1 2003/11/05 14:58:53 gronej -- working PER code merged with esnacc_1_6 -- -- Revision 1.1.1.1 2000/08/21 20:36:15 leonberp -- First CVS Version of SNACC. -- -- Revision 1.3 1995/07/24 15:12:35 rj -- useful.asn1 renamed to asn-useful.asn1 to accomodate to snacc's new file name generation scheme. -- -- Revision 1.2 1994/08/28 09:54:19 rj -- comment leader fixed. -- -- Revision 1.1 1994/08/28 09:51:15 rj -- first check-in. ObjectDescriptor ::= -- isPdu:"TRUE" -- [UNIVERSAL 7] IMPLICIT OCTET STRING NumericStringSNACC ::= -- snacc isPdu:"TRUE" -- [UNIVERSAL 18] IMPLICIT OCTET STRING PrintableStringSNACC ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 19] IMPLICIT OCTET STRING TeletexStringSNACC ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 20] IMPLICIT OCTET STRING T61StringSNACC ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 20] IMPLICIT OCTET STRING VideotexString ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 21] IMPLICIT OCTET STRING IA5StringSNACC ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 22] IMPLICIT OCTET STRING GraphicString ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 25] IMPLICIT OCTET STRING VisibleString ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 26] IMPLICIT OCTET STRING ISO646String ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 26] IMPLICIT OCTET STRING GeneralString ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 27] IMPLICIT OCTET STRING UTCTime ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 23] IMPLICIT OCTET STRING GeneralizedTime ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 24] IMPLICIT OCTET STRING UniversalStringSNACC ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 28] IMPLICIT OCTET STRING BMPStringSNACC ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 30] IMPLICIT OCTET STRING UTF8StringSNACC ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 12] IMPLICIT OCTET STRING EXTERNAL ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 8] IMPLICIT SEQUENCE { direct-reference OBJECT IDENTIFIER OPTIONAL, indirect-reference INTEGER OPTIONAL, data-value-descriptor ObjectDescriptor OPTIONAL, encoding CHOICE { single-ASN1-type [0] OCTET STRING, -- should be ANY octet-aligned [1] IMPLICIT OCTET STRING, arbitrary [2] IMPLICIT BIT STRING } } END -- of ASN-USEFUL type definitions esnacc-ng-1.8.1/asn1specs/asn1module.asn1000066400000000000000000000427431302010526100201130ustar00rootroot00000000000000-- file: .../asn1specs/asn1module.asn1 -- -- This module describes the data structure used to reprsent the -- compiled ASN.1. -- Using ASN.1 for the internal data structure allows writing -- (encoding) to disk for storage (not done yet due to recursive -- refs back to the module) -- -- Mike Sample 91/08/29 -- Modifed 92/05 MS -- -- $Header: /baseline/SNACC/asn1specs/asn1module.asn1,v 1.4 2004/03/22 20:04:18 gronej Exp $ -- $Log: asn1module.asn1,v $ -- Revision 1.4 2004/03/22 20:04:18 gronej -- took IBM references out of the code (to the best of our knowledge, we don't use any of it anymore) -- -- Revision 1.3 2003/12/17 19:05:03 gronej -- SNACC baseline merged with PER v1_7 tag -- -- Revision 1.2.2.1 2003/11/05 14:58:53 gronej -- working PER code merged with esnacc_1_6 -- -- Revision 1.2 2001/09/27 13:04:57 rwc -- Updated to allow SNACC compilation: typeName is now an internal routine name, -- changed the ASN.1 name to typeNameVDA. Also moved -- ValueDefList ::= SEQUENCE OF ValueDef -- up in the .asn1 file to properly C++ compile. -- -- Revision 1.1.1.1 2000/08/21 20:36:15 leonberp -- First CVS Version of SNACC. -- -- Revision 1.3 1995/07/25 20:04:04 rj -- data structures added for idl backend. -- -- Revision 1.2 1994/08/28 09:54:16 rj -- comment leader fixed. -- -- Revision 1.1 1994/08/28 09:51:11 rj -- first check-in. Asn1Module DEFINITIONS IMPLICIT TAGS ::= BEGIN -- exports everything -- imports nothing ValueDefList ::= SEQUENCE OF ValueDef NamedNumberList ::= ValueDefList Modules ::= [APPLICATION 0] IMPLICIT SEQUENCE { creationTime INTEGER, modules ModuleList } ModuleList ::= SEQUENCE OF Module Module ::= SEQUENCE { status ENUMERATED { mod-ok(0), mod-not-linked(1), mod-error(2) }, modId ModuleId, tagDefault ENUMERATED { explicit-tags(0), implicit-tags(1) }, exportStatus ENUMERATED { exports-all(0), exports-nothing(1), exports-some(2) }, imports ImportModuleList, typeDefs TypeDefList, valueDefs ValueDefList, hasAnys BOOLEAN, asn1SrcFileName MyString, cHdrFileName MyString, cSrcFileName MyString, cxxHdrFileName MyString, cxxSrcFileName MyString, cxxname MyString, -- META idlFileName MyString, -- IDL idlname MyString -- IDL } ModuleId ::= SEQUENCE { name MyString, oid OBJECT IDENTIFIER OPTIONAL --snacc cTypeName:"OID" isPtr:"TRUE" } ImportModuleList ::= SEQUENCE OF ImportModule ImportModule ::= SEQUENCE { modId ModuleId, importElmts ImportElmtList, moduleRef Module, --snacc isEncDec:"FALSE" lineNo INTEGER } ImportElmtList ::= SEQUENCE OF ImportElmt ImportElmt ::= SEQUENCE { resolvedRef CHOICE { type [0] TypeDef, -- not encoded value [1] ValueDef -- not encoded } OPTIONAL, name MyString, privateScope BOOLEAN, -- true if from MODNAME.TYPE ref lineNo INTEGER } TypeDefList ::= SEQUENCE OF TypeDef OidOrInt ::= CHOICE { oid OBJECT IDENTIFIER, intId INTEGER } AnyRef ::= SEQUENCE { anyIdName MyString, id OidOrInt } AnyRefList ::= SEQUENCE OF AnyRef TypeDef ::= SEQUENCE { exported BOOLEAN, recursive BOOLEAN, isPdu BOOLEAN, localRefCount INTEGER, importRefCount INTEGER, tmpRefCount INTEGER, visited BOOLEAN, definedName MyString, type Type, cTypeDefInfo CTDI, cxxTypeDefInfo CxxTDI, attrList AttributeList, refList TypeDefList, anyRefs AnyRefList } Tag ::= SEQUENCE { tclass INTEGER, -- swap this for the BER_CLASS enum from basetypes.h form INTEGER, -- swap this for the BER_FORM enum code INTEGER, explicitVDA BOOLEAN, -- MODIFIED due to C++ keyword. valueRef Value } Type ::= SEQUENCE { optional BOOLEAN, implicit BOOLEAN, tags TagList, defaultVal [0] IMPLICIT NamedValue OPTIONAL, subtypes [1] Subtype OPTIONAL, basicType [2] BasicType, lineNo INTEGER, cTypeRefInfo CTRI, cxxTypeRefInfo CxxTRI, attrList AttributeList } TagList ::= SEQUENCE OF Tag AttributeList ::= SEQUENCE OF MyString -- BasicTypes with NULL need no more info that which type it is -- (this is known from the choice id) BasicType ::= CHOICE { unknown [0] IMPLICIT NULL, boolean [1] IMPLICIT NULL, integer [2] IMPLICIT NamedNumberList, bitString [3] IMPLICIT NamedNumberList, octetString [4] IMPLICIT NULL, null [5] IMPLICIT NULL, oid [6] IMPLICIT NULL, real [7] IMPLICIT NULL, enumerated [8] IMPLICIT NamedNumberList, sequence [9] IMPLICIT NamedTypeList, sequenceOf [10] IMPLICIT Type, set [11] IMPLICIT NamedTypeList, setOf [12] IMPLICIT Type, choice [13] IMPLICIT NamedTypeList, selection [14] IMPLICIT SelectionType, componentsOf [15] IMPLICIT Type, -- [Resolved](local/import) type ref any [16] IMPLICIT NULL, anyDefinedBy [17] IMPLICIT AnyDefinedByType, localTypeRef [19] IMPLICIT TypeRef, importTypeRef [20] IMPLICIT TypeRef, macroType [21] MacroType, macroDef [22] IMPLICIT MacroDef --snacc isPtr:"FALSE" } MacroDef ::= MyString -- just keep the text for now MacroType ::= CHOICE { rosOperation [0] IMPLICIT RosOperationMacroType, rosError [1] IMPLICIT RosErrorMacroType, rosBind [2] IMPLICIT RosBindMacroType, rosUnbind [3] IMPLICIT RosBindMacroType, rosAse [4] IMPLICIT RosAseMacroType, rosAc [5] IMPLICIT RosAcMacroType, mtsasExtension [6] IMPLICIT MtsasExtensionMacroType, mtsasExtensions [7] IMPLICIT MtsasExtensionsMacroType, mtsasExtensionAttribute [8] IMPLICIT MtsasExtensionAttributeMacroType, mtsasToken [9] IMPLICIT MtsasTokenMacroType, mtsasTokenData [10] IMPLICIT MtsasTokenDataMacroType, mtsasSecurityCategory [11] IMPLICIT MtsasSecurityCategoryMacroType, asnObject [12] IMPLICIT AsnObjectMacroType, asnPort [13] IMPLICIT AsnPortMacroType, asnRefine [14] IMPLICIT AsnRefineMacroType, asnAbstractBind [15] IMPLICIT AsnAbstractBindMacroType, asnAbstractUnbind [16] IMPLICIT AsnAbstractBindMacroType, asnAbstractOperation [17] IMPLICIT RosOperationMacroType, asnAbstractError [18] IMPLICIT RosErrorMacroType, afAlgorithm [19] IMPLICIT Type, afEncrypted [20] IMPLICIT Type, afProtected [21] IMPLICIT Type, afSignature [22] IMPLICIT Type, afSigned [23] IMPLICIT Type, snmpObjectType [24] IMPLICIT SnmpObjectTypeMacroType } AnyDefinedByType ::= SEQUENCE { fieldName MyString, -- name of field that its defined by link NamedType OPTIONAL -- REFERENCE not encoded } SelectionType ::= SEQUENCE { fieldName MyString, -- name of field in choice typeRef Type, -- [Resolved](local/import) type ref link NamedType OPTIONAL -- REFERENCE not encoded } NamedTypeList ::= SEQUENCE OF NamedType NamedType ::= SEQUENCE { fieldName MyString, -- may be empty or NULL str type Type } TypeRef ::= SEQUENCE { typeNameVDA MyString, moduleName MyString, -- used for "modname.type" refs(may be null) module Module, --snacc isEncDec:"FALSE" link TypeDef --snacc isEncDec:"FALSE" } RosOperationMacroType ::= SEQUENCE { arguments NamedType, result NamedType, errors [0] IMPLICIT TypeOrValueList OPTIONAL, linkedOps [1] IMPLICIT TypeOrValueList OPTIONAL } ValueList ::= SEQUENCE OF Value TypeOrValueList ::= SEQUENCE OF TypeOrValue TypeOrValue ::= CHOICE { type [0] IMPLICIT Type, value [1] IMPLICIT Value } OidList ::= SEQUENCE OF OBJECT IDENTIFIER RosErrorMacroType ::= SEQUENCE { parameter NamedType } RosBindMacroType ::= SEQUENCE { argument NamedType, result NamedType, error NamedType } RosAseMacroType ::= SEQUENCE { operations ValueList, consumerInvokes ValueList, supplierInvokes ValueList } RosAcMacroType ::= SEQUENCE { nonRoElements ValueList, bindMacroType Type, unbindMacroType Type, remoteOperations Value, operationsOf ValueList, initiatorConsumerOf ValueList, responderConsumerOf ValueList, abstractSyntaxes OidList } MtsasExtensionMacroType ::= SEQUENCE { elmtType [0] IMPLICIT NamedType OPTIONAL, defaultValue [1] IMPLICIT Value OPTIONAL, criticalForSubmission [2] IMPLICIT BOOLEAN OPTIONAL, criticalForTransfer [3] IMPLICIT BOOLEAN OPTIONAL, criticalForDelivery [4] IMPLICIT BOOLEAN OPTIONAL } MtsasExtensionsMacroType ::= SEQUENCE { extensions ValueList } MtsasExtensionAttributeMacroType ::= SEQUENCE { type Type OPTIONAL } MtsasTokenMacroType ::= SEQUENCE { type Type OPTIONAL } MtsasTokenDataMacroType ::= SEQUENCE { type Type OPTIONAL } MtsasSecurityCategoryMacroType ::= SEQUENCE { type Type OPTIONAL } AsnObjectMacroType ::= SEQUENCE { ports AsnPortList OPTIONAL } AsnPortList ::= SEQUENCE OF AsnPort AsnPort ::= SEQUENCE { portValue Value, portType ENUMERATED { consumer-port(0), supplier-port(1), symmetric-port(2) } } AsnPortMacroType ::= SEQUENCE { abstractOps [0] IMPLICIT TypeOrValueList OPTIONAL, consumerInvokes [1] IMPLICIT TypeOrValueList OPTIONAL, supplierInvokes [2] IMPLICIT TypeOrValueList OPTIONAL } AsnRefineMacroType ::= INTEGER AsnAbstractBindMacroType ::= SEQUENCE { ports [0] IMPLICIT AsnPortList OPTIONAL, type [1] IMPLICIT Type OPTIONAL } SnmpObjectTypeMacroType ::= SEQUENCE { syntax Type, access ENUMERATED { snmp-read-only(0), snmp-read-write(1), snmp-write-only(2), snmp-not-accessible(3)}, status ENUMERATED { snmp-mandatory(0), snmp-optional(1), snmp-obsolete(2), snmp-deprecated(3)}, description [0] IMPLICIT Value OPTIONAL, reference [1] IMPLICIT Value OPTIONAL, index [2] IMPLICIT TypeOrValueList OPTIONAL, defVal [3] IMPLICIT Value OPTIONAL } Subtype ::= CHOICE { single [0] SubtypeValue, and [1] IMPLICIT SubtypeList, or [2] IMPLICIT SubtypeList, not [3] Subtype } SubtypeList ::= SEQUENCE OF Subtype SubtypeValue ::= CHOICE { singleValue [0] IMPLICIT Value, contained [1] IMPLICIT Type, valueRange [2] IMPLICIT ValueRangeSubtype, permittedAlphabet [3] Subtype, -- only valuerange or singleval sizeConstraint [4] Subtype, -- only single value ints or val range innerSubtype [5] IMPLICIT InnerSubtype } ValueRangeSubtype ::= SEQUENCE { lowerEndInclusive BOOLEAN, upperEndInclusive BOOLEAN, lowerEndValue Value, upperEndValue Value } InnerSubtype ::= SEQUENCE { constraintType ENUMERATED { full-ct(0), partial-ct(1), single-ct(2) }, constraints ConstraintList } ConstraintList ::= SEQUENCE OF Constraint Constraint ::= SEQUENCE { fieldRef MyString, -- not used if in single-ct, may be null presenceConstraint ENUMERATED { present-ct(0), absent-ct(1), empty-ct(2), optional-ct(3) }, valueConstraints Subtype } ValueDef ::= SEQUENCE { exported BOOLEAN, definedName MyString, value Value } Value ::= SEQUENCE { type Type OPTIONAL, valueType INTEGER, -- holds one of choiceId's def'd for BasicType basicValue BasicValue, lineNo INTEGER } BasicValue ::= CHOICE { unknown [0] IMPLICIT NULL, empty [1] IMPLICIT NULL, integer [2] IMPLICIT INTEGER, specialInteger [3] IMPLICIT SpecialIntegerValue, longInteger [4] IMPLICIT INTEGER, -- put LONG before INTGEGER boolean [5] IMPLICIT BOOLEAN, real [6] IMPLICIT REAL, specialReal [7] IMPLICIT SpecialRealValue, asciiText [8] IMPLICIT OCTET STRING, asciiHex [9] IMPLICIT OCTET STRING, asciiBitString [10] IMPLICIT OCTET STRING, oid [11] IMPLICIT OBJECT IDENTIFIER, linkedOid [12] IMPLICIT OBJECT IDENTIFIER, --snacc cTypeName:"OID" berValue [13] IMPLICIT OCTET STRING, perValue [14] IMPLICIT OCTET STRING, namedValue [15] IMPLICIT NamedValue, null [16] IMPLICIT NULL, localValueRef [17] IMPLICIT ValueRef, importValueRef [18] IMPLICIT ValueRef, valueNotation [19] IMPLICIT OCTET STRING } SpecialIntegerValue ::= ENUMERATED { min-int(0), max-int(1) } SpecialRealValue ::= ENUMERATED { minus-infinity-real(0), plus-infinity-real(1) } ValueRef ::= SEQUENCE { valueName MyString, moduleName MyString, -- used for "modname.value" refs (may be null) link ValueDef, --snacc isEncDec:"FALSE" module Module --snacc isEncDec:"FALSE" } NamedValue ::= SEQUENCE { fieldName MyString, -- may be null value Value } NamedValueList ::= SEQUENCE OF NamedValue CTypeId ::= ENUMERATED { c-choice(0), c-list(1), c-any(2), c-anydefinedby(3), c-lib(4), c-struct(5), c-typeref(6), c-no-type(7), c-typedef(8) } -- C Type Def Info - info used for routine naming -- and referencing from other types CTDI ::= SEQUENCE { asn1TypeId INTEGER, --snacc cTypeName:"enum BasicTypeChoiceId" cTypeId CTypeId, cTypeName MyString, isPdu BOOLEAN, isEncDec BOOLEAN, -- if false, no routines are gen -- and not included in encodings isPtrForTypeDef BOOLEAN, isPtrForTypeRef BOOLEAN, isPtrInChoice BOOLEAN, isPtrForOpt BOOLEAN, -- defines these names, used by references optTestRoutineName MyString, -- routine/macro to check whether -- opt type is present defaultFieldName MyString, -- base for generating field names printRoutineName MyString, encodeRoutineName MyString, decodeRoutineName MyString, freeRoutineName MyString, genPrintRoutine BOOLEAN, genEncodeRoutine BOOLEAN, genDecodeRoutine BOOLEAN, genFreeRoutine BOOLEAN, genTypeDef BOOLEAN } -- -- CTRI (C Type Ref Info) is used for generating C typedefinitions -- from the ASN.1 types info CTRI ::= SEQUENCE { cTypeId CTypeId, cFieldName MyString, cTypeName MyString, isPtr BOOLEAN, -- isEndCType BOOLEAN, false for struct/union def -- cNamedElmts CNamedElmts OPTIONAL, -- for C_LIB bits/int/enums choiceIdValue INTEGER, -- enum value of this c field choiceIdSymbol MyString, -- this fields sym in choiceId enum choiceIdEnumName MyString, choiceIdEnumFieldName MyString, optTestRoutineName MyString, -- these names are gained from refd type def printRoutineName MyString, -- or are over-ridden snacc attribute comment encodeRoutineName MyString, decodeRoutineName MyString, freeRoutineName MyString, isEncDec BOOLEAN -- whether part of enc value } CNamedElmts ::= SEQUENCE OF CNamedElmt CNamedElmt ::= SEQUENCE { name MyString, value INTEGER } CxxTDI ::= SEQUENCE { asn1TypeId INTEGER, --snacc cTypeName:"enum BasicTypeChoiceId" className MyString, isPdu BOOLEAN, isEnc BOOLEAN, isPtrForTypeDef BOOLEAN, isPtrForOpt BOOLEAN, isPtrInChoice BOOLEAN, isPtrInSetAndSeq BOOLEAN, isPtrInList BOOLEAN, optTestRoutineName MyString, defaultFieldName MyString -- base for generating field names } CxxTRI ::= SEQUENCE { isEnc BOOLEAN, className MyString, fieldName MyString, isPtr BOOLEAN, namedElmts CNamedElmts, choiceIdSymbol MyString, choiceIdValue INTEGER, optTestRoutineName MyString } IDLTDI ::= SEQUENCE { asn1TypeId INTEGER, --snacc cTypeName:"enum BasicTypeChoiceId" typeNameVDA MyString, isPdu BOOLEAN, isEnc BOOLEAN, isPtrForTypeDef BOOLEAN, isPtrForOpt BOOLEAN, isPtrInChoice BOOLEAN, isPtrInSetAndSeq BOOLEAN, isPtrInList BOOLEAN, optTestRoutineName MyString, defaultFieldName MyString -- base for generating field names } IDLTRI ::= SEQUENCE { isEnc BOOLEAN, typeNameVDA MyString, fieldName MyString, isPtr BOOLEAN, namedElmts CNamedElmts, choiceIdSymbol MyString, choiceIdValue INTEGER, optTestRoutineName MyString } -- use snacc compiler directives to overide the builtin types. -- -- All strings used in module data struct are null terminated so -- can just use a char* -- Note the snacc comments before the PrintableString -- bind with the MyString TypeDef and the ones after PrintableString -- bind with the PrintableString Type ref. MyString ::= --snacc isPtrForTypeDef:"FALSE" --snacc isPtrForTypeRef:"FALSE" --snacc isPtrInChoice:"FALSE" --snacc isPtrForOpt:"FALSE" --snacc optTestRoutineName:"MYSTRING_NON_NULL" --snacc genPrintRoutine:"FALSE" --snacc genEncodeRoutine:"FALSE" --snacc genDecodeRoutine:"FALSE" --snacc genFreeRoutine:"FALSE" --snacc printRoutineName:"printMyString" --snacc encodeRoutineName:"EncMyString" --snacc decodeRoutineName:"DecMyString" --snacc freeRoutineName:"FreeMyString" PrintableString --snacc cTypeName:"char*" END esnacc-ng-1.8.1/asn1specs/authenticationframework.asn1000066400000000000000000000252501302010526100227720ustar00rootroot00000000000000AuthenticationFramework -- {joint-iso-ccitt ds(5) module(1) authenticationFramework(7) 3} DEFINITIONS ::= BEGIN -- EXPORTS All -- -- The types and values defined in this module are exported for use in the other ASN.1 modules contained -- within the Directory Specifications, and for the use of other applications which will use them to access -- Directory services. Other applications may use them for their own purposes, but this will not constrain -- extensions and modifications needed to maintain or improve the Directory service. IMPORTS id-at FROM UsefulDefinitions Name, Attribute FROM InformationFramework ub-user-password FROM UpperBounds UniqueIdentifier FROM SelectedAttributeTypes GeneralNames FROM CertificateExtensions ; --basic certificate definition Certificate ::= --snacc isPdu:"TRUE" -- SEQUENCE { toBeSigned CertificateToBeSigned, algorithm AlgorithmIdentifier, signature BIT STRING } CertificateToBeSigned ::= --snacc isPdu:"TRUE" -- SEQUENCE { version [0] Version DEFAULT v1, serialNumber CertificateSerialNumber, signature AlgorithmIdentifier, issuer Name, validity Validity, subject Name, subjectPublicKeyInfo SubjectPublicKeyInfo, issuerUniqueIdentifier [1] IMPLICIT UniqueIdentifier OPTIONAL, -- if present, version must be v2 or v3 subjectUniqueIdentifier [2] IMPLICIT UniqueIdentifier OPTIONAL, -- if present, version must be v2 or v3 extensions [3] Extensions OPTIONAL -- If present, version must be v3 -- } Version ::= INTEGER { v1(0), v2(1), v3(2) } CertificateSerialNumber ::= [UNIVERSAL 2] IMPLICIT OCTET STRING -- originally INTEGER AlgorithmIdentifier ::= SEQUENCE { algorithm OBJECT IDENTIFIER, parameters ANY DEFINED BY algorithm OPTIONAL } Validity ::= SEQUENCE { notBefore Time, notAfter Time } SubjectPublicKeyInfo ::= SEQUENCE { algorithm AlgorithmIdentifier, subjectPublicKey BIT STRING } Time ::= CHOICE { utcTime UTCTime, generalizedTime GeneralizedTime } Extensions ::= SEQUENCE OF Extension -- For those extensions where ordering of individual extensions within the SEQUENCE is significant, the -- specification of those individual extensions shall include the rules for the significance of the order therein Extension ::= SEQUENCE { extnId OBJECT IDENTIFIER, critical BOOLEAN DEFAULT FALSE, extnValue [UNIVERSAL 4] ANY DEFINED BY extnId -- OCTET STRING -- -- contains a DER encoding of a value of type &ExtnType -- for the extension object identified by extnId -- } -- algorithm-specific constructs: parameters, public keys, and signature values -- parameters dssParameters OBJECT-TYPE SYNTAX Dss-Parms ACCESS read-write STATUS mandatory ::= {id-fortezzaUpdatedSigAlgorithm} Dss-Parms ::= SEQUENCE { p OCTET STRING, q OCTET STRING, g OCTET STRING } keaParameters OBJECT-TYPE SYNTAX Kea-Parms ACCESS read-write STATUS mandatory ::= {id-fortezzaKeyManagementAlgorithm} Kea-Parms ::= SEQUENCE { p OCTET STRING, q OCTET STRING, g OCTET STRING } keaDssParameters OBJECT-TYPE SYNTAX Kea-Dss-Parms ACCESS read-write STATUS mandatory ::= {id-fortezzaKMandUpdSigAlgorithms} Kea-Dss-Parms ::= CHOICE { [0] Different-Parms, [1] Common-Parms } Different-Parms ::= SEQUENCE { Kea-Parms, Dss-Parms } Common-Parms ::= SEQUENCE { p OCTET STRING, q OCTET STRING, g OCTET STRING } dsaParameters OBJECT-TYPE SYNTAX DSAParameters ACCESS read-write STATUS mandatory ::= {id-dsa} DSAParameters ::= SEQUENCE { prime1 [UNIVERSAL 2] IMPLICIT OCTET STRING, -- modulus p - originally INTEGER prime2 [UNIVERSAL 2] IMPLICIT OCTET STRING, -- modulus q - originally INTEGER base [UNIVERSAL 2] IMPLICIT OCTET STRING } -- base g - originally INTEGER dsaWithSHA1Parameters OBJECT-TYPE SYNTAX NULL ACCESS read-write STATUS mandatory ::= {id-dsa-with-sha1} keaIDParameters OBJECT-TYPE SYNTAX OCTET STRING ACCESS read-write STATUS mandatory ::= {id-keyExchangeAlgorithm} rsaParameters OBJECT-TYPE SYNTAX NULL ACCESS read-write STATUS mandatory ::= {rsaEncryption} rsaWithMD2Parameters OBJECT-TYPE SYNTAX NULL ACCESS read-write STATUS mandatory ::= {md2WithRSAEncryption} rsaWithMD4Parameters OBJECT-TYPE SYNTAX NULL ACCESS read-write STATUS mandatory ::= {md4WithRSAEncryption} rsaWithMD5Parameters OBJECT-TYPE SYNTAX NULL ACCESS read-write STATUS mandatory ::= {md5WithRSAEncryption} dhParameters OBJECT-TYPE SYNTAX DHParameter ACCESS read-write STATUS mandatory ::= {dhKeyAgreement} DHParameter ::= SEQUENCE { prime [UNIVERSAL 2] IMPLICIT OCTET STRING, -- p - originally INTEGER base [UNIVERSAL 2] IMPLICIT OCTET STRING, -- g - originally INTEGER privateValueLength INTEGER OPTIONAL } -- public keys DsaPublicKey ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 2] IMPLICIT OCTET STRING -- originally just INTEGER RSAPublicKey ::= --snacc isPdu:"TRUE" -- SEQUENCE { modulus [UNIVERSAL 2] IMPLICIT OCTET STRING, -- n - originally just INTEGER publicExponent [UNIVERSAL 2] IMPLICIT OCTET STRING } -- e - originally just INTEGER DHPublicKey ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 2] IMPLICIT OCTET STRING -- originally just INTEGER -- signature values DSASigValue ::= --snacc isPdu:"TRUE" -- SEQUENCE { r [UNIVERSAL 2] IMPLICIT OCTET STRING, -- originally INTEGER s [UNIVERSAL 2] IMPLICIT OCTET STRING } -- originally INTEGER -- other certificate constructs Certificates ::= --snacc isPdu:"TRUE" -- SEQUENCE { userCertificate Certificate, certificationPath ForwardCertificationPath OPTIONAL} ForwardCertificationPath ::= SEQUENCE OF CrossCertificates CrossCertificates ::= SET OF Certificate CertificationPath ::= --snacc isPdu:"TRUE" -- SEQUENCE { userCertificate Certificate, theCACertificates SEQUENCE OF CertificatePair OPTIONAL} CertificatePair ::= --snacc isPdu:"TRUE" -- SEQUENCE { forward [0] Certificate OPTIONAL, reverse [1] Certificate OPTIONAL -- at least one of the pair shall be present -- } -- certificate revocation list (CRL) CertificateList ::= --snacc isPdu:"TRUE" -- SEQUENCE { toBeSigned CertificateListToBeSigned, algorithm AlgorithmIdentifier, signature BIT STRING } CertificateListToBeSigned ::= --snacc isPdu:"TRUE" -- SEQUENCE { version Version OPTIONAL, -- if present, version must be v2 signature AlgorithmIdentifier, issuer Name, thisUpdate Time, nextUpdate Time OPTIONAL, revokedCertificates SEQUENCE OF SEQUENCE { userCertificate CertificateSerialNumber, revocationDate Time, crlEntryExtensions Extensions OPTIONAL } OPTIONAL, crlExtensions [0] Extensions OPTIONAL } -- attribute certificate AttributeCertificationPath ::= --snacc isPdu:"TRUE" -- SEQUENCE { attributeCertificate AttributeCertificate, acPath SEQUENCE OF ACPathData OPTIONAL } ACPathData ::= SEQUENCE { certificate [0] Certificate OPTIONAL, attributeCertificate [1] AttributeCertificate OPTIONAL } attributeCertificateAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX AttributeCertificate ACCESS read-write STATUS mandatory ::= {id-at-attributeCertificate} AttributeCertificate ::= --snacc isPdu:"TRUE" -- SEQUENCE { toBeSigned AttributeCertificateInfo, algorithm AlgorithmIdentifier, signature BIT STRING } AttributeCertificateInfo ::= --snacc isPdu:"TRUE" -- SEQUENCE { version Version DEFAULT v1, subject CHOICE { baseCertificateID [0] IssuerSerial, -- associated with a Public Key Certificate subjectName [1] GeneralNames }, -- associated with a name issuer GeneralNames, -- CA issuing the attribute certificate signature AlgorithmIdentifier, serialNumber CertificateSerialNumber, attCertValidityPeriod AttCertValidityPeriod, attributes SEQUENCE OF Attribute, issuerUniqueID UniqueIdentifier OPTIONAL, extensions Extensions OPTIONAL } IssuerSerial ::= SEQUENCE { issuer GeneralNames, serial CertificateSerialNumber, issuerUID UniqueIdentifier OPTIONAL} AttCertValidityPeriod ::= SEQUENCE{ notBeforeTime GeneralizedTime, notAfterTime GeneralizedTime } -- attribute types -- userPasswordAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX OCTET STRING (SIZE (0..ub-user-password)) ACCESS read-write STATUS mandatory ::= {id-at-userPassword} userCertificateAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX Certificate ACCESS read-write STATUS mandatory ::= {id-at-userCertificate} cACertificate OBJECT-TYPE -- ATTRIBUTE SYNTAX Certificate ACCESS read-write STATUS mandatory ::= {id-at-cAcertificate} crossCertificatePair OBJECT-TYPE -- ATTRIBUTE SYNTAX CertificatePair ACCESS read-write STATUS mandatory ::= {id-at-crossCertificatePair} authorityRevocationList OBJECT-TYPE -- ATTRIBUTE SYNTAX CertificateList ACCESS read-write STATUS mandatory ::= {id-at-authorityRevocationList} certificateRevocationList OBJECT-TYPE -- ATTRIBUTE SYNTAX CertificateList ACCESS read-write STATUS mandatory ::= {id-at-certificateRevocationList} attributeCertificateRevocationList OBJECT-TYPE -- ATTRIBUTE SYNTAX CertificateList ACCESS read-write STATUS mandatory ::= {id-at-attributeCertificateRevocationList} -- object identifier assignments -- id-at-userPassword OBJECT IDENTIFIER ::= {id-at 35} id-at-userCertificate OBJECT IDENTIFIER ::= {id-at 36} id-at-cAcertificate OBJECT IDENTIFIER ::= {id-at 37} id-at-authorityRevocationList OBJECT IDENTIFIER ::= {id-at 38} id-at-certificateRevocationList OBJECT IDENTIFIER ::= {id-at 39} id-at-crossCertificatePair OBJECT IDENTIFIER ::= {id-at 40} id-at-attributeCertificate OBJECT IDENTIFIER ::= {id-at 58} id-at-attributeCertificateRevocationList OBJECT IDENTIFIER ::= {id-at 59} id-infosec OBJECT IDENTIFIER ::= { joint-iso-ccitt country (16) us (840) organization (1) us-government (101) dod (2) 1 } infosec-algorithm OBJECT IDENTIFIER ::= { id-infosec 1 } id-fortezzaKeyManagementAlgorithm OBJECT IDENTIFIER ::= { infosec-algorithm 10 } id-fortezzaUpdatedSigAlgorithm OBJECT IDENTIFIER ::= { infosec-algorithm 19 } id-fortezzaKMandUpdSigAlgorithms OBJECT IDENTIFIER ::= { infosec-algorithm 20 } id-keyExchangeAlgorithm OBJECT IDENTIFIER ::= { infosec-algorithm 22 } x9cm OBJECT IDENTIFIER ::= { iso member-body us (840) x9-57 (10040) } x9algorithm OBJECT IDENTIFIER ::= { x9cm 4 } id-dsa OBJECT IDENTIFIER ::= { x9algorithm 1 } id-dsa-with-sha1 OBJECT IDENTIFIER ::= { x9algorithm 3 } pkcs OBJECT IDENTIFIER ::= { iso member-body us (840) rsadsi (113549) 1 } pkcs-1 OBJECT IDENTIFIER ::= { pkcs 1 } pkcs-3 OBJECT IDENTIFIER ::= { pkcs 3 } pkcs-9 OBJECT IDENTIFIER ::= { pkcs 9 } rsaEncryption OBJECT IDENTIFIER ::= { pkcs-1 1 } md2WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 2 } md4WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 3 } md5WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 4 } dhKeyAgreement OBJECT IDENTIFIER ::= { pkcs-3 1 } END esnacc-ng-1.8.1/asn1specs/certificateextensions.asn1000066400000000000000000000243671302010526100224470ustar00rootroot00000000000000CertificateExtensions -- {joint-iso-ccitt ds(5) module(1) certificateExtensions(26) 0} DEFINITIONS IMPLICIT TAGS ::= BEGIN -- EXPORTS ALL -- IMPORTS id-at, id-ce, id-mr FROM UsefulDefinitions Name, RelativeDistinguishedName, Attribute FROM InformationFramework CertificateSerialNumber, CertificateList, AlgorithmIdentifier FROM AuthenticationFramework DirectoryString FROM SelectedAttributeTypes ub-name FROM UpperBounds ORAddress FROM ORAddressModule ; -- Unless explicitly noted otherwise, there is no significance to the ordering -- of components of a SEQUENCE OF construct in this specification. -- Key and policy information extensions -- authorityKeyIdentifierExtension OBJECT-TYPE -- EXTENSION SYNTAX AuthorityKeyIdentifier ACCESS read-write STATUS mandatory ::= {id-ce-authorityKeyIdentifier} AuthorityKeyIdentifier ::= SEQUENCE { keyIdentifier [0] KeyIdentifier OPTIONAL, authorityCertIssuer [1] GeneralNames OPTIONAL, authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL } ( WITH COMPONENTS {..., authorityCertIssuer PRESENT, authorityCertSerialNumber PRESENT} | WITH COMPONENTS {..., authorityCertIssuer ABSENT, authorityCertSerialNumber ABSENT} ) KeyIdentifier ::= OCTET STRING subjectKeyIdentifierExtension OBJECT-TYPE -- EXTENSION SYNTAX SubjectKeyIdentifier ACCESS read-write STATUS mandatory ::= {id-ce-subjectKeyIdentifier} SubjectKeyIdentifier ::= KeyIdentifier keyUsageExtension OBJECT-TYPE -- EXTENSION SYNTAX KeyUsage ACCESS read-write STATUS mandatory ::= {id-ce-keyUsage} KeyUsage ::= BIT STRING { digitalSignature (0), nonRepudiation (1), keyEncipherment (2), dataEncipherment (3), keyAgreement (4), keyCertSign (5), cRLSign (6), encipherOnly (7), decipherOnly (8) } extKeyUsageExtension OBJECT-TYPE -- EXTENSION SYNTAX SEQUENCE SIZE (1..MAX) OF KeyPurposeId ACCESS read-write STATUS mandatory ::= {id-ce-extKeyUsage} KeyPurposeId ::= OBJECT IDENTIFIER privateKeyUsagePeriodExtension OBJECT-TYPE -- EXTENSION SYNTAX PrivateKeyUsagePeriod ACCESS read-write STATUS mandatory ::= {id-ce-privateKeyUsagePeriod} PrivateKeyUsagePeriod ::= SEQUENCE { notBefore [0] GeneralizedTime OPTIONAL, notAfter [1] GeneralizedTime OPTIONAL } ( WITH COMPONENTS {..., notBefore PRESENT} | WITH COMPONENTS {..., notAfter PRESENT} ) certificatePoliciesExtension OBJECT-TYPE -- EXTENSION SYNTAX CertificatePoliciesSyntax ACCESS read-write STATUS mandatory ::= {id-ce-certificatePolicies} CertificatePoliciesSyntax ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation PolicyInformation ::= SEQUENCE { policyIdentifier CertPolicyId, policyQualifiers SEQUENCE SIZE (1..MAX) OF PolicyQualifierInfo OPTIONAL } CertPolicyId ::= OBJECT IDENTIFIER PolicyQualifierInfo ::= SEQUENCE { policyQualifierId OBJECT IDENTIFIER, qualifier ANY DEFINED BY policyQualifierId OPTIONAL } policyMappingsExtension OBJECT-TYPE -- EXTENSION SYNTAX PolicyMappingsSyntax ACCESS read-write STATUS mandatory ::= {id-ce-policyMappings} PolicyMappingsSyntax ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE { issuerDomainPolicy CertPolicyId, subjectDomainPolicy CertPolicyId } supportedAlgorithms OBJECT-TYPE -- ATTRIBUTE SYNTAX SupportedAlgorithm ACCESS read-write STATUS mandatory ::= {id-at-supportedAlgorithms} SupportedAlgorithm ::= SEQUENCE { algorithmIdentifier AlgorithmIdentifier, intendedUsage [0] KeyUsage OPTIONAL, intendedCertificatePolicies [1] CertificatePoliciesSyntax OPTIONAL } -- Certificate subject and certificate issuer attributes extensions -- subjectAltName OBJECT-TYPE -- EXTENSION SYNTAX GeneralNames ACCESS read-write STATUS mandatory ::= {id-ce-subjectAltName} GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName GeneralName ::= CHOICE { otherName [0] Other-Name, rfc822Name [1] IA5String, dNSName [2] IA5String, x400Address [3] ORAddress, directoryName [4] Name, ediPartyName [5] EDIPartyName, uniformResourceIdentifier [6] IA5String, iPAddress [7] OCTET STRING, registeredID [8] OBJECT IDENTIFIER } Other-Name ::= SEQUENCE { id OBJECT IDENTIFIER, type ANY DEFINED BY id } EDIPartyName ::= SEQUENCE { nameAssigner [0] DirectoryString (SIZE (1..ub-name)) OPTIONAL, partyName [1] DirectoryString (SIZE (1..ub-name)) } issuerAltName OBJECT-TYPE -- EXTENSION SYNTAX GeneralNames ACCESS read-write STATUS mandatory ::= {id-ce-issuerAltName} subjectDirectoryAttributes OBJECT-TYPE -- EXTENSION SYNTAX AttributesSyntax ACCESS read-write STATUS mandatory ::= {id-ce-subjectDirectoryAttributes} AttributesSyntax ::= SEQUENCE SIZE (1..MAX) OF Attribute -- Certification path constraints extensions -- basicConstraints OBJECT-TYPE -- EXTENSION SYNTAX BasicConstraintsSyntax ACCESS read-write STATUS mandatory ::= {id-ce-basicConstraints} BasicConstraintsSyntax ::= SEQUENCE { cA BOOLEAN DEFAULT FALSE, pathLenConstraint INTEGER (0..MAX) OPTIONAL } nameConstraints OBJECT-TYPE -- EXTENSION SYNTAX NameConstraintsSyntax ACCESS read-write STATUS mandatory ::= {id-ce-nameConstraints} NameConstraintsSyntax ::= SEQUENCE { permittedSubtrees [0] GeneralSubtrees OPTIONAL, excludedSubtrees [1] GeneralSubtrees OPTIONAL } GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree GeneralSubtree ::= SEQUENCE { base GeneralName, minimum [0] BaseDistance DEFAULT 0, maximum [1] BaseDistance OPTIONAL } BaseDistance ::= INTEGER (0..MAX) policyConstraints OBJECT-TYPE -- EXTENSION SYNTAX PolicyConstraintsSyntax ACCESS read-write STATUS mandatory ::= {id-ce-policyConstraints} PolicyConstraintsSyntax ::= SEQUENCE { requireExplicitPolicy [0] SkipCerts OPTIONAL, inhibitPolicyMapping [1] SkipCerts OPTIONAL } SkipCerts ::= INTEGER (0..MAX) CertPolicySet ::= SEQUENCE SIZE(1..MAX) OF CertPolicyId -- Basic CRL extensions -- cRLNumber OBJECT-TYPE -- EXTENSION SYNTAX CRLNumber ACCESS read-write STATUS mandatory ::= {id-ce-cRLNumber} CRLNumber ::= [UNIVERSAL 2] IMPLICIT OCTET STRING -- originally INTEGER (0..MAX) reasonCode OBJECT-TYPE -- EXTENSION SYNTAX CRLReason ACCESS read-write STATUS mandatory ::= {id-ce-reasonCode} CRLReason ::= ENUMERATED { unspecified (0), keyCompromise (1), cACompromise (2), affiliationChanged (3), superseded (4), cessationOfOperation (5), certificateHold (6), removeFromCRL (8) } instructionCode OBJECT-TYPE -- EXTENSION SYNTAX HoldInstruction ACCESS read-write STATUS mandatory ::= {id-ce-instructionCode} HoldInstruction ::= OBJECT IDENTIFIER invalidityDate OBJECT-TYPE -- EXTENSION SYNTAX GeneralizedTime ACCESS read-write STATUS mandatory ::= {id-ce-invalidityDate} -- CRL distribution points and delta-CRL extensions -- cRLDistributionPoints OBJECT-TYPE -- EXTENSION SYNTAX CRLDistPointsSyntax ACCESS read-write STATUS mandatory ::= {id-ce-cRLDistributionPoints} CRLDistPointsSyntax ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint DistributionPoint ::= SEQUENCE { distributionPoint [0] DistributionPointName OPTIONAL, reasons [1] ReasonFlags OPTIONAL, cRLIssuer [2] GeneralNames OPTIONAL } DistributionPointName ::= CHOICE { fullName [0] GeneralNames, nameRelativeToCRLIssuer [1] RelativeDistinguishedName } ReasonFlags ::= BIT STRING { unused (0), keyCompromise (1), caCompromise (2), affiliationChanged (3), superseded (4), cessationOfOperation (5), certificateHold (6) } issuingDistributionPoint OBJECT-TYPE -- EXTENSION SYNTAX IssuingDistPointSyntax ACCESS read-write STATUS mandatory ::= {id-ce-issuingDistributionPoint} IssuingDistPointSyntax ::= SEQUENCE { distributionPoint [0] DistributionPointName OPTIONAL, onlyContainsUserCerts [1] BOOLEAN DEFAULT FALSE, onlyContainsCACerts [2] BOOLEAN DEFAULT FALSE, onlySomeReasons [3] ReasonFlags OPTIONAL, indirectCRL [4] BOOLEAN DEFAULT FALSE } certificateIssuer OBJECT-TYPE -- EXTENSION SYNTAX GeneralNames ACCESS read-write STATUS mandatory ::= {id-ce-certificateIssuer} deltaCRLIndicator OBJECT-TYPE -- EXTENSION ::= { SYNTAX BaseCRLNumber ACCESS read-write STATUS mandatory ::= {id-ce-deltaCRLIndicator} BaseCRLNumber ::= CRLNumber deltaRevocationList OBJECT-TYPE -- ATTRIBUTE SYNTAX CertificateList ACCESS read-write STATUS mandatory ::= {id-at-deltaRevocationList} -- Object identifier assignments -- id-at-supportedAlgorithms OBJECT IDENTIFIER ::= {id-at 52} id-at-deltaRevocationList OBJECT IDENTIFIER ::= {id-at 53} id-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::= {id-ce 9} id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::= {id-ce 14} id-ce-keyUsage OBJECT IDENTIFIER ::= {id-ce 15} id-ce-privateKeyUsagePeriod OBJECT IDENTIFIER ::= {id-ce 16} id-ce-subjectAltName OBJECT IDENTIFIER ::= {id-ce 17} id-ce-issuerAltName OBJECT IDENTIFIER ::= {id-ce 18} id-ce-basicConstraints OBJECT IDENTIFIER ::= {id-ce 19} id-ce-cRLNumber OBJECT IDENTIFIER ::= {id-ce 20} id-ce-reasonCode OBJECT IDENTIFIER ::= {id-ce 21} id-ce-instructionCode OBJECT IDENTIFIER ::= {id-ce 23} id-ce-invalidityDate OBJECT IDENTIFIER ::= {id-ce 24} id-ce-deltaCRLIndicator OBJECT IDENTIFIER ::= {id-ce 27} id-ce-issuingDistributionPoint OBJECT IDENTIFIER ::= {id-ce 28} id-ce-certificateIssuer OBJECT IDENTIFIER ::= {id-ce 29} id-ce-nameConstraints OBJECT IDENTIFIER ::= {id-ce 30} id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::= {id-ce 31} id-ce-certificatePolicies OBJECT IDENTIFIER ::= {id-ce 32} id-ce-policyMappings OBJECT IDENTIFIER ::= {id-ce 33} -- deprecated OBJECT IDENTIFIER ::= {id-ce 34} id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::= {id-ce 35} id-ce-policyConstraints OBJECT IDENTIFIER ::= {id-ce 36} id-ce-extKeyUsage OBJECT IDENTIFIER ::= {id-ce 37} id-mr-certificateExactMatch OBJECT IDENTIFIER ::= {id-mr 34} id-mr-certificateMatch OBJECT IDENTIFIER ::= {id-mr 35} id-mr-certificatePairExactMatch OBJECT IDENTIFIER ::= {id-mr 36} id-mr-certificatePairMatch OBJECT IDENTIFIER ::= {id-mr 37} id-mr-certificateListExactMatch OBJECT IDENTIFIER ::= {id-mr 38} id-mr-certificateListMatch OBJECT IDENTIFIER ::= {id-mr 39} id-mr-algorithmIdentifierMatch OBJECT IDENTIFIER ::= {id-mr 40} -- The following OBJECT IDENTIFIERS are not used by this specification: -- {id-ce 2}, {id-ce 3}, {id-ce 4}, {id-ce 5}, {id-ce 6}, {id-ce 7}, -- {id-ce 8}, {id-ce 10}, {id-ce 11}, {id-ce 12}, {id-ce 13}, -- {id-ce 22}, {id-ce 25}, {id-ce 26} END esnacc-ng-1.8.1/asn1specs/err-test.asn1000066400000000000000000000110611302010526100175750ustar00rootroot00000000000000-- .../asn1specs/err_test.asn1 -- -- This module exercises snacc's semantic error checking of ASN.1 types. -- Every line that has the "error" comment should cause snacc to produce -- at least one error message -- -- Mike Sample 92/07 -- -- $Header: /baseline/SNACC/asn1specs/err-test.asn1,v 1.2 2003/12/17 19:05:03 gronej Exp $ -- $Log: err-test.asn1,v $ -- Revision 1.2 2003/12/17 19:05:03 gronej -- SNACC baseline merged with PER v1_7 tag -- -- Revision 1.1.2.1 2003/11/05 14:58:53 gronej -- working PER code merged with esnacc_1_6 -- -- Revision 1.1.1.1 2000/08/21 20:36:15 leonberp -- First CVS Version of SNACC. -- -- Revision 1.3 1995/07/25 19:53:16 rj -- changed `_' to `-' in file names. -- -- Revision 1.2 1994/08/28 09:54:17 rj -- comment leader fixed. -- -- Revision 1.1 1994/08/28 09:51:13 rj -- first check-in. ERROR-TEST DEFINITIONS ::= BEGIN -- first check that CHOICEs and SETs without distinct tags -- cause error msgs AChoice ::= CHOICE -- error { f1 [0] INTEGER, -- these two have the same f2 [0] INTEGER, -- tags f3 INTEGER, -- the tag of f3 f4 AChoice3 -- conflicts with one of AChoice3's elmt tags } ASet ::= SET -- error { f1 [0] INTEGER, -- same [0] tags f2 [0] INTEGER } T1 ::= INTEGER T2 ::= BOOLEAN AChoice2 ::= CHOICE -- error { T1, INTEGER } ASet2 ::= SET -- error { T2, BOOLEAN } AChoice3 ::= CHOICE { T1, T2 } -- -- now check that Sequence have distinct tags -- on one or consective optional elmts and following (if any) -- non-optional elmt -- ASequence ::= SEQUENCE -- no errors { f1 [0] INTEGER, f2 [0] BOOLEAN } ASequence1 ::= SEQUENCE { INTEGER OPTIONAL, INTEGER OPTIONAL, -- error, ambiguous values possible INTEGER, -- error INTEGER } ASequence3 ::= SEQUENCE { f1 [0] OBJECT IDENTIFIER OPTIONAL, f2 [1] INTEGER OPTIONAL, f3 [0] BOOLEAN, -- error f4 [2] OCTET STRING OPTIONAL, f5 [2] BIT STRING OPTIONAL, -- error f6 [3] ASequence OPTIONAL, f7 [3] INTEGER, -- error f8 [4] BOOLEAN OPTIONAL, f9 [4] INTEGER OPTIONAL -- error } -- -- now check that duplicate APPLICATION tag errors are reported -- Foo1 ::= [APPLICATION 0] INTEGER Foo2 ::= [APPLICATION 1] INTEGER Bar1 ::= [APPLICATION 0] IMPLICIT INTEGER -- error Bar2 ::= [APPLICATION 1] IMPLICIT INTEGER -- error -- -- check that field name errors are reported -- AChoice4 ::= CHOICE { f1 INTEGER, f2 BOOLEAN, [0] AChoice4 } ASet3 ::= SET { f1 [0] INTEGER, f2 [1] INTEGER, f3 [2] BOOLEAN, f3 [3] BOOLEAN, -- error, field name conflict [4] AChoice4 -- error, field name conflict too } -- -- now check some recursive type related errors -- A2 ::= A2 -- error A1 ::= B1 -- error B1 ::= A1 -- error C1 ::= D1 -- error D1 ::= E1 -- error E1 ::= F1 -- error F1 ::= C1 -- error RecSeq ::= SEQUENCE { INTEGER, BOOLEAN, RecSeq, -- warning, infinitely large values? RecSeq OPTIONAL -- this should be ok 'cause it's optional } -- -- now check some named bit and named number related errors -- aVal INTEGER ::= -4 Enum1 ::= ENUMERATED { zero(0), one(1), two(2), one(0) } -- 2 errors Int1 ::= INTEGER { zero(0), one(1), two(2), yoyo(2), one(7), foo(aVal) } -- 2 errors Bits1 ::= BIT STRING { zero(0), one(1), two(2), one(4), foo(-2), pogo(0), gogo(aVal) } -- 4 errors -- -- now check that implicitly tagged CHOICE, ANY and ANY DEFINED BY -- cause error msgs -- BChoice1 ::= [APPLICATION 5] IMPLICIT CHOICE -- error { INTEGER, BOOLEAN } BChoice2 ::= CHOICE -- no error { INTEGER, BOOLEAN } BChoice3 ::= [APPLICATION 6] CHOICE -- no error { INTEGER, BOOLEAN } BSeq ::= SEQUENCE { INTEGER, BOOLEAN, [0] IMPLICIT BChoice2, -- error [1] IMPLICIT BChoice3, -- no error [2] IMPLICIT CHOICE {INTEGER, BOOLEAN} -- error } -- -- now test that errors are reported for multiply defined -- types and valus -- TypeCopy1 ::= INTEGER TypeCopy1 ::= BOOLEAN TypeCopy1 ::= INTEGER valCopy1 INTEGER ::= 1 valCopy1 BOOLEAN ::= TRUE valCopy1 INTEGER ::= 1 -- -- test some OBJECT IDENTIFER value errors -- oid1 OBJECT IDENTIFIER ::= { oid1 ms(1) 1 } -- error: recursive value oid2 OBJECT IDENTIFIER ::= { oid1 ms(1) 2 } -- error: can only ref other oid values from first arc oid3 OBJECT IDENTIFIER ::= { ms(1) oid2 2 } boolVal BOOLEAN ::= TRUE intVal1 INTEGER ::= 1 intVal2 INTEGER ::= -1 oid4 OBJECT IDENTIFIER ::= { oid2 intVal1 intVal2 boolVal 1} oid5 OBJECT IDENTIFIER ::= { 1 2 -4} oid6 OBJECT IDENTIFIER ::= { oid7 1} oid7 OBJECT IDENTIFIER ::= { oid6 1 } END esnacc-ng-1.8.1/asn1specs/ex1.asn1000066400000000000000000000020651302010526100165310ustar00rootroot00000000000000-- file: .../asn1specs/ex1.asn1 -- -- This is an example ASN.1 module used in the documentation -- -- MS 92 -- -- $Header: /baseline/SNACC/asn1specs/ex1.asn1,v 1.2 2003/12/17 19:05:03 gronej Exp $ -- $Log: ex1.asn1,v $ -- Revision 1.2 2003/12/17 19:05:03 gronej -- SNACC baseline merged with PER v1_7 tag -- -- Revision 1.1.2.1 2003/11/05 14:58:53 gronej -- working PER code merged with esnacc_1_6 -- -- Revision 1.1.1.1 2000/08/21 20:36:15 leonberp -- First CVS Version of SNACC. -- -- Revision 1.2 1997/02/16 20:25:22 rj -- check-in of a few cosmetic changes -- -- Revision 1.1 1994/10/08 05:41:32 rj -- initial check-in. -- EX1 DEFINITIONS ::= BEGIN anOidVal OBJECT IDENTIFIER ::= { joint-iso-ccitt 40 foobar(29) } theSameOidVal OBJECT IDENTIFIER ::= { 2 40 29 } anIntVal INTEGER ::= 1 aBoolVal BOOLEAN ::= TRUE T1 ::= SEQUENCE { INTEGER OPTIONAL, OCTET STRING OPTIONAL, ENUMERATED { a(0), b(1), c(2) }, SEQUENCE OF INTEGER, SEQUENCE { id OBJECT IDENTIFIER, value OCTET STRING }, CHOICE { INTEGER, OBJECT IDENTIFIER } } END esnacc-ng-1.8.1/asn1specs/informationframework.asn1000066400000000000000000000050631302010526100223000ustar00rootroot00000000000000InformationFramework -- {joint-iso-ccitt ds(5) module(1) informationFramework(1) 3} DEFINITIONS ::= BEGIN -- EXPORTS All -- -- The types and values defined in this module are exported for use in the other ASN.1 modules contained -- within the Directory Specifications, and for the use of other applications which will use them to access -- Directory services. Other applications may use them for their own purposes, but this will not constrain -- extensions and modifications needed to maintain or improve the Directory service. IMPORTS id-at FROM UsefulDefinitions ; -- attribute data types -- Attribute ::= SEQUENCE { type OBJECT IDENTIFIER, values SET SIZE (1 .. MAX) OF ANY -- DEFINED BY type -- } AttributeType ::= OBJECT IDENTIFIER -- AttributeValue ::= ANY AttributeTypeAndValue ::= SEQUENCE { type OBJECT IDENTIFIER, value ANY DEFINED BY type } -- naming data types -- Name ::= CHOICE { -- only one possibility for now -- rdnSequence RDNSequence } RDNSequence ::= SEQUENCE OF RelativeDistinguishedName DistinguishedName ::= --snacc isPdu:"TRUE" -- RDNSequence RelativeDistinguishedName ::= SET SIZE (1 .. MAX) OF AttributeTypeAndDistinguishedValue --RWC;4/3/01;AttributeTypeAndDistinguishedValue ::= SEQUENCE { --RWC;4/3/01; type OBJECT IDENTIFIER, --RWC;4/3/01; value ANY DEFINED BY type, --RWC;4/3/01; primaryDistinguished BOOLEAN DEFAULT TRUE, --RWC;4/3/01; valuesWithContext SET SIZE (1 .. MAX) OF SEQUENCE{ --RWC;4/3/01; distingAttrValue ANY - DEFINED BY type - OPTIONAL, --RWC;4/3/01; contextList SET SIZE (1 .. MAX) OF Context } OPTIONAL } AttributeTypeAndDistinguishedValue ::= SEQUENCE { type OBJECT IDENTIFIER, value ANY, primaryDistinguished BOOLEAN DEFAULT TRUE, valuesWithContext SET SIZE (1 .. MAX) OF SEQUENCE { distingAttrValue OBJECT IDENTIFIER OPTIONAL, contextList SET SIZE (1 .. MAX) OF ANY } OPTIONAL } Context ::= SEQUENCE { contextType OBJECT IDENTIFIER, contextValues SET SIZE (1 .. MAX) OF ANY -- DEFINED BY contextType --, fallback BOOLEAN DEFAULT FALSE } -- attributes -- objectClassAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX OBJECT IDENTIFIER ACCESS read-write STATUS mandatory ::= {id-at-objectClass} aliasedEntryNameAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX DistinguishedName ACCESS read-write STATUS mandatory ::= {id-at-aliasedEntryName} -- object identifier assignments -- -- attributes -- id-at-objectClass OBJECT IDENTIFIER ::= {id-at 0} id-at-aliasedEntryName OBJECT IDENTIFIER ::= {id-at 1} END esnacc-ng-1.8.1/asn1specs/oraddress.asn1000066400000000000000000000244341302010526100200260ustar00rootroot00000000000000ORAddressModule -- From MTSAbstractService { joint-iso-ccitt mhs(6) mts(3) -- modules(0) mts-abstract-service(1) version-1994 (0) } DEFINITIONS IMPLICIT TAGS ::= BEGIN -- EXPORTS ALL -- IMPORTS PresentationAddress FROM SelectedAttributeTypes ; ORAddress ::= --snacc isPdu:"TRUE" -- SEQUENCE { standardAttributes StandardAttributes, domainDefinedAttributes DomainDefinedAttributes OPTIONAL, extensionAttributes ExtensionAttributes OPTIONAL } StandardAttributes ::= SEQUENCE { countryName CountryName OPTIONAL, administrationDomainName AdministrationDomainName OPTIONAL, networkAddress [0] NetworkAddress OPTIONAL, terminalIdentifier [1] TerminalIdentifier OPTIONAL, privateDomainName [2] PrivateDomainName OPTIONAL, organizationName [3] OrganizationName OPTIONAL, numericUserIdentifier [4] NumericUserIdentifier OPTIONAL, personalName [5] PersonalName OPTIONAL, organizationalUnitNames [6] OrganizationalUnitNames OPTIONAL } CountryName ::= [APPLICATION 1] CHOICE { x121DccCode NumericString (SIZE (ub-country-name-numeric-length)), iso3166Alpha2Code PrintableString (SIZE (ub-country-name-alpha-length)) } AdministrationDomainName ::= [APPLICATION 2] CHOICE { numericString NumericString (SIZE (0..ub-domain-name-length)), printableString PrintableString (SIZE (0..ub-domain-name-length)) } NetworkAddress ::= X121Address X121Address ::= NumericString (SIZE (1..ub-x121-address-length)) TerminalIdentifier ::= PrintableString (SIZE (1..ub-terminal-id-length)) PrivateDomainName ::= CHOICE { numericString NumericString (SIZE (0..ub-domain-name-length)), printableString PrintableString (SIZE (0..ub-domain-name-length)) } OrganizationName ::= PrintableString (SIZE (1..ub-organization-name-length)) NumericUserIdentifier ::= NumericString (SIZE (1..ub-numeric-user-id-length)) PersonalName ::= SET { surname [0] PrintableString (SIZE(1..ub-surname-length)), given-name [1] PrintableString (SIZE(1..ub-given-name-length)), initials [2] PrintableString (SIZE(1..ub-initials-length)), generation-qualifier [3] PrintableString (SIZE(1..ub-generation-qualifier-length)) OPTIONAL } OrganizationalUnitName ::= PrintableString (SIZE (1..ub-organizational-unit-name-length)) OrganizationalUnitNames ::= SEQUENCE SIZE (1..ub-organizational-units) OF OrganizationalUnitName DomainDefinedAttributes ::= SEQUENCE SIZE (1..ub-domain-defined-attributes) OF DomainDefinedAttribute DomainDefinedAttribute ::= SEQUENCE { type PrintableString (SIZE (0..ub-domain-defined-attribute-type-length)), value PrintableString (SIZE (0..ub-domain-defined-attribute-value-length)) } ExtensionAttributes ::= SET SIZE (1..ub-extension-attributes) OF ExtensionAttribute ExtensionAttribute ::= SEQUENCE { extensionAttributeType [0] INTEGER, extensionAttributeValue [1] ANY DEFINED BY extensionAttributeType } commonNameExtAttribute OBJECT-TYPE -- EXTENSION-ATTRIBUTE SYNTAX CommonName ACCESS read-write STATUS mandatory ::= 1 CommonName ::= PrintableString (SIZE (1..ub-common-name-length)) teletexCommonNameExtAttribute OBJECT-TYPE -- EXTENSION-ATTRIBUTE SYNTAX TeletexCommonName ACCESS read-write STATUS mandatory ::= 2 TeletexCommonName ::= TeletexString (SIZE (1..ub-common-name-length)) teletexOrganizationNameExtAttribute OBJECT-TYPE -- EXTENSION-ATTRIBUTE SYNTAX TeletexOrganizationalName ACCESS read-write STATUS mandatory ::= 3 TeletexOrganizationalName ::= TeletexString (SIZE (1..ub-organization-name-length)) teletexPersonalNameExtAttribute OBJECT-TYPE -- EXTENSION-ATTRIBUTE SYNTAX TeletexPersonalName ACCESS read-write STATUS mandatory ::= 4 TeletexPersonalName ::= SET { surname [0] TeletexString (SIZE (1..ub-surname-length)), given-name [1] TeletexString (SIZE (1..ub-given-name-length)) OPTIONAL, initials [2] TeletexString (SIZE (1..ub-initials-length)) OPTIONAL, generation-qualifier [3] TeletexString (SIZE (1..ub-generation-qualifier-length)) OPTIONAL } teletexOrganizationalUnitNamesExtAttribute OBJECT-TYPE -- EXTENSION-ATTRIBUTE SYNTAX TeletexOrganizationUnitNames ACCESS read-write STATUS mandatory ::= 5 TeletexOrganizationUnitNames ::= SEQUENCE SIZE (1..ub-organizational-units) OF TeletexOrganizationalUnitName TeletexOrganizationalUnitName ::= TeletexString (SIZE (1..ub-organizational-unit-name-length)) teletexDomainDefinedAttributesExtAttribute OBJECT-TYPE -- EXTENSION-ATTRIBUTE SYNTAX TeletexDomainDefinedAttributes ACCESS read-write STATUS mandatory ::= 6 TeletexDomainDefinedAttributes ::= SEQUENCE SIZE (1..ub-domain-defined-attributes) OF TeletexDomainDefinedAttribute TeletexDomainDefinedAttribute ::= SEQUENCE { type TeletexString (SIZE (1..ub-domain-defined-attribute-type-length)), value TeletexString (SIZE (1..ub-domain-defined-attribute-value-length)) } pdsNameExtAttribute OBJECT-TYPE -- EXTENSION-ATTRIBUTE SYNTAX PDSName ACCESS read-write STATUS mandatory ::= 7 PDSName ::= PrintableString (SIZE (1..ub-pds-name-length)) physicalDeliveryCountryNameExtAttribute OBJECT-TYPE -- EXTENSION-ATTRIBUTE SYNTAX PhysicalDeliveryCountryName ACCESS read-write STATUS mandatory ::= 8 PhysicalDeliveryCountryName ::= CHOICE { x121-dcc-code NumericString (SIZE (ub-country-name-numeric-length)), iso-3166-alpha2-code PrintableString (SIZE (ub-country-name-numeric-length)) } postalCodeExtAttribute OBJECT-TYPE -- EXTENSION-ATTRIBUTE SYNTAX PostalCode ACCESS read-write STATUS mandatory ::= 9 PostalCode ::= CHOICE { numericCode NumericString (SIZE (1..ub-postal-code-length)), printableCode PrintableString (SIZE (1..ub-postal-code-length)) } physicalDeliveryOfficeNameExtAttribute OBJECT-TYPE -- EXTENSION-ATTRIBUTE SYNTAX PhysicalDeliveryOfficeName ACCESS read-write STATUS mandatory ::= 10 PhysicalDeliveryOfficeName ::= PDSParameter physicalDeliveryOfficeNumberExtAttribute OBJECT-TYPE -- EXTENSION-ATTRIBUTE SYNTAX PhysicalDeliveryOfficeNumber ACCESS read-write STATUS mandatory ::= 11 PhysicalDeliveryOfficeNumber ::= PDSParameter extensionORAddressComponentsExtAttribute OBJECT-TYPE -- EXTENSION-ATTRIBUTE SYNTAX ExtensionORAddressComponents ACCESS read-write STATUS mandatory ::= 12 ExtensionORAddressComponents ::= PDSParameter physicalDeliveryPersonalNameExtAttribute OBJECT-TYPE -- EXTENSION-ATTRIBUTE SYNTAX PhysicalDeliveryPersonalName ACCESS read-write STATUS mandatory ::= 13 PhysicalDeliveryPersonalName ::= PDSParameter physicalDeliveryOrganizationNameExtAttribute OBJECT-TYPE -- EXTENSION-ATTRIBUTE SYNTAX PhysicalDeliveryOrganizationName ACCESS read-write STATUS mandatory ::= 14 PhysicalDeliveryOrganizationName ::= PDSParameter extensionPhysicalDeliveryAddressComponentsExtAttribute OBJECT-TYPE -- EXTENSION-ATTRIBUTE SYNTAX ExtensionPhysicalDeliveryAddressComponents ACCESS read-write STATUS mandatory ::= 15 ExtensionPhysicalDeliveryAddressComponents ::= PDSParameter unformattedPostalAddressExtAttribute OBJECT-TYPE -- EXTENSION-ATTRIBUTE SYNTAX UnformattedPostalAddress ACCESS read-write STATUS mandatory ::= 16 UnformattedPostalAddress ::= SET { printableAddress SEQUENCE SIZE(1..ub-pds-physical-address-lines) OF PrintableString (SIZE (1..ub-pds-parameter-length)) OPTIONAL, teletexString TeletexString (SIZE (1..ub-unformatted-address-length)) OPTIONAL } streetAddressExtAttribute OBJECT-TYPE -- EXTENSION-ATTRIBUTE SYNTAX StreetAddress ACCESS read-write STATUS mandatory ::= 17 StreetAddress ::= PDSParameter postOfficeBoxAddressExtAttribute OBJECT-TYPE -- EXTENSION-ATTRIBUTE SYNTAX PostOfficeBoxAddress ACCESS read-write STATUS mandatory ::= 18 PostOfficeBoxAddress ::= PDSParameter posteRestanteAddressExtAttribute OBJECT-TYPE -- EXTENSION-ATTRIBUTE SYNTAX PosteRestanteAddress ACCESS read-write STATUS mandatory ::= 19 PosteRestanteAddress ::= PDSParameter uniquePostalNameExtAttribute OBJECT-TYPE -- EXTENSION-ATTRIBUTE SYNTAX UniquePostalName ACCESS read-write STATUS mandatory ::= 20 UniquePostalName ::= PDSParameter localPostalAttributesExtAttribute OBJECT-TYPE -- EXTENSION-ATTRIBUTE SYNTAX LocalPostalAttributes ACCESS read-write STATUS mandatory ::= 21 LocalPostalAttributes ::= PDSParameter PDSParameter ::= SET { printableString PrintableString (SIZE (1..ub-pds-parameter-length)) OPTIONAL, teletexString TeletexString (SIZE (1..ub-pds-parameter-length)) OPTIONAL } extendedNetworkAddressExtAttribute OBJECT-TYPE -- EXTENSION-ATTRIBUTE SYNTAX ExtendedNetworkAddress ACCESS read-write STATUS mandatory ::= 22 ExtendedNetworkAddress ::= CHOICE { e1634Address SEQUENCE { number [0] NumericString (SIZE (1..ub-e163-4-number-length)), subAddress [1] NumericString (SIZE (1..ub-e163-4-sub-address-length )) OPTIONAL }, psapAddress [0] PresentationAddress } terminalTypeExtAttribute OBJECT-TYPE -- EXTENSION-ATTRIBUTE SYNTAX TerminalType ACCESS read-write STATUS mandatory ::= 23 TerminalType ::= INTEGER { telex (3), teletex (4), g3Facsimile (5), g4Facsimile (6), ia5Terminal (7), videotex (8) } (SIZE (0..ub-integer-options)) -- Upper bounds -- from MTSUpperBounds ub-integer-options INTEGER ::= 256 ub-x121-address-length INTEGER ::= 15 ub-country-name-numeric-length INTEGER ::= 3 ub-country-name-alpha-length INTEGER ::= 2 ub-domain-name-length INTEGER ::= 16 ub-terminal-id-length INTEGER ::= 24 ub-organization-name-length INTEGER ::= 64 ub-numeric-user-id-length INTEGER ::= 32 ub-surname-length INTEGER ::= 40 ub-given-name-length INTEGER ::= 16 ub-initials-length INTEGER ::= 5 ub-generation-qualifier-length INTEGER ::= 3 ub-organizational-units INTEGER ::= 4 ub-organizational-unit-name-length INTEGER ::= 32 ub-domain-defined-attributes INTEGER ::= 4 ub-domain-defined-attribute-type-length INTEGER ::= 8 ub-domain-defined-attribute-value-length INTEGER ::= 128 ub-extension-attributes INTEGER ::= 256 ub-common-name-length INTEGER ::= 64 ub-pds-name-length INTEGER ::= 16 ub-postal-code-length INTEGER ::= 16 ub-pds-parameter-length INTEGER ::= 30 ub-pds-physical-address-lines INTEGER ::= 6 ub-unformatted-address-length INTEGER ::= 180 ub-e163-4-number-length INTEGER ::= 15 ub-e163-4-sub-address-length INTEGER ::= 40 END esnacc-ng-1.8.1/asn1specs/p-rec.asn1000066400000000000000000000025211302010526100170370ustar00rootroot00000000000000-- file: .../asn1specs/p_rec.asn1 -- -- this file is used in ../c{,++}-examples/simple/ -- -- $Header: /baseline/SNACC/asn1specs/p-rec.asn1,v 1.2 2003/12/17 19:05:03 gronej Exp $ -- $Log: p-rec.asn1,v $ -- Revision 1.2 2003/12/17 19:05:03 gronej -- SNACC baseline merged with PER v1_7 tag -- -- Revision 1.1.2.1 2003/11/05 14:58:53 gronej -- working PER code merged with esnacc_1_6 -- -- Revision 1.1.1.1 2000/08/21 20:36:15 leonberp -- First CVS Version of SNACC. -- -- Revision 1.3 1997/09/16 14:55:30 wan -- Added test for "tag dividable by 128" case. -- -- Revision 1.2 1995/07/25 19:53:17 rj -- changed `_' to `-' in file names. -- -- Revision 1.1 1994/08/31 23:05:47 rj -- first check-in. -- P-REC DEFINITIONS ::= BEGIN PersonnelRecord ::= --snacc isPdu:"TRUE" -- [APPLICATION 0] IMPLICIT SET { name Name, title [0] IA5String, employeeNumber EmployeeNumber, dateOfHire [1] Date, nameOfSpouse [2] Name, children [3] IMPLICIT SEQUENCE OF ChildInformation DEFAULT {} } ChildInformation ::= SET { name Name, dateOfBirth [0] Date } Name ::= [APPLICATION 1] IMPLICIT SEQUENCE { givenName IA5String, initial IA5String, familyName IA5String } EmployeeNumber ::= [APPLICATION 128] IMPLICIT INTEGER Date ::= [APPLICATION 3] IMPLICIT IA5String -- YYYYMMDD END esnacc-ng-1.8.1/asn1specs/pkcs8.asn1000066400000000000000000000030551302010526100170640ustar00rootroot00000000000000PrivateKeyInfoSyntax -- from PKCS #8 and PKCS #1 DEFINITIONS ::= BEGIN EXPORTS EncryptedPrivateKeyInfo, PrivateKeyInfo ; IMPORTS Attribute FROM InformationFramework AlgorithmIdentifier FROM AuthenticationFramework ; EncryptedPrivateKeyInfo ::= --snacc isPdu:"TRUE" -- SEQUENCE { encryptionAlgorithm EncryptionAlgorithmIdentifier, encryptedData EncryptedData } EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier EncryptedData ::= OCTET STRING -- the encrypted PrivateKeyInfo PrivateKeyInfo ::= --snacc isPdu:"TRUE" -- SEQUENCE { version Version, privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, privateKey PrivateKey, attributes [0] IMPLICIT Attributes OPTIONAL } Version ::= INTEGER PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier PrivateKey ::= OCTET STRING -- for RSA, the BER encoding of RSAPrivateKey Attributes ::= SET OF Attribute RSAPrivateKey ::= --snacc isPdu:"TRUE" -- SEQUENCE { version Version, modulus [UNIVERSAL 2] IMPLICIT OCTET STRING, -- n publicExponent [UNIVERSAL 2] IMPLICIT OCTET STRING, -- e privateExponent [UNIVERSAL 2] IMPLICIT OCTET STRING, -- d prime1 [UNIVERSAL 2] IMPLICIT OCTET STRING, -- p prime2 [UNIVERSAL 2] IMPLICIT OCTET STRING, -- q exponent1 [UNIVERSAL 2] IMPLICIT OCTET STRING, -- d mod (p-1) exponent2 [UNIVERSAL 2] IMPLICIT OCTET STRING, -- d mod (q-1) coefficient [UNIVERSAL 2] IMPLICIT OCTET STRING } -- (inverse of q) mod p -- The above OCTET STRINGs in the RSAPrivateKey were originally INTEGERs -- Version is 0 for v1.5 of PKCS #1 END esnacc-ng-1.8.1/asn1specs/rfc1155-smi.asn1000066400000000000000000000121051302010526100177040ustar00rootroot00000000000000-- file: asn1specs/1155_smi.asn1 -- -- this file is used in ../c{,++}-examples/snmp/ -- -- $Header: /baseline/SNACC/asn1specs/rfc1155-smi.asn1,v 1.3 2003/12/17 19:05:03 gronej Exp $ -- $Log: rfc1155-smi.asn1,v $ -- Revision 1.3 2003/12/17 19:05:03 gronej -- SNACC baseline merged with PER v1_7 tag -- -- Revision 1.2.2.1 2003/11/05 14:58:53 gronej -- working PER code merged with esnacc_1_6 -- -- Revision 1.2 2002/02/28 21:41:28 vracarl -- changed private to myprivate because it's a C++ keyword -- -- Revision 1.1.1.1 2000/08/21 20:36:15 leonberp -- First CVS Version of SNACC. -- -- Revision 1.3 1995/07/27 08:29:16 rj -- rfc1155-smi.asn1, rfc1157-snmp.asn1 and rfc1213-mib2.asn1 renamed from 1155-smi.asn1, 1157-snmp.asn1 and 1213-mib2.asn1 to accomodate to snacc's new file name generation scheme. -- -- Revision 1.2 1995/07/25 19:53:12 rj -- changed `_' to `-' in file names. -- -- Revision 1.1 1994/08/31 23:08:26 rj -- first check-in. -- RFC1155-SMI DEFINITIONS ::= BEGIN EXPORTS -- EVERYTHING internet, directory, mgmt, experimental, myprivate, enterprises, OBJECT-TYPE, ObjectName, ObjectSyntax, SimpleSyntax, ApplicationSyntax, NetworkAddress, IpAddress, Counter, Gauge, TimeTicks, Opaque; -- the path to the root internet OBJECT IDENTIFIER ::= { iso org(3) dod(6) 1 } directory OBJECT IDENTIFIER ::= { internet 1 } mgmt OBJECT IDENTIFIER ::= { internet 2 } experimental OBJECT IDENTIFIER ::= { internet 3 } -- Commented out because private is a C++ keyword LTV -- private OBJECT IDENTIFIER ::= { internet 4 } myprivate OBJECT IDENTIFIER ::= { internet 4 } enterprises OBJECT IDENTIFIER ::= { myprivate 1 } -- definition of object types OBJECT-TYPE MACRO ::= BEGIN TYPE NOTATION ::= "SYNTAX" type (TYPE ObjectSyntax) "ACCESS" Access "STATUS" Status VALUE NOTATION ::= value (VALUE ObjectName) Access ::= "read-only" | "read-write" | "write-only" | "not-accessible" Status ::= "mandatory" | "optional" | "obsolete" END -- names of objects in the MIB ObjectName ::= OBJECT IDENTIFIER -- syntax of objects in the MIB ObjectSyntax ::= CHOICE { simple SimpleSyntax, -- note that simple SEQUENCEs are not directly -- mentioned here to keep things simple (i.e., -- prevent mis-use). However, application-wide -- types which are IMPLICITly encoded simple -- SEQUENCEs may appear in the following CHOICE application-wide ApplicationSyntax } SimpleSyntax ::= CHOICE { number INTEGER, string OCTET STRING, object OBJECT IDENTIFIER, empty NULL } ApplicationSyntax ::= CHOICE { address NetworkAddress, counter Counter, gauge Gauge, ticks TimeTicks, arbitrary Opaque -- other application-wide types, as they are -- defined, will be added here } -- application-wide types NetworkAddress ::= CHOICE { internet IpAddress } IpAddress ::= [APPLICATION 0] -- in network-byte order IMPLICIT OCTET STRING (SIZE (4)) Counter ::= [APPLICATION 1] IMPLICIT INTEGER (0..4294967295) Gauge ::= [APPLICATION 2] IMPLICIT INTEGER (0..4294967295) TimeTicks ::= [APPLICATION 3] IMPLICIT INTEGER (0..4294967295) Opaque ::= [APPLICATION 4] -- arbitrary ASN.1 value, IMPLICIT OCTET STRING -- "double-wrapped" END esnacc-ng-1.8.1/asn1specs/rfc1157-snmp.asn1000066400000000000000000000115441302010526100201010ustar00rootroot00000000000000-- file: asn1specs/1157_snmp.asn1 -- -- this file is used in ../c{,++}-examples/snmp/ -- -- $Header: /baseline/SNACC/asn1specs/rfc1157-snmp.asn1,v 1.2 2003/12/17 19:05:03 gronej Exp $ -- $Log: rfc1157-snmp.asn1,v $ -- Revision 1.2 2003/12/17 19:05:03 gronej -- SNACC baseline merged with PER v1_7 tag -- -- Revision 1.1.2.1 2003/11/05 14:58:53 gronej -- working PER code merged with esnacc_1_6 -- -- Revision 1.1.1.1 2000/08/21 20:36:15 leonberp -- First CVS Version of SNACC. -- -- Revision 1.3 1995/07/27 08:29:17 rj -- rfc1155-smi.asn1, rfc1157-snmp.asn1 and rfc1213-mib2.asn1 renamed from 1155-smi.asn1, 1157-snmp.asn1 and 1213-mib2.asn1 to accomodate to snacc's new file name generation scheme. -- -- Revision 1.2 1995/07/25 19:53:13 rj -- changed `_' to `-' in file names. -- -- Revision 1.1 1994/08/31 23:08:27 rj -- first check-in. -- RFC1157-SNMP DEFINITIONS ::= BEGIN IMPORTS ObjectName, ObjectSyntax, NetworkAddress, IpAddress, TimeTicks FROM RFC1155-SMI; -- top-level message Message ::= SEQUENCE { version -- version-1 for this RFC INTEGER { version-1(0) }, community -- community name OCTET STRING, data -- e.g., PDUs if trivial PDUs -- authentication is being used } -- protocol data units PDUs ::= CHOICE { get-request GetRequest-PDU, get-next-request GetNextRequest-PDU, get-response GetResponse-PDU, set-request SetRequest-PDU, trap Trap-PDU } -- PDUs GetRequest-PDU ::= [0] IMPLICIT PDU GetNextRequest-PDU ::= [1] IMPLICIT PDU GetResponse-PDU ::= [2] IMPLICIT PDU SetRequest-PDU ::= [3] IMPLICIT PDU PDU ::= SEQUENCE { request-id INTEGER, error-status -- sometimes ignored INTEGER { noError(0), tooBig(1), noSuchName(2), badValue(3), readOnly(4), genErr(5) }, error-index -- sometimes ignored INTEGER, variable-bindings -- values are sometimes ignored VarBindList } Trap-PDU ::= [4] IMPLICIT SEQUENCE { enterprise -- type of object generating -- trap, see sysObjectID in [5] OBJECT IDENTIFIER, agent-addr -- address of object generating NetworkAddress, -- trap generic-trap -- generic trap type INTEGER { coldStart(0), warmStart(1), linkDown(2), linkUp(3), authenticationFailure(4), egpNeighborLoss(5), enterpriseSpecific(6) }, specific-trap -- specific code, present even INTEGER, -- if generic-trap is not -- enterpriseSpecific time-stamp -- time elapsed between the last TimeTicks, -- (re)initialization of the -- network -- entity and the generation of the -- trap variable-bindings -- "interesting" information VarBindList } -- variable bindings VarBind ::= SEQUENCE { name ObjectName, value ObjectSyntax } VarBindList ::= SEQUENCE OF VarBind END esnacc-ng-1.8.1/asn1specs/rfc1213-mib2.asn1000066400000000000000000003124271302010526100177520ustar00rootroot00000000000000-- file: asn1specs/1213_mib2.asn1 -- -- this file is used in ../c{,++}-examples/snmp/ -- -- $Header: /baseline/SNACC/asn1specs/rfc1213-mib2.asn1,v 1.2 2003/12/17 19:05:03 gronej Exp $ -- $Log: rfc1213-mib2.asn1,v $ -- Revision 1.2 2003/12/17 19:05:03 gronej -- SNACC baseline merged with PER v1_7 tag -- -- Revision 1.1.2.1 2003/11/05 14:58:53 gronej -- working PER code merged with esnacc_1_6 -- -- Revision 1.1.1.1 2000/08/21 20:36:15 leonberp -- First CVS Version of SNACC. -- -- Revision 1.3 1995/07/27 08:29:19 rj -- rfc1155-smi.asn1, rfc1157-snmp.asn1 and rfc1213-mib2.asn1 renamed from 1155-smi.asn1, 1157-snmp.asn1 and 1213-mib2.asn1 to accomodate to snacc's new file name generation scheme. -- -- Revision 1.2 1995/07/25 19:53:14 rj -- changed `_' to `-' in file names. -- -- Revision 1.1 1994/08/31 23:08:28 rj -- first check-in. -- RFC1213-MIB DEFINITIONS ::= BEGIN IMPORTS mgmt, NetworkAddress, IpAddress, Counter, Gauge, TimeTicks FROM RFC1155-SMI -- OBJECT-TYPE -- FROM RFC-1212 ; -- This MIB module uses the extended OBJECT-TYPE macro as -- defined in [14]; -- MIB-II (same prefix as MIB-I) mib-2 OBJECT IDENTIFIER ::= { mgmt 1 } -- textual conventions DisplayString ::= OCTET STRING -- This data type is used to model textual information taken -- from the NVT ASCII character set. By convention, objects -- with this syntax are declared as having -- SIZE (0..255) PhysAddress ::= OCTET STRING -- This data type is used to model media addresses. For many -- types of media, this will be in a binary representation. -- For example, an ethernet address would be represented as -- a string of 6 octets. -- groups in MIB-II system OBJECT IDENTIFIER ::= { mib-2 1 } interfaces OBJECT IDENTIFIER ::= { mib-2 2 } at OBJECT IDENTIFIER ::= { mib-2 3 } ip OBJECT IDENTIFIER ::= { mib-2 4 } icmp OBJECT IDENTIFIER ::= { mib-2 5 } tcp OBJECT IDENTIFIER ::= { mib-2 6 } udp OBJECT IDENTIFIER ::= { mib-2 7 } egp OBJECT IDENTIFIER ::= { mib-2 8 } -- historical (some say hysterical) -- cmot OBJECT IDENTIFIER ::= { mib-2 9 } transmission OBJECT IDENTIFIER ::= { mib-2 10 } snmp OBJECT IDENTIFIER ::= { mib-2 11 } -- the System group -- Implementation of the System group is mandatory for all -- systems. If an agent is not configured to have a value -- for any of these variables, a string of length 0 is -- returned. sysDescr OBJECT-TYPE SYNTAX DisplayString (SIZE (0..255)) ACCESS read-only STATUS mandatory DESCRIPTION "A textual description of the entity. This value should include the full name and version identification of the system's hardware type, software operating-system, and networking software. It is mandatory that this only contain printable ASCII characters." ::= { system 1 } sysObjectID OBJECT-TYPE SYNTAX OBJECT IDENTIFIER ACCESS read-only STATUS mandatory DESCRIPTION "The vendor's authoritative identification of the network management subsystem contained in the entity. This value is allocated within the SMI enterprises subtree (1.3.6.1.4.1) and provides an easy and unambiguous means for determining `what kind of box' is being managed. For example, if vendor `Flintstones, Inc.' was assigned the subtree 1.3.6.1.4.1.4242, it could assign the identifier 1.3.6.1.4.1.4242.1.1 to its `Fred Router'." ::= { system 2 } sysUpTime OBJECT-TYPE SYNTAX TimeTicks ACCESS read-only STATUS mandatory DESCRIPTION "The time (in hundredths of a second) since the network management portion of the system was last re-initialized." ::= { system 3 } sysContact OBJECT-TYPE SYNTAX DisplayString (SIZE (0..255)) ACCESS read-write STATUS mandatory DESCRIPTION "The textual identification of the contact person for this managed node, together with information on how to contact this person." ::= { system 4 } sysName OBJECT-TYPE SYNTAX DisplayString (SIZE (0..255)) ACCESS read-write STATUS mandatory DESCRIPTION "An administratively-assigned name for this managed node. By convention, this is the node's fully-qualified domain name." ::= { system 5 } sysLocation OBJECT-TYPE SYNTAX DisplayString (SIZE (0..255)) ACCESS read-write STATUS mandatory DESCRIPTION "The physical location of this node (e.g., `telephone closet, 3rd floor')." ::= { system 6 } sysServices OBJECT-TYPE SYNTAX INTEGER (0..127) ACCESS read-only STATUS mandatory DESCRIPTION "A value which indicates the set of services that this entity primarily offers. The value is a sum. This sum initially takes the value zero, Then, for each layer, L, in the range 1 through 7, that this node performs transactions for, 2 raised to (L - 1) is added to the sum. For example, a node which performs primarily routing functions would have a value of 4 (2^(3-1)). In contrast, a node which is a host offering application services would have a value of 72 (2^(4-1) + 2^(7-1)). Note that in the context of the Internet suite of protocols, values should be calculated accordingly: layer functionality 1 physical (e.g., repeaters) 2 datalink/subnetwork (e.g., bridges) 3 internet (e.g., IP gateways) 4 end-to-end (e.g., IP hosts) 7 applications (e.g., mail relays) For systems including OSI protocols, layers 5 and 6 may also be counted." ::= { system 7 } -- the Interfaces group -- Implementation of the Interfaces group is mandatory for -- all systems. ifNumber OBJECT-TYPE SYNTAX INTEGER ACCESS read-only STATUS mandatory DESCRIPTION "The number of network interfaces (regardless of their current state) present on this system." ::= { interfaces 1 } -- the Interfaces table -- The Interfaces table contains information on the entity's -- interfaces. Each interface is thought of as being -- attached to a `subnetwork'. Note that this term should -- not be confused with `subnet' which refers to an -- addressing partitioning scheme used in the Internet suite -- of protocols. ifTable OBJECT-TYPE SYNTAX SEQUENCE OF IfEntry ACCESS not-accessible STATUS mandatory DESCRIPTION "A list of interface entries. The number of entries is given by the value of ifNumber." ::= { interfaces 2 } ifEntry OBJECT-TYPE SYNTAX IfEntry ACCESS not-accessible STATUS mandatory DESCRIPTION "An interface entry containing objects at the subnetwork layer and below for a particular interface." INDEX { ifIndex } ::= { ifTable 1 } IfEntry ::= SEQUENCE { ifIndex INTEGER, ifDescr DisplayString, ifType INTEGER, ifMtu INTEGER, ifSpeed Gauge, ifPhysAddress PhysAddress, ifAdminStatus INTEGER, ifOperStatus INTEGER, ifLastChange TimeTicks, ifInOctets Counter, ifInUcastPkts Counter, ifInNUcastPkts Counter, ifInDiscards Counter, ifInErrors Counter, ifInUnknownProtos Counter, ifOutOctets Counter, ifOutUcastPkts Counter, ifOutNUcastPkts Counter, ifOutDiscards Counter, ifOutErrors Counter, ifOutQLen Gauge, ifSpecific OBJECT IDENTIFIER } ifIndex OBJECT-TYPE SYNTAX INTEGER ACCESS read-only STATUS mandatory DESCRIPTION "A unique value for each interface. Its value ranges between 1 and the value of ifNumber. The value for each interface must remain constant at least from one re-initialization of the entity's network management system to the next re- initialization." ::= { ifEntry 1 } ifDescr OBJECT-TYPE SYNTAX DisplayString (SIZE (0..255)) ACCESS read-only STATUS mandatory DESCRIPTION "A textual string containing information about the interface. This string should include the name of the manufacturer, the product name and the version of the hardware interface." ::= { ifEntry 2 } ifType OBJECT-TYPE SYNTAX INTEGER { other(1), -- none of the following regular1822(2), hdh1822(3), ddn-x25(4), rfc877-x25(5), ethernet-csmacd(6), iso88023-csmacd(7), iso88024-tokenBus(8), iso88025-tokenRing(9), iso88026-man(10), starLan(11), proteon-10Mbit(12), proteon-80Mbit(13), hyperchannel(14), fddi(15), lapb(16), sdlc(17), ds1(18), -- T-1 e1(19), -- european equiv. of T-1 basicISDN(20), primaryISDN(21), -- proprietary serial propPointToPointSerial(22), ppp(23), softwareLoopback(24), eon(25), -- CLNP over IP [11] ethernet-3Mbit(26), nsip(27), -- XNS over IP slip(28), -- generic SLIP ultra(29), -- ULTRA technologies ds3(30), -- T-3 sip(31), -- SMDS frame-relay(32) } ACCESS read-only STATUS mandatory DESCRIPTION "The type of interface, distinguished according to the physical/link protocol(s) immediately `below' the network layer in the protocol stack." ::= { ifEntry 3 } ifMtu OBJECT-TYPE SYNTAX INTEGER ACCESS read-only STATUS mandatory DESCRIPTION "The size of the largest datagram which can be sent/received on the interface, specified in octets. For interfaces that are used for transmitting network datagrams, this is the size of the largest network datagram that can be sent on the interface." ::= { ifEntry 4 } ifSpeed OBJECT-TYPE SYNTAX Gauge ACCESS read-only STATUS mandatory DESCRIPTION "An estimate of the interface's current bandwidth in bits per second. For interfaces which do not vary in bandwidth or for those where no accurate estimation can be made, this object should contain the nominal bandwidth." ::= { ifEntry 5 } ifPhysAddress OBJECT-TYPE SYNTAX PhysAddress ACCESS read-only STATUS mandatory DESCRIPTION "The interface's address at the protocol layer immediately `below' the network layer in the protocol stack. For interfaces which do not have such an address (e.g., a serial line), this object should contain an octet string of zero length." ::= { ifEntry 6 } ifAdminStatus OBJECT-TYPE SYNTAX INTEGER { up(1), -- ready to pass packets down(2), testing(3) -- in some test mode } ACCESS read-write STATUS mandatory DESCRIPTION "The desired state of the interface. The testing(3) state indicates that no operational packets can be passed." ::= { ifEntry 7 } ifOperStatus OBJECT-TYPE SYNTAX INTEGER { up(1), -- ready to pass packets down(2), testing(3) -- in some test mode } ACCESS read-only STATUS mandatory DESCRIPTION "The current operational state of the interface. The testing(3) state indicates that no operational packets can be passed." ::= { ifEntry 8 } ifLastChange OBJECT-TYPE SYNTAX TimeTicks ACCESS read-only STATUS mandatory DESCRIPTION "The value of sysUpTime at the time the interface entered its current operational state. If the current state was entered prior to the last re- initialization of the local network management subsystem, then this object contains a zero value." ::= { ifEntry 9 } ifInOctets OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of octets received on the interface, including framing characters." ::= { ifEntry 10 } ifInUcastPkts OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of subnetwork-unicast packets delivered to a higher-layer protocol." ::= { ifEntry 11 } ifInNUcastPkts OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of non-unicast (i.e., subnetwork- broadcast or subnetwork-multicast) packets delivered to a higher-layer protocol." ::= { ifEntry 12 } ifInDiscards OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of inbound packets which were chosen to be discarded even though no errors had been detected to prevent their being deliverable to a higher-layer protocol. One possible reason for discarding such a packet could be to free up buffer space." ::= { ifEntry 13 } ifInErrors OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of inbound packets that contained errors preventing them from being deliverable to a higher-layer protocol." ::= { ifEntry 14 } ifInUnknownProtos OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of packets received via the interface which were discarded because of an unknown or unsupported protocol." ::= { ifEntry 15 } ifOutOctets OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of octets transmitted out of the interface, including framing characters." ::= { ifEntry 16 } ifOutUcastPkts OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of packets that higher-level protocols requested be transmitted to a subnetwork-unicast address, including those that were discarded or not sent." ::= { ifEntry 17 } ifOutNUcastPkts OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of packets that higher-level protocols requested be transmitted to a non- unicast (i.e., a subnetwork-broadcast or subnetwork-multicast) address, including those that were discarded or not sent." ::= { ifEntry 18 } ifOutDiscards OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of outbound packets which were chosen to be discarded even though no errors had been detected to prevent their being transmitted. One possible reason for discarding such a packet could be to free up buffer space." ::= { ifEntry 19 } ifOutErrors OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of outbound packets that could not be transmitted because of errors." ::= { ifEntry 20 } ifOutQLen OBJECT-TYPE SYNTAX Gauge ACCESS read-only STATUS mandatory DESCRIPTION "The length of the output packet queue (in packets)." ::= { ifEntry 21 } ifSpecific OBJECT-TYPE SYNTAX OBJECT IDENTIFIER ACCESS read-only STATUS mandatory DESCRIPTION "A reference to MIB definitions specific to the particular media being used to realize the interface. For example, if the interface is realized by an ethernet, then the value of this object refers to a document defining objects specific to ethernet. If this information is not present, its value should be set to the OBJECT IDENTIFIER { 0 0 }, which is a syntatically valid object identifier, and any conformant implementation of ASN.1 and BER must be able to generate and recognize this value." ::= { ifEntry 22 } -- the Address Translation group -- Implementation of the Address Translation group is -- mandatory for all systems. Note however that this group -- is deprecated by MIB-II. That is, it is being included -- solely for compatibility with MIB-I nodes, and will most -- likely be excluded from MIB-III nodes. From MIB-II and -- onwards, each network protocol group contains its own -- address translation tables. -- The Address Translation group contains one table which is -- the union across all interfaces of the translation tables -- for converting a NetworkAddress (e.g., an IP address) into -- a subnetwork-specific address. For lack of a better term, -- this document refers to such a subnetwork-specific address -- as a `physical' address. -- Examples of such translation tables are: for broadcast -- media where ARP is in use, the translation table is -- equivalent to the ARP cache; or, on an X.25 network where -- non-algorithmic translation to X.121 addresses is -- required, the translation table contains the -- NetworkAddress to X.121 address equivalences. atTable OBJECT-TYPE SYNTAX SEQUENCE OF AtEntry ACCESS not-accessible STATUS deprecated DESCRIPTION "The Address Translation tables contain the NetworkAddress to `physical' address equivalences. Some interfaces do not use translation tables for determining address equivalences (e.g., DDN-X.25 has an algorithmic method); if all interfaces are of this type, then the Address Translation table is empty, i.e., has zero entries." ::= { at 1 } atEntry OBJECT-TYPE SYNTAX AtEntry ACCESS not-accessible STATUS deprecated DESCRIPTION "Each entry contains one NetworkAddress to `physical' address equivalence." INDEX { atIfIndex, atNetAddress } ::= { atTable 1 } AtEntry ::= SEQUENCE { atIfIndex INTEGER, atPhysAddress PhysAddress, atNetAddress NetworkAddress } atIfIndex OBJECT-TYPE SYNTAX INTEGER ACCESS read-write STATUS deprecated DESCRIPTION "The interface on which this entry's equivalence is effective. The interface identified by a particular value of this index is the same interface as identified by the same value of ifIndex." ::= { atEntry 1 } atPhysAddress OBJECT-TYPE SYNTAX PhysAddress ACCESS read-write STATUS deprecated DESCRIPTION "The media-dependent `physical' address. Setting this object to a null string (one of zero length) has the effect of invaliding the corresponding entry in the atTable object. That is, it effectively dissasociates the interface identified with said entry from the mapping identified with said entry. It is an implementation-specific matter as to whether the agent removes an invalidated entry from the table. Accordingly, management stations must be prepared to receive tabular information from agents that corresponds to entries not currently in use. Proper interpretation of such entries requires examination of the relevant atPhysAddress object." ::= { atEntry 2 } atNetAddress OBJECT-TYPE SYNTAX NetworkAddress ACCESS read-write STATUS deprecated DESCRIPTION "The NetworkAddress (e.g., the IP address) corresponding to the media-dependent `physical' address." ::= { atEntry 3 } -- the IP group -- Implementation of the IP group is mandatory for all -- systems. ipForwarding OBJECT-TYPE SYNTAX INTEGER { forwarding(1), -- acting as a gateway not-forwarding(2) -- NOT acting as a gateway } ACCESS read-write STATUS mandatory DESCRIPTION "The indication of whether this entity is acting as an IP gateway in respect to the forwarding of datagrams received by, but not addressed to, this entity. IP gateways forward datagrams. IP hosts do not (except those source-routed via the host). Note that for some managed nodes, this object may take on only a subset of the values possible. Accordingly, it is appropriate for an agent to return a `badValue' response if a management station attempts to change this object to an inappropriate value." ::= { ip 1 } ipDefaultTTL OBJECT-TYPE SYNTAX INTEGER ACCESS read-write STATUS mandatory DESCRIPTION "The default value inserted into the Time-To-Live field of the IP header of datagrams originated at this entity, whenever a TTL value is not supplied by the transport layer protocol." ::= { ip 2 } ipInReceives OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of input datagrams received from interfaces, including those received in error." ::= { ip 3 } ipInHdrErrors OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of input datagrams discarded due to errors in their IP headers, including bad checksums, version number mismatch, other format errors, time-to-live exceeded, errors discovered in processing their IP options, etc." ::= { ip 4 } ipInAddrErrors OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of input datagrams discarded because the IP address in their IP header's destination field was not a valid address to be received at this entity. This count includes invalid addresses (e.g., 0.0.0.0) and addresses of unsupported Classes (e.g., Class E). For entities which are not IP Gateways and therefore do not forward datagrams, this counter includes datagrams discarded because the destination address was not a local address." ::= { ip 5 } ipForwDatagrams OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of input datagrams for which this entity was not their final IP destination, as a result of which an attempt was made to find a route to forward them to that final destination. In entities which do not act as IP Gateways, this counter will include only those packets which were Source-Routed via this entity, and the Source- Route option processing was successful." ::= { ip 6 } ipInUnknownProtos OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of locally-addressed datagrams received successfully but discarded because of an unknown or unsupported protocol." ::= { ip 7 } ipInDiscards OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of input IP datagrams for which no problems were encountered to prevent their continued processing, but which were discarded (e.g., for lack of buffer space). Note that this counter does not include any datagrams discarded while awaiting re-assembly." ::= { ip 8 } ipInDelivers OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of input datagrams successfully delivered to IP user-protocols (including ICMP)." ::= { ip 9 } ipOutRequests OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of IP datagrams which local IP user-protocols (including ICMP) supplied to IP in requests for transmission. Note that this counter does not include any datagrams counted in ipForwDatagrams." ::= { ip 10 } ipOutDiscards OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of output IP datagrams for which no problem was encountered to prevent their transmission to their destination, but which were discarded (e.g., for lack of buffer space). Note that this counter would include datagrams counted in ipForwDatagrams if any such packets met this (discretionary) discard criterion." ::= { ip 11 } ipOutNoRoutes OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of IP datagrams discarded because no route could be found to transmit them to their destination. Note that this counter includes any packets counted in ipForwDatagrams which meet this `no-route' criterion. Note that this includes any datagarms which a host cannot route because all of its default gateways are down." ::= { ip 12 } ipReasmTimeout OBJECT-TYPE SYNTAX INTEGER ACCESS read-only STATUS mandatory DESCRIPTION "The maximum number of seconds which received fragments are held while they are awaiting reassembly at this entity." ::= { ip 13 } ipReasmReqds OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of IP fragments received which needed to be reassembled at this entity." ::= { ip 14 } ipReasmOKs OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of IP datagrams successfully re- assembled." ::= { ip 15 } ipReasmFails OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of failures detected by the IP re- assembly algorithm (for whatever reason: timed out, errors, etc). Note that this is not necessarily a count of discarded IP fragments since some algorithms (notably the algorithm in RFC 815) can lose track of the number of fragments by combining them as they are received." ::= { ip 16 } ipFragOKs OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of IP datagrams that have been successfully fragmented at this entity." ::= { ip 17 } ipFragFails OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of IP datagrams that have been discarded because they needed to be fragmented at this entity but could not be, e.g., because their Don't Fragment flag was set." ::= { ip 18 } ipFragCreates OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of IP datagram fragments that have been generated as a result of fragmentation at this entity." ::= { ip 19 } -- the IP address table -- The IP address table contains this entity's IP addressing -- information. ipAddrTable OBJECT-TYPE SYNTAX SEQUENCE OF IpAddrEntry ACCESS not-accessible STATUS mandatory DESCRIPTION "The table of addressing information relevant to this entity's IP addresses." ::= { ip 20 } ipAddrEntry OBJECT-TYPE SYNTAX IpAddrEntry ACCESS not-accessible STATUS mandatory DESCRIPTION "The addressing information for one of this entity's IP addresses." INDEX { ipAdEntAddr } ::= { ipAddrTable 1 } IpAddrEntry ::= SEQUENCE { ipAdEntAddr IpAddress, ipAdEntIfIndex INTEGER, ipAdEntNetMask IpAddress, ipAdEntBcastAddr INTEGER, ipAdEntReasmMaxSize INTEGER (0..65535) } ipAdEntAddr OBJECT-TYPE SYNTAX IpAddress ACCESS read-only STATUS mandatory DESCRIPTION "The IP address to which this entry's addressing information pertains." ::= { ipAddrEntry 1 } ipAdEntIfIndex OBJECT-TYPE SYNTAX INTEGER ACCESS read-only STATUS mandatory DESCRIPTION "The index value which uniquely identifies the interface to which this entry is applicable. The interface identified by a particular value of this index is the same interface as identified by the same value of ifIndex." ::= { ipAddrEntry 2 } ipAdEntNetMask OBJECT-TYPE SYNTAX IpAddress ACCESS read-only STATUS mandatory DESCRIPTION "The subnet mask associated with the IP address of this entry. The value of the mask is an IP address with all the network bits set to 1 and all the hosts bits set to 0." ::= { ipAddrEntry 3 } ipAdEntBcastAddr OBJECT-TYPE SYNTAX INTEGER ACCESS read-only STATUS mandatory DESCRIPTION "The value of the least-significant bit in the IP broadcast address used for sending datagrams on the (logical) interface associated with the IP address of this entry. For example, when the Internet standard all-ones broadcast address is used, the value will be 1. This value applies to both the subnet and network broadcasts addresses used by the entity on this (logical) interface." ::= { ipAddrEntry 4 } ipAdEntReasmMaxSize OBJECT-TYPE SYNTAX INTEGER (0..65535) ACCESS read-only STATUS mandatory DESCRIPTION "The size of the largest IP datagram which this entity can re-assemble from incoming IP fragmented datagrams received on this interface." ::= { ipAddrEntry 5 } -- the IP routing table -- The IP routing table contains an entry for each route -- presently known to this entity. ipRouteTable OBJECT-TYPE SYNTAX SEQUENCE OF IpRouteEntry ACCESS not-accessible STATUS mandatory DESCRIPTION "This entity's IP Routing table." ::= { ip 21 } ipRouteEntry OBJECT-TYPE SYNTAX IpRouteEntry ACCESS not-accessible STATUS mandatory DESCRIPTION "A route to a particular destination." INDEX { ipRouteDest } ::= { ipRouteTable 1 } IpRouteEntry ::= SEQUENCE { ipRouteDest IpAddress, ipRouteIfIndex INTEGER, ipRouteMetric1 INTEGER, ipRouteMetric2 INTEGER, ipRouteMetric3 INTEGER, ipRouteMetric4 INTEGER, ipRouteNextHop IpAddress, ipRouteType INTEGER, ipRouteProto INTEGER, ipRouteAge INTEGER, ipRouteMask IpAddress, ipRouteMetric5 INTEGER, ipRouteInfo OBJECT IDENTIFIER } ipRouteDest OBJECT-TYPE SYNTAX IpAddress ACCESS read-write STATUS mandatory DESCRIPTION "The destination IP address of this route. An entry with a value of 0.0.0.0 is considered a default route. Multiple routes to a single destination can appear in the table, but access to such multiple entries is dependent on the table- access mechanisms defined by the network management protocol in use." ::= { ipRouteEntry 1 } ipRouteIfIndex OBJECT-TYPE SYNTAX INTEGER ACCESS read-write STATUS mandatory DESCRIPTION "The index value which uniquely identifies the local interface through which the next hop of this route should be reached. The interface identified by a particular value of this index is the same interface as identified by the same value of ifIndex." ::= { ipRouteEntry 2 } ipRouteMetric1 OBJECT-TYPE SYNTAX INTEGER ACCESS read-write STATUS mandatory DESCRIPTION "The primary routing metric for this route. The semantics of this metric are determined by the routing-protocol specified in the route's ipRouteProto value. If this metric is not used, its value should be set to -1." ::= { ipRouteEntry 3 } ipRouteMetric2 OBJECT-TYPE SYNTAX INTEGER ACCESS read-write STATUS mandatory DESCRIPTION "An alternate routing metric for this route. The semantics of this metric are determined by the routing-protocol specified in the route's ipRouteProto value. If this metric is not used, its value should be set to -1." ::= { ipRouteEntry 4 } ipRouteMetric3 OBJECT-TYPE SYNTAX INTEGER ACCESS read-write STATUS mandatory DESCRIPTION "An alternate routing metric for this route. The semantics of this metric are determined by the routing-protocol specified in the route's ipRouteProto value. If this metric is not used, its value should be set to -1." ::= { ipRouteEntry 5 } ipRouteMetric4 OBJECT-TYPE SYNTAX INTEGER ACCESS read-write STATUS mandatory DESCRIPTION "An alternate routing metric for this route. The semantics of this metric are determined by the routing-protocol specified in the route's ipRouteProto value. If this metric is not used, its value should be set to -1." ::= { ipRouteEntry 6 } ipRouteNextHop OBJECT-TYPE SYNTAX IpAddress ACCESS read-write STATUS mandatory DESCRIPTION "The IP address of the next hop of this route. (In the case of a route bound to an interface which is realized via a broadcast media, the value of this field is the agent's IP address on that interface.)" ::= { ipRouteEntry 7 } ipRouteType OBJECT-TYPE SYNTAX INTEGER { other(1), -- none of the following invalid(2), -- an invalidated route -- route to directly direct(3), -- connected (sub-)network -- route to a non-local indirect(4) -- host/network/sub-network } ACCESS read-write STATUS mandatory DESCRIPTION "The type of route. Note that the values direct(3) and indirect(4) refer to the notion of direct and indirect routing in the IP architecture. Setting this object to the value invalid(2) has the effect of invalidating the corresponding entry in the ipRouteTable object. That is, it effectively dissasociates the destination identified with said entry from the route identified with said entry. It is an implementation-specific matter as to whether the agent removes an invalidated entry from the table. Accordingly, management stations must be prepared to receive tabular information from agents that corresponds to entries not currently in use. Proper interpretation of such entries requires examination of the relevant ipRouteType object." ::= { ipRouteEntry 8 } ipRouteProto OBJECT-TYPE SYNTAX INTEGER { other(1), -- none of the following -- non-protocol information, -- e.g., manually configured local(2), -- entries -- set via a network netmgmt(3), -- management protocol -- obtained via ICMP, icmp(4), -- e.g., Redirect -- the remaining values are -- all gateway routing -- protocols egp(5), ggp(6), hello(7), rip(8), is-is(9), es-is(10), ciscoIgrp(11), bbnSpfIgp(12), ospf(13), bgp(14) } ACCESS read-only STATUS mandatory DESCRIPTION "The routing mechanism via which this route was learned. Inclusion of values for gateway routing protocols is not intended to imply that hosts should support those protocols." ::= { ipRouteEntry 9 } ipRouteAge OBJECT-TYPE SYNTAX INTEGER ACCESS read-write STATUS mandatory DESCRIPTION "The number of seconds since this route was last updated or otherwise determined to be correct. Note that no semantics of `too old' can be implied except through knowledge of the routing protocol by which the route was learned." ::= { ipRouteEntry 10 } ipRouteMask OBJECT-TYPE SYNTAX IpAddress ACCESS read-write STATUS mandatory DESCRIPTION "Indicate the mask to be logical-ANDed with the destination address before being compared to the value in the ipRouteDest field. For those systems that do not support arbitrary subnet masks, an agent constructs the value of the ipRouteMask by determining whether the value of the correspondent ipRouteDest field belong to a class-A, B, or C network, and then using one of: mask network 255.0.0.0 class-A 255.255.0.0 class-B 255.255.255.0 class-C If the value of the ipRouteDest is 0.0.0.0 (a default route), then the mask value is also 0.0.0.0. It should be noted that all IP routing subsystems implicitly use this mechanism." ::= { ipRouteEntry 11 } ipRouteMetric5 OBJECT-TYPE SYNTAX INTEGER ACCESS read-write STATUS mandatory DESCRIPTION "An alternate routing metric for this route. The semantics of this metric are determined by the routing-protocol specified in the route's ipRouteProto value. If this metric is not used, its value should be set to -1." ::= { ipRouteEntry 12 } ipRouteInfo OBJECT-TYPE SYNTAX OBJECT IDENTIFIER ACCESS read-only STATUS mandatory DESCRIPTION "A reference to MIB definitions specific to the particular routing protocol which is responsible for this route, as determined by the value specified in the route's ipRouteProto value. If this information is not present, its value should be set to the OBJECT IDENTIFIER { 0 0 }, which is a syntatically valid object identifier, and any conformant implementation of ASN.1 and BER must be able to generate and recognize this value." ::= { ipRouteEntry 13 } -- the IP Address Translation table -- The IP address translation table contain the IpAddress to -- `physical' address equivalences. Some interfaces do not -- use translation tables for determining address -- equivalences (e.g., DDN-X.25 has an algorithmic method); -- if all interfaces are of this type, then the Address -- Translation table is empty, i.e., has zero entries. ipNetToMediaTable OBJECT-TYPE SYNTAX SEQUENCE OF IpNetToMediaEntry ACCESS not-accessible STATUS mandatory DESCRIPTION "The IP Address Translation table used for mapping from IP addresses to physical addresses." ::= { ip 22 } ipNetToMediaEntry OBJECT-TYPE SYNTAX IpNetToMediaEntry ACCESS not-accessible STATUS mandatory DESCRIPTION "Each entry contains one IpAddress to `physical' address equivalence." INDEX { ipNetToMediaIfIndex, ipNetToMediaNetAddress } ::= { ipNetToMediaTable 1 } IpNetToMediaEntry ::= SEQUENCE { ipNetToMediaIfIndex INTEGER, ipNetToMediaPhysAddress PhysAddress, ipNetToMediaNetAddress IpAddress, ipNetToMediaType INTEGER } ipNetToMediaIfIndex OBJECT-TYPE SYNTAX INTEGER ACCESS read-write STATUS mandatory DESCRIPTION "The interface on which this entry's equivalence is effective. The interface identified by a particular value of this index is the same interface as identified by the same value of ifIndex." ::= { ipNetToMediaEntry 1 } ipNetToMediaPhysAddress OBJECT-TYPE SYNTAX PhysAddress ACCESS read-write STATUS mandatory DESCRIPTION "The media-dependent `physical' address." ::= { ipNetToMediaEntry 2 } ipNetToMediaNetAddress OBJECT-TYPE SYNTAX IpAddress ACCESS read-write STATUS mandatory DESCRIPTION "The IpAddress corresponding to the media- dependent `physical' address." ::= { ipNetToMediaEntry 3 } ipNetToMediaType OBJECT-TYPE SYNTAX INTEGER { other(1), -- none of the following invalid(2), -- an invalidated mapping dynamic(3), static(4) } ACCESS read-write STATUS mandatory DESCRIPTION "The type of mapping. Setting this object to the value invalid(2) has the effect of invalidating the corresponding entry in the ipNetToMediaTable. That is, it effectively dissasociates the interface identified with said entry from the mapping identified with said entry. It is an implementation-specific matter as to whether the agent removes an invalidated entry from the table. Accordingly, management stations must be prepared to receive tabular information from agents that corresponds to entries not currently in use. Proper interpretation of such entries requires examination of the relevant ipNetToMediaType object." ::= { ipNetToMediaEntry 4 } -- additional IP objects ipRoutingDiscards OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of routing entries which were chosen to be discarded even though they are valid. One possible reason for discarding such an entry could be to free-up buffer space for other routing entries." ::= { ip 23 } -- the ICMP group -- Implementation of the ICMP group is mandatory for all -- systems. icmpInMsgs OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of ICMP messages which the entity received. Note that this counter includes all those counted by icmpInErrors." ::= { icmp 1 } icmpInErrors OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of ICMP messages which the entity received but determined as having ICMP-specific errors (bad ICMP checksums, bad length, etc.)." ::= { icmp 2 } icmpInDestUnreachs OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of ICMP Destination Unreachable messages received." ::= { icmp 3 } icmpInTimeExcds OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of ICMP Time Exceeded messages received." ::= { icmp 4 } icmpInParmProbs OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of ICMP Parameter Problem messages received." ::= { icmp 5 } icmpInSrcQuenchs OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of ICMP Source Quench messages received." ::= { icmp 6 } icmpInRedirects OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of ICMP Redirect messages received." ::= { icmp 7 } icmpInEchos OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of ICMP Echo (request) messages received." ::= { icmp 8 } icmpInEchoReps OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of ICMP Echo Reply messages received." ::= { icmp 9 } icmpInTimestamps OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of ICMP Timestamp (request) messages received." ::= { icmp 10 } icmpInTimestampReps OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of ICMP Timestamp Reply messages received." ::= { icmp 11 } icmpInAddrMasks OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of ICMP Address Mask Request messages received." ::= { icmp 12 } icmpInAddrMaskReps OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of ICMP Address Mask Reply messages received." ::= { icmp 13 } icmpOutMsgs OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of ICMP messages which this entity attempted to send. Note that this counter includes all those counted by icmpOutErrors." ::= { icmp 14 } icmpOutErrors OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of ICMP messages which this entity did not send due to problems discovered within ICMP such as a lack of buffers. This value should not include errors discovered outside the ICMP layer such as the inability of IP to route the resultant datagram. In some implementations there may be no types of error which contribute to this counter's value." ::= { icmp 15 } icmpOutDestUnreachs OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of ICMP Destination Unreachable messages sent." ::= { icmp 16 } icmpOutTimeExcds OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of ICMP Time Exceeded messages sent." ::= { icmp 17 } icmpOutParmProbs OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of ICMP Parameter Problem messages sent." ::= { icmp 18 } icmpOutSrcQuenchs OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of ICMP Source Quench messages sent." ::= { icmp 19 } icmpOutRedirects OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of ICMP Redirect messages sent. For a host, this object will always be zero, since hosts do not send redirects." ::= { icmp 20 } icmpOutEchos OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of ICMP Echo (request) messages sent." ::= { icmp 21 } icmpOutEchoReps OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of ICMP Echo Reply messages sent." ::= { icmp 22 } icmpOutTimestamps OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of ICMP Timestamp (request) messages sent." ::= { icmp 23 } icmpOutTimestampReps OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of ICMP Timestamp Reply messages sent." ::= { icmp 24 } icmpOutAddrMasks OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of ICMP Address Mask Request messages sent." ::= { icmp 25 } icmpOutAddrMaskReps OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of ICMP Address Mask Reply messages sent." ::= { icmp 26 } -- the TCP group -- Implementation of the TCP group is mandatory for all -- systems that implement the TCP. -- Note that instances of object types that represent -- information about a particular TCP connection are -- transient; they persist only as long as the connection -- in question. tcpRtoAlgorithm OBJECT-TYPE SYNTAX INTEGER { other(1), -- none of the following constant(2), -- a constant rto rsre(3), -- MIL-STD-1778, Appendix B vanj(4) -- Van Jacobson's algorithm [10] } ACCESS read-only STATUS mandatory DESCRIPTION "The algorithm used to determine the timeout value used for retransmitting unacknowledged octets." ::= { tcp 1 } tcpRtoMin OBJECT-TYPE SYNTAX INTEGER ACCESS read-only STATUS mandatory DESCRIPTION "The minimum value permitted by a TCP implementation for the retransmission timeout, measured in milliseconds. More refined semantics for objects of this type depend upon the algorithm used to determine the retransmission timeout. In particular, when the timeout algorithm is rsre(3), an object of this type has the semantics of the LBOUND quantity described in RFC 793." ::= { tcp 2 } tcpRtoMax OBJECT-TYPE SYNTAX INTEGER ACCESS read-only STATUS mandatory DESCRIPTION "The maximum value permitted by a TCP implementation for the retransmission timeout, measured in milliseconds. More refined semantics for objects of this type depend upon the algorithm used to determine the retransmission timeout. In particular, when the timeout algorithm is rsre(3), an object of this type has the semantics of the UBOUND quantity described in RFC 793." ::= { tcp 3 } tcpMaxConn OBJECT-TYPE SYNTAX INTEGER ACCESS read-only STATUS mandatory DESCRIPTION "The limit on the total number of TCP connections the entity can support. In entities where the maximum number of connections is dynamic, this object should contain the value -1." ::= { tcp 4 } tcpActiveOpens OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of times TCP connections have made a direct transition to the SYN-SENT state from the CLOSED state." ::= { tcp 5 } tcpPassiveOpens OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of times TCP connections have made a direct transition to the SYN-RCVD state from the LISTEN state." ::= { tcp 6 } tcpAttemptFails OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of times TCP connections have made a direct transition to the CLOSED state from either the SYN-SENT state or the SYN-RCVD state, plus the number of times TCP connections have made a direct transition to the LISTEN state from the SYN-RCVD state." ::= { tcp 7 } tcpEstabResets OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of times TCP connections have made a direct transition to the CLOSED state from either the ESTABLISHED state or the CLOSE-WAIT state." ::= { tcp 8 } tcpCurrEstab OBJECT-TYPE SYNTAX Gauge ACCESS read-only STATUS mandatory DESCRIPTION "The number of TCP connections for which the current state is either ESTABLISHED or CLOSE- WAIT." ::= { tcp 9 } tcpInSegs OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of segments received, including those received in error. This count includes segments received on currently established connections." ::= { tcp 10 } tcpOutSegs OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of segments sent, including those on current connections but excluding those containing only retransmitted octets." ::= { tcp 11 } tcpRetransSegs OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of segments retransmitted - that is, the number of TCP segments transmitted containing one or more previously transmitted octets." ::= { tcp 12 } -- the TCP Connection table -- The TCP connection table contains information about this -- entity's existing TCP connections. tcpConnTable OBJECT-TYPE SYNTAX SEQUENCE OF TcpConnEntry ACCESS not-accessible STATUS mandatory DESCRIPTION "A table containing TCP connection-specific information." ::= { tcp 13 } tcpConnEntry OBJECT-TYPE SYNTAX TcpConnEntry ACCESS not-accessible STATUS mandatory DESCRIPTION "Information about a particular current TCP connection. An object of this type is transient, in that it ceases to exist when (or soon after) the connection makes the transition to the CLOSED state." INDEX { tcpConnLocalAddress, tcpConnLocalPort, tcpConnRemAddress, tcpConnRemPort } ::= { tcpConnTable 1 } TcpConnEntry ::= SEQUENCE { tcpConnState INTEGER, tcpConnLocalAddress IpAddress, tcpConnLocalPort INTEGER (0..65535), tcpConnRemAddress IpAddress, tcpConnRemPort INTEGER (0..65535) } tcpConnState OBJECT-TYPE SYNTAX INTEGER { closed(1), listen(2), synSent(3), synReceived(4), established(5), finWait1(6), finWait2(7), closeWait(8), lastAck(9), closing(10), timeWait(11), deleteTCB(12) } ACCESS read-write STATUS mandatory DESCRIPTION "The state of this TCP connection. The only value which may be set by a management station is deleteTCB(12). Accordingly, it is appropriate for an agent to return a `badValue' response if a management station attempts to set this object to any other value. If a management station sets this object to the value deleteTCB(12), then this has the effect of deleting the TCB (as defined in RFC 793) of the corresponding connection on the managed node, resulting in immediate termination of the connection. As an implementation-specific option, a RST segment may be sent from the managed node to the other TCP endpoint (note however that RST segments are not sent reliably)." ::= { tcpConnEntry 1 } tcpConnLocalAddress OBJECT-TYPE SYNTAX IpAddress ACCESS read-only STATUS mandatory DESCRIPTION "The local IP address for this TCP connection. In the case of a connection in the listen state which is willing to accept connections for any IP interface associated with the node, the value 0.0.0.0 is used." ::= { tcpConnEntry 2 } tcpConnLocalPort OBJECT-TYPE SYNTAX INTEGER (0..65535) ACCESS read-only STATUS mandatory DESCRIPTION "The local port number for this TCP connection." ::= { tcpConnEntry 3 } tcpConnRemAddress OBJECT-TYPE SYNTAX IpAddress ACCESS read-only STATUS mandatory DESCRIPTION "The remote IP address for this TCP connection." ::= { tcpConnEntry 4 } tcpConnRemPort OBJECT-TYPE SYNTAX INTEGER (0..65535) ACCESS read-only STATUS mandatory DESCRIPTION "The remote port number for this TCP connection." ::= { tcpConnEntry 5 } -- additional TCP objects tcpInErrs OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of segments received in error (e.g., bad TCP checksums)." ::= { tcp 14 } tcpOutRsts OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of TCP segments sent containing the RST flag." ::= { tcp 15 } -- the UDP group -- Implementation of the UDP group is mandatory for all -- systems which implement the UDP. udpInDatagrams OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of UDP datagrams delivered to UDP users." ::= { udp 1 } udpNoPorts OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of received UDP datagrams for which there was no application at the destination port." ::= { udp 2 } udpInErrors OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of received UDP datagrams that could not be delivered for reasons other than the lack of an application at the destination port." ::= { udp 3 } udpOutDatagrams OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of UDP datagrams sent from this entity." ::= { udp 4 } -- the UDP Listener table -- The UDP listener table contains information about this -- entity's UDP end-points on which a local application is -- currently accepting datagrams. udpTable OBJECT-TYPE SYNTAX SEQUENCE OF UdpEntry ACCESS not-accessible STATUS mandatory DESCRIPTION "A table containing UDP listener information." ::= { udp 5 } udpEntry OBJECT-TYPE SYNTAX UdpEntry ACCESS not-accessible STATUS mandatory DESCRIPTION "Information about a particular current UDP listener." INDEX { udpLocalAddress, udpLocalPort } ::= { udpTable 1 } UdpEntry ::= SEQUENCE { udpLocalAddress IpAddress, udpLocalPort INTEGER (0..65535) } udpLocalAddress OBJECT-TYPE SYNTAX IpAddress ACCESS read-only STATUS mandatory DESCRIPTION "The local IP address for this UDP listener. In the case of a UDP listener which is willing to accept datagrams for any IP interface associated with the node, the value 0.0.0.0 is used." ::= { udpEntry 1 } udpLocalPort OBJECT-TYPE SYNTAX INTEGER (0..65535) ACCESS read-only STATUS mandatory DESCRIPTION "The local port number for this UDP listener." ::= { udpEntry 2 } -- the EGP group -- Implementation of the EGP group is mandatory for all -- systems which implement the EGP. egpInMsgs OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of EGP messages received without error." ::= { egp 1 } egpInErrors OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of EGP messages received that proved to be in error." ::= { egp 2 } egpOutMsgs OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of locally generated EGP messages." ::= { egp 3 } egpOutErrors OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of locally generated EGP messages not sent due to resource limitations within an EGP entity." ::= { egp 4 } -- the EGP Neighbor table -- The EGP neighbor table contains information about this -- entity's EGP neighbors. egpNeighTable OBJECT-TYPE SYNTAX SEQUENCE OF EgpNeighEntry ACCESS not-accessible STATUS mandatory DESCRIPTION "The EGP neighbor table." ::= { egp 5 } egpNeighEntry OBJECT-TYPE SYNTAX EgpNeighEntry ACCESS not-accessible STATUS mandatory DESCRIPTION "Information about this entity's relationship with a particular EGP neighbor." INDEX { egpNeighAddr } ::= { egpNeighTable 1 } EgpNeighEntry ::= SEQUENCE { egpNeighState INTEGER, egpNeighAddr IpAddress, egpNeighAs INTEGER, egpNeighInMsgs Counter, egpNeighInErrs Counter, egpNeighOutMsgs Counter, egpNeighOutErrs Counter, egpNeighInErrMsgs Counter, egpNeighOutErrMsgs Counter, egpNeighStateUps Counter, egpNeighStateDowns Counter, egpNeighIntervalHello INTEGER, egpNeighIntervalPoll INTEGER, egpNeighMode INTEGER, egpNeighEventTrigger INTEGER } egpNeighState OBJECT-TYPE SYNTAX INTEGER { idle(1), acquisition(2), down(3), up(4), cease(5) } ACCESS read-only STATUS mandatory DESCRIPTION "The EGP state of the local system with respect to this entry's EGP neighbor. Each EGP state is represented by a value that is one greater than the numerical value associated with said state in RFC 904." ::= { egpNeighEntry 1 } egpNeighAddr OBJECT-TYPE SYNTAX IpAddress ACCESS read-only STATUS mandatory DESCRIPTION "The IP address of this entry's EGP neighbor." ::= { egpNeighEntry 2 } egpNeighAs OBJECT-TYPE SYNTAX INTEGER ACCESS read-only STATUS mandatory DESCRIPTION "The autonomous system of this EGP peer. Zero should be specified if the autonomous system number of the neighbor is not yet known." ::= { egpNeighEntry 3 } egpNeighInMsgs OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of EGP messages received without error from this EGP peer." ::= { egpNeighEntry 4 } egpNeighInErrs OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of EGP messages received from this EGP peer that proved to be in error (e.g., bad EGP checksum)." ::= { egpNeighEntry 5 } egpNeighOutMsgs OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of locally generated EGP messages to this EGP peer." ::= { egpNeighEntry 6 } egpNeighOutErrs OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of locally generated EGP messages not sent to this EGP peer due to resource limitations within an EGP entity." ::= { egpNeighEntry 7 } egpNeighInErrMsgs OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of EGP-defined error messages received from this EGP peer." ::= { egpNeighEntry 8 } egpNeighOutErrMsgs OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of EGP-defined error messages sent to this EGP peer." ::= { egpNeighEntry 9 } egpNeighStateUps OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of EGP state transitions to the UP state with this EGP peer." ::= { egpNeighEntry 10 } egpNeighStateDowns OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The number of EGP state transitions from the UP state to any other state with this EGP peer." ::= { egpNeighEntry 11 } egpNeighIntervalHello OBJECT-TYPE SYNTAX INTEGER ACCESS read-only STATUS mandatory DESCRIPTION "The interval between EGP Hello command retransmissions (in hundredths of a second). This represents the t1 timer as defined in RFC 904." ::= { egpNeighEntry 12 } egpNeighIntervalPoll OBJECT-TYPE SYNTAX INTEGER ACCESS read-only STATUS mandatory DESCRIPTION "The interval between EGP poll command retransmissions (in hundredths of a second). This represents the t3 timer as defined in RFC 904." ::= { egpNeighEntry 13 } egpNeighMode OBJECT-TYPE SYNTAX INTEGER { active(1), passive(2) } ACCESS read-only STATUS mandatory DESCRIPTION "The polling mode of this EGP entity, either passive or active." ::= { egpNeighEntry 14 } egpNeighEventTrigger OBJECT-TYPE SYNTAX INTEGER { start(1), stop(2) } ACCESS read-write STATUS mandatory DESCRIPTION "A control variable used to trigger operator- initiated Start and Stop events. When read, this variable always returns the most recent value that egpNeighEventTrigger was set to. If it has not been set since the last initialization of the network management subsystem on the node, it returns a value of `stop'. When set, this variable causes a Start or Stop event on the specified neighbor, as specified on pages 8-10 of RFC 904. Briefly, a Start event causes an Idle peer to begin neighbor acquisition and a non-Idle peer to reinitiate neighbor acquisition. A stop event causes a non-Idle peer to return to the Idle state until a Start event occurs, either via egpNeighEventTrigger or otherwise." ::= { egpNeighEntry 15 } -- additional EGP objects egpAs OBJECT-TYPE SYNTAX INTEGER ACCESS read-only STATUS mandatory DESCRIPTION "The autonomous system number of this EGP entity." ::= { egp 6 } -- the Transmission group -- Based on the transmission media underlying each interface -- on a system, the corresponding portion of the Transmission -- group is mandatory for that system. -- When Internet-standard definitions for managing -- transmission media are defined, the transmission group is -- used to provide a prefix for the names of those objects. -- Typically, such definitions reside in the experimental -- portion of the MIB until they are "proven", then as a -- part of the Internet standardization process, the -- definitions are accordingly elevated and a new object -- identifier, under the transmission group is defined. By -- convention, the name assigned is: -- -- type OBJECT IDENTIFIER ::= { transmission number } -- -- where "type" is the symbolic value used for the media in -- the ifType column of the ifTable object, and "number" is -- the actual integer value corresponding to the symbol. -- the SNMP group -- Implementation of the SNMP group is mandatory for all -- systems which support an SNMP protocol entity. Some of -- the objects defined below will be zero-valued in those -- SNMP implementations that are optimized to support only -- those functions specific to either a management agent or -- a management station. In particular, it should be -- observed that the objects below refer to an SNMP entity, -- and there may be several SNMP entities residing on a -- managed node (e.g., if the node is hosting acting as -- a management station). snmpInPkts OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of Messages delivered to the SNMP entity from the transport service." ::= { snmp 1 } snmpOutPkts OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of SNMP Messages which were passed from the SNMP protocol entity to the transport service." ::= { snmp 2 } snmpInBadVersions OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of SNMP Messages which were delivered to the SNMP protocol entity and were for an unsupported SNMP version." ::= { snmp 3 } snmpInBadCommunityNames OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of SNMP Messages delivered to the SNMP protocol entity which used a SNMP community name not known to said entity." ::= { snmp 4 } snmpInBadCommunityUses OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of SNMP Messages delivered to the SNMP protocol entity which represented an SNMP operation which was not allowed by the SNMP community named in the Message." ::= { snmp 5 } snmpInASNParseErrs OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of ASN.1 or BER errors encountered by the SNMP protocol entity when decoding received SNMP Messages." ::= { snmp 6 } -- { snmp 7 } is not used snmpInTooBigs OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of SNMP PDUs which were delivered to the SNMP protocol entity and for which the value of the error-status field is `tooBig'." ::= { snmp 8 } snmpInNoSuchNames OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of SNMP PDUs which were delivered to the SNMP protocol entity and for which the value of the error-status field is `noSuchName'." ::= { snmp 9 } snmpInBadValues OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of SNMP PDUs which were delivered to the SNMP protocol entity and for which the value of the error-status field is `badValue'." ::= { snmp 10 } snmpInReadOnlys OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number valid SNMP PDUs which were delivered to the SNMP protocol entity and for which the value of the error-status field is `readOnly'. It should be noted that it is a protocol error to generate an SNMP PDU which contains the value `readOnly' in the error-status field, as such this object is provided as a means of detecting incorrect implementations of the SNMP." ::= { snmp 11 } snmpInGenErrs OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of SNMP PDUs which were delivered to the SNMP protocol entity and for which the value of the error-status field is `genErr'." ::= { snmp 12 } snmpInTotalReqVars OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of MIB objects which have been retrieved successfully by the SNMP protocol entity as the result of receiving valid SNMP Get-Request and Get-Next PDUs." ::= { snmp 13 } snmpInTotalSetVars OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of MIB objects which have been altered successfully by the SNMP protocol entity as the result of receiving valid SNMP Set-Request PDUs." ::= { snmp 14 } snmpInGetRequests OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of SNMP Get-Request PDUs which have been accepted and processed by the SNMP protocol entity." ::= { snmp 15 } snmpInGetNexts OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of SNMP Get-Next PDUs which have been accepted and processed by the SNMP protocol entity." ::= { snmp 16 } snmpInSetRequests OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of SNMP Set-Request PDUs which have been accepted and processed by the SNMP protocol entity." ::= { snmp 17 } snmpInGetResponses OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of SNMP Get-Response PDUs which have been accepted and processed by the SNMP protocol entity." ::= { snmp 18 } snmpInTraps OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of SNMP Trap PDUs which have been accepted and processed by the SNMP protocol entity." ::= { snmp 19 } snmpOutTooBigs OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of SNMP PDUs which were generated by the SNMP protocol entity and for which the value of the error-status field is `tooBig.'" ::= { snmp 20 } snmpOutNoSuchNames OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of SNMP PDUs which were generated by the SNMP protocol entity and for which the value of the error-status is `noSuchName'." ::= { snmp 21 } snmpOutBadValues OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of SNMP PDUs which were generated by the SNMP protocol entity and for which the value of the error-status field is `badValue'." ::= { snmp 22 } -- { snmp 23 } is not used snmpOutGenErrs OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of SNMP PDUs which were generated by the SNMP protocol entity and for which the value of the error-status field is `genErr'." ::= { snmp 24 } snmpOutGetRequests OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of SNMP Get-Request PDUs which have been generated by the SNMP protocol entity." ::= { snmp 25 } snmpOutGetNexts OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of SNMP Get-Next PDUs which have been generated by the SNMP protocol entity." ::= { snmp 26 } snmpOutSetRequests OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of SNMP Set-Request PDUs which have been generated by the SNMP protocol entity." ::= { snmp 27 } snmpOutGetResponses OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of SNMP Get-Response PDUs which have been generated by the SNMP protocol entity." ::= { snmp 28 } snmpOutTraps OBJECT-TYPE SYNTAX Counter ACCESS read-only STATUS mandatory DESCRIPTION "The total number of SNMP Trap PDUs which have been generated by the SNMP protocol entity." ::= { snmp 29 } snmpEnableAuthenTraps OBJECT-TYPE SYNTAX INTEGER { enabled(1), disabled(2) } ACCESS read-write STATUS mandatory DESCRIPTION "Indicates whether the SNMP agent process is permitted to generate authentication-failure traps. The value of this object overrides any configuration information; as such, it provides a means whereby all authentication-failure traps may be disabled. Note that it is strongly recommended that this object be stored in non-volatile memory so that it remains constant between re-initializations of the network management system." ::= { snmp 30 } END esnacc-ng-1.8.1/asn1specs/selectedattributetypes.asn1000066400000000000000000000607421302010526100226430ustar00rootroot00000000000000SelectedAttributeTypes -- {joint-iso-ccitt ds(5) module(1) selectedAttributeTypes(5) 2} DEFINITIONS ::= BEGIN -- EXPORTS All -- -- The types and values defined in this module are exported for use in the other ASN.1 modules contained -- within the Directory Specifications, and for the use of other applications which will use them to access -- Directory services. Other applications may use them for their own purposes, but this will not constrain -- extensions and modifications needed to maintain or improve the Directory service. IMPORTS id-at FROM UsefulDefinitions AttributeType, DistinguishedName FROM InformationFramework ub-answerback, ub-name, ub-common-name, ub-serial-number, ub-locality-name, ub-state-name, ub-street-address, ub-organization-name, ub-organizational-unit-name, ub-title, ub-description, ub-business-category, ub-postal-line, ub-postal-string, ub-postal-code, ub-post-office-box, ub-physical-office-name, ub-telex-number, ub-country-code, ub-teletex-terminal-id, ub-telephone-number, ub-x121-address, ub-international-isdn-number, ub-destination-indicator, ub-knowledge-information FROM UpperBounds pkcs-9 FROM AuthenticationFramework ; -- Directory string type -- DirectoryString -- { INTEGER : maxSize } -- ::= CHOICE { teletexString TeletexString (SIZE (1..MAX)), printableString PrintableString (SIZE (1..MAX)), universalString UniversalString (SIZE (1..MAX)), bmpString BMPString (SIZE (1..MAX)), uTF8String UTF8String (SIZE (1..MAX)) } -- Attribute types -- knowledgeInformationAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX DirectoryString (SIZE (1..ub-knowledge-information)) -- {ub-knowledge-information} ACCESS read-write STATUS mandatory ::= {id-at-knowledgeInformation} nameAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX DirectoryString (SIZE (1..ub-name)) -- {ub-name} ACCESS read-write STATUS mandatory ::= {id-at-name} commonNameAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX DirectoryString (SIZE (1..ub-common-name)) -- {ub-common-name} ACCESS read-write STATUS mandatory ::= {id-at-commonName} surnameAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX DirectoryString (SIZE (1..ub-name)) -- {ub-name} ACCESS read-write STATUS mandatory ::= {id-at-surname} givenNameAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX DirectoryString (SIZE (1..ub-name)) -- {ub-name} ACCESS read-write STATUS mandatory ::= {id-at-givenName} initialsAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX DirectoryString (SIZE (1..ub-name)) -- {ub-name} ACCESS read-write STATUS mandatory ::= {id-at-initials} generationQualifierAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX DirectoryString (SIZE (1..ub-name)) -- {ub-name} ACCESS read-write STATUS mandatory ::= {id-at-generationQualifier} uniqueIdentifierAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX UniqueIdentifier ACCESS read-write STATUS mandatory ::= {id-at-uniqueIdentifier} UniqueIdentifier ::= BIT STRING dnQualifierAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX PrintableString ACCESS read-write STATUS mandatory ::= {id-at-dnQualifier} serialNumberAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX PrintableString (SIZE (1..ub-serial-number)) ACCESS read-write STATUS mandatory ::= {id-at-serialNumber} countryNameAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX PrintableString (SIZE (2)) -- IS 3166 codes only ACCESS read-write STATUS mandatory ::= {id-at-countryName} localityNameAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX DirectoryString (SIZE (1..ub-locality-name)) -- {ub-locality-name} ACCESS read-write STATUS mandatory ::= {id-at-localityName} collectiveLocalityNameAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX DirectoryString (SIZE (1..ub-locality-name)) -- {ub-locality-name} ACCESS read-write STATUS mandatory ::= {id-at-collectiveLocalityName} stateOrProvinceNameAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX DirectoryString (SIZE (1..ub-state-name)) -- {ub-state-name} ACCESS read-write STATUS mandatory ::= {id-at-stateOrProvinceName} collectiveStateOrProvinceNameAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX DirectoryString (SIZE (1..ub-state-name)) -- {ub-state-name} ACCESS read-write STATUS mandatory ::= {id-at-collectiveStateOrProvinceName} streetAddressAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX DirectoryString (SIZE (1..ub-street-address)) -- {ub-street-address} ACCESS read-write STATUS mandatory ::= {id-at-streetAddress} collectiveStreetAddressAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX DirectoryString (SIZE (1..ub-street-address)) -- {ub-street-address} ACCESS read-write STATUS mandatory ::= {id-at-collectiveStreetAddress} houseIdentifierAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX DirectoryString (SIZE (1..ub-name)) -- {ub-name} ACCESS read-write STATUS mandatory ::= {id-at-houseIdentifier} organizationNameAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX DirectoryString (SIZE (1..ub-organization-name)) -- {ub-organization-name} ACCESS read-write STATUS mandatory ::= {id-at-organizationName} collectiveOrganizationNameAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX DirectoryString (SIZE (1..ub-organization-name)) -- {ub-organization-name} ACCESS read-write STATUS mandatory ::= {id-at-collectiveOrganizationName} organizationalUnitNameAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX DirectoryString (SIZE (1..ub-organizational-unit-name)) -- {ub-organizational-unit-name} ACCESS read-write STATUS mandatory ::= {id-at-organizationalUnitName} collectiveOrganizationalUnitNameAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX DirectoryString (SIZE (1..ub-organizational-unit-name)) -- {ub-organizational-unit-name} ACCESS read-write STATUS mandatory ::= {id-at-collectiveOrganizationalUnitName} titleAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX DirectoryString (SIZE (1..ub-title)) -- {ub-title} ACCESS read-write STATUS mandatory ::= {id-at-title} descriptionAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX DirectoryString (SIZE (1..ub-description)) -- {ub-description} ACCESS read-write STATUS mandatory ::= {id-at-description} searchGuideAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX Guide ACCESS read-write STATUS mandatory ::= {id-at-searchGuide} Guide ::= SET { objectClass [0] OBJECT IDENTIFIER OPTIONAL, criteria [1] Criteria } Criteria ::= CHOICE { type [0] CriteriaItem, and [1] SET OF Criteria, or [2] SET OF Criteria, not [3] Criteria } CriteriaItem ::= CHOICE { equality [0] AttributeType, substrings [1] AttributeType, greaterOrEqual [2] AttributeType, lessOrEqual [3] AttributeType, approximateMatch [4] AttributeType } enhancedSearchGuideAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX EnhancedGuide ACCESS read-write STATUS mandatory ::= {id-at-enhancedSearchGuide} EnhancedGuide ::= SEQUENCE { objectClass [0] OBJECT IDENTIFIER, criteria [1] Criteria, subset [2] INTEGER { baseObject (0), oneLevel (1), wholeSubtree (2) } DEFAULT oneLevel } businessCategoryAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX DirectoryString (SIZE (1..ub-business-category)) -- {ub-business-category} ACCESS read-write STATUS mandatory ::= {id-at-businessCategory} postalAddressAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX PostalAddress ACCESS read-write STATUS mandatory ::= {id-at-postalAddress} PostalAddress ::= SEQUENCE SIZE(1..ub-postal-line) OF DirectoryString (SIZE (1..ub-postal-string)) -- {ub-postal-string} collectivePostalAddressAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX PostalAddress ACCESS read-write STATUS mandatory ::= {id-at-collectivePostalAddress} postalCodeAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX DirectoryString (SIZE (1..ub-postal-code)) -- {ub-postal-code} ACCESS read-write STATUS mandatory ::= {id-at-postalCode} collectivePostalCodeAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX DirectoryString (SIZE (1..ub-postal-code)) -- {ub-postal-code} ACCESS read-write STATUS mandatory ::= {id-at-collectivePostalCode} postOfficeBoxAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX DirectoryString (SIZE (1..ub-post-office-box)) -- {ub-post-office-box} ACCESS read-write STATUS mandatory ::= {id-at-postOfficeBox} collectivePostOfficeBoxAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX DirectoryString (SIZE (1..ub-post-office-box)) -- {ub-post-office-box} ACCESS read-write STATUS mandatory ::= {id-at-collectivePostOfficeBox} physicalDeliveryOfficeNameAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX DirectoryString (SIZE (1..ub-physical-office-name)) -- {ub-physical-office-name} ACCESS read-write STATUS mandatory ::= {id-at-physicalDeliveryOfficeName} collectivePhysicalDeliveryOfficeNameAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX DirectoryString (SIZE (1..ub-physical-office-name)) -- {ub-physical-office-name} ACCESS read-write STATUS mandatory ::= {id-at-collectivePhysicalDeliveryOfficeName} telephoneNumberAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX PrintableString (SIZE (1..ub-telephone-number)) ACCESS read-write STATUS mandatory ::= {id-at-telephoneNumber} collectiveTelephoneNumberAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX PrintableString (SIZE (1..ub-telephone-number)) ACCESS read-write STATUS mandatory ::= {id-at-collectiveTelephoneNumber} telexNumberAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX TelexNumber ACCESS read-write STATUS mandatory ::= {id-at-telexNumber} TelexNumber ::= SEQUENCE { telexNumber PrintableString (SIZE(1..ub-telex-number)), countryCode PrintableString (SIZE(1..ub-country-code)), answerback PrintableString (SIZE(1..ub-answerback))} collectiveTelexNumberAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX TelexNumber ACCESS read-write STATUS mandatory ::= {id-at-collectiveTelexNumber} teletexTerminalIdentifierAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX TeletexTerminalIdentifier ACCESS read-write STATUS mandatory ::= {id-at-teletexTerminalIdentifier} TeletexTerminalIdentifier ::= SEQUENCE { teletexTerminal PrintableString (SIZE(1..ub-teletex-terminal-id)), parameters TeletexNonBasicParameters OPTIONAL} TeletexNonBasicParameters ::= SET { graphic-character-sets [0] TeletexString OPTIONAL, control-character-sets [1] TeletexString OPTIONAL, page-formats [2] OCTET STRING OPTIONAL, miscellaneous-terminal-capabilities [3] TeletexString OPTIONAL, private-use [4] OCTET STRING OPTIONAL -- maximum ub-teletex-private-use-length octets -- } -- as defined in Recommendation T.62 collectiveTeletexTerminalIdentifierAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX TeletexTerminalIdentifier ACCESS read-write STATUS mandatory ::= {id-at-collectiveTeletexTerminalIdentifier} facsimileTelephoneNumberAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX FacsimileTelephoneNumber ACCESS read-write STATUS mandatory ::= {id-at-facsimileTelephoneNumber} FacsimileTelephoneNumber ::= SEQUENCE { telephoneNumber PrintableString (SIZE(1.. ub-telephone-number)), parameters G3FacsimileNonBasicParameters OPTIONAL} G3FacsimileNonBasicParameters ::= BIT STRING { two-dimensional (8), fine-resolution (9), unlimited-length (20), b4-length (21), a3-width (22), b4-width (23), uncompressed (30) } -- as defined in Recommendation T.30 collectiveFacsimileTelephoneNumberAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX FacsimileTelephoneNumber ACCESS read-write STATUS mandatory ::= {id-at-collectiveFacsimileTelephoneNumber} x121AddressAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX NumericString (SIZE (1..ub-x121-address)) ACCESS read-write STATUS mandatory ::= {id-at-x121Address} internationalISDNNumberAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX NumericString (SIZE (1..ub-international-isdn-number)) ACCESS read-write STATUS mandatory ::= {id-at-internationalISDNNumber} collectiveInternationalISDNNumberAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX NumericString (SIZE (1..ub-international-isdn-number)) ACCESS read-write STATUS mandatory ::= {id-at-collectiveInternationalISDNNumber} registeredAddressAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX PostalAddress ACCESS read-write STATUS mandatory ::= {id-at-registeredAddress} destinationIndicatorAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX PrintableString (SIZE (1..ub-destination-indicator)) -- alphabetical characters only ACCESS read-write STATUS mandatory ::= {id-at-destinationIndicator} preferredDeliveryMethodAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX SEQUENCE OF INTEGER { any-delivery-method (0), mhs-delivery (1), physical-delivery (2), telex-delivery (3), teletex-delivery (4), g3-facsimile-delivery (5), g4-facsimile-delivery (6), ia5-terminal-delivery (7), videotex-delivery (8), telephone-delivery (9) } ACCESS read-write STATUS mandatory ::= {id-at-preferredDeliveryMethod} presentationAddressAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX PresentationAddress ACCESS read-write STATUS mandatory ::= {id-at-presentationAddress} PresentationAddress ::= SEQUENCE { pSelector [0] OCTET STRING OPTIONAL, sSelector [1] OCTET STRING OPTIONAL, tSelector [2] OCTET STRING OPTIONAL, nAddresses [3] SET SIZE (1..MAX) OF OCTET STRING} supportedApplicationContextAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX OBJECT IDENTIFIER ACCESS read-write STATUS mandatory ::= {id-at-supportedApplicationContext} protocolInformationAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX ProtocolInformation ACCESS read-write STATUS mandatory ::= {id-at-protocolInformation} ProtocolInformation ::= SEQUENCE { nAddress OCTET STRING, profiles SET OF OBJECT IDENTIFIER } distinguishedNameAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX DistinguishedName ACCESS read-write STATUS mandatory ::= {id-at-distinguishedName} memberAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX DistinguishedName ACCESS read-write STATUS mandatory ::= {id-at-member} uniqueMemberAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX NameAndOptionalUID ACCESS read-write STATUS mandatory ::= {id-at-uniqueMember} NameAndOptionalUID ::= SEQUENCE { dn DistinguishedName, uid UniqueIdentifier OPTIONAL } ownerAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX DistinguishedName ACCESS read-write STATUS mandatory ::= {id-at-owner} roleOccupantAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX DistinguishedName ACCESS read-write STATUS mandatory ::= {id-at-roleOccupant} seeAlsoAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX DistinguishedName ACCESS read-write STATUS mandatory ::= {id-at-seeAlso} -- PKCS #9 e-mail address attribute emailAddressAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX IA5String ACCESS read-write STATUS mandatory ::= { pkcs-9 1 } -- COSINE and Internet X.500 Pilot attributes -- from RFC 1274 -- used in DistinguishedNames useridAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX DirectoryString (SIZE (1..ub-user-identifier)) -- {ub-user-identifier} ACCESS read-write STATUS mandatory ::= { pilotAttributeType 1 } domainComponentAttribute OBJECT-TYPE -- ATTRIBUTE SYNTAX IA5String ACCESS read-write STATUS mandatory ::= { pilotAttributeType 25 } ub-user-identifier INTEGER ::= 256 -- Object identifier assignments -- -- object identifiers assigned in other modules are shown in comments -- Attributes -- --id-at-objectClass OBJECT IDENTIFIER ::= {id-at 0} --id-at-aliasedEntryName OBJECT IDENTIFIER ::= {id-at 1} id-at-encryptedAliasedEntryName OBJECT IDENTIFIER ::= {id-at 1 2} id-at-knowledgeInformation OBJECT IDENTIFIER ::= {id-at 2} id-at-commonName OBJECT IDENTIFIER ::= {id-at 3} id-at-encryptedCommonName OBJECT IDENTIFIER ::= {id-at 3 2} id-at-surname OBJECT IDENTIFIER ::= {id-at 4} id-at-encryptedSurname OBJECT IDENTIFIER ::= {id-at 4 2} id-at-serialNumber OBJECT IDENTIFIER ::= {id-at 5} id-at-encryptedSerialNumber OBJECT IDENTIFIER ::= {id-at 5 2} id-at-countryName OBJECT IDENTIFIER ::= {id-at 6} id-at-encryptedCountryName OBJECT IDENTIFIER ::= {id-at 6 2} id-at-localityName OBJECT IDENTIFIER ::= {id-at 7} id-at-encryptedLocalityName OBJECT IDENTIFIER ::= {id-at 7 2} id-at-collectiveLocalityName OBJECT IDENTIFIER ::= {id-at 7 1} id-at-encryptedCollectiveLocalityName OBJECT IDENTIFIER ::= {id-at 7 1 2} id-at-stateOrProvinceName OBJECT IDENTIFIER ::= {id-at 8} id-at-encryptedStateOrProvinceName OBJECT IDENTIFIER ::= {id-at 8 2} id-at-collectiveStateOrProvinceName OBJECT IDENTIFIER ::= {id-at 8 1} id-at-encryptedCollectiveStateOrProvinceName OBJECT IDENTIFIER ::= {id-at 8 1 2} id-at-streetAddress OBJECT IDENTIFIER ::= {id-at 9} id-at-encryptedStreetAddress OBJECT IDENTIFIER ::= {id-at 9 2} id-at-collectiveStreetAddress OBJECT IDENTIFIER ::= {id-at 9 1} id-at-encryptedCollectiveStreetAddress OBJECT IDENTIFIER ::= {id-at 9 1 2} id-at-organizationName OBJECT IDENTIFIER ::= {id-at 10} id-at-encryptedOrganizationName OBJECT IDENTIFIER ::= {id-at 10 2} id-at-collectiveOrganizationName OBJECT IDENTIFIER ::= {id-at 10 1} id-at-encryptedCollectiveOrganizationName OBJECT IDENTIFIER ::= {id-at 10 1 2} id-at-organizationalUnitName OBJECT IDENTIFIER ::= {id-at 11} id-at-encryptedOrganizationalUnitName OBJECT IDENTIFIER ::= {id-at 11 2} id-at-collectiveOrganizationalUnitName OBJECT IDENTIFIER ::= {id-at 11 1} id-at-encryptedCollectiveOrganizationalUnitName OBJECT IDENTIFIER ::= {id-at 11 1 2} id-at-title OBJECT IDENTIFIER ::= {id-at 12} id-at-encryptedTitle OBJECT IDENTIFIER ::= {id-at 12 2} id-at-description OBJECT IDENTIFIER ::= {id-at 13} id-at-encryptedDescription OBJECT IDENTIFIER ::= {id-at 13 2} id-at-searchGuide OBJECT IDENTIFIER ::= {id-at 14} id-at-encryptedSearchGuide OBJECT IDENTIFIER ::= {id-at 14 2} id-at-businessCategory OBJECT IDENTIFIER ::= {id-at 15} id-at-encryptedBusinessCategory OBJECT IDENTIFIER ::= {id-at 15 2} id-at-postalAddress OBJECT IDENTIFIER ::= {id-at 16} id-at-encryptedPostalAddress OBJECT IDENTIFIER ::= {id-at 16 2} id-at-collectivePostalAddress OBJECT IDENTIFIER ::= {id-at 16 1} id-at-encryptedCollectivePostalAddress OBJECT IDENTIFIER ::= {id-at 16 1 2} id-at-postalCode OBJECT IDENTIFIER ::= {id-at 17} id-at-encryptedPostalCode OBJECT IDENTIFIER ::= {id-at 17 2} id-at-collectivePostalCode OBJECT IDENTIFIER ::= {id-at 17 1} id-at-encryptedCollectivePostalCode OBJECT IDENTIFIER ::= {id-at 17 1 2} id-at-postOfficeBox OBJECT IDENTIFIER ::= {id-at 18} id-at-encryptedPostOfficeBox OBJECT IDENTIFIER ::= {id-at 18 2} id-at-collectivePostOfficeBox OBJECT IDENTIFIER ::= {id-at 18 1} id-at-encryptedCollectivePostOfficeBox OBJECT IDENTIFIER ::= {id-at 18 1 2} id-at-physicalDeliveryOfficeName OBJECT IDENTIFIER ::= {id-at 19} id-at-encryptedPhysicalDeliveryOfficeName OBJECT IDENTIFIER ::= {id-at 19 2} id-at-collectivePhysicalDeliveryOfficeName OBJECT IDENTIFIER ::= {id-at 19 1} id-at-encryptedCollectivePhysicalDeliveryOfficeName OBJECT IDENTIFIER ::= {id-at 19 1 2} id-at-telephoneNumber OBJECT IDENTIFIER ::= {id-at 20} id-at-encryptedTelephoneNumber OBJECT IDENTIFIER ::= {id-at 20 2} id-at-collectiveTelephoneNumber OBJECT IDENTIFIER ::= {id-at 20 1} id-at-encryptedCollectiveTelephoneNumber OBJECT IDENTIFIER ::= {id-at 20 1 2} id-at-telexNumber OBJECT IDENTIFIER ::= {id-at 21} id-at-encryptedTelexNumber OBJECT IDENTIFIER ::= {id-at 21 2} id-at-collectiveTelexNumber OBJECT IDENTIFIER ::= {id-at 21 1} id-at-encryptedCollectiveTelexNumber OBJECT IDENTIFIER ::= {id-at 21 1 2} id-at-teletexTerminalIdentifier OBJECT IDENTIFIER ::= {id-at 22} id-at-encryptedTeletexTerminalIdentifier OBJECT IDENTIFIER ::= {id-at 22 2} id-at-collectiveTeletexTerminalIdentifier OBJECT IDENTIFIER ::= {id-at 22 1} id-at-encryptedCollectiveTeletexTerminalIdentifier OBJECT IDENTIFIER ::= {id-at 22 1 2} id-at-facsimileTelephoneNumber OBJECT IDENTIFIER ::= {id-at 23} id-at-encryptedFacsimileTelephoneNumber OBJECT IDENTIFIER ::= {id-at 23 2} id-at-collectiveFacsimileTelephoneNumber OBJECT IDENTIFIER ::= {id-at 23 1} id-at-encryptedCollectiveFacsimileTelephoneNumber OBJECT IDENTIFIER ::= {id-at 23 1 2} id-at-x121Address OBJECT IDENTIFIER ::= {id-at 24} id-at-encryptedX121Address OBJECT IDENTIFIER ::= {id-at 24 2} id-at-internationalISDNNumber OBJECT IDENTIFIER ::= {id-at 25} id-at-encryptedInternationalISDNNumber OBJECT IDENTIFIER ::= {id-at 25 2} id-at-collectiveInternationalISDNNumber OBJECT IDENTIFIER ::= {id-at 25 1} id-at-encryptedCollectiveInternationalISDNNumber OBJECT IDENTIFIER ::= {id-at 25 1 2} id-at-registeredAddress OBJECT IDENTIFIER ::= {id-at 26} id-at-encryptedRegisteredAddress OBJECT IDENTIFIER ::= {id-at 26 2} id-at-destinationIndicator OBJECT IDENTIFIER ::= {id-at 27} id-at-encryptedDestinationIndicator OBJECT IDENTIFIER ::= {id-at 27 2} id-at-preferredDeliveryMethod OBJECT IDENTIFIER ::= {id-at 28} id-at-encryptedPreferredDeliveryMethod OBJECT IDENTIFIER ::= {id-at 28 2} id-at-presentationAddress OBJECT IDENTIFIER ::= {id-at 29} id-at-encryptedPresentationAddress OBJECT IDENTIFIER ::= {id-at 29 2} id-at-supportedApplicationContext OBJECT IDENTIFIER ::= {id-at 30} id-at-encryptedSupportedApplicationContext OBJECT IDENTIFIER ::= {id-at 30 2} id-at-member OBJECT IDENTIFIER ::= {id-at 31} id-at-encryptedMember OBJECT IDENTIFIER ::= {id-at 31 2} id-at-owner OBJECT IDENTIFIER ::= {id-at 32} id-at-encryptedOwner OBJECT IDENTIFIER ::= {id-at 32 2} id-at-roleOccupant OBJECT IDENTIFIER ::= {id-at 33} id-at-encryptedRoleOccupant OBJECT IDENTIFIER ::= {id-at 33 2} id-at-seeAlso OBJECT IDENTIFIER ::= {id-at 34} id-at-encryptedSeeAlso OBJECT IDENTIFIER ::= {id-at 34 2} -- id-at-userPassword OBJECT IDENTIFIER ::= {id-at 35} id-at-encryptedUserPassword OBJECT IDENTIFIER ::= {id-at 35 2} -- id-at-userCertificate OBJECT IDENTIFIER ::= {id-at 36} id-at-encryptedUserCertificate OBJECT IDENTIFIER ::= {id-at 36 2} -- id-at-cACertificate OBJECT IDENTIFIER ::= {id-at 37} id-at-encryptedCACertificate OBJECT IDENTIFIER ::= {id-at 37 2} -- id-at-authorityRevocationList OBJECT IDENTIFIER ::= {id-at 38} id-at-encryptedAuthorityRevocationList OBJECT IDENTIFIER ::= {id-at 38 2} -- id-at-certificateRevocationList OBJECT IDENTIFIER ::= {id-at 39} id-at-encryptedCertificateRevocationList OBJECT IDENTIFIER ::= {id-at 39 2} -- id-at-crossCertificatePair OBJECT IDENTIFIER ::= {id-at 40} id-at-encryptedCrossCertificatePair OBJECT IDENTIFIER ::= {id-at 40 2} id-at-name OBJECT IDENTIFIER ::= {id-at 41} id-at-givenName OBJECT IDENTIFIER ::= {id-at 42} id-at-encryptedGivenName OBJECT IDENTIFIER ::= {id-at 42 2} id-at-initials OBJECT IDENTIFIER ::= {id-at 43} id-at-encryptedInitials OBJECT IDENTIFIER ::= {id-at 43 2} id-at-generationQualifier OBJECT IDENTIFIER ::= {id-at 44} id-at-encryptedGenerationQualifier OBJECT IDENTIFIER ::= {id-at 44 2} id-at-uniqueIdentifier OBJECT IDENTIFIER ::= {id-at 45} id-at-encryptedUniqueIdentifier OBJECT IDENTIFIER ::= {id-at 45 2} id-at-dnQualifier OBJECT IDENTIFIER ::= {id-at 46} id-at-encryptedDnQualifier OBJECT IDENTIFIER ::= {id-at 46 2} id-at-enhancedSearchGuide OBJECT IDENTIFIER ::= {id-at 47} id-at-encryptedEnhancedSearchGuide OBJECT IDENTIFIER ::= {id-at 47 2} id-at-protocolInformation OBJECT IDENTIFIER ::= {id-at 48} id-at-encryptedProtocolInformation OBJECT IDENTIFIER ::= {id-at 48 2} id-at-distinguishedName OBJECT IDENTIFIER ::= {id-at 49} id-at-encryptedDistinguishedName OBJECT IDENTIFIER ::= {id-at 49 2} id-at-uniqueMember OBJECT IDENTIFIER ::= {id-at 50} id-at-encryptedUniqueMember OBJECT IDENTIFIER ::= {id-at 50 2} id-at-houseIdentifier OBJECT IDENTIFIER ::= {id-at 51} id-at-encryptedHouseIdentifier OBJECT IDENTIFIER ::= {id-at 51 2} --id-at-supportedAlgorithms OBJECT IDENTIFIER ::= {id-at 52} id-at-encryptedSupportedAlgorithms OBJECT IDENTIFIER ::= {id-at 52 2} --id-at-deltaRevocationList OBJECT IDENTIFIER ::= {id-at 53} id-at-encryptedDeltaRevocationList OBJECT IDENTIFIER ::= {id-at 53 2} id-at-dmdName OBJECT IDENTIFIER ::= {id-at 54} id-at-encryptedDmdName OBJECT IDENTIFIER ::= {id-at 54 2} -- id-at-clearance OBJECT IDENTIFIER ::= {id-at 55} id-at-encryptedClearance OBJECT IDENTIFIER ::= {id-at 55 2} -- id-at-defaultDirQop OBJECT IDENTIFIER ::= {id-at 56} id-at-encryptedDefaultDirQop OBJECT IDENTIFIER ::= {id-at 56 2} -- id-at-attributeIntegrityInfo OBJECT IDENTIFIER ::= {id-at 57} id-at-encryptedAttributeIntegrityInfo OBJECT IDENTIFIER ::= {id-at 57 2} --id-at-attributeCertificate OBJECT IDENTIFIER ::= {id-at 58} id-at-encryptedAttributeCertificate OBJECT IDENTIFIER ::= {id-at 58 2} -- id-at-attributeCertificateRevocationList OBJECT IDENTIFIER ::= {id-at 59} id-at-encryptedAttributeCertificateRevocationList OBJECT IDENTIFIER ::= {id-at 59 2} -- id-at-confKeyInfo OBJECT IDENTIFIER ::= {id-at 60} id-at-encryptedConfKeyInfo OBJECT IDENTIFIER ::= {id-at 60 2} data OBJECT IDENTIFIER ::= {ccitt 9} pss OBJECT IDENTIFIER ::= {data 2342} ucl OBJECT IDENTIFIER ::= {pss 19200300} pilot OBJECT IDENTIFIER ::= {ucl 100} pilotAttributeType OBJECT IDENTIFIER ::= {pilot 1} END esnacc-ng-1.8.1/asn1specs/tbl.asn1000066400000000000000000000104301302010526100166100ustar00rootroot00000000000000-- .../asn1specs/tbl.asn1 -- -- TBL types describe ASN.1 data structures. -- These can be used in generic, interpretive encoders/decoders. -- Interpretive decoders are typically slower, but don't eat memory -- with type-specific encoding and decoding code. -- The tbl types can also be sent over the network -- and allow dynamic re-configuration of encoders/decoders. -- -- To understand how this type table structure is used -- look in: -- 1. .../compiler/core/gen-tbls.c -- this will show you how various things are generated -- from the big parse tree (asn1module.asn1). -- Pay particular attention to the typeDefId use -- -- 2. look in .../c-lib/makefile for an example of how you can -- modify the tbl.h file generated from this module to suit -- your own needs. -- -- 3. look in .../tbl-tools/ptbl/pasn1.c to see how the -- TBL data struct relates to the original ASN.1 -- -- -- -- Mike Sample, April 11, 1992 -- Mods MS Feb 7/93 -- -- $Header: /baseline/SNACC/asn1specs/tbl.asn1,v 1.2 2003/12/17 19:05:03 gronej Exp $ -- $Log: tbl.asn1,v $ -- Revision 1.2 2003/12/17 19:05:03 gronej -- SNACC baseline merged with PER v1_7 tag -- -- Revision 1.1.2.1 2003/11/05 14:58:53 gronej -- working PER code merged with esnacc_1_6 -- -- Revision 1.1.1.1 2000/08/21 20:36:16 leonberp -- First CVS Version of SNACC. -- -- Revision 1.3.1.1 1997/08/20 23:14:48 povey -- -- -- Revision 1.3 1995/07/25 19:56:00 rj -- introductory comments adjusted to match changed file names. -- -- changed `_' to `-' in file names. -- -- Revision 1.2 1994/08/28 09:54:18 rj -- comment leader fixed. -- -- Revision 1.1 1994/08/28 09:51:14 rj -- first check-in. TBL DEFINITIONS ::= BEGIN -- imports nothing -- exports nothing TBL ::= --snacc isPdu:"TRUE" -- SEQUENCE { totalNumModules INTEGER, -- these totals can help allocation totalNumTypeDefs INTEGER, -- when decoding (ie use arrays) totalNumTypes INTEGER, totalNumTags INTEGER, totalNumStrings INTEGER, totalLenStrings INTEGER, modules SEQUENCE OF TBLModule } TBLModule ::= SEQUENCE { name [0] IMPLICIT PrintableString, id [1] IMPLICIT OBJECT IDENTIFIER OPTIONAL, isUseful [2] IMPLICIT BOOLEAN, -- true if useful types module typeDefs [3] IMPLICIT SEQUENCE OF TBLTypeDef } -- -- The typedefId is just an integer that uniquely identifies -- each TBLTypeDef (type references use these as "pointers"). -- The typeDefId's in each module will have consecutive type ids. -- The first typedef in a module will have the lowest Id and the -- last typedef will have the highest. Thus if the first typedef -- in a module has the id of 12 and the last typedef in that module -- has the id of 27, the module contains the typdefs in the range -- 12..27 (inclusive). This can be used to re-compute the -- IMPORT information for modules in a type table. -- -- (The LoadTBL routine hides this integer/ptr crap from the user -- by adding real pointers to the tbl.h data structures where useful. -- When loading, the typeDefIds are converted into these real ptrs) -- TBLTypeDef ::= SEQUENCE { typeDefId TBLTypeDefId, typeName PrintableString OPTIONAL, -- I have forgotten why this is opt! -- I can see no good reason for it type TBLType } TBLType ::= SEQUENCE { typeId [0] IMPLICIT TBLTypeId, optional [1] IMPLICIT BOOLEAN, tagList [2] IMPLICIT SEQUENCE OF TBLTag OPTIONAL, content [3] TBLTypeContent, fieldName [4] IMPLICIT PrintableString OPTIONAL } TBLTypeContent ::= CHOICE { primType [0] IMPLICIT NULL, elmts [1] IMPLICIT SEQUENCE OF TBLType, typeRef [2] IMPLICIT TBLTypeRef } TBLTypeRef ::= SEQUENCE { typeDef TBLTypeDefId, implicit BOOLEAN } TBLTypeId ::= ENUMERATED { tbl-boolean (0), tbl-integer (1), tbl-bitstring (2), tbl-octetstring (3), tbl-null (4), tbl-oid (5), tbl-real (6), tbl-enumerated (7), tbl-sequence (8), tbl-set (9), tbl-sequenceof (10), tbl-setof (11), tbl-choice (12), tbl-typeref (13) } TBLTypeDefId ::= INTEGER TBLTag ::= SEQUENCE { tclass TBLTagClass, code INTEGER (0..MAX) } TBLTagClass ::= ENUMERATED { universal (0), application (1), context (2), private (3) } END esnacc-ng-1.8.1/asn1specs/upperbounds.asn1000066400000000000000000000033301302010526100203760ustar00rootroot00000000000000UpperBounds -- {joint-iso-ccitt ds(5) module(1) upperBounds(10) 2} DEFINITIONS ::= BEGIN -- EXPORTS All -- -- The types and values defined in this module are exported for use in the other ASN.1 modules contained -- within the Directory Specifications, and for the use of other applications which will use them to access -- Directory services. Other applications may use them for their own purposes, but this will not constrain -- extensions and modifications needed to maintain or improve the Directory service. ub-answerback INTEGER ::= 8 ub-business-category INTEGER ::= 128 ub-common-name INTEGER ::= 64 ub-country-code INTEGER ::= 4 ub-description INTEGER ::= 1024 ub-destination-indicator INTEGER ::= 128 ub-directory-string-first-component-match INTEGER ::= 32768 ub-international-isdn-number INTEGER ::= 16 ub-knowledge-information INTEGER ::= 32768 ub-locality-name INTEGER ::= 128 ub-match INTEGER ::= 128 ub-name INTEGER ::= 32768 ub-organization-name INTEGER ::= 64 ub-organizational-unit-name INTEGER ::= 64 ub-physical-office-name INTEGER ::= 128 ub-post-office-box INTEGER ::= 40 ub-postal-code INTEGER ::= 40 ub-postal-line INTEGER ::= 6 ub-postal-string INTEGER ::= 30 ub-schema INTEGER ::= 1024 ub-serial-number INTEGER ::= 64 ub-state-name INTEGER ::= 128 ub-street-address INTEGER ::= 128 ub-surname INTEGER ::= 64 ub-tag INTEGER ::= 64 ub-telephone-number INTEGER ::= 32 ub-teletex-terminal-id INTEGER ::= 1024 ub-telex-number INTEGER ::= 14 ub-title INTEGER ::= 64 ub-user-password INTEGER ::= 128 ub-x121-address INTEGER ::= 15 END esnacc-ng-1.8.1/asn1specs/usefuldefinitions.asn1000066400000000000000000000123001302010526100215640ustar00rootroot00000000000000UsefulDefinitions -- {joint-iso-ccitt ds(5) module(1) usefulDefinitions(0) 2} DEFINITIONS ::= BEGIN -- EXPORTS All -- -- The types and values defined in this module are exported for use in the other ASN.1 modules contained -- within the Directory Specifications, and for the use of other applications which will use them to access -- Directory services. Other applications may use them for their own purposes, but this will not constrain -- extensions and modifications needed to maintain or improve the Directory service. ID ::= OBJECT IDENTIFIER ds ID ::= {joint-iso-ccitt ds(5)} -- categories of information object -- module ID ::= {ds 1} serviceElement ID ::= {ds 2} applicationContext ID ::= {ds 3} attributeType ID ::= {ds 4} attributeSyntax ID ::= {ds 5} objectClass ID ::= {ds 6} -- attributeSet ID ::= {ds 7} algorithm ID ::= {ds 8} abstractSyntax ID ::= {ds 9} -- object ID ::= {ds 10} -- port ID ::= {ds 11} dsaOperationalAttribute ID ::= {ds 12} matchingRule ID ::= {ds 13} knowledgeMatchingRule ID ::= {ds 14} nameForm ID ::= {ds 15} group ID ::= {ds 16} subentry ID ::= {ds 17} operationalAttributeType ID ::= {ds 18} operationalBinding ID ::= {ds 19} schemaObjectClass ID ::= {ds 20} schemaOperationalAttribute ID ::= {ds 21} administrativeRoles ID ::= {ds 23} accessControlAttribute ID ::= {ds 24} rosObject ID ::= {ds 25} contract ID ::= {ds 26} package ID ::= {ds 27} accessControlSchemes ID ::= {ds 28} certificateExtension ID ::= {ds 29} managementObject ID ::= {ds 30} -- modules -- usefulDefinitions ID ::= {module usefulDefinitions(0) 3} informationFramework ID ::= {module informationFramework(1) 3} directoryAbstractService ID ::= {module directoryAbstractService(2) 3} distributedOperations ID ::= {module distributedOperations(3) 3} protocolObjectIdentifiers ID ::= {module protocolObjectIdentifiers (4) 3} selectedAttributeTypes ID ::= {module selectedAttributeTypes(5) 3} selectedObjectClasses ID ::= {module selectedObjectClasses(6) 3} authenticationFramework ID ::= {module authenticationFramework(7) 3} algorithmObjectIdentifiers ID ::= {module algorithmObjectIdentifiers(8) 3} directoryObjectIdentifiers ID ::= {module directoryObjectIdentifiers(9) 3} upperBounds ID ::= {module upperBounds(10) 3} dap ID ::= {module dap(11) 3} dsp ID ::= {module dsp(12) 3} distributedDirectoryOIDs ID ::= {module distributedDirectoryOIDs(13) 3} directoryShadowOIDs ID ::= {module directoryShadowOIDs(14) 3} directoryShadowAbstractService ID ::= {module directoryShadowAbstractService(15) 3} disp ID ::= {module disp(16) 3} dop ID ::= {module dop(17) 3} opBindingManagement ID ::= {module opBindingManagement(18) 3} opBindingOIDs ID ::= {module opBindingOIDs(19) 3} hierarchicalOperationalBindings ID ::= {module hierarchicalOperationalBindings(20) 3} dsaOperationalAttributeTypes ID ::= {module dsaOperationalAttributeTypes(22) 3} schemaAdministration ID ::= {module schemaAdministration(23) 3} basicAccessControl ID ::= {module basicAccessControl(24) 3} directoryOperationalBindingTypes ID ::= {module directoryOperationalBindingTypes(25) 3} certificateExtensions ID ::= {module certificateExtensions (26) 0} directoryManagement ID ::= {module directoryManagement (27) 1} enhancedSecurity ID ::= {module enhancedSecurity (28) } -- synonyms -- id-oc ID ::= objectClass id-at ID ::= attributeType id-as ID ::= abstractSyntax id-mr ID ::= matchingRule id-nf ID ::= nameForm id-sc ID ::= subentry id-oa ID ::= operationalAttributeType id-ob ID ::= operationalBinding id-doa ID ::= dsaOperationalAttribute id-kmr ID ::= knowledgeMatchingRule id-soc ID ::= schemaObjectClass id-soa ID ::= schemaOperationalAttribute id-ar ID ::= administrativeRoles id-aca ID ::= accessControlAttribute id-ac ID ::= applicationContext id-rosObject ID ::= rosObject id-contract ID ::= contract id-package ID ::= package id-acScheme ID ::= accessControlSchemes id-ce ID ::= certificateExtension id-mgt ID ::= managementObject -- obsolete module identifiers -- -- usefulDefinitions ID ::= {module 0} -- informationFramework ID ::= {module 1} -- directoryAbstractService ID ::= {module 2} -- distributedOperations ID ::= {module 3} -- protocolObjectIdentifiers ID ::= {module 4} -- selectedAttributeTypes ID ::= {module 5} -- selectedObjectClasses ID ::= {module 6} -- authenticationFramework ID ::= {module 7} -- algorithmObjectIdentifiers ID ::= {module 8} -- directoryObjectIdentifiers ID ::= {module 9} -- upperBounds ID ::= {module 10} -- dap ID ::= {module 11} -- dsp ID ::= {module 12} -- distributedDirectoryObjectIdentifiers -- ID ::= {module 13} -- unused module identifiers -- -- directoryShadowOIDs ID ::= {module 14} -- directoryShadowAbstractService ID ::= {module 15} -- disp ID ::= {module 16} -- dop ID ::= {module 17} -- opBindingManagement ID ::= {module 18} -- opBindingOIDs ID ::= {module 19} -- hierarchicalOperationalBindings ID ::= {module 20} -- dsaOperationalAttributeTypes ID ::= {module 22} -- schemaAdministration ID ::= {module 23} -- basicAccessControl ID ::= {module 24} -- operationalBindingOIDs ID ::= {module 25} END esnacc-ng-1.8.1/boot.sh000077500000000000000000000000501302010526100146420ustar00rootroot00000000000000#! /bin/sh autoreconf --install --force esnacc-ng-1.8.1/build-aux/000077500000000000000000000000001302010526100152375ustar00rootroot00000000000000esnacc-ng-1.8.1/build-aux/cccl000066400000000000000000000110411302010526100160630ustar00rootroot00000000000000#!/bin/sh # cccl # Wrapper around MS's cl.exe and link.exe to make them act more like # Unix cc and ld # # Copyright (C) 2000-2003 Geoffrey Wossum (gwossum@acm.org) # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # usage() { cat <anyDefBy), (v->id)); itemLen = BEncAsnAnyDefinedBy (b, (&v->anyDefBy)); totalLen += itemLen; itemLen = BEncAsnIntContent (b, (&v->id)); BEncDefLenTo127 (b, itemLen); itemLen++; itemLen += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE); totalLen += itemLen; return totalLen; } /* BEncAttrValue1Content */ void BDecAttrValue1Content PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env), GenBuf * b _AND_ AsnTag tagId0 _AND_ AsnLen elmtLen0 _AND_ AttrValue1 *v _AND_ AsnLen *bytesDecoded _AND_ ENV_TYPE env) { int seqDone = FALSE; AsnLen totalElmtsLen1 = 0; AsnLen elmtLen1; AsnTag tagId1; int mandatoryElmtCount1 = 0; tagId1 = BDecTag (b, &totalElmtsLen1, env); if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); BDecAsnIntContent (b, tagId1, elmtLen1, (&v->id), &totalElmtsLen1, env); } else longjmp (env, -103); { SetAnyTypeByInt ((&v->anyDefBy), (v->id)); BDecAsnAnyDefinedBy (b, (&v->anyDefBy), &totalElmtsLen1, env); seqDone = TRUE; if (elmtLen0 == INDEFINITE_LEN) BDecEoc (b, &totalElmtsLen1, env); else if (totalElmtsLen1 != elmtLen0) longjmp (env, -104); } if (!seqDone) longjmp (env, -105); (*bytesDecoded) += totalElmtsLen1; } /* BDecAttrValue1Content */ void PrintAttrValue1 PARAMS ((f, v, indent), FILE* f _AND_ AttrValue1 *v _AND_ unsigned short int indent) { if (v == NULL) return; fprintf (f,"{ -- SEQUENCE --\n"); Indent (f, (unsigned short)(indent + stdIndentG)); fprintf (f,"id "); PrintAsnInt (f, (&v->id), (unsigned short)(indent + stdIndentG)); fprintf (f, ",\n"); Indent (f, (unsigned short)(indent + stdIndentG)); PrintAsnAnyDefinedBy (f, (&v->anyDefBy), (unsigned short)(indent + stdIndentG)); fprintf (f,"\n"); Indent (f, indent); fprintf (f,"}"); } /* PrintAttrValue1 */ void FreeAttrValue1 PARAMS ((v), AttrValue1 *v) { if (v == NULL) return; FreeAsnInt ((&v->id)); FreeAsnAnyDefinedBy ((&v->anyDefBy)); } /* FreeAttrValue1 */ AsnLen BEncAttrValue2Content PARAMS ((b, v), GenBuf * b _AND_ AttrValue2 *v) { AsnLen totalLen = 0; AsnLen itemLen; AsnLen listLen; void *component; SetAnyTypeByOid ((&v->anyDefBy), (&v->id)); itemLen = BEncAsnAnyDefinedBy (b, (&v->anyDefBy)); totalLen += itemLen; itemLen = BEncAsnOidContent (b, (&v->id)); itemLen += BEncDefLen (b, itemLen); itemLen += BEncTag1 (b, UNIV, PRIM, OID_TAG_CODE); totalLen += itemLen; return totalLen; } /* BEncAttrValue2Content */ void BDecAttrValue2Content PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env), GenBuf * b _AND_ AsnTag tagId0 _AND_ AsnLen elmtLen0 _AND_ AttrValue2 *v _AND_ AsnLen *bytesDecoded _AND_ ENV_TYPE env) { int seqDone = FALSE; AsnLen totalElmtsLen1 = 0; AsnLen elmtLen1; AsnTag tagId1; int mandatoryElmtCount1 = 0; tagId1 = BDecTag (b, &totalElmtsLen1, env); if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE)))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); BDecAsnOidContent (b, tagId1, elmtLen1, (&v->id), &totalElmtsLen1, env); } else longjmp (env, -106); { SetAnyTypeByOid ((&v->anyDefBy), (&v->id)); BDecAsnAnyDefinedBy (b, (&v->anyDefBy), &totalElmtsLen1, env); seqDone = TRUE; if (elmtLen0 == INDEFINITE_LEN) BDecEoc (b, &totalElmtsLen1, env); else if (totalElmtsLen1 != elmtLen0) longjmp (env, -107); } if (!seqDone) longjmp (env, -108); (*bytesDecoded) += totalElmtsLen1; } /* BDecAttrValue2Content */ void PrintAttrValue2 PARAMS ((f, v, indent), FILE* f _AND_ AttrValue2 *v _AND_ unsigned short int indent) { if (v == NULL) return; fprintf (f,"{ -- SEQUENCE --\n"); Indent (f, (unsigned short)(indent + stdIndentG)); fprintf (f,"id "); PrintAsnOid (f, (&v->id), (unsigned short)(indent + stdIndentG)); fprintf (f, ",\n"); Indent (f, (unsigned short)(indent + stdIndentG)); PrintAsnAnyDefinedBy (f, (&v->anyDefBy), (unsigned short)(indent + stdIndentG)); fprintf (f,"\n"); Indent (f, indent); fprintf (f,"}"); } /* PrintAttrValue2 */ void FreeAttrValue2 PARAMS ((v), AttrValue2 *v) { if (v == NULL) return; FreeAsnOid ((&v->id)); FreeAsnAnyDefinedBy ((&v->anyDefBy)); } /* FreeAttrValue2 */ AsnLen BEncTSeq1Content PARAMS ((b, v), GenBuf * b _AND_ TSeq1 *v) { AsnLen totalLen = 0; AsnLen itemLen; AsnLen listLen; void *component; listLen = 0; FOR_EACH_LIST_ELMT_RVS (component, v) { BEncEocIfNec (b); itemLen = BEncAttrValue1Content (b, component); itemLen += BEncConsLen (b, itemLen); itemLen += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE); listLen += itemLen; } return listLen; } /* BEncTSeq1Content */ void BDecTSeq1Content PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env), GenBuf * b _AND_ AsnTag tagId0 _AND_ AsnLen elmtLen0 _AND_ TSeq1 *v _AND_ AsnLen *bytesDecoded _AND_ ENV_TYPE env) { int seqDone = FALSE; AsnLen totalElmtsLen1 = 0; AsnLen elmtLen1; AsnTag tagId1; int mandatoryElmtCount1 = 0; for (totalElmtsLen1 = 0; (totalElmtsLen1 < elmtLen0) || (elmtLen0 == INDEFINITE_LEN);) { AttrValue1 **tmpVar; tagId1 = BDecTag (b, &totalElmtsLen1, env); if ((tagId1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN)) { BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env) break; /* got EOC so can exit this SET OF/SEQ OF's for loop*/ } if ((tagId1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); tmpVar = (AttrValue1**) AsnListAppend (v); (*tmpVar) = (AttrValue1*) Asn1Alloc (sizeof (AttrValue1)); CheckAsn1Alloc ((*tmpVar), env); BDecAttrValue1Content (b, tagId1, elmtLen1, (*tmpVar), &totalElmtsLen1, env); } /* end of tag check if */ else /* wrong tag */ { Asn1Error ("Unexpected Tag\n"); longjmp (env, -109); } } /* end of for */ (*bytesDecoded) += totalElmtsLen1; } /* BDecTSeq1Content */ void PrintTSeq1 PARAMS ((f, v, indent), FILE* f _AND_ TSeq1 *v _AND_ unsigned short int indent) { AttrValue1 *tmp; if (v == NULL) return; fprintf (f,"{ -- SEQUENCE OF -- \n"); FOR_EACH_LIST_ELMT (tmp, v) { Indent (f, (unsigned short)(indent+ stdIndentG)); PrintAttrValue1 (f, tmp, (unsigned short)(indent + stdIndentG)); if (tmp != (AttrValue1*)LAST_LIST_ELMT (v)) fprintf (f,",\n"); } fprintf (f,"\n"); Indent (f, indent); fprintf (f,"}"); } /* PrintTSeq1 */ void FreeTSeq1 PARAMS ((v), TSeq1 *v) { AsnListNode *l; AsnListNode *tmp; if (v == NULL) return; for (l = FIRST_LIST_NODE (v); l != NULL; ) { FreeAttrValue1 ((l->data)); tmp = l->next; Asn1Free (l->data); Asn1Free (l); l = tmp; } } /* FreeTSeq1 */ AsnLen BEncTSeq2Content PARAMS ((b, v), GenBuf * b _AND_ TSeq2 *v) { AsnLen totalLen = 0; AsnLen itemLen; AsnLen listLen; void *component; listLen = 0; FOR_EACH_LIST_ELMT_RVS (component, v) { BEncEocIfNec (b); itemLen = BEncAttrValue2Content (b, component); itemLen += BEncConsLen (b, itemLen); itemLen += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE); listLen += itemLen; } return listLen; } /* BEncTSeq2Content */ void BDecTSeq2Content PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env), GenBuf * b _AND_ AsnTag tagId0 _AND_ AsnLen elmtLen0 _AND_ TSeq2 *v _AND_ AsnLen *bytesDecoded _AND_ ENV_TYPE env) { int seqDone = FALSE; AsnLen totalElmtsLen1 = 0; AsnLen elmtLen1; AsnTag tagId1; int mandatoryElmtCount1 = 0; for (totalElmtsLen1 = 0; (totalElmtsLen1 < elmtLen0) || (elmtLen0 == INDEFINITE_LEN);) { AttrValue2 **tmpVar; tagId1 = BDecTag (b, &totalElmtsLen1, env); if ((tagId1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN)) { BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env) break; /* got EOC so can exit this SET OF/SEQ OF's for loop*/ } if ((tagId1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); tmpVar = (AttrValue2**) AsnListAppend (v); (*tmpVar) = (AttrValue2*) Asn1Alloc (sizeof (AttrValue2)); CheckAsn1Alloc ((*tmpVar), env); BDecAttrValue2Content (b, tagId1, elmtLen1, (*tmpVar), &totalElmtsLen1, env); } /* end of tag check if */ else /* wrong tag */ { Asn1Error ("Unexpected Tag\n"); longjmp (env, -110); } } /* end of for */ (*bytesDecoded) += totalElmtsLen1; } /* BDecTSeq2Content */ void PrintTSeq2 PARAMS ((f, v, indent), FILE* f _AND_ TSeq2 *v _AND_ unsigned short int indent) { AttrValue2 *tmp; if (v == NULL) return; fprintf (f,"{ -- SEQUENCE OF -- \n"); FOR_EACH_LIST_ELMT (tmp, v) { Indent (f, (unsigned short)(indent+ stdIndentG)); PrintAttrValue2 (f, tmp, (unsigned short)(indent + stdIndentG)); if (tmp != (AttrValue2*)LAST_LIST_ELMT (v)) fprintf (f,",\n"); } fprintf (f,"\n"); Indent (f, indent); fprintf (f,"}"); } /* PrintTSeq2 */ void FreeTSeq2 PARAMS ((v), TSeq2 *v) { AsnListNode *l; AsnListNode *tmp; if (v == NULL) return; for (l = FIRST_LIST_NODE (v); l != NULL; ) { FreeAttrValue2 ((l->data)); tmp = l->next; Asn1Free (l->data); Asn1Free (l); l = tmp; } } /* FreeTSeq2 */ AsnLen BEncAnyTestType PARAMS ((b, v), GenBuf * b _AND_ AnyTestType *v) { AsnLen l=0; BEncEocIfNec (b); l = BEncAnyTestTypeContent (b, v); l += BEncConsLen (b, l); l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE); return l; } /* BEncAnyTestType */ void BDecAnyTestType PARAMS ((b, result, bytesDecoded, env), GenBuf * b _AND_ AnyTestType *result _AND_ AsnLen *bytesDecoded _AND_ ENV_TYPE env) { AsnTag tag; AsnLen elmtLen1; if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))) { Asn1Error ("BDecAnyTestType: ERROR - wrong tag\n"); longjmp (env, -111); } elmtLen1 = BDecLen (b, bytesDecoded, env); BDecAnyTestTypeContent (b, tag, elmtLen1, result, bytesDecoded, env); } /* BDecAnyTestType */ AsnLen BEncAnyTestTypeContent PARAMS ((b, v), GenBuf * b _AND_ AnyTestType *v) { AsnLen totalLen = 0; AsnLen itemLen; AsnLen listLen; void *component; BEncEocIfNec (b); itemLen = BEncTSeq2Content (b, (v->oidMap)); itemLen += BEncConsLen (b, itemLen); itemLen += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE); totalLen += itemLen; BEncEocIfNec (b); itemLen = BEncTSeq1Content (b, (v->intMap)); itemLen += BEncConsLen (b, itemLen); itemLen += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE); totalLen += itemLen; return totalLen; } /* BEncAnyTestTypeContent */ void BDecAnyTestTypeContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env), GenBuf * b _AND_ AsnTag tagId0 _AND_ AsnLen elmtLen0 _AND_ AnyTestType *v _AND_ AsnLen *bytesDecoded _AND_ ENV_TYPE env) { int seqDone = FALSE; AsnLen totalElmtsLen1 = 0; AsnLen elmtLen1; AsnTag tagId1; int mandatoryElmtCount1 = 0; tagId1 = BDecTag (b, &totalElmtsLen1, env); if (((tagId1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); (v->intMap) = AsnListNew (sizeof (char*)); CheckAsn1Alloc ((v->intMap), env); BDecTSeq1Content (b, tagId1, elmtLen1, (v->intMap), &totalElmtsLen1, env); tagId1 = BDecTag (b, &totalElmtsLen1, env); } else longjmp (env, -112); if (((tagId1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); (v->oidMap) = AsnListNew (sizeof (char*)); CheckAsn1Alloc ((v->oidMap), env); BDecTSeq2Content (b, tagId1, elmtLen1, (v->oidMap), &totalElmtsLen1, env); seqDone = TRUE; if (elmtLen0 == INDEFINITE_LEN) BDecEoc (b, &totalElmtsLen1, env); else if (totalElmtsLen1 != elmtLen0) longjmp (env, -113); } else longjmp (env, -114); if (!seqDone) longjmp (env, -115); (*bytesDecoded) += totalElmtsLen1; } /* BDecAnyTestTypeContent */ void PrintAnyTestType PARAMS ((f, v, indent), FILE* f _AND_ AnyTestType *v _AND_ unsigned short int indent) { if (v == NULL) return; fprintf (f,"{ -- SEQUENCE --\n"); Indent (f, (unsigned short)(indent + stdIndentG)); fprintf (f,"intMap "); PrintTSeq1 (f, (v->intMap), (unsigned short)(indent + stdIndentG)); fprintf (f, ",\n"); Indent (f, (unsigned short)(indent + stdIndentG)); fprintf (f,"oidMap "); PrintTSeq2 (f, (v->oidMap), (unsigned short)(indent + stdIndentG)); fprintf (f,"\n"); Indent (f, indent); fprintf (f,"}"); } /* PrintAnyTestType */ void FreeAnyTestType PARAMS ((v), AnyTestType *v) { if (v == NULL) return; FreeTSeq1 ((v->intMap)); Asn1Free ((v->intMap)); FreeTSeq2 ((v->oidMap)); Asn1Free ((v->oidMap)); } /* FreeAnyTestType */ esnacc-ng-1.8.1/c-examples/any/any.h000066400000000000000000000075141302010526100171410ustar00rootroot00000000000000/* * any.h * * "ANY-TEST" ASN.1 module C type definitions and prototypes * * This .h file was generated by snacc on Wed Oct 23 09:29:42 2002 * * UBC snacc written compiler by Mike Sample * * NOTE: This is a machine generated file--editing not recommended */ #ifndef _any_h_ #define _any_h_ #include "asn-incl.h" typedef enum ANY_TESTAnyId { intId_ANY_ID = 0, boolId_ANY_ID = 1, octsId_ANY_ID = 2, bitsId_ANY_ID = 3, realId_ANY_ID = 4, intOid_ANY_ID = 5, boolOid_ANY_ID = 6, octsOid_ANY_ID = 7, bitsOid_ANY_ID = 8, realOid_ANY_ID = 9} ANY_TESTAnyId; void InitAnyANY_TEST(); typedef AsnBits BitsId; /* [PRIVATE 1] BIT STRING */ AsnLen BEncBitsId PROTO ((GenBuf * b, BitsId *v)); void BDecBitsId PROTO ((GenBuf * b, BitsId *result, AsnLen *bytesDecoded, ENV_TYPE env)); #define BEncBitsIdContent BEncAsnBitsContent #define BDecBitsIdContent BDecAsnBitsContent #define PrintBitsId PrintAsnBits #define FreeBitsId FreeAsnBits typedef AsnOcts OctsId; /* [PRIVATE 2] IMPLICIT OCTET STRING */ AsnLen BEncOctsId PROTO ((GenBuf * b, OctsId *v)); void BDecOctsId PROTO ((GenBuf * b, OctsId *result, AsnLen *bytesDecoded, ENV_TYPE env)); #define BEncOctsIdContent BEncAsnOctsContent #define BDecOctsIdContent BDecAsnOctsContent #define PrintOctsId PrintAsnOcts #define FreeOctsId FreeAsnOcts typedef struct AttrValue1 /* SEQUENCE */ { AsnInt id; /* INTEGER */ AsnAnyDefinedBy anyDefBy; /* ANY DEFINED BY id */ } AttrValue1; AsnLen BEncAttrValue1Content PROTO ((GenBuf * b, AttrValue1 *v)); void BDecAttrValue1Content PROTO ((GenBuf * b, AsnTag tagId0, AsnLen elmtLen0, AttrValue1 *v, AsnLen *bytesDecoded, ENV_TYPE env)); void PrintAttrValue1 PROTO ((FILE* f, AttrValue1 *v, unsigned short int indent)); void FreeAttrValue1 PROTO ((AttrValue1 *v)); typedef struct AttrValue2 /* SEQUENCE */ { AsnOid id; /* OBJECT IDENTIFIER */ AsnAnyDefinedBy anyDefBy; /* ANY DEFINED BY id */ } AttrValue2; AsnLen BEncAttrValue2Content PROTO ((GenBuf * b, AttrValue2 *v)); void BDecAttrValue2Content PROTO ((GenBuf * b, AsnTag tagId0, AsnLen elmtLen0, AttrValue2 *v, AsnLen *bytesDecoded, ENV_TYPE env)); void PrintAttrValue2 PROTO ((FILE* f, AttrValue2 *v, unsigned short int indent)); void FreeAttrValue2 PROTO ((AttrValue2 *v)); typedef AsnList TSeq1; /* SEQUENCE OF AttrValue1 */ AsnLen BEncTSeq1Content PROTO ((GenBuf * b, TSeq1 *v)); void BDecTSeq1Content PROTO ((GenBuf * b, AsnTag tagId0, AsnLen elmtLen0, TSeq1 *v, AsnLen *bytesDecoded, ENV_TYPE env)); void PrintTSeq1 PROTO ((FILE* f, TSeq1 *v, unsigned short int indent)); void FreeTSeq1 PROTO ((TSeq1 *v)); typedef AsnList TSeq2; /* SEQUENCE OF AttrValue2 */ AsnLen BEncTSeq2Content PROTO ((GenBuf * b, TSeq2 *v)); void BDecTSeq2Content PROTO ((GenBuf * b, AsnTag tagId0, AsnLen elmtLen0, TSeq2 *v, AsnLen *bytesDecoded, ENV_TYPE env)); void PrintTSeq2 PROTO ((FILE* f, TSeq2 *v, unsigned short int indent)); void FreeTSeq2 PROTO ((TSeq2 *v)); typedef struct AnyTestType /* SEQUENCE */ { TSeq1* intMap; /* TSeq1 */ TSeq2* oidMap; /* TSeq2 */ } AnyTestType; AsnLen BEncAnyTestType PROTO ((GenBuf * b, AnyTestType *v)); void BDecAnyTestType PROTO ((GenBuf * b, AnyTestType *result, AsnLen *bytesDecoded, ENV_TYPE env)); AsnLen BEncAnyTestTypeContent PROTO ((GenBuf * b, AnyTestType *v)); void BDecAnyTestTypeContent PROTO ((GenBuf * b, AsnTag tagId0, AsnLen elmtLen0, AnyTestType *v, AsnLen *bytesDecoded, ENV_TYPE env)); void PrintAnyTestType PROTO ((FILE* f, AnyTestType *v, unsigned short int indent)); void FreeAnyTestType PROTO ((AnyTestType *v)); extern AsnInt intId; extern AsnInt boolId; extern AsnInt octsId; extern AsnInt bitsId; extern AsnInt realId; extern AsnOid intOid; extern AsnOid boolOid; extern AsnOid octsOid; extern AsnOid bitsOid; extern AsnOid realOid; #endif /* conditional include of any.h */ esnacc-ng-1.8.1/c-examples/any/example.c000066400000000000000000000127101302010526100177720ustar00rootroot00000000000000/* * c-examples/any/example.c - an example of how to call C ASN.1-BER * encoders and decoders generated by snacc * * AUTHOR: Mike Sample * DATE: Mar 92 * * $Header: /baseline/SNACC/c-examples/any/example.c,v 1.7 2003/12/17 19:05:03 gronej Exp $ * $Log: example.c,v $ * Revision 1.7 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.6.2.1 2003/11/05 14:58:53 gronej * working PER code merged with esnacc_1_6 * * Revision 1.6 2003/01/15 17:45:23 mcphersc * *** empty log message *** * * Revision 1.5 2003/01/15 17:41:47 mcphersc * *** empty log message *** * * Revision 1.4 2002/10/24 15:18:40 mcphersc * took out win32 fwrite * * Revision 1.3 2002/10/24 14:48:28 mcphersc * Changed test routine to use GenBufs * * Revision 1.2 2002/10/23 12:42:56 mcphersc * Added "C" files instead of C++ files * * Revision 1.3.1.1 1997/08/20 23:14:52 povey * * * Revision 1.6 1997/02/16 20:26:15 rj * check-in of a few cosmetic changes * * Revision 1.5 1995/07/24 20:40:19 rj * any-test.[hc] becomes any.[hc] due to to snacc's new file name generation scheme. * * changed `_' to `-' in file names. * * Revision 1.4 1995/02/18 15:17:35 rj * cosmetic changes * * Revision 1.3 1994/08/31 23:45:45 rj * more portable .h file inclusion. * * Revision 1.2 1994/08/31 08:59:31 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include "asn-incl.h" #include #include #include #include #include "any.h" extern unsigned short stdIndentG = 4; main PARAMS ((argc, argv), int argc _AND_ char *argv[]) { int fd; SBuf *buf; ExpBuf *ebuf; SBuf *encBuf; GenBuf *genBuf = 0; char *encData; AsnLen encodedLen; AsnLen decodedLen; int val; AnyTestType att; int size; int err = 0; int useExpBuf = 0, currArg; char *origData; struct stat sbuf; jmp_buf env; if ((argc < 2) || (argc > 3)) { fprintf (stderr, "Usage: %s <-E> \n", argv[0]); fprintf (stderr, " Decodes the given PersonnelRecord BER data file\n"); fprintf (stderr, " and re-encodes it to stdout\n"); fprintf (stderr, " -E use ExpBuf memory buffers (Optional)\n"); exit (1); } for (currArg = 1; (currArg < argc); ) { if ((argv[currArg][0] == '-')) { switch (argv[currArg][1]) { case 'E': useExpBuf = 1; currArg++; break; default: currArg++; break; } } else { #ifdef WIN32 fd = open (argv[currArg], O_RDONLY|O_BINARY, 0); #else fd = open (argv[currArg], O_RDONLY, 0); #endif if (fd < 0) { perror ("main: fopen"); exit (1); } if (fstat (fd, &sbuf) < 0) { perror ("main: fstat"); exit (1); } currArg++; } } size = sbuf.st_size; origData = (char*)malloc (size); if ((err = read (fd, origData, size)) != size) { perror ("main: read"); exit (1); } close (fd); if (useExpBuf) { ebuf = ExpBufAllocBuf(); ExpBufInstallDataInBuf (ebuf, origData, size); ExpBuftoGenBuf (ebuf, &genBuf); } else { /* * puts the given data 'origData' of 'size' bytes * into an SBuf and sets the SBuf up for reading * origData from the beginning */ buf = (SBuf *)malloc(sizeof (SBuf)); SBufInstallData (buf, origData, size); SBuftoGenBuf (buf, &genBuf); } /* * the first argument (512) is the number of bytes to * initially allocate for the decoder to allocate from. * The second argument (512) is the size in bytes to * enlarge the nibble memory by when it fills up */ InitNibbleMem (512, 512); /* * initialize the hash table for the * the ANY type mappings. * This only needs to be done once per execution * (before any encoding or decoding is done) */ InitAnyANY_TEST(); decodedLen = 0; if ((val = setjmp (env)) == 0) { BDecAnyTestType (genBuf, &att, &decodedLen, env); } else { fprintf (stderr, "ERROR - Decode routines returned %d\n",val); exit (1); } fprintf (stderr, "decodedValue AnyTestType ::= "); PrintAnyTestType (stderr, &att, 0); fprintf (stderr, "\n\n"); Asn1Free(genBuf); if (useExpBuf) { ebuf = ExpBufAllocBufAndData(); ExpBufResetInWriteRvsMode (ebuf); ExpBuftoGenBuf (ebuf, &genBuf); } else { /* * setup a new buffer set up for writing. * make sure size is big enough to hold the encoded * value (may be larger than decoded value if encoding * with indef lengths - so add 512 slush bytes) */ encData = (char*) malloc (size + 512); encBuf = (SBuf *)malloc(sizeof (SBuf)); SBufInit (encBuf, encData, size + 512); SBufResetInWriteRvsMode (encBuf); SBuftoGenBuf (encBuf, &genBuf); } encodedLen = BEncAnyTestType (genBuf, &att); if ((encodedLen <= 0) || BufWriteError (genBuf)) { fprintf (stderr, "ERROR - buffer to hold the encoded value was too small\n"); exit (1); } /* * free all of the decoded value since * it has been encoded into the buffer. * This is much more efficient than freeing * each compontent of the value individually */ ResetNibbleMem(); /* * write encoded value from encBuf * to stdout */ fwrite (SBufDataPtr (genBuf->spare), SBufDataLen (genBuf->spare), 1, stdout); return 0; } esnacc-ng-1.8.1/c-examples/any/genber.c000066400000000000000000000131411302010526100176000ustar00rootroot00000000000000/* * c-examples/any/genber.c - builds an AnyTestType value and writes BER form * of the value to a file called "att.ber" * * Shows how to build internal rep of lists and ANY values. * * MS 92 * * $Header: /baseline/SNACC/c-examples/any/genber.c,v 1.5 2003/12/17 19:05:03 gronej Exp $ * $Log: genber.c,v $ * Revision 1.5 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.4.2.1 2003/11/05 14:58:53 gronej * working PER code merged with esnacc_1_6 * * Revision 1.4 2002/10/24 14:48:12 mcphersc * Added binary mode to fopen * * Revision 1.3 2002/10/24 11:50:49 mcphersc * Changed SBufResetinReadMode to BufResetinReadmode * * Revision 1.2 2002/10/23 17:55:55 mcphersc * Fixes to support GenBuf * * Revision 1.1 2002/10/23 12:42:56 mcphersc * Added "C" files instead of C++ files * * Revision 1.3.1.1 1997/08/20 23:14:52 povey * * * Revision 1.5 1995/07/24 20:40:50 rj * any-test.[hc] becomes any.[hc] due to to snacc's new file name generation scheme. * * changed `_' to `-' in file names. * * Revision 1.4 1995/02/18 15:17:36 rj * cosmetic changes * * Revision 1.3 1994/08/31 23:48:06 rj * more portable .h file inclusion. * * Revision 1.2 1994/08/31 08:59:32 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include /* this must be before stddef for gcc-2.3.1 */ #include #include #include #include #include #include "asn-incl.h" #include "any.h" extern unsigned short stdIndentG = 4; main (int argc, char *argv[]) { FILE *outputFile; SBuf *outputBuf; GenBuf *genBuf; unsigned long int encodedLen; int dataSize = 2048; int i; char data[2048]; AnyTestType att; AttrValue1 **atv1Hndl; AttrValue2 **atv2Hndl; AsnInt intVal; AsnBool boolVal; AsnOcts octsVal; AsnBits bitsVal; AsnReal realVal; /* used to alloc part of value (Asn1Alloc & AsnListAppend) */ InitNibbleMem (512,512); /* init id to type ANY hash table */ InitAnyANY_TEST(); att.intMap = AsnListNew (sizeof (void*)); atv1Hndl = (AttrValue1**)AsnListAppend (att.intMap); *atv1Hndl = (AttrValue1*) Asn1Alloc (sizeof (AttrValue1)); (*atv1Hndl)->id = intId; /* the id's are defined in the generated code */ intVal = -99; (*atv1Hndl)->anyDefBy.value = (void*) &intVal; atv1Hndl = (AttrValue1**)AsnListAppend (att.intMap); *atv1Hndl = (AttrValue1*) Asn1Alloc (sizeof (AttrValue1)); (*atv1Hndl)->id = boolId; boolVal = TRUE; (*atv1Hndl)->anyDefBy.value = (void*)&boolVal; atv1Hndl = (AttrValue1**)AsnListAppend (att.intMap); *atv1Hndl = (AttrValue1*) Asn1Alloc (sizeof (AttrValue1)); (*atv1Hndl)->id = octsId; octsVal.octs = "Hi Mom"; octsVal.octetLen = strlen (octsVal.octs); (*atv1Hndl)->anyDefBy.value = (void*)&octsVal; atv1Hndl = (AttrValue1**)AsnListAppend (att.intMap); *atv1Hndl = (AttrValue1*) Asn1Alloc (sizeof (AttrValue1)); (*atv1Hndl)->id = bitsId; bitsVal.bitLen = 10; bitsVal.bits = (char*)&i; SetAsnBit (&bitsVal, 0); ClrAsnBit (&bitsVal, 1); SetAsnBit (&bitsVal, 2); ClrAsnBit (&bitsVal, 3); SetAsnBit (&bitsVal, 4); ClrAsnBit (&bitsVal, 5); SetAsnBit (&bitsVal, 6); ClrAsnBit (&bitsVal, 7); SetAsnBit (&bitsVal, 8); ClrAsnBit (&bitsVal, 9); (*atv1Hndl)->anyDefBy.value = (void*)&bitsVal; atv1Hndl = (AttrValue1**)AsnListAppend (att.intMap); *atv1Hndl = (AttrValue1*) Asn1Alloc (sizeof (AttrValue1)); (*atv1Hndl)->id = realId; realVal = 108.3838; (*atv1Hndl)->anyDefBy.value = (void*)&realVal; /* now do TSeq2 with same vals but use OID as identifier */ att.oidMap = AsnListNew (sizeof (void*)); atv2Hndl = (AttrValue2**)AsnListAppend (att.oidMap); *atv2Hndl = (AttrValue2*) Asn1Alloc (sizeof (AttrValue2)); (*atv2Hndl)->id = intOid; (*atv2Hndl)->anyDefBy.value = (void*)&intVal; atv2Hndl = (AttrValue2**)AsnListAppend (att.oidMap); *atv2Hndl = (AttrValue2*) Asn1Alloc (sizeof (AttrValue2)); (*atv2Hndl)->id = boolOid; (*atv2Hndl)->anyDefBy.value = (void*)&boolVal; atv2Hndl = (AttrValue2**)AsnListAppend (att.oidMap); *atv2Hndl = (AttrValue2*) Asn1Alloc (sizeof (AttrValue2)); (*atv2Hndl)->id = octsOid; (*atv2Hndl)->anyDefBy.value = (void*)&octsVal; atv2Hndl = (AttrValue2**)AsnListAppend (att.oidMap); *atv2Hndl = (AttrValue2*) Asn1Alloc (sizeof (AttrValue2)); (*atv2Hndl)->id = bitsOid; (*atv2Hndl)->anyDefBy.value = (void*)&bitsVal; atv2Hndl = (AttrValue2**)AsnListAppend (att.oidMap); *atv2Hndl = (AttrValue2*) Asn1Alloc (sizeof (AttrValue2)); (*atv2Hndl)->id = realOid; (*atv2Hndl)->anyDefBy.value = (void*)&realVal; outputBuf = (SBuf *)Asn1Alloc(sizeof(SBuf)); SBufInit (outputBuf,data, dataSize); SBufResetInWriteRvsMode (outputBuf); SBuftoGenBuf (outputBuf, &genBuf); // encodedLen = BEncAnyTestType (&outputBuf, &att); encodedLen = BEncAnyTestType (genBuf, &att); if ((encodedLen <= 0) || (BufWriteError (genBuf))) { fprintf (stderr, "failed encoding AnyTestType value\n"); exit (1); } outputFile = fopen ("att.ber", "wb"); if (!outputFile) { perror ("fopen:"); exit (1); } BufResetInReadMode (genBuf); for ( ; encodedLen > 0; encodedLen--) fputc (BufGetByte (genBuf), outputFile); printf ("Wrote the following BER AnyTestType value to att.ber.\n"); printf ("Test it with \"def\" and \"indef\"\n"); PrintAnyTestType (stdout, &att, 0); printf ("\n"); return 0; } esnacc-ng-1.8.1/c-examples/any/readme000066400000000000000000000112741302010526100173570ustar00rootroot00000000000000(RCS control information is at the end of this file.) C ANY example README ------------------ This example shows how the snacc compiler handles the ANY DEFINED BY type in C. ANY types (not ANY DEFINED BY) require the modifications to the generated code. Type "make" to build this example. This directory should have the following files in it: README genber.c example.c makefile There are 3 programs generated by the makefile: genber - builds a BER value of the AnyTestType and writes it to a file called "att.ber" def - takes file name of an AnyTestType value. Decodes the file and re-encodes it to stdout. Uses definite lengths for constructed values. indef - takes file name of an AnyTestType value. Decodes the file and re-encodes it to stdout. Uses indefinite lengths for constructed values. These files use the code generated by snacc from the snacc/asn1specs/any.asn1 file. (see the makefile) Look at genber.c to see how values can be built and printed. Look at the generated code in any_test.c and any_test.h to see how the any hash table is built. try the following commands in your c-shell: %1 genber # generate the att.ber file %2 indef att.ber > tmp.ber # decode att.ber an re-encode into tmp.ber %3 def tmp.ber > tmp2.ber # decode tmp.ber an re-encode into tmp2.ber %4 diff att.ber tmp2.ber # compare .ber files (should be the same) You can also try different memory buffers when running the indef and def utilities. To try ExpBuf use the -E argument when executing these utilities. Example: indef -E att.ber > tmp.ber # decode att.ber using the ExpBuf and re-encode into tmp.ber def -E att.ber > tmp.ber # decode att.ber using the ExpBuf and re-encode into tmp.ber When you are finished with the example type "make clean" to remove the binaries and generated code. Things To Note -------------- Snacc ASN.1 comment commands In the snacc/asn1specs/any.asn1 file, the AnyTestType has a special "--snacc" ASN.1 comment after ::= to give snacc some extra information about the AnyTestType. AnyTestType ::= --snacc isPdu:"TRUE" -- SEQUENCE { ... etc. ... } The "isPdu" flag tells snacc that the AnyTestType is a PDU type that you will be calling the encoding and decoding routines directly from your code. This causes snacc to generate the "BEncAnyTestType" and "BDecAnyTestType" routines in addition to the standard "BEncAnyTestTypeContent" and "BDecAnyTestTypeContent". The Content encoding and decoding routines only deal with the content of the type, ignoring all of the tag and length pairs on the given type (in this case the UNIVERSAL (CONSTRUCTED) 16 tag and the length for the SEQUENCE). The "BEncAnyTestType" and "BDecAnyTestType" routines do encode the SEQUENCE tag and its length. This design is motivated by IMPLICIT tagging. The compiler generated routines generally only call the content oriented routines except in the case of ANY and ANY DEFINED BY types. For ANY and ANY DEFINED BY types the PDU form of the rouine is called since the tags are not known by the containing type. SNMP OBJECT-TYPE Macro The SNMP OBJECT-TYPE macro is used to define the id to type mapping for ANY DEFINED BY types. The macro has been modified to accept both INTEGERs and OBJECT IDENTIFIERs as values (see snacc/asn1specs/any.asn1). This macro can be used with other protocols to define the id to type mapping. Two hash tables are used to hold the id to type mappings. One for INTEGER to type mappings and the other for OBJECT IDENTIFIER to type mappings. You must explicitly initialize the hash tables by calling generated init routines once at the beginning of your program. Each module that has OBJECT-TYPE macros in it will generate an "InitAny" routine. You must call every init routine to add all the mappings to the hash table(s). #------------------------------------------------------------------------------- # $Header: /baseline/SNACC/c-examples/any/readme,v 1.4 2003/12/17 19:05:03 gronej Exp $ # $Log: readme,v $ # Revision 1.4 2003/12/17 19:05:03 gronej # SNACC baseline merged with PER v1_7 tag # # Revision 1.3.2.1 2003/11/05 14:58:53 gronej # working PER code merged with esnacc_1_6 # # Revision 1.3 2002/10/24 14:47:41 mcphersc # Added comments to new test routines # # Revision 1.2 2002/10/23 12:42:56 mcphersc # Added "C" files instead of C++ files # # Revision 1.3.1.1 1997/08/20 23:14:52 povey # # # Revision 1.2 1997/02/16 20:26:14 rj # check-in of a few cosmetic changes # # Revision 1.1 1994/08/31 08:46:17 rj # first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. # esnacc-ng-1.8.1/c-examples/automake.mk000066400000000000000000000027601302010526100175470ustar00rootroot00000000000000TESTS += c-examples/simple/genber \ c-examples/simple/minbuf \ c-examples/simple/expbuf \ c-examples/simple/sbuf \ c-examples/test-lib/testlib check_PROGRAMS += c-examples/simple/genber \ c-examples/simple/minbuf \ c-examples/simple/expbuf \ c-examples/simple/sbuf \ c-examples/test-lib/testlib c_examples_simple_CFLAGS = \ -I$(top_srcdir)/asn1specs \ -I$(builddir)/asn1specs \ -I$(top_srcdir)/c-lib/inc c_examples_simple_genber_SOURCES = \ asn1specs/p-rec.asn1 \ c-examples/simple/genber.c c_examples_simple_genber_CFLAGS = \ $(c_examples_simple_CFLAGS) c_examples_simple_genber_LDADD = \ c-lib/libcasn1.la c_examples_simple_minbuf_SOURCES = \ asn1specs/p-rec.asn1 \ c-examples/simple/minbuf-ex.c c_examples_simple_minbuf_CFLAGS = \ $(c_examples_simple_CFLAGS) c_examples_simple_minbuf_LDADD = \ c-lib/libcasn1.la c_examples_simple_expbuf_SOURCES = \ asn1specs/p-rec.asn1 \ c-examples/simple/expbuf-ex.c c_examples_simple_expbuf_CFLAGS = \ $(c_examples_simple_CFLAGS) c_examples_simple_expbuf_LDADD = \ c-lib/libcasn1.la c_examples_simple_sbuf_SOURCES = \ asn1specs/p-rec.asn1 \ c-examples/simple/sbuf-ex.c c_examples_simple_sbuf_CFLAGS = \ $(c_examples_simple_CFLAGS) c_examples_simple_sbuf_LDADD = \ c-lib/libcasn1.la c_examples_test_lib_testlib_SOURCES = \ c-examples/test-lib/test-lib.c c_examples_test_lib_testlib_CFLAGS = \ -I$(top_srcdir)/c-lib/inc c_examples_test_lib_testlib_LDADD = \ c-lib/libcasn1.la CLEANFILES += asn1specs/p-rec.h asn1specs/p-rec.c pr.ber esnacc-ng-1.8.1/c-examples/simple/000077500000000000000000000000001302010526100166745ustar00rootroot00000000000000esnacc-ng-1.8.1/c-examples/simple/example.c000066400000000000000000000062471302010526100205040ustar00rootroot00000000000000// c++_examples/simple/example.C - an example of how to use C++ ASN.1-BER // encoders and decoders generated by snacc // // AUTHOR: Mike Sample // DATE: Aug 92 // // $Header: /baseline/SNACC/c-examples/simple/example.c,v 1.2 2003/12/17 19:05:03 gronej Exp $ // $Log: example.c,v $ // Revision 1.2 2003/12/17 19:05:03 gronej // SNACC baseline merged with PER v1_7 tag // // Revision 1.1.2.1 2003/11/05 14:58:57 gronej // working PER code merged with esnacc_1_6 // // Revision 1.1.1.1 2000/08/21 20:36:07 leonberp // First CVS Version of SNACC. // // Revision 1.5 1995/07/24 15:36:03 rj // check return value of new. // // changed `_' to `-' in file names. // // Revision 1.4 1995/02/18 13:54:18 rj // added #define HAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS since not every C++ compiler provides them. // // Revision 1.3 1994/10/08 01:27:02 rj // several \size_t' // // Revision 1.2 1994/08/31 08:56:32 rj // first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. // #include #include #include #include #include "asn-incl.h" #include "p-rec.h" main (int argc, char *argv[]) { AsnBuf inputBuf; AsnBuf outputBuf; size_t encodedLen; size_t decodedLen; size_t dataSize; ifstream dataFile; PersonnelRecord pr; if (argc != 2) { cerr << "Usage: " << argv[0] << " " << endl; cerr << " Decodes the given PersonnelRecord BER data file" << endl; cerr << " and re-encodes it to stdout" << endl; exit (1); } // open the data file dataFile.open (argv[1]); if (!dataFile) { perror ("ifstream::open"); exit (1); } // get size of the data file file dataFile.seekg (0, ios::end); dataSize = dataFile.tellg(); dataFile.seekg (0); // read data from file into contiguous block for a buffer #if HAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS char data[dataSize]; #else char *data = new char[dataSize]; if (!data) return 1; #endif /* HAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS */ dataFile.read (data, dataSize); dataFile.close(); // // put the BER data read from the file // into buffer format, ready for reading from the // beginning // inputBuf.InstallData (data, dataSize); if (!pr.BDecPdu (inputBuf, decodedLen)) { cerr << "--- ERROR - Decode routines failed, exiting..." << endl; exit (1); } cerr << "decodedValue PersonnelRecord ::= " << pr << endl << endl; // // allocate a new buffer set up for writing to // #if HAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS char outputData[dataSize + 512]; #else char *outputData = new char[dataSize + 512]; if (!outputData) return 1; #endif /* HAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS */ outputBuf.Init (outputData, dataSize+512); outputBuf.ResetInWriteRvsMode(); if (!pr.BEncPdu (outputBuf, encodedLen)) { cerr << "--- ERROR - Encode routines failed" << endl; } // write the BER value to cout outputBuf.ResetInReadMode(); for (; encodedLen > 0; encodedLen--) cout.put (outputBuf.GetByte()); return 0; } esnacc-ng-1.8.1/c-examples/simple/expbuf-ex.c000066400000000000000000000066701302010526100207540ustar00rootroot00000000000000/* * c_examples/simple/expbuf_ex.c - an example of how to call C ASN.1-BER * encoders and decoders generated by snacc * with the ExpBuf buffer. * * AUTHOR: Mike Sample * DATE: Mar 92 * * $Header: /baseline/SNACC/c-examples/simple/expbuf-ex.c,v 1.2 2003/12/17 19:05:03 gronej Exp $ * $Log: expbuf-ex.c,v $ * Revision 1.2 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.1.2.1 2003/11/05 14:58:57 gronej * working PER code merged with esnacc_1_6 * * Revision 1.1.1.1 2000/08/21 20:36:07 leonberp * First CVS Version of SNACC. * * Revision 1.5 1995/07/24 20:44:58 rj * changed `_' to `-' in file names. * * Revision 1.4 1995/02/18 15:12:53 rj * cosmetic changes * * Revision 1.3 1994/08/31 23:48:29 rj * more portable .h file inclusion. * * Revision 1.2 1994/08/31 08:59:34 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include "snacc.h" #include "asn-incl.h" #include #include #if HAVE_FCNTL_H #include #endif #include #include #include "p-rec.h" int main PARAMS ((argc, argv), int argc _AND_ char *argv[]) { int fd; GenBuf *buf = NULL, *encBuf = NULL; ExpBuf *ebuf, *tmpBuf, b; AsnLen decodedLen; int val; PersonnelRecord pr; int size; char *origData; struct stat sbuf; jmp_buf env; int decodeErr; char *filename; if (argc != 2) { filename = "pr.ber"; } else { filename = argv[1]; } fd = open(filename, O_RDONLY, 0); if (fd < 0) { fprintf(stderr, "Usage: %s \n", argv[0]); fprintf(stderr, " Decodes the given PersonnelRecord BER data " "file\n"); fprintf(stderr, " and re-encodes it to stdout\n"); exit(1); } if (fstat(fd, &sbuf) < 0) { perror("main: fstat"); exit(1); } size = sbuf.st_size; origData = (char*)malloc(size); if (read(fd, origData, size) != size) { perror("main: read"); exit(1); } close(fd); /* * the "1024" is the size in bytes of the data * blk to allocate when writing to a buffer that * fills up. */ ExpBufInit (1024); /* * put the BER data read from the file * into buffer format, ready for reading from the * beginning */ ebuf = &b; ExpBufInstallDataInBuf (ebuf, origData, size); ExpBuftoGenBuf(ebuf, &buf); decodedLen = 0; decodeErr = FALSE; if ((val = setjmp (env)) == 0) { BDecPersonnelRecord(buf, &pr, &decodedLen, env); } else { decodeErr = TRUE; fprintf(stderr, "ERROR - Decode routines returned %d\n",val); } if (decodeErr) exit(1); fprintf(stderr, "decodedValue PersonnelRecord ::= "); PrintPersonnelRecord(stderr, &pr, 0); fprintf(stderr, "\n\n"); /* * allocate a new buffer set up for writing to */ tmpBuf = ExpBufAllocBufAndData(); ExpBuftoGenBuf(tmpBuf, &encBuf); (void)BEncPersonnelRecord(encBuf, &pr); /* * Alway check for a buffer write error after encoding */ if (ExpBufWriteError (&tmpBuf)) { fprintf (stderr, "ERROR - buffer write error during encoding\n"); exit (1); } ExpBufFreeBufAndData(tmpBuf); printf("Freed tmpBuf\n"); ExpBufFreeData(ebuf->blkStart); return 0; } esnacc-ng-1.8.1/c-examples/simple/genber.c000066400000000000000000000112231302010526100203010ustar00rootroot00000000000000// file: .../c++examples/simple/genber.C---builds an PersonnelRecord value and writes BER form of the value to a file called "pr.ber" // // MS 92 // // $Header: /baseline/SNACC/c-examples/simple/genber.c,v 1.2 2003/12/17 19:05:03 gronej Exp $ // $Log: genber.c,v $ // Revision 1.2 2003/12/17 19:05:03 gronej // SNACC baseline merged with PER v1_7 tag // // Revision 1.1.2.1 2003/11/05 14:58:57 gronej // working PER code merged with esnacc_1_6 // // Revision 1.1.1.1 2000/08/21 20:36:07 leonberp // First CVS Version of SNACC. // // Revision 1.5 1995/07/24 15:40:32 rj // changed `_' to `-' in file names. // // Revision 1.4 1994/12/11 15:36:14 rj // const for a constant value [DEC] // // Revision 1.3 1994/10/08 01:27:03 rj // several \size_t' // // Revision 1.2 1994/08/31 08:56:33 rj // first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. // #include #include #include #include #include #include "asn-incl.h" #include "sbuf.h" #include "nibble-alloc.h" #include "p-rec.h" int main (int argc, char *argv[]) { FILE *outputFile; SBuf outputBuf; SBuf *outputBufP = &outputBuf; GenBuf *genOutputBuf = 0; unsigned long int encodedLen; int i; char data[2048] = {0}; int dataSize = sizeof(data); PersonnelRecord pr; ChildInformation **childHndl; InitNibbleMem(512,512); pr.name = (Name *)Asn1Alloc(sizeof(Name)); pr.name->givenName.octs = "John"; pr.name->givenName.octetLen = strlen(pr.name->givenName.octs); pr.name->initial.octs = "E"; pr.name->initial.octetLen = strlen(pr.name->initial.octs); pr.name->familyName.octs = "Smith"; pr.name->familyName.octetLen = strlen(pr.name->familyName.octs); pr.title.octs = "El Presidente"; pr.title.octetLen = strlen(pr.title.octs); pr.employeeNumber = 91991; pr.dateOfHire.octs = "20071024"; pr.dateOfHire.octetLen = strlen(pr.dateOfHire.octs); pr.nameOfSpouse = (Name *) Asn1Alloc(sizeof(Name)); pr.nameOfSpouse->givenName.octs = "Mary"; pr.nameOfSpouse->givenName.octetLen = strlen(pr.nameOfSpouse->givenName.octs); pr.nameOfSpouse->initial.octs = "F"; pr.nameOfSpouse->initial.octetLen = strlen(pr.nameOfSpouse->initial.octs); pr.nameOfSpouse->familyName.octs = "Smith"; pr.nameOfSpouse->familyName.octetLen = strlen(pr.nameOfSpouse->familyName.octs); pr.children = AsnListNew(sizeof(void*)); childHndl = AsnListAppend(pr.children); *childHndl = Asn1Alloc(sizeof(ChildInformation)); (*childHndl)->dateOfBirth.octs = "20090123"; (*childHndl)->dateOfBirth.octetLen = strlen((*childHndl)->dateOfBirth.octs); (*childHndl)->name = (Name*)Asn1Alloc(sizeof(Name)); (*childHndl)->name->givenName.octs = "Jacob"; (*childHndl)->name->givenName.octetLen = strlen((*childHndl)->name->givenName.octs); (*childHndl)->name->initial.octs = "J"; (*childHndl)->name->initial.octetLen = strlen((*childHndl)->name->initial.octs); (*childHndl)->name->familyName.octs = "Smith"; (*childHndl)->name->familyName.octetLen = strlen((*childHndl)->name->initial.octs); childHndl = AsnListAppend(pr.children); *childHndl = Asn1Alloc(sizeof(ChildInformation)); (*childHndl)->dateOfBirth.octs = "20101130"; (*childHndl)->dateOfBirth.octetLen = strlen((*childHndl)->dateOfBirth.octs); (*childHndl)->name = (Name*)Asn1Alloc(sizeof(Name)); (*childHndl)->name->givenName.octs = "Jane"; (*childHndl)->name->givenName.octetLen = strlen((*childHndl)->name->givenName.octs); (*childHndl)->name->initial.octs = "D"; (*childHndl)->name->initial.octetLen = strlen((*childHndl)->name->initial.octs); (*childHndl)->name->familyName.octs = "Smith"; (*childHndl)->name->familyName.octetLen = strlen((*childHndl)->name->initial.octs); SBufInit(&outputBuf, data, dataSize); SBufResetInWriteRvsMode(&outputBuf); SBuftoGenBuf(&outputBuf, &genOutputBuf); encodedLen = BEncPersonnelRecord(genOutputBuf, &pr); if ((encodedLen <= 0) || (SBufWriteError(&outputBufP))) { fprintf(stderr, "failed encoding Personnel Record: 0x%x\n", SBufWriteError(&outputBufP)); exit(1); } outputFile = fopen("pr.ber", "w"); if (!outputFile) { perror("fopen"); exit(1); } SBufResetInReadMode(&outputBufP); for (;encodedLen > 0;encodedLen--){ fputc(SBufGetByte(&outputBufP), outputFile); } printf("wrote the BER value to pr.ber\n"); printf("test with \"def\" and \"indef\"\n"); PrintPersonnelRecord(stdout, &pr, 0); printf("\n"); return 0; } esnacc-ng-1.8.1/c-examples/simple/good-pr.ber000066400000000000000000000002221302010526100207310ustar00rootroot00000000000000`ŒaJohnESmith The Big CheeseB†Ÿ¡ C19820104¢aMaryLSmith£A1aJamesRSmith  C195703101aLisaMSmith  C19610621esnacc-ng-1.8.1/c-examples/simple/minbuf-ex.c000066400000000000000000000062671302010526100207450ustar00rootroot00000000000000/* * c_examples/simple/minbuf_ex.c - an example of how to call C ASN.1-BER * encoders and decoders generated by snacc * using the MinBuf buffer. * * AUTHOR: Mike Sample * DATE: Mar 92 * * $Header: /baseline/SNACC/c-examples/simple/minbuf-ex.c,v 1.2 2003/12/17 19:05:03 gronej Exp $ * $Log: minbuf-ex.c,v $ * Revision 1.2 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.1.2.1 2003/11/05 14:58:57 gronej * working PER code merged with esnacc_1_6 * * Revision 1.1.1.1 2000/08/21 20:36:07 leonberp * First CVS Version of SNACC. * * Revision 1.5 1995/07/24 20:46:59 rj * changed `_' to `-' in file names. * * Revision 1.4 1995/02/18 15:12:55 rj * cosmetic changes * * Revision 1.3 1994/09/01 01:02:38 rj * more portable .h file inclusion. * * Revision 1.2 1994/08/31 08:59:36 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include "snacc.h" #include "asn-incl.h" #include #include #if HAVE_FCNTL_H #include #endif #include #include #include "p-rec.h" #include "min-buf.h" int main PARAMS ((argc, argv), int argc _AND_ char *argv[]) { int fd; GenBuf buf, encBuf; char *encData; int encBufSize; AsnLen decodedLen; int val; PersonnelRecord pr; int size; char *origData; struct stat sbuf; jmp_buf env; int decodeErr; char *filename; if (argc != 2) { filename = "pr.ber"; } else { filename = argv[1]; } fd = open(filename, O_RDONLY, 0); if (fd < 0) { fprintf(stderr, "Usage: %s \n", argv[0]); fprintf(stderr, " Decodes the given PersonnelRecord BER data " "file\n"); fprintf(stderr, " and re-encodes it to stdout\n"); exit(1); } if (fstat(fd, &sbuf) < 0) { perror("main: fstat"); exit(1); } size = sbuf.st_size; origData = (char*)malloc(size); if (read(fd, origData, size) != size) { perror("main: read"); exit(1); } close(fd); /* set up min buf */ GenBufFromMinBuf(&buf, origData); decodedLen = 0; decodeErr = FALSE; if ((val = setjmp(env)) == 0) { BDecPersonnelRecord(&buf, &pr, &decodedLen, env); } else { decodeErr = TRUE; fprintf(stderr, "ERROR - Decode routines returned %d\n", val); } if (decodeErr) exit(1); fprintf(stderr, "decodedValue PersonnelRecord ::= "); PrintPersonnelRecord(stderr, &pr, 0); fprintf(stderr, "\n\n"); /* * setup a new buffer set up for writing. * make sure size is big enough to hold the encoded * value (may be larger than decoded value if encoding * with indef lengths - so add 512 slush bytes) */ encBufSize = size + 512; encData = (char*) malloc(encBufSize); /* * set 'buffer' up for writing by setting ptr * byte after last byte of the block */ GenBufFromMinBuf(&encBuf, encData + encBufSize); (void)BEncPersonnelRecord(&encBuf, &pr); free(encData); free(origData); return 0; } esnacc-ng-1.8.1/c-examples/simple/readme000066400000000000000000000117771302010526100200710ustar00rootroot00000000000000(RCS control information is at the end of this file.) C Simple Example README ----------------------- This directory should have 8 files in it: README - this file genber.c - C source code for a program that creates and encodes a PersonnelRecord value to a file. expbuf_ex.c - C source code for a program that calls the generated PersonnelRecord encoder and decoder routines using the ExpBuf buffer type minbuf_ex.c - C source code for program that calls the generated PersonnelRecord encoder and decoder routines using the MinBuf buffer type sbuf_ex.c - C source code for a program that calls the generated PersonnelRecord encoder and decoder routines using the MinBuf buffer type makefile - compiles the example programs good_pr.ber - BER encoding of a Personnel Record (all definite lengths) Type "make" to generate the 7 example programs: genber expbuf_def expbuf_indef minbuf_def minbuf_indef sbuf_def sbuf_indef snacc is called from the makefile on snacc/asn1specs/p_rec.asn1 to generate the following files: p_rec.h - C data structs for PersonnelRecord and prototypes for the generated encode, decode, print and free routines. p_rec.c - C source code for the PersonnelRecord encode, decode, print, and free routines. These source files are then compiled with *_ex.c and genber.c files to make 7 programs. Each program takes 1 argument (except genber), the name of a file containing an BER encoded PersonnelRecord value. Try the following: (or use the makefile's `check' phony target) eg% ./genber # create a file called pr.ber eg% ./sbuf_indef good_pr.ber > indef_pr.ber eg% ./sbuf_def indef_pr.ber > def_pr.ber eg% diff good_pr.ber def_pr.ber # should be no differences The above commands decode the BER value in "good_pr.ber" and indef_pr.ber respectively and then re-encode then to stdout. Both programs will decode any valid BER representation of a PersonnelRecord value but, the sbuf_def program will re-encode the given data using only the definite length BER format and the sbuf_indef program will re-encode the given data using only the indefinite length BER format. Compare the lengths of the def_pr.ber and indef_pr.ber files, indefinite length encodings are usually larger. Things to Note -------------- Look at genber.c to see how to build a C value and then encode it. look at the *_ex.c files to see the different types of buffer manipulation. Read the comments in the code. It should be relatively simple to change the memory and buffer management to fit your target environment. (see snacc/c_include/asn_config.h.) Snacc ASN.1 comment commands Notice the special "--snacc" ASN.1 comment in snacc/asn1specs/p_rec.asn1. PersonnelRecord ::= --snacc isPdu:"TRUE" -- [APPLICATION 0] IMPLICIT SET { ... etc. ... } The "isPdu" flag tells snacc that the PersonnelRecord is a PDU type that you will be calling the encoding and decoding routines directly from your code. This causes snacc to generate the "BEncPersonnelRecord" and "BDecPersonnelRecord" routines in addition to the standard "BEncPersonnelRecordContent" and "BDecPersonnelRecordContent". The Content encoding and decoding routines only deal with the content of the type, ignoring all of the tag and length pairs on the given type (in this case the APPLICATION (CONSTRUCTED) 0 tag and the length for the SET). The "BEncPersonnelRecord" and "BDecPersonnelRecord" routines do encode the APPLICATION tag and the SET's length. This design is motivated by IMPLICIT tagging. The compiler generated routines generally only call the content oriented routines except in the case of ANY and ANY DEFINED BY types. For ANY and ANY DEFINED BY types the PDU form of the rouine is called since the tags are not known by the containing type. Length formats Each pair of *_def and *_indef programs were generated from the same source file, *_ex.c. Indefinite length encoders can be created by giving the -DUSE_INDEF_LEN flag to the C compiler when compiling. Currently the indefinite/definite length encoder choice is made a compile time. To change this to a run-time decision, a simple solution would be to modify BerEncodeConsLen and BerEncodeEocIfNec macros in snacc/c_lib/asn_len.h to check a global flag. #------------------------------------------------------------------------------- # $Header: /baseline/SNACC/c-examples/simple/readme,v 1.2 2003/12/17 19:05:03 gronej Exp $ # $Log: readme,v $ # Revision 1.2 2003/12/17 19:05:03 gronej # SNACC baseline merged with PER v1_7 tag # # Revision 1.1.2.1 2003/11/05 14:58:57 gronej # working PER code merged with esnacc_1_6 # # Revision 1.1.1.1 2000/08/21 20:36:07 leonberp # First CVS Version of SNACC. # # Revision 1.2 1995/02/17 16:17:24 rj # reflect the test script's integration into the makefile. # # Revision 1.1 1994/08/31 08:46:22 rj # first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. # esnacc-ng-1.8.1/c-examples/simple/sbuf-ex.c000066400000000000000000000073031302010526100204140ustar00rootroot00000000000000/* * c_examples/simple/sbuf_ex.c - an example of how to call C ASN.1-BER * encoders and decoders generated by snacc * using the SBuf buffer. * * AUTHOR: Mike Sample * DATE: Mar 92 * * $Header: /baseline/SNACC/c-examples/simple/sbuf-ex.c,v 1.2 2003/12/17 19:05:03 gronej Exp $ * $Log: sbuf-ex.c,v $ * Revision 1.2 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.1.2.1 2003/11/05 14:58:57 gronej * working PER code merged with esnacc_1_6 * * Revision 1.1.1.1 2000/08/21 20:36:07 leonberp * First CVS Version of SNACC. * * Revision 1.5 1995/07/24 20:47:00 rj * changed `_' to `-' in file names. * * Revision 1.4 1995/02/18 15:12:56 rj * cosmetic changes * * Revision 1.3 1994/09/01 01:02:39 rj * more portable .h file inclusion. * * Revision 1.2 1994/08/31 08:59:37 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include "asn-incl.h" #include #include #include #include #include #include "sbuf.h" #include "p-rec.h" int main PARAMS ((argc, argv), int argc _AND_ char *argv[]) { int fd; SBuf buf; SBuf encBuf, *ebuf = &encBuf; GenBuf *gbuf, *gebuf; char *filename; char *encData; AsnLen decodedLen; int val; PersonnelRecord pr; int size; char *origData; struct stat sbuf; jmp_buf env; int decodeErr; if (argc != 2) { filename = "pr.ber"; } else { filename = argv[1]; } fd = open(filename, O_RDONLY, 0); if (fd < 0) { fprintf(stderr, "Usage: %s \n", argv[0]); fprintf(stderr, " Decodes the given PersonnelRecord BER data " "file\n"); fprintf(stderr, " and re-encodes it to stdout\n"); exit(1); } if (fstat(fd, &sbuf) < 0) { perror("main: fstat"); exit(1); } size = sbuf.st_size; origData = (char*)malloc(size); if (read(fd, origData, size) != size) { perror("main: read"); exit(1); } close(fd); /* * puts the given data 'origData' of 'size' bytes * into an SBuf and sets the SBuf up for reading * origData from the beginning */ SBufInstallData (&buf, origData, size); decodedLen = 0; decodeErr = FALSE; if ((val = setjmp(env)) == 0) { SBuftoGenBuf(&buf, &gbuf); BDecPersonnelRecord(gbuf, &pr, &decodedLen, env); } else { decodeErr = TRUE; fprintf(stderr, "ERROR - Decode routines returned %d\n", val); } if (decodeErr) exit (1); fprintf(stderr, "decodedValue PersonnelRecord ::= "); PrintPersonnelRecord(stderr, &pr, 0); fprintf(stderr, "\n\n"); /* * setup a new buffer set up for writing. * make sure size is big enough to hold the encoded * value (may be larger than decoded value if encoding * with indef lengths - so add 512 slush bytes) */ encData = (char*) malloc(size + 512); SBufInit(&encBuf, encData, size + 512); SBufResetInWriteRvsMode(&encBuf); SBuftoGenBuf(&encBuf, &gebuf); (void) BEncPersonnelRecord(gebuf, &pr); if (SBufWriteError(&ebuf)) { fprintf (stderr, "ERROR - buffer to hold the encoded value was too small\n"); exit (1); } /* * write encoded value from encBuf * to stdout */ fwrite(SBufDataPtr (&encBuf), SBufDataLen (&encBuf), 1, stdout); FreePersonnelRecord(&pr); GenBufFree(gebuf); GenBufFree(gbuf); SBufInstallData(&encBuf, NULL, 0); SBufInstallData(&buf, NULL, 0); free(encData); free(origData); return 0; } esnacc-ng-1.8.1/c-examples/snmp/000077500000000000000000000000001302010526100163605ustar00rootroot00000000000000esnacc-ng-1.8.1/c-examples/snmp/readme000066400000000000000000000117611302010526100175460ustar00rootroot00000000000000(RCS control information is at the end of this file.) C SNMP Example - Mike Sample Mar 92 ----------------------------------- This example illustrates a few more features of the compiler than the simple example. It also shows some deficiencies. No executable programs are generated by the makefile, it only generates the snmp code and compiles it without linking. This directory contains 2 files: README makefile Snacc generates source from the following ASN.1 files: snacc/asn1specs/rfc1155_smi.asn1 snacc/asn1specs/rfc1157_snmp.asn1 snacc/asn1specs/rfc1213_mib2.asn1 multi-module compilation The IMPORT/EXPORT mechanisms of ASN.1 '88 are supported so you don't have to dump all of the ASN.1 definitions into a single file The order of the ASN.1 file arguments is the order that they are included in the generated source files. For example: %1 snacc rfc1155-smi.asn1 rfc1157-snmp.asn1 rfc1213-mib2.asn1 causes the order in which hdr files are included in rfc1213-mib.c to be: #include "asn-incl.h" #include "rfc1155-smi.h" #include "rfc1157-snmp.h" #include "rfc1213-mib2.h" Currently, snacc assumes that each ASN.1 file given on the command line depends on all of the others on the command line. There is no attempt to compute the dependencies via the import lists alone. SNMP OBJECT-TYPE macro parsing / ANY type hash table The SNMP OBJECT-TYPE macro is parsed. This results in the type in the "SYNTAX" part of the macro is put into the ANY type hash table using the OBJECT-TYPE macro's value as the hash key. Also if the type in the SYNTAX field is not defined outsided of the macro (could be different tagging etc), a proper type definition is generated for it. If you want to change the way the macro is handled, modify the corresponding routine in "do_macros.c". value definitions The OBJECT IDENTIFIER values are turned into statically initialized C values and included in the generated source and include file. This is also done for INTEGER and BOOLEAN values. More complex values are ignored by the compiler at the moment. (modify parse_vals.c if you want to improve this) -P option of snacc is demonstrated The ASN.1 for the parsed modules is generated from the internal data structure. This can be useful for making sure the compiler is handling your ASN.1 files correctly. It is also useful to see how the types are modified and sorted to simplify code generation. (see the snacc.output file after typeing "make") Deficiencies A deficiency in parsing large integers is shown when parsing the following rfc 1155 types: Counter ::= [APPLICATION 1] IMPLICIT INTEGER (0..4294967295) Gauge ::= [APPLICATION 2] IMPLICIT INTEGER (0..4294967295) TimeTicks ::= [APPLICATION 3] IMPLICIT INTEGER (0..4294967295) Due the size of a C long int the above ASN.1 is represented internally as: Counter ::= [APPLICATION 1] IMPLICIT INTEGER (0..-1) Gauge ::= [APPLICATION 2] IMPLICIT INTEGER (0..-1) TimeTicks ::= [APPLICATION 3] IMPLICIT INTEGER (0..-1) The ASN.1 library contains routines for encoding/decoding unsigned long integers but you must hand code the cases where it is used - the compiler never generates code that calls them. Note also that the produced code for the SNMP ASN.1 must be modified to correclty handle the "Opaque" data type. SNMP does not use the ANY DEFINED BY type in an effort to simplify things. Instead an OCTET STRING is used to hold and encoded value whose type is defined by an OBJECT IDENTIFIER. With some simple modifications you can use the snacc AsnAnyDefinedBy type instead of the OCTET STRING to achieve the desired results. This should underline the danger of blindly trusting the compiler to do the right thing for protocols such as SNMP or X.500 where the type of an encoded value depends on a mechanism outside of ASN.1 or the ANY type (ANY DEFINED BY types should work automatically). #------------------------------------------------------------------------------- # $Header: /baseline/SNACC/c-examples/snmp/readme,v 1.2 2003/12/17 19:05:03 gronej Exp $ # $Log: readme,v $ # Revision 1.2 2003/12/17 19:05:03 gronej # SNACC baseline merged with PER v1_7 tag # # Revision 1.1.2.1 2003/11/05 14:58:59 gronej # working PER code merged with esnacc_1_6 # # Revision 1.1.1.1 2000/08/21 20:36:07 leonberp # First CVS Version of SNACC. # # Revision 1.3 1995/07/27 09:58:31 rj # rfc1155-smi.asn1, rfc1157-snmp.asn1 and rfc1213-mib2.asn1 renamed from 1155-smi.asn1, 1157-snmp.asn1 and 1213-mib2.asn1 to accomodate to snacc's new file name generation scheme. # # Revision 1.2 1995/07/24 20:47:39 rj # changed `_' to `-' in file names. # # Revision 1.1 1994/08/31 08:46:33 rj # first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. # esnacc-ng-1.8.1/c-examples/test-lib/000077500000000000000000000000001302010526100171265ustar00rootroot00000000000000esnacc-ng-1.8.1/c-examples/test-lib/test-lib.c000066400000000000000000000517721302010526100210310ustar00rootroot00000000000000/* * c_examples/test_lib/test_lib.c * * uses SBufs for buffers * * MS 92 * * $Header: /baseline/SNACC/c-examples/test-lib/test-lib.c,v 1.3 2003/12/17 19:05:03 gronej Exp $ * $Log: test-lib.c,v $ * Revision 1.3 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.2.2.1 2003/11/05 14:59:00 gronej * working PER code merged with esnacc_1_6 * * Revision 1.2 2002/10/24 16:24:53 mcphersc * Changed to GenBuf usage * * Revision 1.3.1.1 1997/08/20 23:14:51 povey * * * Revision 1.5 1995/07/24 20:50:34 rj * ``#error "..."'' instead of ``#error ...''. * * changed `_' to `-' in file names. * * Revision 1.4 1995/02/18 16:17:44 rj * utilize either isinf(3) or finite(3), whatever happens to be present. * * Revision 1.3 1994/08/31 23:48:45 rj * more portable .h file inclusion. * * Revision 1.2 1994/08/31 08:59:39 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include #ifdef WIN32 #include "windows.h" #include "float.h" #endif #include "asn-incl.h" #include "sbuf.h" int TestAsnBuffers(); int TestAsnTag(); int TestAsnLen(); int TestAsnBool(); int TestAsnInt(); int TestAsnReal(); int TestAsnOcts(); int TestAsnBits(); int TestAsnOid(); int TestAsnList(); int bufSize = 256; int main() { int isErr = FALSE; /* set up the PLUS and MINUS INFINITY globals */ InitAsnInfinity(); /* needed for OCTET STRING, BIT STRING and OBJECT IDENTIFIER decoding */ InitNibbleMem (256, 256); if (!TestAsnBuffers()) { fprintf (stdout, "Failed buffer tests, no point in proceeding ... bye!\n"); return 1; } if (!TestAsnTag()) { fprintf (stdout, "Failed Tag test.\n" ); isErr = TRUE; } if (!TestAsnLen()) { fprintf (stdout, "Failed Length test.\n" ); isErr = TRUE; } if (!TestAsnBool()) { fprintf (stdout, "Failed BOOLEAN test.\n" ); isErr = TRUE; } if (!TestAsnInt()) { fprintf (stdout, "Failed INTEGER test.\n" ); isErr = TRUE; } if (!TestAsnOcts()) { fprintf (stdout, "Failed OCTET STRING test.\n" ); isErr = TRUE; } if (!TestAsnBits()) { fprintf (stdout, "Failed BIT STRING test.\n" ); isErr = TRUE; } if (!TestAsnOid()) { fprintf (stdout, "Failed OBJECT IDENTIFIER test.\n" ); isErr = TRUE; } if (!TestAsnReal()) { fprintf (stdout, "Failed REAL test.\n" ); isErr = TRUE; } if (isErr) { fprintf (stdout, "There are errors in the primitive type encoding/decoding\n" ); fprintf (stdout, "library for this architecture. Time for gdb...\n" ); } else { fprintf (stdout, "The primitive type encoding/decoding library passed simple tests.\n"); fprintf (stdout, "It should be safe to use...\n" ); } return isErr; } /* * returns TRUE if passes encode/decode tests */ int TestAsnBuffers() { int i,j; int noErr = TRUE; SBuf b; GenBuf *gb; char bufData[256]; /* initialize buffer */ SBufInit (&b, bufData, 256); SBufResetInWriteRvsMode (&b); SBuftoGenBuf (&b, &gb); /* * write whole range of byte (0..255) * remember, write works in reverse */ for (i = 0; i < 256; i++) BufPutByteRvs (gb,i); if (BufWriteError (gb)) { fprintf (stdout, "Error writing to buffer.\n" ); noErr = FALSE; } /* read in values & verify */ BufResetInReadMode (gb); for (i = 255; i >= 0; i--) if (BufGetByte (gb) != i) { fprintf (stdout, "Error verifying data written to buffer.\n" ); noErr = FALSE; } if (BufReadError (gb)) { fprintf (stdout, "Error reading from buffer.\n" ); noErr = FALSE; } /* now make sure errors are detected */ SBufResetInWriteRvsMode (gb->spare); for (i = 0; i < 257; i++) /* write past end of buffer */ BufPutByteRvs (gb,0); if (!BufWriteError (gb)) { fprintf (stdout, "Buffers failed to report buffer write overflow.\n" ); noErr = FALSE; } BufResetInReadMode (gb); for (i = 256; i >= 0; i--) /* read past end of buffer */ BufGetByte (gb); if (!BufReadError (gb)) { fprintf (stdout, "Buffers failed to report buffer read overflow.\n" ); noErr = FALSE; } return noErr; } /* TestAsnBuffers */ /* * returns TRUE if passes encode/decode tests */ int TestAsnTag() { AsnTag aTag1; AsnTag aTag2; int i, j; AsnLen len1; AsnLen len2; AsnTag tag; int noErr = TRUE; ENV_TYPE env; SBuf b; GenBuf *gb; char bufData[256]; long int val; BER_CLASS class; BER_FORM form; BER_UNIV_CODE code; /* initialize buffer */ SBufInit (&b, bufData, 256); SBuftoGenBuf (&b, &gb); /* encode a true value and verify */ class = UNIV; form = PRIM; code = INTEGER_TAG_CODE; aTag1 = MAKE_TAG_ID (class, form, code); for (i = 0; i < 2; i++) { SBufResetInWriteRvsMode (gb->spare); len1 = BEncTag1 (gb, class, form, code); if (BufWriteError (gb)) { noErr = FALSE; fprintf (stdout, "Error encoding a Tag.\n" ); } BufResetInReadMode (gb); aTag2 = 0; /* make sure no decode errors and that it decodes to same tag */ len2 = 0; if ((val = setjmp (env)) == 0) { aTag2 = BDecTag (gb, &len2, env); } else { noErr = FALSE; fprintf (stdout, "Error decoding a Tag - error number %d\n", val); } if (noErr && ((aTag2 != aTag1) || (len1 != len2))) { noErr = FALSE; fprintf (stdout, "Error decoded Tag does not match encoded Tag.\n" ); } /* set a new test tag value */ class = CNTX; form = CONS; code = 29; aTag1 = MAKE_TAG_ID (class, form, code); } return noErr; } /* TestAsnTag */ /* * returns TRUE if passes encode/decode tests */ int TestAsnLen() { AsnLen aLen1; AsnLen aLen2; int i,j; AsnLen len1; AsnLen len2; AsnTag tag; int noErr = TRUE; ENV_TYPE env; SBuf b; GenBuf *gb; char bufData[256]; long int val; /* initialize buffer */ SBufInit (&b, bufData, 256); SBuftoGenBuf (&b, &gb); /* encode a true value and verify */ aLen1 = 99999; for (i = 0; i < 2; i++) { SBufResetInWriteRvsMode (gb->spare); len1 = BEncDefLen (gb, aLen1); if (BufWriteError (gb)) { noErr = FALSE; fprintf (stdout, "Error encoding Length.\n" ); } BufResetInReadMode (gb); aLen2 = 0; /* make sure no decode errors and that it decodes to true */ len2 = 0; if ((val = setjmp (env)) == 0) { aLen2 = BDecLen (gb, &len2, env); } else { noErr = FALSE; fprintf (stdout, "Error decoding Length - error number %d\n", val); } if (noErr && ((aLen2 != aLen1) || (len1 != len2))) { noErr = FALSE; fprintf (stdout, "Error - decoded lenght does not match encoded length\n"); } aLen1 = 2; } /* test indef len */ SBufResetInWriteRvsMode (gb->spare); len1 = BEncIndefLen (gb); if (BufWriteError (gb)) { noErr = FALSE; fprintf (stdout, "Error encoding indefinite Length.\n" ); } BufResetInReadMode (gb); aLen2 = 0; /* make sure no decode errors */ len2 = 0; if ((val = setjmp (env)) == 0) { aLen2 = BDecLen (gb, &len2, env); } else { noErr = FALSE; fprintf (stdout, "Error decoding Length - error number %d\n", val); } if (noErr && ((aLen2 != INDEFINITE_LEN) || (len1 != len2))) { noErr = FALSE; fprintf (stdout, "Error - decoded length does not match encoded length\n"); } /* test EOC */ SBufResetInWriteRvsMode (gb->spare); len1 = BEncEoc (gb); if (BufWriteError (gb)) { noErr = FALSE; fprintf (stdout, "Error encoding indefinite Length.\n" ); } BufResetInReadMode (gb); aLen2 = 0; /* make sure no decode errors */ len2 = 0; if ((val = setjmp (env)) == 0) { BDecEoc (gb, &len2, env); } else { noErr = FALSE; fprintf (stdout, "Error decoding Length - error number %d\n", val); } if (noErr && (len1 != len2)) { noErr = FALSE; fprintf (stdout, "Error - decoded EOC length error.\n"); } return noErr; } /* TestAsnLen */ /* * returns TRUE if passes encode/decode tests */ int TestAsnBool() { AsnBool aBool1; AsnBool aBool2; int j; AsnLen len1; AsnLen len2; AsnTag tag; int noErr = TRUE; ENV_TYPE env; SBuf b; GenBuf *gb; char bufData[256]; long int val; /* initialize buffer */ SBufInit (&b, bufData, 256); SBufResetInWriteRvsMode (&b); SBuftoGenBuf(&b, &gb); /* encode a true value and verify */ aBool1 = TRUE; len1 = BEncAsnBoolContent (gb, &aBool1); if (BufWriteError (gb)) { noErr = FALSE; fprintf (stdout, "Error encoding TRUE BOOLEAN value.\n" ); } BufResetInReadMode (gb); aBool2 = FALSE; /* set to opposite of expected value */ /* make sure no decode errors and that it decodes to true */ len2 = 0; if ((val = setjmp (env)) == 0) { BDecAsnBoolContent (gb, tag, len1, &aBool2, &len2, env); } else { noErr = FALSE; fprintf (stdout, "Error decoding a BOOLEAN - error number %d\n", val); } if (noErr && ((aBool2 != aBool1) || (len1 != len2))) { noErr = FALSE; fprintf (stdout, "Error decoding TRUE BOOLEAN value.\n" ); } /* now encode a false value and verify */ SBufResetInWriteRvsMode (gb->spare); aBool1 = FALSE; len1 = BEncAsnBoolContent (gb, &aBool1); if (BufWriteError (gb)) { noErr = FALSE; fprintf (stdout, "Error encoding FALSE BOOLEAN value.\n" ); } BufResetInReadMode (gb); aBool2 = TRUE; /* set to opposite of expected value */ /* make sure no decode errors and that it decodes to true */ len2 = 0; if ((val = setjmp (env)) == 0) { BDecAsnBoolContent (gb, tag, len1, &aBool2, &len2, env); } else { noErr = FALSE; fprintf (stdout, "Error decoding a BOOLEAN - error number %d\n", val); } if (noErr && ((aBool2 != aBool1) || (len1 != len2))) { noErr = FALSE; fprintf (stdout, "Error decoding TRUE BOOLEAN value.\n" ); } /* make sure no decode errors and that it decodes to false */ return noErr; } /* TestAsnBool */ /* * returns TRUE if passes encode/decode tests */ int TestAsnInt() { AsnInt a1; AsnInt a2; int i,j; AsnLen len1; AsnLen len2; AsnTag tag; int noErr = TRUE; ENV_TYPE env; SBuf b; GenBuf *gb; char bufData[256]; long int val; int sign; /* initialize buffer */ SBufInit (&b, bufData, 256); SBuftoGenBuf (&b, &gb); /* * Encode a range of integers: negative & positive in * the 1 to sizeof (AsnInt) range */ sign = 1; for (j = 0; j < 2; j++) { for (i = 0; i < sizeof (AsnInt); i++) { SBufResetInWriteRvsMode (gb->spare); a1 = sign * (17 << (i * 8)); /* 17 is a random choice :) */ len1 = BEncAsnIntContent (gb, &a1); if (BufWriteError (gb)) { noErr = FALSE; fprintf (stdout, "Error encoding INTEGER value %d.\n", a1 ); } BufResetInReadMode (gb); /* make sure no decode errors and that it decodes to true */ len2 = 0; if ((val = setjmp (env)) == 0) { BDecAsnIntContent (gb, tag, len1, &a2, &len2, env); } else { noErr = FALSE; fprintf (stdout, "Error decoding a INTEGER - error number %d\n", val); } if (noErr && ((a2 != a1) || (len1 != len2))) { noErr = FALSE; fprintf (stdout, "Error decoding INTEGER value %d.\n", a1 ); } } sign = -1; } return noErr; } /* TestAsnInt */ /* * returns TRUE if passes encode/decode tests */ int TestAsnOcts() { AsnOcts a1; AsnOcts a2; int i,j; AsnLen len1; AsnLen len2; AsnTag tag; int noErr = TRUE; ENV_TYPE env; SBuf b; GenBuf *gb; char bufData[256]; long int val; /* initialize buffer */ SBufInit (&b, bufData, 256); SBuftoGenBuf (&b, &gb); a1.octs = "Hello Gumby"; a1.octetLen = strlen (a1.octs); /* * octet string decoder needs to know tag form * (snacc always encodes octet strings as primitives) */ tag = MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE); for (j = 0; j < 2; j++) { SBufResetInWriteRvsMode (gb->spare); len1 = BEncAsnOctsContent (gb, &a1); if (BufWriteError (gb)) { noErr = FALSE; fprintf (stdout, "Error encoding OCTET STRING value \"%s\".\n", a1.octs ); } BufResetInReadMode (gb); /* make sure no decode errors and that it decodes to true */ len2 = 0; if ((val = setjmp (env)) == 0) { BDecAsnOctsContent (gb, tag, len1, &a2, &len2, env); } else { noErr = FALSE; fprintf (stdout, "Error decoding an OCTET STRING - error number %d\n", val); } if (noErr && (!AsnOctsEquiv (&a2,&a1) || (len1 != len2))) { noErr = FALSE; fprintf (stdout, "Error decoding OCTET STRING value %s.\n", a1.octs ); } a1.octs = ""; /* test empty string */ a1.octetLen = strlen (a1.octs); } ResetNibbleMem(); return noErr; } /* TestAsnOcts */ /* * returns TRUE if passes encode/decode tests */ int TestAsnBits() { AsnBits a1; AsnBits a2; int i,j; AsnLen len1; AsnLen len2; AsnTag tag; int noErr = TRUE; ENV_TYPE env; SBuf b; GenBuf *gb; char bufData[256]; long int val; short bitsToSet[35]; /* * init bitsToSet - old compilers don't support automatic init * of aggregate types. */ bitsToSet[0] = 0; bitsToSet[1] = 1; bitsToSet[2] = 0; bitsToSet[3] = 0; bitsToSet[4] = 1; bitsToSet[5] = 1; bitsToSet[6] = 0; bitsToSet[7] = 1; bitsToSet[8] = 0; bitsToSet[9] = 1; bitsToSet[10] = 0; bitsToSet[11] = 0; bitsToSet[12] = 1; bitsToSet[13] = 1; bitsToSet[14] = 0; bitsToSet[15] = 1; bitsToSet[16] = 0; bitsToSet[17] = 1; bitsToSet[18] = 0; bitsToSet[19] = 0; bitsToSet[20] = 1; bitsToSet[21] = 1; bitsToSet[22] = 0; bitsToSet[23] = 1; bitsToSet[24] = 0; bitsToSet[25] = 1; bitsToSet[26] = 0; bitsToSet[27] = 1; bitsToSet[28] = 1; bitsToSet[29] = 0; bitsToSet[30] = 1; bitsToSet[31] = 1; bitsToSet[32] = 0; bitsToSet[33] = 1; bitsToSet[34] = 0; /* initialize buffer */ SBufInit (&b, bufData, 256); SBuftoGenBuf (&b, &gb); /* initialize bit string */ a1.bits = Asn1Alloc (5); a1.bitLen = 35; for (i = 0; i < 35; i++) { if (bitsToSet[i]) SetAsnBit (&a1, i); else ClrAsnBit (&a1, i); } /* * bit string decoder needs to know tag form * (snacc always encodes bit strings as primitives) */ tag = MAKE_TAG_ID (UNIV, PRIM, BITSTRING_TAG_CODE); SBufResetInWriteRvsMode (gb->spare); len1 = BEncAsnBitsContent (gb, &a1); if (BufWriteError (gb)) { noErr = FALSE; fprintf (stdout, "Error encoding BIT STRING value "); PrintAsnBits (stdout, &a1, 0); fprintf (stdout, "\n"); } BufResetInReadMode (gb); /* make sure no decode errors and that it decodes to true */ len2 = 0; if ((val = setjmp (env)) == 0) { BDecAsnBitsContent (gb, tag, len1, &a2, &len2, env); } else { noErr = FALSE; fprintf (stdout, "Error decoding an BIT STRING - error number %d\n", val); } if (noErr && (!AsnBitsEquiv (&a2,&a1) || (len1 != len2))) { noErr = FALSE; fprintf (stdout, "Error decoding BIT STRING value "); PrintAsnBits (stdout, &a1, 0); fprintf (stdout, "\n"); } ResetNibbleMem(); return noErr; } /* TestAsnBits */ /* * returns TRUE if passes encode/decode tests */ int TestAsnOid() { AsnOid a1; AsnOid a2; int i,j; AsnLen len1; AsnLen len2; AsnTag tag; int noErr = TRUE; ENV_TYPE env; SBuf b; GenBuf *gb; char bufData[256]; long int val; /* initialize buffer */ SBufInit (&b, bufData, 256); SBuftoGenBuf (&b, &gb); /* mib-2 oid { iso 3 6 1 2 1 }*/ a1.octetLen = 5; a1.octs = "\53\6\1\2\1"; for (j = 0; j < 2; j++) { SBufResetInWriteRvsMode (&b); len1 = BEncAsnOidContent (gb, &a1); if (BufWriteError (gb)) { noErr = FALSE; fprintf (stdout, "Error encoding OCTET STRING value \"%s\".\n", a1.octs ); } BufResetInReadMode (gb); /* make sure no decode errors and that it decodes to true */ len2 = 0; if ((val = setjmp (env)) == 0) { BDecAsnOidContent (gb, tag, len1, &a2, &len2, env); } else { noErr = FALSE; fprintf (stdout, "Error decoding an OCTET STRING - error number %d\n", val); } if (noErr && (!AsnOidsEquiv (&a2,&a1) || (len1 != len2))) { noErr = FALSE; fprintf (stdout, "Error decoding OCTET STRING value %s.\n", a1.octs ); } /* system { mib-2 1 }*/ a1.octs = "\53\6\1\2\1\1"; a1.octetLen = 6; } ResetNibbleMem(); return noErr; } /* TestAsnOid */ /* * returns TRUE if passes encode/decode tests */ int TestAsnReal() { AsnReal a1[5]; AsnReal a2; int i,j; AsnLen len1; AsnLen len2; AsnTag tag; int noErr = TRUE; int elmtErr = FALSE; ENV_TYPE env; SBuf b; GenBuf *gb; char bufData[256]; long int val; int sign; AsnReal inf; unsigned char *c; /* * if you do not have the ieee_functions in your math lib, * this will not link. Comment it out and cross you fingers. * (or check/set the +/-infinity values for you architecture) */ #if HAVE_ISINFx if (!isinf (PLUS_INFINITY) || !isinf (MINUS_INFINITY)) #else #if HAVE_FINITEx if (finite (PLUS_INFINITY) || finite (MINUS_INFINITY)) #else #define YUCK //warning "oops: you've got neither isinf(3) nor finite(3)?!" #endif #endif { // fprintf (stdout, "WARNING: PLUS_INFINITY and MINUS_INFINITY in asn_real.c are not\n"); // fprintf (stdout, "correct for this architecture. Modify the InitAsnInfinity() Routine.\n"); } /* * init test value array. * some old compilers don't support automatic init of aggregate types * like: * AsnReal a1[] = { 0.0, 0.8, -22.484848, PLUS_INFINITY, MINUS_INFINITY}; */ a1[0] = 0.0; a1[1] = 0.8; a1[2] = -22.484848; a1[3] = PLUS_INFINITY; a1[4] = MINUS_INFINITY; /* initialize buffer */ SBufInit (&b, bufData, 256); SBuftoGenBuf (&b, &gb); /* * Encode a range of integers: negative & positive in * the 1 to sizeof (AsnInt) range */ for (i = 0; i < 5; i++) { elmtErr = FALSE; SBufResetInWriteRvsMode (gb->spare); len1 = BEncAsnRealContent (gb, &a1[i]); if (BufWriteError (gb)) { elmtErr = TRUE; fprintf (stdout, "Error encoding REAL value "); PrintAsnReal (stdout,&a1[i],0); fprintf (stdout, ".\n"); } BufResetInReadMode (gb); /* make sure no decode errors and that it decodes to true */ len2 = 0; if ((val = setjmp (env)) == 0) { BDecAsnRealContent (gb, tag, len1, &a2, &len2, env); } else { elmtErr = TRUE; fprintf (stdout, "Error decoding a REAL - error number %d\n", val); } /* testing reals for equality is sketchy */ if (!elmtErr && ((a2 != a1[i]) || (len1 != len2))) { elmtErr = TRUE; fprintf (stdout, "Error decoding REAL value "); PrintAsnReal (stdout, &a1[i], 0); fprintf (stdout, ".\n"); if (len1 == len2) /* therefore a2 != a1[i] */ { fprintf (stdout, "The value decoded was "); PrintAsnReal (stdout, &a2, 0); fprintf (stdout, ".\n"); } else fprintf (stdout, "The encoded and decoded length disagree.\n"); } if (elmtErr) noErr = FALSE; } return noErr; } /* TestAsnReal */ esnacc-ng-1.8.1/c-examples/vdatestC/000077500000000000000000000000001302010526100171605ustar00rootroot00000000000000esnacc-ng-1.8.1/c-examples/vdatestC/gfsi.c000066400000000000000000000066551302010526100202700ustar00rootroot00000000000000#include #include #include #if defined(WIN32) || defined(WIN16) #include #include #include #include #include #else #include #include #include #endif #include "gfsi.h" // GFSI_GetFirstFile: // PURPOSE: Returns first file in a path // char *GFSI_GetFirstFile(GFSI_HANDLE *gfsi_handle, char *path, char *extension) { char *fn = NULL; #ifdef WIN32 char real_path[256]; WIN32_FIND_DATA findData; *gfsi_handle = NULL; if (extension == NULL) sprintf(real_path,"%s\\*.*",path); else sprintf(real_path,"%s\\*.%s", path, extension); do { if (fn == NULL) *gfsi_handle = (GFSI_HANDLE) FindFirstFile(real_path, &findData); else FindNextFile((HANDLE) *gfsi_handle, &findData); if (*gfsi_handle != NULL && (int) *gfsi_handle != -1) fn = strdup(findData.cFileName); } while ((gfsi_handle != INVALID_HANDLE_VALUE) && (findData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)); #else struct dirent *dirEntry = NULL; *gfsi_handle = NULL; *gfsi_handle = (GFSI_HANDLE) opendir(path); if (*gfsi_handle != NULL) { if (extension != NULL) { while ((dirEntry = readdir( (DIR *) *gfsi_handle)) != NULL) { fn = strstr(dirEntry->d_name, extension); if (fn != NULL) { fn = strdup(dirEntry->d_name); break; } } } else { while ((dirEntry = readdir( (DIR *) *gfsi_handle)) != NULL) { fn = dirEntry->d_name; if ((fn != NULL) && (strcmp(fn,".") != 0) && (strcmp(fn, "..") != 0)) { fn = strdup(dirEntry->d_name); break; } } } } #endif return fn; } // END OF FUNCTION GFSI_GetFirstFile // GFSI_GetNextFile: // PURPOSE: Returns next file in a path // char *GFSI_GetNextFile( GFSI_HANDLE *gfsi_handle, char *extension) { char *fn = NULL; #ifdef WIN32 WIN32_FIND_DATA findData; int bDone = 0; // NOTE: We ignore the extension paramater for the WIN32 Case do { if (FindNextFile((HANDLE) *gfsi_handle, &findData)) { if (findData.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY) fn = strdup(findData.cFileName); } else { bDone = 1; } } while (!bDone && (fn == NULL)); #else struct dirent *dirEntry = NULL; if (extension != NULL) { while ((dirEntry = readdir( (DIR *) *gfsi_handle)) != NULL) { fn = strstr(dirEntry->d_name, extension); if (fn != NULL) { fn = strdup(dirEntry->d_name); break; } } } else { if ((dirEntry = readdir( (DIR *) *gfsi_handle)) != NULL) { fn = strdup(dirEntry->d_name); } } #endif return fn; } // END OF FUNCTION GFSI_GetNextFile // GFSI_Close: // void GFSI_Close( GFSI_HANDLE *gfsi_handle ) { #ifdef WIN32 FindClose((HANDLE) *gfsi_handle); #else if (*gfsi_handle != NULL) { closedir((DIR *) *gfsi_handle); } #endif } // END OF FUNCTION GFSI_Close long findFileSize(char *fileName) { struct stat buf; int result; /* Get data associated with "stat.c": */ result = stat(fileName, &buf); /* Check if statistics are valid: */ if (result != 0) return 0; else return(buf.st_size); } // EOF acl_FileFuncs.cpp esnacc-ng-1.8.1/c-examples/vdatestC/gfsi.h000066400000000000000000000005671302010526100202710ustar00rootroot00000000000000#ifdef WIN32 #pragma warning(disable: 4305 4309 4101) #endif typedef void * GFSI_HANDLE; /* Generic File System Interface (GFSI) */ char * GFSI_GetFirstFile(GFSI_HANDLE *gfsi_handle, char *path, char *extension); char * GFSI_GetNextFile(GFSI_HANDLE *gfsi_handle, char *extension); void GFSI_Close(GFSI_HANDLE *gfsi_handle); esnacc-ng-1.8.1/c-examples/vdatestC/rfc1155-smi.asn1000066400000000000000000000122401302010526100216170ustar00rootroot00000000000000-- file: asn1specs/1155_smi.asn1 -- -- this file is used in ../c{,++}-examples/snmp/ -- -- $Header: /baseline/SNACC/c-examples/vdatestC/rfc1155-smi.asn1,v 1.2 2003/12/17 19:05:03 gronej Exp $ -- $Log: rfc1155-smi.asn1,v $ -- Revision 1.2 2003/12/17 19:05:03 gronej -- SNACC baseline merged with PER v1_7 tag -- -- Revision 1.1.2.1 2003/11/05 14:58:58 gronej -- working PER code merged with esnacc_1_6 -- -- Revision 1.1 2002/03/05 18:37:04 vracarl -- added a snmp_compliance_test -- -- Revision 1.2 2002/02/28 21:41:28 vracarl -- changed private to myprivate because it's a C++ keyword -- -- Revision 1.1.1.1 2000/08/21 20:36:15 leonberp -- First CVS Version of SNACC. -- -- Revision 1.3 1995/07/27 08:29:16 rj -- rfc1155-smi.asn1, rfc1157-snmp.asn1 and rfc1213-mib2.asn1 renamed from 1155-smi.asn1, 1157-snmp.asn1 and 1213-mib2.asn1 to accomodate to snacc's new file name generation scheme. -- -- Revision 1.2 1995/07/25 19:53:12 rj -- changed `_' to `-' in file names. -- -- Revision 1.1 1994/08/31 23:08:26 rj -- first check-in. -- RFC1155-SMI DEFINITIONS ::= BEGIN EXPORTS -- EVERYTHING internet, directory, mgmt, experimental, myprivate, enterprises, OBJECT-TYPE, ObjectName, ObjectSyntax, SimpleSyntax, ApplicationSyntax, NetworkAddress, IpAddress, Counter, Gauge, TimeTicks, Opaque; -- the path to the root internet OBJECT IDENTIFIER ::= { iso org(3) dod(6) 1 } directory OBJECT IDENTIFIER ::= { internet 1 } mgmt OBJECT IDENTIFIER ::= { internet 2 } experimental OBJECT IDENTIFIER ::= { internet 3 } -- Commented out because private is a C++ keyword LTV -- private OBJECT IDENTIFIER ::= { internet 4 } myprivate OBJECT IDENTIFIER ::= { internet 4 } enterprises OBJECT IDENTIFIER ::= { myprivate 1 } -- definition of object types OBJECT-TYPE MACRO ::= BEGIN TYPE NOTATION ::= "SYNTAX" type (TYPE ObjectSyntax) "ACCESS" Access "STATUS" Status VALUE NOTATION ::= value (VALUE ObjectName) Access ::= "read-only" | "read-write" | "write-only" | "not-accessible" Status ::= "mandatory" | "optional" | "obsolete" END -- names of objects in the MIB ObjectName ::= OBJECT IDENTIFIER -- syntax of objects in the MIB ObjectSyntax ::= CHOICE { simple SimpleSyntax, -- note that simple SEQUENCEs are not directly -- mentioned here to keep things simple (i.e., -- prevent mis-use). However, application-wide -- types which are IMPLICITly encoded simple -- SEQUENCEs may appear in the following CHOICE application-wide ApplicationSyntax } SimpleSyntax ::= CHOICE { number INTEGER, string OCTET STRING, object OBJECT IDENTIFIER, empty NULL } ApplicationSyntax ::= CHOICE { address NetworkAddress, counter Counter, gauge Gauge, ticks TimeTicks, arbitrary Opaque -- other application-wide types, as they are -- defined, will be added here } -- application-wide types NetworkAddress ::= CHOICE { internet IpAddress } IpAddress ::= [APPLICATION 0] -- in network-byte order IMPLICIT OCTET STRING (SIZE (4)) Counter ::= [APPLICATION 1] IMPLICIT INTEGER (0..4294967295) Gauge ::= [APPLICATION 2] IMPLICIT INTEGER (0..4294967295) TimeTicks ::= [APPLICATION 3] IMPLICIT INTEGER (0..4294967295) Opaque ::= [APPLICATION 4] -- arbitrary ASN.1 value, IMPLICIT OCTET STRING -- "double-wrapped" END esnacc-ng-1.8.1/c-examples/vdatestC/rfc1157-snmp.asn1000066400000000000000000000117301302010526100220110ustar00rootroot00000000000000-- file: asn1specs/1157_snmp.asn1 -- -- this file is used in ../c{,++}-examples/snmp/ -- -- $Header: /baseline/SNACC/c-examples/vdatestC/rfc1157-snmp.asn1,v 1.2 2003/12/17 19:05:03 gronej Exp $ -- $Log: rfc1157-snmp.asn1,v $ -- Revision 1.2 2003/12/17 19:05:03 gronej -- SNACC baseline merged with PER v1_7 tag -- -- Revision 1.1.2.1 2003/11/05 14:58:58 gronej -- working PER code merged with esnacc_1_6 -- -- Revision 1.1 2002/03/05 18:37:05 vracarl -- added a snmp_compliance_test -- -- Revision 1.1.1.1 2000/08/21 20:36:15 leonberp -- First CVS Version of SNACC. -- -- Revision 1.3 1995/07/27 08:29:17 rj -- rfc1155-smi.asn1, rfc1157-snmp.asn1 and rfc1213-mib2.asn1 renamed from 1155-smi.asn1, 1157-snmp.asn1 and 1213-mib2.asn1 to accomodate to snacc's new file name generation scheme. -- -- Revision 1.2 1995/07/25 19:53:13 rj -- changed `_' to `-' in file names. -- -- Revision 1.1 1994/08/31 23:08:27 rj -- first check-in. -- RFC1157-SNMP DEFINITIONS ::= BEGIN IMPORTS ObjectName, ObjectSyntax, NetworkAddress, IpAddress, TimeTicks FROM RFC1155-SMI; -- top-level message Message ::= --snacc isPdu:"TRUE" -- SEQUENCE { version -- version-1 for this RFC INTEGER { version-1(0) }, community -- community name OCTET STRING, data -- e.g., PDUs if trivial PDUs -- authentication is being used } -- protocol data units PDUs ::= CHOICE { get-request GetRequest-PDU, get-next-request GetNextRequest-PDU, get-response GetResponse-PDU, set-request SetRequest-PDU, trap Trap-PDU } -- PDUs GetRequest-PDU ::= [0] IMPLICIT PDU GetNextRequest-PDU ::= [1] IMPLICIT PDU GetResponse-PDU ::= [2] IMPLICIT PDU SetRequest-PDU ::= [3] IMPLICIT PDU PDU ::= SEQUENCE { request-id INTEGER, error-status -- sometimes ignored INTEGER { noError(0), tooBig(1), noSuchName(2), badValue(3), readOnly(4), genErr(5) }, error-index -- sometimes ignored INTEGER, variable-bindings -- values are sometimes ignored VarBindList } Trap-PDU ::= [4] IMPLICIT SEQUENCE { enterprise -- type of object generating -- trap, see sysObjectID in [5] OBJECT IDENTIFIER, agent-addr -- address of object generating NetworkAddress, -- trap generic-trap -- generic trap type INTEGER { coldStart(0), warmStart(1), linkDown(2), linkUp(3), authenticationFailure(4), egpNeighborLoss(5), enterpriseSpecific(6) }, specific-trap -- specific code, present even INTEGER, -- if generic-trap is not -- enterpriseSpecific time-stamp -- time elapsed between the last TimeTicks, -- (re)initialization of the -- network -- entity and the generation of the -- trap variable-bindings -- "interesting" information VarBindList } -- variable bindings VarBind ::= SEQUENCE { name ObjectName, value ObjectSyntax } VarBindList ::= SEQUENCE OF VarBind END esnacc-ng-1.8.1/c-examples/vdatestC/snmp.c000066400000000000000000000061551302010526100203100ustar00rootroot00000000000000#include #include #include "asn-incl.h" #include "gen-buf.h" #include "exp-buf.h" #include "rfc1155-smi.h" #include "rfc1157-snmp.h" #include "gfsi.h" #ifdef WIN32 #include #include #else #include #include #include #include #endif char* LoadFile (char *fileName, size_t *size); /* * FUNCTION: test_snmp_file() * * Attempt to decode the SNMP file and indicate success or failure to std::cout */ void test_snmp_file(char *pszfn) { Message a; int status = -1; AsnLen bytesDecoded = 0; ENV_TYPE env; size_t fsize; char *fileData; int val; GenBuf *pGenBuf = (GenBuf *) calloc(1, sizeof(GenBuf)); ExpBuf *pExpBuf = (ExpBuf *) calloc(1, sizeof(ExpBuf)); fileData = LoadFile (pszfn, &fsize); if (fileData == NULL) { printf("Failed to load file: %s\n", pszfn); return; } ExpBufInstallDataInBuf(pExpBuf, fileData, fsize); ExpBufResetInReadMode(&pExpBuf); PutExpBufInGenBuf(pExpBuf, pGenBuf); if ((val = setjmp (env)) == 0) DDecMessage(pGenBuf, &a, &bytesDecoded, env); else printf("test_snmp_file() failure %s\n", pszfn); } /************************************************************************ FUNCTION: run_snmp_tests() Description: This functions traverses through a directory containing SNMP V1 objects and uses test_snmp_test() to decode them. The SNMP objects distributed with eSNACC should all decode succesfully. ************************************************************************/ void run_snmp_tests(char *path) { char *fn = NULL; char fullPath[256]; GFSI_HANDLE gfsi_handle; printf("\n*** SNMP V1 TESTS ***\n\n"); fn = GFSI_GetFirstFile(&gfsi_handle, path, NULL); if (fn == NULL) { printf("ERROR: Bath path or directory is empty\n"); } while (fn != NULL) { sprintf(fullPath,"%s/%s",path,fn); test_snmp_file(fullPath); fn = GFSI_GetNextFile(&gfsi_handle, NULL); } GFSI_Close(&gfsi_handle); printf("\n*** END OF SNMP V1 TESTS ***\n"); } /* * opens given filename, determines its size, allocs a block * of that size and reads the file into it. returns a pointer * to this block. Prints an err msgs is something screwed up * and returns NULL. Sets the size param to the size of the file. */ char* LoadFile (char *fileName, size_t *size) { FILE *f; unsigned long int fsize; char *fileData; f = fopen (fileName, "rb"); if (f == NULL) { Asn1Error("Could not open file for reading.\n"); return NULL; } fseek (f, 0, 2); /* seek to end */ fsize = ftell (f); /* get size of file */ fseek (f, 0, 0); /* seek to beginning */ *size = fsize; fileData = (char *) malloc (fsize); if (fileData == NULL) { Asn1Error("Not enough memory to read in file.\n"); return NULL; } if (fread (fileData, sizeof (char), fsize, f) != fsize) { free (fileData); fileData = NULL; Asn1Error("Trouble reading file.\n"); } fclose (f); return fileData; } /* LoadFile */ esnacc-ng-1.8.1/c-examples/vdatestC/vdatestC.c000066400000000000000000001255431302010526100211130ustar00rootroot00000000000000/* vdatestC.c : Defines the entry point for the console application. */ #include #include #include #include #include #include #include #include #include #include "asn-incl.h" #include "exp-buf.h" #include "vdatestC_asn.h" #include "vdatest_asn2C.h" void run_snmp_tests(char *path); void test_AsnOid(); void ASN1init(); void ANY_test(); void ANY_DEFINED_BY_test(); void ANY_DEFINED_BY_test_2(); void InitAnyVdaTestModule2(); void test_timing(); #define TEST_ENCODE_BUF 1 #define TEST_DECODE_BUF 2 void outhex2(unsigned char *outChar, int Len); int utf8compare2(unsigned char *expected, wchar_t *actual, int Len); void InitAnyVdaTestModule(); void test_big_buffer(); /* fails - not supported */ void Test_ASN_1_Strings(); void test_bits(); int append_test(); extern unsigned short stdIndentG = 4; int main(int argc, char* argv[]) { ASN1init(); ANY_test(); if (argc > 1) { run_snmp_tests(argv[1]); exit(0); } InitAnyVdaTestModule(); InitAnyVdaTestModule2(); ANY_DEFINED_BY_test(); test_AsnOid(); ANY_DEFINED_BY_test_2(); test_timing(); test_big_buffer(); test_bits(); Test_ASN_1_Strings(); append_test(); return 0; } /* */ void test_AsnOid() { AsnOid tmpoid; OID *pResult = NULL; AsnOid *poid = (AsnOid *) calloc(1, sizeof(AsnOid)); long arrLength=19; unsigned long arcNumArr[]={1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}; OID *poida = (OID *)calloc(1, sizeof(OID)); OID *ptmpOid = poida; OID *ptmpOid2; int i; printf("test_AsnOid()\n"); for (i=0; i < arrLength; i++) { ptmpOid->arcNum = arcNumArr[i]; if (i < arrLength - 1) { ptmpOid->next = (OID *)calloc(1, sizeof(OID)); ptmpOid = ptmpOid->next; } } poid->octs = (char *)calloc(1,100); tmpoid.octs = (char *)calloc(1,100); BuildEncodedOid(poida, poid); UnbuildEncodedOid(poid, &pResult); BuildEncodedOid(pResult, &tmpoid); if (AsnOidsEquiv(&tmpoid, poid)) printf("AsnOids encode and decode SUCCESSFUL\n"); else printf("AsnOids encode and decode UNSUCCESSFUL\n"); ptmpOid = poida; ptmpOid2 = pResult; i=0; while (ptmpOid && ptmpOid2) { if (ptmpOid->arcNum != ptmpOid2->arcNum) { printf("AsnOid OID [%d] comparison failed\n",i); break; } ptmpOid = ptmpOid->next; ptmpOid2 = ptmpOid2->next; } if (ptmpOid || ptmpOid2) printf("AsnOid OID [%d] count difference\n",i); ptmpOid = poida; ptmpOid2 = pResult; while (ptmpOid && ptmpOid2) { OID *p1 = ptmpOid->next; OID *p2 = ptmpOid2->next; free(ptmpOid); ptmpOid = p1; free(ptmpOid2); ptmpOid2 = p2; } FreeAsnOid(poid); free(poid); free(tmpoid.octs); } void test_bits() { AsnBits A, C, A2; struct ExpBuf *pB = NULL; struct GenBuf *gB; ENV_TYPE env; int val; unsigned int bytesDecoded=0; char data[10]={(char)0x00, (char)0x00, (char)0x00, (char)0xff, (char)0xff, (char)0xff, (char)0xff, (char)0xff, (char)0x00, (char)0x00}; char pchBuffer[1000]; printf("test_bits()\n"); pB = ExpBufAllocBufAndData(); ExpBufInstallDataInBuf(pB, &pchBuffer[0], 1000); ExpBuftoGenBuf (pB, &gB); ExpBufResetInWriteRvsMode(pB); A.bits = data; A.bitLen = 22; SetAsnBit(&(A), 14); ExpBufResetInWriteRvsMode(pB); BEncAsnBits(gB, &A); ExpBufResetInReadMode(&pB); if ((val = setjmp (env)) == 0) BDecAsnBits(gB, &C, &bytesDecoded, env); else printf("BDecAsnBits failed!\n"); if (C.bitLen == 14+1) printf("test_bits: Successful 0's removed!!!\n"); else printf("test_bits: ####ERROR, UNSuccessful 0's removed!!!####\n"); A.bits = data; A.bitLen = 22; ExpBufResetInWriteRvsMode(gB->spare); BEncAsnBits(gB, &A); ExpBufResetInReadMode(gB->bufInfo); if ((val = setjmp (env)) == 0) BDecAsnBits(gB, &C, &bytesDecoded, env); else printf("BDecAsnBits failed!\n"); if (C.bitLen == 22 && GetAsnBit(&C, 0) == FALSE) /* False if bit is 0 */ printf("test_bits: Successful ALL 0 BITS(No NamedBitListRules)!!!\n"); else printf("test_bits: ####ERROR, UNSuccessful ALL 0 BITS(No NamedBitListRules)!!!####\n"); A.bits = data; A.bitLen = 22; ExpBufResetInWriteRvsMode(gB->spare); BEncAsnBits(gB, &A); ExpBufResetInReadMode(gB->bufInfo); if ((val = setjmp (env)) == 0) BDecAsnBits(gB, &C, &bytesDecoded, env); else printf("BDecAsnBits failed!\n"); if (C.bitLen == 0) printf("test_bits: Successful ALL 0 BITS(NamedBitListRules)!!!\n"); else printf("test_bits: ####ERROR, UNSuccessful ALL 0 BITS(NamedBitListRules)!!!####\n"); A.bits = data; A.bitLen = 24; SetAsnBit(&(A), 15); ExpBufResetInWriteRvsMode(gB->spare); BEncAsnBits(gB, &A); ExpBufResetInReadMode(gB->bufInfo); if ((val = setjmp (env)) == 0) BDecAsnBits(gB, &C, &bytesDecoded, env); else printf("BDecAsnBits failed!\n"); if (C.bitLen == 15+1) printf("test_bits: Successful 0's removed2!!!\n"); else printf("test_bits: ####ERROR, UNSuccessful 0's removed2!!!####\n"); A2.bits = data; A2.bitLen = 80; SetAsnBit(&(A2), 79); ExpBufResetInWriteRvsMode(gB->spare); BEncAsnBits(gB, &A2); ExpBufResetInReadMode(gB->bufInfo); if ((val = setjmp (env)) == 0) BDecAsnBits(gB, &C, &bytesDecoded, env); else printf("BDecAsnBits failed!\n"); if (C.bitLen == 79+1) printf("test_bits: Successful top 1 set!!!\n"); else printf("test_bits: ####ERROR, UNSuccessful top 1 set!!!####\n"); } void test_big_buffer() { char pchBuffer[200000]; struct ExpBuf *pM = NULL; struct GenBuf GenBufpM; AsnOcts N; AsnLen bytesDecoded = 0; ENV_TYPE env; int val; printf("test_big_buffer()\n"); pM = (struct ExpBuf *) calloc(1, sizeof(struct ExpBuf)); memset(&N,'\0', sizeof(AsnOcts)); memset(pchBuffer, 'A', 200000); N.octs = pchBuffer; N.octetLen = 200000; /* ENCODE_BUF(&N, pM); */ ExpBufResetInWriteRvsMode(pM); PutExpBufInGenBuf(pM, &GenBufpM); BEncAsnOcts(&GenBufpM, &N); printf("test_big_buffer: Octet String encoded length of 200000 byte buf= %d \n", ExpBufDataSize(GenBufpM.spare)); /* DECODE_BUF_NOFAIL(&N, pM, status); */ if ((val = setjmp (env)) == 0) BDecAsnOcts(&GenBufpM, &N, &bytesDecoded, env); else printf("BDecAsnOcts failed. Expected - C Snacc doesn't support big buffers.\n"); ExpBufFreeData(GenBufpM.spare); free(pM); } /* */ void ANY_DEFINED_BY_test() { AsnOid testOid3; struct ExpBuf *pBUF; struct GenBuf *gBUF; TestDefinedByUsage A, A2, A3; PrintableString *pB; PrintableString *pPS; AsnLen bytesDecoded = 0; ENV_TYPE env; int val; int result = 0; char *octs1 = ("1.2.3.4.5.5.5.5.6"); char *test = ("THIS IS A TEST"); printf("ANY_DEFINED_BY_test()\n"); testOid3.octs = octs1; testOid3.octetLen = strlen(octs1); pBUF = ExpBufAllocBufAndData(); ExpBuftoGenBuf(pBUF, &gBUF); pB = (PrintableString *) calloc(1, sizeof(PrintableString)); pB->octs = strdup(test); pB->octetLen = strlen(test); memset(&A,'\0', sizeof(A)); memset(&A2,'\0', sizeof(A2)); memset(&A3,'\0', sizeof(A3)); A.id = testOID2; A.anyDefBy.value = pB; A.i1 = 1; A.i2 = 2; A.i3 = 3; A.i4 = 4; /* ENCODE_BUF(&A, pBUF); */ ExpBufResetInWriteRvsMode(gBUF->spare); result = DEncTestDefinedByUsage(gBUF, &A); if (result == 0) printf("DEncTestDefinedByUsage FAILED!\n"); /* DECODE_BUF(&A2, pBUF); */ ExpBufResetInReadMode(gBUF->bufInfo); if ((val = setjmp (env)) == 0) DDecTestDefinedByUsage(gBUF, &A2, &bytesDecoded, env); else printf("DDecTestDefinedByUsage FAILED!\n"); ExpBufFreeBufAndData(pBUF); /* WE HAVE TO CHECK EXPLICITLY, but the decode is automatic. */ result = memcmp(A2.id.octs, testOID2.octs, A2.id.octetLen); if (result == 0) { pPS = (PrintableString *)A2.anyDefBy.value; /* WE MUST KNOW what the OID is associated with. */ printf("ANY_DEFINED_BY_test: Good id, == testOID2. %s\n", pPS->octs); } else { printf("ANY_DEFINED_BY_test: Bad id, <> testOID2.\n"); } FreePrintableString(pB); free(pB); } /* THIS Version tests the newly added ability of the SNACC compiler to handle multiple Object-Type definitions in separate .asn files. */ void ANY_DEFINED_BY_test_2() { AsnOid testOid3; TestDefinedByUsage_2 A, A2, A3; struct ExpBuf *pBUF; struct GenBuf *gBUF; PrintableString *pB; PrintableString *pPS; AsnLen bytesDecoded = 0; ENV_TYPE env; int val; char *octs1 = ("1.2.3.4.5.5.5.5.6"); char *test = ("THIS IS A TEST"); int result = 0; printf("ANY_DEFINED_BY_test_2()\n"); testOid3.octs = octs1; testOid3.octetLen = strlen(octs1); pBUF = ExpBufAllocBufAndData(); ExpBuftoGenBuf(pBUF, &gBUF); pB = (PrintableString *) calloc(1, sizeof(PrintableString)); pB->octs = strdup(test); pB->octetLen = strlen(test); memset(&A,'\0', sizeof(A)); memset(&A2,'\0', sizeof(A2)); memset(&A3,'\0', sizeof(A3)); A.id = testOID2_2; A.anyDefBy.value = pB; /* ENCODE_BUF(&A, pBUF); */ ExpBufResetInWriteRvsMode(gBUF->spare); // result = DEncTestDefinedByUsage_2(&pBUF, &A); result = DEncTestDefinedByUsage_2(gBUF, &A); if (result == 0) printf("DEncTestDefinedByUsage_2 FAILED!\n"); /* DECODE_BUF(&A2, pBUF); */ ExpBufResetInReadMode(gBUF->bufInfo); if ((val = setjmp (env)) == 0) DDecTestDefinedByUsage_2(gBUF, &A2, &bytesDecoded, env); else printf("DDecTestDefinedByUsage_2 FAILED!\n"); ExpBufFreeBufAndData(gBUF->spare); result = memcmp(A2.id.octs, testOID2_2.octs, A2.id.octetLen); if (result == 0) /* WE HAVE TO CHECK EXPLICITELY, but the decode is automatic. */ { pPS = (PrintableString *)A2.anyDefBy.value; /* WE MUST KNOW what the OID is associated with. */ printf("ANY_DEFINED_BY_test: Good id, == testOID2_2. %s\n", pPS->octs); } else { printf("ANY_DEFINED_BY_test: Bad id, <> testOID2_2.\n"); } FreePrintableString(pB); free(pB); } int append_test() { VDATestSet *ptestSet; VDATestSet *ptestSet2; VDATestSet *ptestSetBER; char testSeqBlobTbl[] = { 0x30, 0x06, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02 }; /* SET OF Integers, 04 tag, 01 length, 01 then 02 data. */ char testSetBlobTbl[] = { 0x31, 0x06, 0x04, 0x01, 0x01, 0x04, 0x01, 0x02 }; char testSetBlobTblVaryLengths[] = { 0x31, 54, 0x04, 0x01, 0x71, 0x04, 0x02, 0x72, 0x72, 0x04, 0x03, 0x72, 0x73, 0x74, 0x04, 0x03, 0x74, 0x72, 0x73, 0x04, 0x03, 0x74, 0x72, 0x79, 0x04, 0x03, 0x74, 0x72, 0x78, 0x04, 0x05, 0x74, 0x72, 0x73, 0x73, 0x73, 0x04, 0x03, 0x74, 0x72, 0x77, 0x04, 0x03, 0x74, 0x72, 0x76, 0x04, 0x03, 0x74, 0x72, 0x75, 0x04, 0x03, 0x74, 0x72, 0x74 }; /* THESE SHOULD all be ordered */ char testSetBlobBERTbl[] = { 0x31, 0x06, 0x04, 0x01, 0x02, 0x04, 0x01, 0x01 }; char testSetOfAnyBlobTbl[] = { 0x31, 0x08, 0x03, 0x02, 0x04, 0x0F, 0x03, 0x02, 0x05, 0x0E }; char testNullBitString[] = { 0x03, 0x01, 0x00 }; char testBit1BitString[] = { 0x03, 0x02, 0x02, 0x20}; /* 2 unused bits, data 0x20 (2nd bit set). */ AsnOid TestOid; int err = 1; struct ExpBuf testNullBitStringBlob; struct ExpBuf *ptestNullBitStringBlob2; struct GenBuf ptestNullBitStringBlob2GenBuf; struct ExpBuf *ptestSeqBlob; struct ExpBuf *ptestSeqBlob2; struct ExpBuf *ptestSetBlob; struct GenBuf *ptestSetBlobGenBuf; struct ExpBuf *ptestSetBlobBER; struct GenBuf *ptestSetBlobBERGenBuf; struct ExpBuf *ptestSetBlobVaryingLengths; struct GenBuf *GenBufptestSetBlobVaryingLengths; struct ExpBuf *ptestSetBlob2; struct GenBuf *ptestSetBlob2GenBuf; struct ExpBuf *ptestSetBlob4; struct GenBuf *ptestSetBlob4GenBuf; struct ExpBuf testSetOfAnyBlob; AsnBits snaccNullBitString; VDATestBitString snaccNullBitString3; SequenceOfDefaults AA; struct ExpBuf tmpBuf; struct ExpBuf *ptmpBlob; struct GenBuf ptmpBlobGenBuf; AsnBits snaccBitStr; FILE *fp; int result; int size1 = 0; int size2 = 0; AsnLen bytesDecoded = 0; ENV_TYPE env; int val; char *octs1 = ("1.2.3.4.5.0.0.0"); char *octs2 = ("1.2.3.4.5.6.8.8.8"); /*Test_ASN_1_Strings(); */ printf("append_test()\n"); /* the following tables are DER encoded results for VDATestSequence, VDATestSet, and VDATestSetOfAny. Decode these tables and then re-encode them to determine if we come up with the same results. note: this doesn't test every scenario. */ memset(&snaccNullBitString,'\0', sizeof(AsnBits)); memset(&snaccNullBitString3,'\0', sizeof(VDATestBitString)); memset(&testNullBitStringBlob,'\0', sizeof(struct ExpBuf)); memset(&AA,'\0', sizeof(SequenceOfDefaults)); ExpBufInstallDataInBuf(&testNullBitStringBlob, &testNullBitString[0], 3); ptestNullBitStringBlob2 = ExpBufAllocBufAndData(); ptmpBlob = ExpBufAllocBufAndData(); ptestSeqBlob2 = ExpBufAllocBufAndData(); ptestSeqBlob = ExpBufAllocBufAndData(); ptestSetBlob = ExpBufAllocBufAndData(); ptestSetBlob2 = ExpBufAllocBufAndData(); ptestSetBlob4 = ExpBufAllocBufAndData(); ptestSetBlobBER = ExpBufAllocBufAndData(); ptestSet = (VDATestSet *) calloc(1, sizeof(VDATestSet)); ptestSet2 = (VDATestSet *) calloc(1, sizeof(VDATestSet)); ptestSetBER = (VDATestSet *) calloc(1, sizeof(VDATestSet)); /* RWC;12/18/00; THIS SET of tests require that the Named Bit rules be applied. Named Bit rules are set only for declared ASN SNACC compiler processed Bit Strings, not for "AsnBits" declared vars as in "snaccNullBitString" above. THIS 1st test should not produce 030100. */ /* ENCODE_BUF_NO_ALLOC(&snaccNullBitString3, &testNullBitStringBlob2); */ AA.defBitstring.bits = (char *) calloc(1,2); AA.defBitstring.bitLen = 9; snaccNullBitString.bits = (char *) calloc(1,2); snaccNullBitString.bitLen = 9; free(snaccNullBitString.bits); snaccNullBitString.bits = NULL; snaccNullBitString3.bits = (char *) calloc(1,2); snaccNullBitString3.bitLen = 8; /* ENCODE_BUF_NO_ALLOC(AA.defBitstring , &testNullBitStringBlob2); */ ExpBufResetInWriteRvsMode(ptestNullBitStringBlob2); PutExpBufInGenBuf(ptestNullBitStringBlob2, &ptestNullBitStringBlob2GenBuf); DEncAsnBits(&ptestNullBitStringBlob2GenBuf, &AA.defBitstring); size1 = ExpBufDataSize(ptestNullBitStringBlob2GenBuf.spare); size2 = ExpBufDataSize(&testNullBitStringBlob); if (size1 != size2) printf("NULL BIT STRING 1 FAILED SIZE COMPARE!\n"); else { result = memcmp(ExpBufDataPtr(ptestNullBitStringBlob2), ExpBufDataPtr(&testNullBitStringBlob), size1); if (result == 0) { printf("NULL BIT STRING 1 TEST PASSED!\n"); } else { printf("NULL BIT STRING TEST 1 FAILED!\n"); printf("ENCODED VALUE IS:\n"); printf("\nIT SHOULD BE:\n"); printf("\n"); } } /* ENCODE_BUF_NO_ALLOC(&snaccNullBitString3, &testNullBitStringBlob2); */ ExpBufResetInWriteRvsMode(ptestNullBitStringBlob2); PutExpBufInGenBuf(ptestNullBitStringBlob2, &ptestNullBitStringBlob2GenBuf); DEncAsnBits(&ptestNullBitStringBlob2GenBuf, &snaccNullBitString3); free(snaccNullBitString3.bits); snaccNullBitString3.bits = NULL; size1 = ExpBufDataSize(ptestNullBitStringBlob2GenBuf.spare); size2 = ExpBufDataSize(&testNullBitStringBlob); if (size1 != size2) printf("NULL BIT STRING 2 FAILED SIZE COMPARE!\n"); else { result = memcmp(ExpBufDataPtr(ptestNullBitStringBlob2GenBuf.spare), ExpBufDataPtr(&testNullBitStringBlob), size1); if (result == 0) { printf("NULL BIT STRING 2 TEST PASSED!\n"); } else { printf("NULL BIT STRING TEST 2 FAILED!\n"); printf("ENCODED VALUE IS:\n"); printf("\nIT SHOULD NOT BE:\n"); printf("\n"); } } free(AA.defBitstring.bits); AA.defBitstring.bits = NULL; /* Now let's test a bits string that has more than one octet that is null. The resulting encoding should look like the testNullBitString above. */ memset(&AA,'\0', sizeof(SequenceOfDefaults)); AA.defBitstring.bits = (char *) calloc(1,3); AA.defBitstring.bitLen = 18; SetAsnBit(&(AA.defBitstring), 18); /* testNullBitStringBlob2.Clear(); */ ExpBufFreeBufAndData (ptestNullBitStringBlob2GenBuf.spare); ptestNullBitStringBlob2 = (struct ExpBuf *) calloc(1, sizeof(struct ExpBuf)); /* ENCODE_BUF_NO_ALLOC(AA.defBitstring, &testNullBitStringBlob2); */ ExpBufResetInWriteRvsMode(ptestNullBitStringBlob2); PutExpBufInGenBuf(ptestNullBitStringBlob2, &ptestNullBitStringBlob2GenBuf); DEncAsnBits(&ptestNullBitStringBlob2GenBuf, &AA.defBitstring); free(AA.defBitstring.bits); AA.defBitstring.bits = NULL; size1 = ExpBufDataSize(ptestNullBitStringBlob2GenBuf.spare); size2 = ExpBufDataSize(&testNullBitStringBlob); if (size1 != size2) printf("NULL BIT STRING 3 FAILED SIZE COMPARE!\n"); else { result = memcmp(ExpBufDataPtr(ptestNullBitStringBlob2GenBuf.spare), ExpBufDataPtr(&testNullBitStringBlob), size1); if (result == 0) { printf("Multiple null octets NULL BIT STRING test 3 passed!\n"); } else { printf("Multiple null octets NULL BIT STRING TEST 3 FAILED!\n"); printf("ENCODED VALUE IS:\n"); /* testNullBitStringBlob2.ReportHexBuffer(cout); */ printf("\nIT SHOULD BE:\n"); /* testNullBitStringBlob.ReportHexBuffer(cout); */ printf("\n"); } } free(ptestNullBitStringBlob2); ptestNullBitStringBlob2 = NULL; /* Test BIT STRING with only the first bit set. */ memset(&tmpBuf,'\0', sizeof(struct ExpBuf)); ExpBufInstallDataInBuf(&tmpBuf, testBit1BitString, 4); snaccBitStr.bits = (char *) calloc(1,1); snaccBitStr.bitLen = 6; SetAsnBit(&(snaccBitStr), 2); /* ENCODE_BUF_NO_ALLOC(&snaccBitStr, &tmpBlob); */ ExpBufResetInWriteRvsMode(ptmpBlob); PutExpBufInGenBuf(ptmpBlob, &ptmpBlobGenBuf); DEncAsnBits(&ptmpBlobGenBuf, &snaccBitStr); free(snaccBitStr.bits); snaccBitStr.bits = NULL; size1 = ExpBufDataSize(ptmpBlobGenBuf.spare); size2 = ExpBufDataSize(&tmpBuf); if (size1 != size2) printf("Bitstring with first bit set and uneven bit count FAILED SIZE COMPARE!\n"); else { result = memcmp(ExpBufDataPtr(ptmpBlobGenBuf.spare), ExpBufDataPtr(&tmpBuf), size1); if (result == 0) { printf("Bitstring with first bit set and uneven bit count PASSED!\n"); } else { printf("Bitstring with first bit set and uneven bit count FAILED!\n"); printf("BitString Encoded as:\n"); /* tmpBlob.ReportHexBuffer(cout); */ printf("It should be:\n"); /* tmpBuf.ReportHexBuffer(cout); */ printf("\n"); } } /* sequence of to integers */ ExpBufInstallDataInBuf(ptestSeqBlob, &testSeqBlobTbl[0], 8); /* sequence of two octet strings */ ExpBufInstallDataInBuf(ptestSetBlob, &testSetBlobTbl[0], 8); ExpBufInstallDataInBuf(ptestSetBlobBER, &testSetBlobBERTbl[0] , 8); ptestSetBlobVaryingLengths = ExpBufAllocBufAndData(); ExpBuftoGenBuf(ptestSetBlobVaryingLengths, &GenBufptestSetBlobVaryingLengths); ExpBufInstallDataInBuf(GenBufptestSetBlobVaryingLengths->spare, &testSetBlobTblVaryLengths[0], 56); /* sequence of two ANYs. In this case the any's are two BIT STRINGS */ ExpBufInstallDataInBuf(&testSetOfAnyBlob, &testSetOfAnyBlobTbl[0] , 10); /* Decode, Encode, and Compare Test Sequence */ /* BDecAsnBits(&ptestSeqBlob, testSeq.first, &bytesDecoded, env); ExpBufResetInWriteRvsMode(ptestSeqBlob2); DEncAsnBits(&ptestSeqBlob2, &testSeq); size1 = ExpBufDataSize(ptestSeqBlob2); size2 = ExpBufDataSize(ptestSeqBlob); if (size1 != size2) printf("Sequence test count FAILED SIZE COMPARE!\n"); else { result = memcmp(ExpBufDataPtr(ptestSeqBlob2), ExpBufDataPtr(ptestSeqBlob), size1); if (result == 0) printf("Passed Sequence test ...\n"); else printf("Failed Sequence test ...\n"); } */ /* Decode, Encode, and Compare Test Set */ /* DECODE_BUF( &testSet, &ptestSetBlob); */ ExpBuftoGenBuf(ptestSetBlob, &ptestSetBlobGenBuf); // PutExpBufInGenBuf(ptestSetBlob, &ptestSetBlobGenBuf); if ((val = setjmp (env)) == 0) DDecVDATestSet(ptestSetBlobGenBuf, ptestSet, &bytesDecoded, env); else return 0; /* ENCODE_BUF_NO_ALLOC( &testSet, &ptestSetBlob2); */ ExpBufResetInWriteRvsMode(ptestSetBlobGenBuf->spare); DEncVDATestSet(ptestSetBlobGenBuf, ptestSet); ExpBufInstallDataInBuf(ptestSetBlob2, ExpBufDataPtr(ptestSetBlobGenBuf->spare), ExpBufDataSize(ptestSetBlobGenBuf->spare)); ExpBufResetInReadMode(ptestSetBlobGenBuf->bufInfo); size1 = ExpBufDataSize(ptestSetBlobGenBuf->spare); size2 = ExpBufDataSize(ptestSetBlob); if (size1 != size2) printf("Set test count FAILED SIZE COMPARE!\n"); else { result = memcmp(ExpBufDataPtr(ptestSetBlobGenBuf->spare), testSetBlobTbl, size1); if (result == 0) printf("Passed SET test ... \n"); else printf("Failed SET test ... \n"); } /* This test should sort the various SET OF integers of varying lengths, REGARDLESS OF LENGTH (per X.690 specification section 11.6). */ FreeVDATestSet(ptestSet); free(ptestSet); ptestSet = (VDATestSet *) calloc(1, sizeof(VDATestSet)); /* DECODE_BUF( &testSet, &testSetBlobVaryingLengths); */ if ((val = setjmp (env)) == 0) DDecVDATestSet(ptestSetBlobGenBuf, ptestSet, &bytesDecoded, env); else return 0; /* ENCODE_BUF_NO_ALLOC( &testSet, &testSetBlob2); */ ExpBufResetInWriteRvsMode(ptestSetBlob2); ExpBuftoGenBuf(ptestSetBlob2, &ptestSetBlob2GenBuf); DEncVDATestSet(ptestSetBlob2GenBuf, ptestSet); free(ptestSet); ptestSet = NULL; bytesDecoded = 0; /* DECODE_BUF( &testSet2, &testSetBlob2); */ /* Had to move data into a new buffer because encoding left data pointers unusable for decoding. */ ExpBufInstallDataInBuf(ptestSetBlob4, ExpBufDataPtr(ptestSetBlob2GenBuf->spare), ExpBufDataSize(ptestSetBlob2GenBuf->spare)); ExpBufResetInReadMode(&ptestSetBlob4); ExpBuftoGenBuf (ptestSetBlob4, &ptestSetBlob4GenBuf); if ((val = setjmp (env)) == 0) { DDecVDATestSet(ptestSetBlob4GenBuf, ptestSet2, &bytesDecoded, env); } else return 0; fp=fopen("vdatest.txt", "w"); /* need a different print - testSet2 is an AsnList */ PrintVDATestSet(fp, ptestSet2, 1); /* PRINT results, should be in proper order. */ fclose(fp); free(ptestSet2); /* Decode, Encode, and Compare Test SET OF ANY */ /* RWC;10/07/00; */ /* DECODE_BUF( &testSetOfAny, &testSetOfAnyBlob); ENCODE_BUF_NO_ALLOC( &testSetOfAny, &testSetOfAnyBlob2); if (testSetOfAnyBlob2.Compare(testSetOfAnyBlob) == 0) cout << "Passed SET OF ANY test ...\n"; else cout << "Failed SET OF ANY test ...\n"; */ /* Decode BER, Encode DER, and Compare Encoded DER to known DER encoding. */ /*RWC;Causes crash on Linux;testSetBlob2.~CSM_Buffer(); */ /* DECODE_BUF( &testSetBER, &testSetBlobBER); */ bytesDecoded = 0; ExpBuftoGenBuf(ptestSetBlobBER, &ptestSetBlobBERGenBuf); if ((val = setjmp (env)) == 0) DDecVDATestSet(ptestSetBlobBERGenBuf, ptestSetBER, &bytesDecoded, env); else return 0; /* ENCODE_BUF_NO_ALLOC( &testSetBER, &testSetBlob2); */ ExpBufResetInWriteRvsMode(ptestSetBlob2GenBuf->spare); DEncVDATestSet(ptestSetBlob2GenBuf, ptestSetBER); size1 = ExpBufDataSize(ptestSetBlob2GenBuf->spare); size2 = ExpBufDataSize(ptestSetBlob); free(ptestSetBER); if (size1 != size2) printf("DER test count FAILED SIZE COMPARE!\n"); else { result = memcmp(ExpBufDataPtr(ptestSetBlob2GenBuf->spare), ExpBufDataPtr(ptestSetBlob), size1); if (result == 0) printf("Passed DER test ... \n"); else { printf("Failed DER test ... \n"); size2 = ExpBufDataSize(ptestSetBlobBER); if (size1 != size2) printf("BER decoded and re-encode as BER insteaded of DER count FAILED SIZE COMPARE!\n"); else { result = memcmp(ExpBufDataPtr(ptestSetBlob2), ExpBufDataPtr(ptestSetBlobBER), size1); if (result == 0) printf("\tBER decoded and re-encode as BER insteaded of DER\n"); else { /* testSetBlob2.ReportHexBuffer( cout, testSetBlob2.Access(), testSetBlob2.Length()); */ printf("Still failed DER test ... \n"); } } } } printf ("At TestOid\n"); TestOid.octs = octs1; TestOid.octetLen = strlen(octs1); printf("TestOid = %s\n", TestOid.octs); TestOid.octs = octs2; TestOid.octetLen = strlen(octs2); printf("TestOid = %s\n", TestOid.octs); /* RWC; TEST Override for "<<" operator to avoid stdout prints... RWC; Override is only used within SNACC generated code, not in snacc RWC; run-time includes. RWC; Force failure printf("######### THE NEXT SET OF STATEMENTS SHOULD FAIL, YOU WILL ####\n"); printf("######### SEE THE ERROR FROM SNACC AT THE TOP OF THE ####\n"); printf("######### STACK ####\n"); VDATestSequence aa; struct ExpBuf cBuf("aaa", 3); DECODE_BUF(&aa, &cBuf); */ return 1; } /* append_test */ void Test_ASN_1_Strings() { /* RFC 2253 Test Data */ unsigned char RFC2253TestData[] = { 0x4c, 0x75, 0xC4, 0x8d, 0x69, 0xC4, 0x87, 0x00, 0x00 }; const int RFC2253TestDataLen = 9; /* RFC 2279 Test Data Section 4 (Examples) Example 1 */ unsigned char RFC2279TestData1[] = { 0x41, 0xE2, 0x89, 0xA2, 0xCE, 0x91, 0x2E, 0x00 }; unsigned char RFC2279TestResult1[] = {0x00, 0x41, 0x22, 0x62, 0x03, 0x91, 0x00, 0x2E }; /* RFC 2279 Test Data Section 4 (Examples) Example 2 */ unsigned char RFC2279TestData2[] = { 0xED ,0x95 ,0x9C ,0xEA, 0xB5, 0xAD, 0xEC, 0x96, 0xB4,0x00 }; unsigned char RFC2279TestResult2[] = { 0xD5, 0x5C, 0xAD, 0x6D, 0xC5, 0xB4 }; /* RFC 2279 Test Data Section 4 (Examples) Example 3 */ unsigned char RFC2279TestData3[] = { 0xE6, 0x97, 0xA5, 0xE6, 0x9C, 0xAC, 0xE8, 0xAA, 0x9E }; unsigned char RFC2279TestResult3[] = { 0x65, 0xE5, 0x67, 0x2C, 0x8A, 0x9E }; /* RFC 2279 Test Data Section 4 (Examples) Example 4 */ unsigned char UTF8TestData4[] = { 0x00,0x4c,0x80, 0x80,0x01, 0x0d, 0x00, 0x69, 0x01, 0x07, 0x00, 0x00 }; /* unsigned char RFC2279TestResult4[] = { 0x */ const int RFC2279TestData1Len = 8; const int RFC2279TestData2Len = 10; const int RFC2279TestData3Len = 9; const int RFC2279TestData4Len = 12; const int RFC2279TestResult1Len = 8; const int RFC2279TestResult2Len = 6; const int RFC2279TestResult3Len = 6; /* Universal String is 4 bytes long */ char universal_string[] = { 0x00, 0x00,0x00,0x4c,0x00, 0x00,0x00, 0x75,0x00, 0x00, 0x01, 0x0d, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x01, 0x07, 0x00, 0x00,0x00,0x00 }; char bmp_string[] = {0x00, 'T', 0x00, 'E', 0x00, 'S', 0x00, 'T'}; wchar_t bmpTest[] = {'T', 'E', 'S', 'T'}; int universal_stringLen = 24; long status=0; UniversalString A; UTF8String C; PrintableString AP, AP2; BMPString bmp; wchar_t *pWchar=NULL; char *tempChar = NULL; char *blahstr = ("blah PrintableString"); struct ExpBuf *pBUF; struct GenBuf gBUF; AsnLen bytesDecoded = 0; ENV_TYPE env; int val; int result = 0; /* printf("######### Test_ASN_1_Strings: START OF TEST ####\n"); A.octs = (char *)calloc(1, sizeof(char)); A.octs = (const char *)universal_string; A.octetLen = universal_stringLen; printf("Test_ASN_1_Strings: A(UniversalString)= %s\n",A.GetChar()); printf("Converting from 4 byte wide characters to wchar_t %d bytes wide \n", sizeof(wchar_t)); printf("UniversalString Results \n"); tempChar = (char *)A.octs; for (i=0; i < universal_stringLen+1/2; i++) { printf("0x %d",(int)tempChar[i]); printf(" "); if ((tempChar[i+1] == 0x00) && (tempChar[i+2] == 0x00) && (tempChar[i+3] == 0x00) && (tempChar[i+4] == 0x00)) i = universal_stringLen+10; } printf("\n"); printf("######### Test_ASN_1_Strings: END OF TEST ####\n\n"); */ printf("######### Test_ASN_1_Strings: START OF TEST ####\n\n"); printf("\n"); /* cout << "Test_ASN_1_Strings: pWchar of A=" << TmpChar << "\n"; */ AP.octs = blahstr; AP.octetLen = strlen(blahstr); printf("Test_ASN_1_Strings: AP(PrintableString)= %s\n", AP.octs); A = AP; /* TEST Multi-byte assignment to single-byte ASN.1 def. */ printf("Test_ASN_1_Strings: A(UniversalString<-PrintableString)= %s\n",A.octs); printf("######### Test_ASN_1_Strings: END OF TEST ####\n\n"); printf("######### Test_ASN_1_Strings: START OF ENC/DEC TEST ####"); printf("\n"); pBUF = ExpBufAllocBufAndData(); ExpBufResetInWriteRvsMode(pBUF); PutExpBufInGenBuf (pBUF, &gBUF); result = BEncPrintableString(&gBUF, &AP); if (result == 0) printf("BEncPrintableString FAILED!\n"); ExpBufResetInReadMode(gBUF.bufInfo); if ((val = setjmp (env)) == 0) BDecPrintableString(&gBUF, &AP2, &bytesDecoded, env); else printf("BDecPrintableString FAILED!\n"); ExpBufFreeBufAndData(gBUF.spare); result = memcmp(AP2.octs, AP.octs, AP2.octetLen); if (result == 0) { printf("BEncPrintableString Success! \n"); } else { printf("BEncPrintableString Failed! \n"); } printf("######### Test_ASN_1_Strings: END OF ENC/DEC TEST ####\n\n"); printf("######### Test_ASN_1_Strings: START OF TESTS ####\n"); printf("Test 1 input data is: \n"); outhex2(RFC2279TestData1, RFC2279TestData1Len); printf("\n"); /* AP.Set((char *)RFC2279TestData1); */ AP.octs = RFC2279TestData1; AP.octetLen = RFC2279TestData1Len; C = AP; /* TEST Multi-byte assignment to single-byte ASN.1 def. */ printf("Test 1 Expected Result:\n"); outhex2(RFC2279TestResult1, RFC2279TestResult1Len); /* C.Set((char *)RFC2279TestData1, RFC2279TestData1Len); */ C.octs = RFC2279TestData1; C.octetLen = RFC2279TestData1Len; /* pWchar = C; */ /* Transform the UTF-8 to Wide Character */ status = CvtUTF8String2wchar(&C, &pWchar); printf("\nTest 1 Actual Test Result(Intel platforms will have bytes flipped):\n"); if (pWchar != NULL) { outhex2((unsigned char *)pWchar, RFC2279TestResult1Len); status = utf8compare2(RFC2279TestResult1, pWchar, RFC2279TestData1Len); if (status != 0) printf("Actual Results do not compare with expected results\n"); else printf("######### Results compare\n"); } else printf("pWchar is NULL, which is in error\n"); printf("\n"); printf("Test 2 input data is: \n"); outhex2(RFC2279TestData2, RFC2279TestData2Len); printf("\n"); /* AP.Set((char *)RFC2279TestData2); */ AP.octs = RFC2279TestData2; AP.octetLen = RFC2279TestData2Len; C = AP; /* TEST Multi-byte assignment to single-byte ASN.1 def. */ printf("Test 2 Expected Result:\n"); outhex2(RFC2279TestResult2, RFC2279TestResult2Len); /* C.Set((char *)RFC2279TestData2, RFC2279TestData2Len); */ C.octs = RFC2279TestData2; C.octetLen = RFC2279TestData2Len; /* pWchar = C; */ /* Transform the UTF-8 to Wide Character */ status = CvtUTF8String2wchar(&C, &pWchar); printf("\nTest 2 Actual Test Result(Intel platforms will have bytes flipped):\n"); if (pWchar != NULL) { outhex2((unsigned char *)pWchar, RFC2279TestResult2Len); status = utf8compare2(RFC2279TestResult2, pWchar, RFC2279TestResult2Len); if (status != 0) printf("Actual Results do not compare with expected results\n"); else printf("######### Results compare\n"); } else printf("pWchar is NULL, which is in error\n"); printf("\n"); printf("\n"); printf("Test 3 input data is: \n"); outhex2(RFC2279TestData3, RFC2279TestData3Len); printf("\n"); /* AP.Set((char *)RFC2279TestData3); */ AP.octs = RFC2279TestData3; AP.octetLen = RFC2279TestData3Len; C = AP; /* TEST Multi-byte assignment to single-byte ASN.1 def. */ printf("Test 3 Expected Result:\n"); outhex2(RFC2279TestResult3, RFC2279TestResult3Len); /* C.Set((char *)RFC2279TestData3, RFC2279TestData3Len); */ C.octs = (char *)calloc(1, strlen(RFC2279TestData3) + 1); C.octetLen = RFC2279TestData3Len; memcpy(C.octs, RFC2279TestData3, C.octetLen); /* pWchar = C; */ /* Transform the UTF-8 to Wide Character */ status = CvtUTF8String2wchar(&C, &pWchar); free(C.octs); C.octs = NULL; printf("\nTest 3 Actual Test Result(Intel platforms will have bytes flipped):\n"); if (pWchar != NULL) { outhex2((unsigned char *)pWchar, RFC2279TestResult3Len); status = utf8compare2(RFC2279TestResult3, pWchar, RFC2279TestResult3Len); if (status != 0) printf("Actual Results do not compare with expected results\n"); else printf("######### Results compare\n"); } else printf("pWchar is NULL, which is in error\n"); printf("\n"); printf("######### Test_ASN_1_Strings: END OF TEST 3 ####\n\n"); printf("\n"); printf("######### Test_ASN_1_Strings: START OF TESTS ####\n"); printf("Test 4 input data is: \n"); outhex2((unsigned char *)bmp_string, 8); printf("\n"); /* D.Set((char *)bmpTest, 8); */ bmp.octs = (char *)calloc(1, 8 + 1); bmp.octetLen = 8; memcpy(bmp.octs, bmpTest, bmp.octetLen); status = CvtBMPString2wchar(&bmp, &pWchar); free(bmp.octs); bmp.octs = NULL; printf("Test 4 actual BMPString -> wchar_t is:\n"); outhex2((unsigned char *)pWchar, 8); printf("\n"); printf("######### Test_ASN_1_Strings: END OF TEST 4 ####\n\n"); printf("\n"); } void outhex2(unsigned char *outChar, int Len) { int i = 0; for (i=0; i < Len; i++) { printf ("0x%x ", outChar[i]); printf(" "); } printf ("\n"); } int utf8compare2(unsigned char *expected, wchar_t *actual, int Len) { long value = 1; int stat = 0; #define TWO #define WCHAR_SIZE sizeof (wchar_t) #ifdef WIN32 unsigned short *buf; #else unsigned long *buf; #endif /* Check which byte the value 1 is in (Little Endian stuff)*/ if (*(char *)&value == 1) { #ifdef WIN32 /* We have to flip the wchar_t for comparison */ int j; unsigned short tempnum; buf = (unsigned short *)actual; for ( j = 0; j < Len/2; j++ ) { tempnum = (unsigned short)((buf[j] << 8) | (buf[j] >> 8)); buf[j] = tempnum; } #else int j; unsigned long tempnum; buf = (unsigned long *)actual; for ( j = 0; j < Len/4; j++ ) { tempnum = (buf[j] << 16) | (buf[j] >> 16); buf[j] = ((tempnum & 0xff00ff00L) >> 8) | ((tempnum & 0x00ff00ffL) << 8); } #endif } else #ifdef WIN32 buf = (unsigned short *)actual; #else buf = (unsigned long *)actual; #endif /* Compare the strings */ stat = strncmp((const char *)expected, (const char *)actual, Len); return stat; } /* Timing */ void test_timingDoTestPrint(long BYTE_COUNT, long iCount, long lTestType); void test_timing() { long iCount=1000; test_timingDoTestPrint(1000, iCount, TEST_ENCODE_BUF); test_timingDoTestPrint(1000, iCount, TEST_ENCODE_BUF); test_timingDoTestPrint(1000, iCount, TEST_DECODE_BUF); test_timingDoTestPrint(1000, iCount, TEST_DECODE_BUF); #ifdef TESTS_ALREADY_DONE #endif /*RELEASE Version test_timing: Start. test_timing: OLD ENCODE_BUF iCount=1000, Time=10.160000, single=0.010160 Size=90000bytes. test_timing: Start. test_timing: NEW ENCODE_BUF iCount=1000, Time=2.640000, single=0.002640 Size=90000bytes. DEBUG Version test_timing: Start. test_timing: OLD ENCODE_BUF iCount=1000, Time=14.060000, single=0.014060 Size=90000bytes. test_timing: Start. test_timing: NEW ENCODE_BUF iCount=1000, Time=6.860000, single=0.006860 Size=90000bytes. test_timing: Start. test_timing: OLD DECODE_BUF iCount=1000, Time=7.910000, single=0.007910 Size=90000bytes. test_timing: Start. test_timing: NEW DECODE_BUF iCount=1000, Time=1.210000, single=0.001210 Size=90000bytes. */ } double test_timingDoTest(long BYTE_COUNT, long iCount, long lTestType); void test_timingDoTestPrint(long lByteCount, long iCount, long lTestType) { double dSingle; double dResult; char *lpszTypeFlag; dResult = test_timingDoTest(lByteCount, iCount, lTestType); dSingle = dResult / iCount; if (lTestType == TEST_ENCODE_BUF) lpszTypeFlag = "ENCODE_BUF"; else if (lTestType == TEST_DECODE_BUF) lpszTypeFlag = "DECODE_BUF"; printf("test_timing: %s iCount=%d, Time=%f, single=%f Size=%ldbytes.\n", lpszTypeFlag, iCount, dResult, dSingle, lByteCount); } #ifndef WIN32 /* artificially fix symbols. */ #define _timeb timeb #define _ftime ftime #endif double test_timingDoTest(long BYTE_COUNT, long iCount, long lTestType) { double dTime, dTime2, dSingle; struct _timeb timebuffer; PrintableString AA; PrintableString *pAA; /* CANNOT use "AA" due to SNACC limitation where it does not free previous memory on subsequent decodes!!!#@$% */ struct ExpBuf *pBB=NULL; struct GenBuf *genpBB = NULL; struct ExpBuf *pCANNEDTmpEncodedBuf=NULL; struct GenBuf *pCANNEDTmpEncodedGenBuf; struct ExpBuf *pCANNEDEncodedBuf=NULL; struct GenBuf CANNEDEncodedGenBuf; int i; int result; ENV_TYPE env; int val; unsigned int bytesDecoded=0; char *pChar=(char *)calloc(1, BYTE_COUNT); printf("test_big_buffer()"); printf("test_timing: Start.\n"); memset((void *)pChar, 'R', BYTE_COUNT); pBB = ExpBufAllocBufAndData(); pCANNEDTmpEncodedBuf = ExpBufAllocBufAndData(); pCANNEDEncodedBuf = ExpBufAllocBufAndData(); ExpBuftoGenBuf(pCANNEDTmpEncodedBuf, &pCANNEDTmpEncodedGenBuf); AA.octs = pChar; AA.octetLen = BYTE_COUNT; /* ENCODE_BUF22(&AA, pCANNEDTmpEncodedBuf); */ /* FOR DECODE_BUF ops. */ ExpBufResetInWriteRvsMode(pCANNEDTmpEncodedGenBuf->spare); result = BEncPrintableString(pCANNEDTmpEncodedGenBuf, &AA); if (result == 0) printf("BEncPrintableString FAILED!\n"); /* pCANNEDEncodedBuf = new CSM_Buffer(*pCANNEDTmpEncodedBuf); */ /* delete pCANNEDTmpEncodedBuf; */ /* need to copy to avoid oversized buffer from ENCODE_BUF ops. */ ExpBufInstallDataInBuf(pCANNEDEncodedBuf, ExpBufDataPtr(pCANNEDTmpEncodedGenBuf->spare), ExpBufDataSize(pCANNEDTmpEncodedGenBuf->spare)); /* ExpBufFreeBufAndData(pCANNEDTmpEncodedBuf); */ _ftime( &timebuffer); dTime = timebuffer.time; dTime += (.001) * timebuffer.millitm; for (i=0; i < iCount; i++) { pBB = NULL; if (lTestType == TEST_ENCODE_BUF) { pBB = ExpBufAllocBufAndData(); ExpBuftoGenBuf (pBB, &genpBB); ExpBufResetInWriteRvsMode(genpBB->spare); result = BEncPrintableString(genpBB, &AA); ExpBufFreeBufAndData(genpBB->spare); free (genpBB); } else if (lTestType == TEST_DECODE_BUF) { pAA = (PrintableString *) calloc(1, sizeof(PrintableString)); ExpBufResetInReadMode(&pCANNEDEncodedBuf); PutExpBufInGenBuf(pCANNEDEncodedBuf, &CANNEDEncodedGenBuf); if ((val = setjmp (env)) == 0) BDecPrintableString(&CANNEDEncodedGenBuf, pAA, &bytesDecoded, env); else printf("BDecPrintableString FAILED!\n"); FreePrintableString(pAA); free(pAA); } } _ftime( &timebuffer); dTime2 = timebuffer.time; dTime2 += (.001) * timebuffer.millitm; dSingle = dTime2 - dTime; free(pChar); return(dSingle); } void ANY_test() { //AsnOid testOid3; TestANYUsage A4, A5; //TestDefinedByUsage_2 A, A2, A3; struct ExpBuf *pBUF, *pBUF2=NULL; struct GenBuf *gBUF, *gBUF2=NULL; PrintableString *pB; PrintableString *pPS; AsnLen bytesDecoded = 0; ENV_TYPE env; int val; //char *octs1 = ("1.2.3.4.5.5.5.5.6"); char *test = ("THIS IS A TEST"); int result = 0; AsnLen iAnyLen; printf("ANY_test()\n"); //AsnLen BEncAsnAny(GenBuf *b, AsnAny *v); //void BDecAsnAny(GenBuf *b, AsnAny *result, AsnLen *bytesDecoded, ENV_TYPE env); // FIRST, load PrintableString for ANY. pBUF = ExpBufAllocBufAndData(); ExpBuftoGenBuf(pBUF, &gBUF); pB = (PrintableString *) calloc(1, sizeof(PrintableString)); pB->octs = strdup(test); pB->octetLen = strlen(test); ExpBufResetInWriteRvsMode(gBUF->spare); result = BEncPrintableString(gBUF, pB); FreePrintableString(pB); free(pB); ExpBufResetInReadMode(gBUF->bufInfo); if (result) { // NEXT, load encoded PrintableString (in gBUF) into ANY of A4 memset(&A4,'\0', sizeof(A4)); SetAnyTypeUnknown((&A4.aBlob)); // SETUP for this buffer of ANY... iAnyLen = 0; BDecAsnAny(gBUF, &A4.aBlob, &iAnyLen, env); if (iAnyLen) { pBUF2 = ExpBufAllocBufAndData(); ExpBuftoGenBuf(pBUF2, &gBUF2); printf("ANY_test: SUCCESSFUL ANY load.\n"); ExpBufResetInWriteRvsMode(gBUF2->spare); result = DEncTestANYUsage(gBUF2, &A4); if (result) printf("ANY_test: SUCCESSFUL TestANYUsage encode, with ANY.\n"); else printf("ANY_test: ***** UNSUCCESSFUL TestANYUsage encode, with ANY.\n"); ExpBufResetInReadMode(gBUF2->bufInfo); } // END IF ANY loaded. else printf("ANY_test: ***** UNSUCCESSFUL ANY load.\n"); } // END IF encode or PrintableString else printf("ANY_test: ***** UNSUCCESSFUL PrintableString encode.\n"); // NOW that we have an encoded TestANYUsage, attempt to decode and // reference data. if (gBUF2) { iAnyLen = 0; if ((val = setjmp (env)) == 0) DDecTestANYUsage(gBUF2, &A5, &iAnyLen, env); else { printf("***** DDecTestANYUsage FAILED!\n"); return; } SetAnyTypeUnknown((&A5.aBlob)); // SETUP for this buffer of ANY... ExpBufResetInWriteRvsMode(gBUF->spare); iAnyLen = BEncAsnAny(gBUF, &A5.aBlob); if (iAnyLen) { pPS = (PrintableString *) calloc(1, sizeof(PrintableString)); iAnyLen = 0; ExpBufResetInReadMode(gBUF->bufInfo); BDecPrintableString(gBUF, pPS, &iAnyLen, env); if (iAnyLen) // SUCCEEDED in deocding ANY, previously encoded // as PrintableString. printf("ANY_test: SUCCESSFUL ANY PrintableString DECODE; |%s|.\n", pPS->octs); else printf("ANY_test: ***** UNSUCCESSFUL ANY PrintableString DECODE.\n"); ExpBufFreeBufAndData(gBUF->spare); FreePrintableString(pPS); free(pPS); } // IF iAnyLen on decode... else printf("ANY_test: ***** UNSUCCESSFUL ANY unload.\n"); ExpBufFreeBufAndData(gBUF2->spare); } // END IF gBUF2 } // END ANY_test() esnacc-ng-1.8.1/c-examples/vdatestC/vdatestC_asn.asn1000066400000000000000000000054351302010526100223710ustar00rootroot00000000000000VdaTestModule DEFINITIONS EXPLICIT TAGS ::= -- DEFINITIONS IMPLICIT TAGS ::= BEGIN VDATestSequence ::= --snacc isPdu:"TRUE" -- SEQUENCE OF INTEGER VDATestSet ::= --snacc isPdu:"TRUE" -- SET OF OCTET STRING -- VDATestSetOfAny ::= SET OF ANY VDATestBitString ::= BIT STRING SequenceOfDefaults ::= SEQUENCE { defBool [0] BOOLEAN DEFAULT FALSE, defBitstring [1] ClassList DEFAULT unclassified , defInteger [2] Version DEFAULT v3, defEnumerated [3] Enumeration DEFAULT one } Enumeration ::= ENUMERATED { one(1), two(2), three(3) } ClassList ::= BIT STRING { unmarked (0), unclassified (1), restricted (2), confidential (3), secret (4), topSecret (5) } Version ::= INTEGER { v1(0), v2(1), v3(2) } --unclassified INTEGER ::= 1 DirectoryString ::= CHOICE { teletexString TeletexString (SIZE (1..MAX)), printableString PrintableString (SIZE (1..MAX)), universalString UniversalString (SIZE (1..MAX)), utf8String UTF8String (SIZE (1..MAX)), bmpString BMPString (SIZE(1..MAX)) } testOID OBJECT IDENTIFIER ::= { 1 2 3 4 5 6 7 8 } TestAllAsnPrimativeTypes ::= SEQUENCE { octsName OCTET STRING, boolTestName BOOLEAN, oidName OBJECT IDENTIFIER OPTIONAL, bitStringName [2] IMPLICIT BIT STRING, integerName INTEGER, enumTestName ENUMERATED { aA(11), aB(12), aC(13) }, realName REAL OPTIONAL, nullName NULL } TestSequence ::= SEQUENCE { seqOfDefaults SequenceOfDefaults OPTIONAL, testSet VDATestSet, -- testSetOfAny VDATestSetOfAny, directoryString DirectoryString, testAllPrimatives TestAllAsnPrimativeTypes } -- THE FOLLOWING DEFINITIONS test the ANY DEFINED BY table setup/usage. testOID2 OBJECT IDENTIFIER ::= { 1 2 3 4 5 6 7 8 2 } TestDefinedByUsage ::= --snacc isPdu:"TRUE" -- SEQUENCE { id OBJECT IDENTIFIER, anyDefBy ANY DEFINED BY id, i1 INTEGER, i2 INTEGER, i3 INTEGER, i4 INTEGER } TestANYUsage ::= --snacc isPdu:"TRUE" -- SEQUENCE { i1 INTEGER, i2 INTEGER, aBlob ANY -- RWC; TEST automatic processing of ANY as buffer. } TestDefinedByType ::= SEQUENCE { octsName OCTET STRING, boolTestName BOOLEAN } maxSIBperMsg INTEGER ::= 16 --CompleteSIB-List ::= SEQUENCE (SIZE (1..maxSIBperMsg)) OF CompleteSIBshort CompleteSIB-List ::= SEQUENCE OF CompleteSIBshort (SIZE (1..maxSIBperMsg)) CompleteSIBshort ::= SEQUENCE { a INTEGER -- Assume that this sequence has some data } -- This last definition syntax is based on SNMP OBJECT-TYPE; it is a special -- SNACC construct to align the DEFINED BY id with a data type -- (see SNACC docs). testDefinedByDesignation OBJECT-TYPE SYNTAX PrintableString ACCESS read-write STATUS mandatory ::= { 1 2 3 4 5 6 7 8 2 } --testOID2 END esnacc-ng-1.8.1/c-examples/vdatestC/vdatest_asn2C.asn1000066400000000000000000000016451302010526100224520ustar00rootroot00000000000000VdaTestModule2 -- DEFINITIONS EXPLICIT TAGS ::= DEFINITIONS IMPLICIT TAGS ::= BEGIN -- THE FOLLOWING DEFINITIONS test the ANY DEFINED BY table setup/usage. -- This specific file tests the SNACC run-time and compiler's ability to -- handle 2 sets of ANY DEFINED BY table loads (test of new feature). testOID2-2 OBJECT IDENTIFIER ::= { 3 4 5 6 7 8 9 10 4 } TestDefinedByUsage-2 ::= --snacc isPdu:"TRUE" -- SEQUENCE { id OBJECT IDENTIFIER, anyDefBy ANY DEFINED BY id } TestDefinedByType-2 ::= --snacc isPdu:"TRUE" -- SEQUENCE { octsName OCTET STRING, boolTestName BOOLEAN } -- This last definition syntax is based on SNMP OBJECT-TYPE; it is a special -- SNACC construct to align the DEFINED BY id with a data type -- (see SNACC docs). testDefinedByDesignation2 OBJECT-TYPE SYNTAX PrintableString ACCESS read-write STATUS mandatory ::= { 3 4 5 6 7 8 9 10 4 } --testOID2-2 END esnacc-ng-1.8.1/c-lib/000077500000000000000000000000001302010526100143335ustar00rootroot00000000000000esnacc-ng-1.8.1/c-lib/.gitignore000066400000000000000000000000431302010526100163200ustar00rootroot00000000000000.dirstamp .libs .deps libesnacc.pc esnacc-ng-1.8.1/c-lib/automake.mk000066400000000000000000000046411302010526100164770ustar00rootroot00000000000000lib_LTLIBRARIES += c-lib/libcasn1.la c_lib_libcasn1_la_SOURCES = \ c-lib/src/asn1init.c \ c-lib/src/asn-octs.c \ c-lib/src/mem.c \ c-lib/src/min-buf.c \ c-lib/src/asn-any.c \ c-lib/src/asn-oid.c \ c-lib/src/nibble-alloc.c \ c-lib/src/asn-bits.c \ c-lib/src/asn-PrintableStr.c \ c-lib/src/print.c \ c-lib/src/asn-BMPString.c \ c-lib/src/asn-real.c \ c-lib/src/sbuf.c \ c-lib/src/asn-bool.c \ c-lib/src/asn-relative-oid.c \ c-lib/src/str-stk.c \ c-lib/src/asn-der.c \ c-lib/src/asn-tag.c \ c-lib/src/tbl-dbg.c \ c-lib/src/asn-enum.c \ c-lib/src/asn-TeletexString.c \ c-lib/src/tbl-dec.c \ c-lib/src/asn-IA5String.c \ c-lib/src/asn-UniversalString.c \ c-lib/src/tbl-enc.c \ c-lib/src/asn-int.c \ c-lib/src/tbl-free.c \ c-lib/src/asn-len.c \ c-lib/src/asn-UTF8String.c \ c-lib/src/tbl-gen.c \ c-lib/src/asn-list.c \ c-lib/src/asn-VisibleString.c \ c-lib/src/tbl-print.c \ c-lib/src/asn-null.c \ c-lib/src/exp-buf.c \ c-lib/src/tbl-util.c \ c-lib/src/asn-NumericString.c \ c-lib/src/hash.c nobase_include_HEADERS += c-lib/inc/asn-any.h \ c-lib/inc/asn-bits.h \ c-lib/inc/asn-BMPString.h \ c-lib/inc/asn-bool.h \ c-lib/inc/asn-config.h \ c-lib/inc/asn-der.h \ c-lib/inc/asn-enum.h \ c-lib/inc/asn-IA5String.h \ c-lib/inc/asn-incl.h \ c-lib/inc/asn-int.h \ c-lib/inc/asn-len.h \ c-lib/inc/asn-list.h \ c-lib/inc/asn-null.h \ c-lib/inc/asn-NumericString.h \ c-lib/inc/asn-octs.h \ c-lib/inc/asn-oid.h \ c-lib/inc/asn-PrintableStr.h \ c-lib/inc/asn-real.h \ c-lib/inc/asn-relative-oid.h \ c-lib/inc/asn-tag.h \ c-lib/inc/asn-TeletexString.h \ c-lib/inc/asn-UniversalString.h \ c-lib/inc/asn-UTF8String.h \ c-lib/inc/asn-VisibleString.h \ c-lib/inc/exp-buf.h \ c-lib/inc/gen-buf.h \ c-lib/inc/hash.h \ c-lib/inc/mem.h \ c-lib/inc/min-buf.h \ c-lib/inc/nibble-alloc.h \ c-lib/inc/print.h \ c-lib/inc/sbuf.h \ c-lib/inc/snaccCder.h \ c-lib/inc/str-stk.h \ c-lib/inc/tbl-dbg.h \ c-lib/inc/tbl-dec.h \ c-lib/inc/tbl-enc.h \ c-lib/inc/tbl-free.h \ c-lib/inc/tbl-gen-c-hdr.h \ c-lib/inc/tbl-gen.h \ c-lib/inc/tbl-incl.h \ c-lib/inc/tbl-print.h \ c-lib/inc/tbl-util.h c_lib_libcasn1_la_CFLAGS = \ -I$(top_srcdir) \ -I$(top_srcdir)/c-lib \ -I$(top_srcdir)/c-lib/src \ -I$(top_srcdir)/c-lib/inc c_lib_libcasn1_la_LDFLAGS = \ $(LDFLAGS) \ $(PTHREAD_CFLAGS) \ $(all_lib_LDFLAGS) EXTRA_DIST += \ c-lib/libesnacc.pc.in pkgconfig_DATA += c-lib/libesnacc.pc DISTCLEANFILES += c-lib/libesnacc.pc esnacc-ng-1.8.1/c-lib/boot/000077500000000000000000000000001302010526100152765ustar00rootroot00000000000000esnacc-ng-1.8.1/c-lib/boot/tbl.c000066400000000000000000001427241302010526100162350ustar00rootroot00000000000000#if TTBL /* * tbl.c * * "TBL" ASN.1 module encode/decode/print/free C src. * * This file was generated by snacc on Mon Jun 2 11:23:56 1997 * * UBC snacc written by Mike Sample * * NOTE: This is a machine generated file - editing not recommended */ #include "asn-incl.h" #include "tbl.h" AsnLen BEncTBLRangeContent PARAMS ((b, v), BUF_TYPE b _AND_ TBLRange *v) { AsnLen totalLen = 0; AsnLen itemLen; AsnLen listLen; void *component; itemLen = BEncAsnIntContent (b, (&v->to)); BEncDefLenTo127 (b, itemLen); itemLen++; itemLen += BEncTag1 (b, CNTX, PRIM, 1); totalLen += itemLen; itemLen = BEncAsnIntContent (b, (&v->from)); BEncDefLenTo127 (b, itemLen); itemLen++; itemLen += BEncTag1 (b, CNTX, PRIM, 0); totalLen += itemLen; return totalLen; } /* BEncTBLRangeContent */ void BDecTBLRangeContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env), BUF_TYPE b _AND_ AsnTag tagId0 _AND_ AsnLen elmtLen0 _AND_ TBLRange *v _AND_ AsnLen *bytesDecoded _AND_ ENV_TYPE env) { int seqDone = FALSE; AsnLen totalElmtsLen1 = 0; AsnLen elmtLen1; AsnTag tagId1; int mandatoryElmtCount1 = 0; tagId1 = BDecTag (b, &totalElmtsLen1, env); if (((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 0)))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); BDecAsnIntContent (b, tagId1, elmtLen1, (&v->from), &totalElmtsLen1, env); tagId1 = BDecTag (b, &totalElmtsLen1, env); } else longjmp (env, -100); if (((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 1)))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); BDecAsnIntContent (b, tagId1, elmtLen1, (&v->to), &totalElmtsLen1, env); seqDone = TRUE; if (elmtLen0 == INDEFINITE_LEN) BDecEoc (b, &totalElmtsLen1, env); else if (totalElmtsLen1 != elmtLen0) longjmp (env, -101); } else longjmp (env, -102); if (!seqDone) longjmp (env, -103); (*bytesDecoded) += totalElmtsLen1; } /* BDecTBLRangeContent */ void PrintTBLRange PARAMS ((f, v, indent), FILE* f _AND_ TBLRange *v _AND_ unsigned short indent) { if (v == NULL) return; fprintf (f,"{ -- SEQUENCE --\n"); Indent (f, indent + stdIndentG); fprintf (f,"from "); PrintAsnInt (f, (&v->from), indent + stdIndentG); fprintf (f, ",\n"); Indent (f, indent + stdIndentG); fprintf (f,"to "); PrintAsnInt (f, (&v->to), indent + stdIndentG); fprintf (f,"\n"); Indent (f, indent); fprintf (f,"}"); } /* PrintTBLRange */ void FreeTBLRange PARAMS ((v), TBLRange *v) { if (v == NULL) return; FreeAsnInt ((&v->from)); FreeAsnInt ((&v->to)); } /* FreeTBLRange */ AsnLen BEncTBLNamedNumberContent PARAMS ((b, v), BUF_TYPE b _AND_ TBLNamedNumber *v) { AsnLen totalLen = 0; AsnLen itemLen; AsnLen listLen; void *component; itemLen = BEncAsnIntContent (b, (&v->value)); BEncDefLenTo127 (b, itemLen); itemLen++; itemLen += BEncTag1 (b, CNTX, PRIM, 1); totalLen += itemLen; itemLen = BEncPrintableStringContent (b, (&v->name)); itemLen += BEncDefLen (b, itemLen); itemLen += BEncTag1 (b, CNTX, PRIM, 0); totalLen += itemLen; return totalLen; } /* BEncTBLNamedNumberContent */ void BDecTBLNamedNumberContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env), BUF_TYPE b _AND_ AsnTag tagId0 _AND_ AsnLen elmtLen0 _AND_ TBLNamedNumber *v _AND_ AsnLen *bytesDecoded _AND_ ENV_TYPE env) { int seqDone = FALSE; AsnLen totalElmtsLen1 = 0; AsnLen elmtLen1; AsnTag tagId1; int mandatoryElmtCount1 = 0; tagId1 = BDecTag (b, &totalElmtsLen1, env); if (((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 0)) || (tagId1 == MAKE_TAG_ID (CNTX, CONS, 0)))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); BDecPrintableStringContent (b, tagId1, elmtLen1, (&v->name), &totalElmtsLen1, env); tagId1 = BDecTag (b, &totalElmtsLen1, env); } else longjmp (env, -104); if (((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 1)))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); BDecAsnIntContent (b, tagId1, elmtLen1, (&v->value), &totalElmtsLen1, env); seqDone = TRUE; if (elmtLen0 == INDEFINITE_LEN) BDecEoc (b, &totalElmtsLen1, env); else if (totalElmtsLen1 != elmtLen0) longjmp (env, -105); } else longjmp (env, -106); if (!seqDone) longjmp (env, -107); (*bytesDecoded) += totalElmtsLen1; } /* BDecTBLNamedNumberContent */ void PrintTBLNamedNumber PARAMS ((f, v, indent), FILE* f _AND_ TBLNamedNumber *v _AND_ unsigned short indent) { if (v == NULL) return; fprintf (f,"{ -- SEQUENCE --\n"); Indent (f, indent + stdIndentG); fprintf (f,"name "); PrintPrintableString (f, (&v->name), indent + stdIndentG); fprintf (f, ",\n"); Indent (f, indent + stdIndentG); fprintf (f,"value "); PrintAsnInt (f, (&v->value), indent + stdIndentG); fprintf (f,"\n"); Indent (f, indent); fprintf (f,"}"); } /* PrintTBLNamedNumber */ void FreeTBLNamedNumber PARAMS ((v), TBLNamedNumber *v) { if (v == NULL) return; FreePrintableString ((&v->name)); FreeAsnInt ((&v->value)); } /* FreeTBLNamedNumber */ AsnLen BEncTBLNamedNumberListContent PARAMS ((b, v), BUF_TYPE b _AND_ TBLNamedNumberList *v) { AsnLen totalLen = 0; AsnLen itemLen; AsnLen listLen; void *component; listLen = 0; FOR_EACH_LIST_ELMT_RVS (component, v) { BEncEocIfNec (b); itemLen = BEncTBLNamedNumberContent (b, component); itemLen += BEncConsLen (b, itemLen); itemLen += BEncTag1 (b, UNIV, CONS, 16); listLen += itemLen; } return listLen; } /* BEncTBLNamedNumberListContent */ void BDecTBLNamedNumberListContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env), BUF_TYPE b _AND_ AsnTag tagId0 _AND_ AsnLen elmtLen0 _AND_ TBLNamedNumberList *v _AND_ AsnLen *bytesDecoded _AND_ ENV_TYPE env) { int seqDone = FALSE; AsnLen totalElmtsLen1 = 0; AsnLen elmtLen1; AsnTag tagId1; int mandatoryElmtCount1 = 0; for (totalElmtsLen1 = 0; (totalElmtsLen1 < elmtLen0) || (elmtLen0 == INDEFINITE_LEN);) { TBLNamedNumber **tmpVar; tagId1 = BDecTag (b, &totalElmtsLen1, env); if ((tagId1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN)) { BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env) break; /* got EOC so can exit this SET OF/SEQ OF's for loop*/ } if ((tagId1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); tmpVar = (TBLNamedNumber**) AsnListAppend (v); (*tmpVar) = (TBLNamedNumber*) Asn1Alloc (sizeof (TBLNamedNumber)); CheckAsn1Alloc ((*tmpVar), env); BDecTBLNamedNumberContent (b, tagId1, elmtLen1, (*tmpVar), &totalElmtsLen1, env); } /* end of tag check if */ else /* wrong tag */ { Asn1Error ("Unexpected Tag\n"); longjmp (env, -108); } } /* end of for */ (*bytesDecoded) += totalElmtsLen1; } /* BDecTBLNamedNumberListContent */ void PrintTBLNamedNumberList PARAMS ((f, v, indent), FILE* f _AND_ TBLNamedNumberList *v _AND_ unsigned short indent) { TBLNamedNumber *tmp; if (v == NULL) return; fprintf (f,"{ -- SEQUENCE OF -- \n"); FOR_EACH_LIST_ELMT (tmp, v) { Indent (f, indent+ stdIndentG); PrintTBLNamedNumber (f, tmp, indent + stdIndentG); if (tmp != (TBLNamedNumber*)LAST_LIST_ELMT (v)) fprintf (f,",\n"); } fprintf (f,"\n"); Indent (f, indent); fprintf (f,"}"); } /* PrintTBLNamedNumberList */ void FreeTBLNamedNumberList PARAMS ((v), TBLNamedNumberList *v) { AsnListNode *l; AsnListNode *tmp; if (v == NULL) return; for (l = FIRST_LIST_NODE (v); l != NULL; ) { FreeTBLNamedNumber ((l->data)); tmp = l->next; Asn1Free (l->data); Asn1Free (l); l = tmp; } } /* FreeTBLNamedNumberList */ AsnLen BEncTBLTypeRefContent PARAMS ((b, v), BUF_TYPE b _AND_ TBLTypeRef *v) { AsnLen totalLen = 0; AsnLen itemLen; AsnLen listLen; void *component; itemLen = BEncAsnBoolContent (b, (&v->implicit)); BEncDefLenTo127 (b, itemLen); itemLen++; itemLen += BEncTag1 (b, UNIV, PRIM, 1); totalLen += itemLen; itemLen = BEncTBLTypeDefIdContent (b, (&v->typeDef)); BEncDefLenTo127 (b, itemLen); itemLen++; itemLen += BEncTag1 (b, UNIV, PRIM, 2); totalLen += itemLen; return totalLen; } /* BEncTBLTypeRefContent */ void BDecTBLTypeRefContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env), BUF_TYPE b _AND_ AsnTag tagId0 _AND_ AsnLen elmtLen0 _AND_ TBLTypeRef *v _AND_ AsnLen *bytesDecoded _AND_ ENV_TYPE env) { int seqDone = FALSE; AsnLen totalElmtsLen1 = 0; AsnLen elmtLen1; AsnTag tagId1; int mandatoryElmtCount1 = 0; tagId1 = BDecTag (b, &totalElmtsLen1, env); if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); BDecTBLTypeDefIdContent (b, tagId1, elmtLen1, (&v->typeDef), &totalElmtsLen1, env); tagId1 = BDecTag (b, &totalElmtsLen1, env); } else longjmp (env, -109); if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, BOOLEAN_TAG_CODE)))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); BDecAsnBoolContent (b, tagId1, elmtLen1, (&v->implicit), &totalElmtsLen1, env); seqDone = TRUE; if (elmtLen0 == INDEFINITE_LEN) BDecEoc (b, &totalElmtsLen1, env); else if (totalElmtsLen1 != elmtLen0) longjmp (env, -110); } else longjmp (env, -111); if (!seqDone) longjmp (env, -112); (*bytesDecoded) += totalElmtsLen1; } /* BDecTBLTypeRefContent */ void PrintTBLTypeRef PARAMS ((f, v, indent), FILE* f _AND_ TBLTypeRef *v _AND_ unsigned short indent) { if (v == NULL) return; fprintf (f,"{ -- SEQUENCE --\n"); Indent (f, indent + stdIndentG); fprintf (f,"typeDef "); PrintTBLTypeDefId (f, (&v->typeDef), indent + stdIndentG); fprintf (f, ",\n"); Indent (f, indent + stdIndentG); fprintf (f,"implicit "); PrintAsnBool (f, (&v->implicit), indent + stdIndentG); fprintf (f,"\n"); Indent (f, indent); fprintf (f,"}"); } /* PrintTBLTypeRef */ void FreeTBLTypeRef PARAMS ((v), TBLTypeRef *v) { if (v == NULL) return; FreeTBLTypeDefId ((&v->typeDef)); FreeAsnBool ((&v->implicit)); } /* FreeTBLTypeRef */ AsnLen BEncTBLTagContent PARAMS ((b, v), BUF_TYPE b _AND_ TBLTag *v) { AsnLen totalLen = 0; AsnLen itemLen; AsnLen listLen; void *component; itemLen = BEncAsnIntContent (b, (&v->code)); BEncDefLenTo127 (b, itemLen); itemLen++; itemLen += BEncTag1 (b, UNIV, PRIM, 2); totalLen += itemLen; itemLen = BEncTBLTagClassContent (b, (&v->tclass)); BEncDefLenTo127 (b, itemLen); itemLen++; itemLen += BEncTag1 (b, UNIV, PRIM, 10); totalLen += itemLen; return totalLen; } /* BEncTBLTagContent */ void BDecTBLTagContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env), BUF_TYPE b _AND_ AsnTag tagId0 _AND_ AsnLen elmtLen0 _AND_ TBLTag *v _AND_ AsnLen *bytesDecoded _AND_ ENV_TYPE env) { int seqDone = FALSE; AsnLen totalElmtsLen1 = 0; AsnLen elmtLen1; AsnTag tagId1; int mandatoryElmtCount1 = 0; tagId1 = BDecTag (b, &totalElmtsLen1, env); if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, ENUM_TAG_CODE)))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); BDecTBLTagClassContent (b, tagId1, elmtLen1, (&v->tclass), &totalElmtsLen1, env); tagId1 = BDecTag (b, &totalElmtsLen1, env); } else longjmp (env, -113); if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); BDecAsnIntContent (b, tagId1, elmtLen1, (&v->code), &totalElmtsLen1, env); seqDone = TRUE; if (elmtLen0 == INDEFINITE_LEN) BDecEoc (b, &totalElmtsLen1, env); else if (totalElmtsLen1 != elmtLen0) longjmp (env, -114); } else longjmp (env, -115); if (!seqDone) longjmp (env, -116); (*bytesDecoded) += totalElmtsLen1; } /* BDecTBLTagContent */ void PrintTBLTag PARAMS ((f, v, indent), FILE* f _AND_ TBLTag *v _AND_ unsigned short indent) { if (v == NULL) return; fprintf (f,"{ -- SEQUENCE --\n"); Indent (f, indent + stdIndentG); fprintf (f,"tclass "); PrintTBLTagClass (f, (&v->tclass), indent + stdIndentG); fprintf (f, ",\n"); Indent (f, indent + stdIndentG); fprintf (f,"code "); PrintAsnInt (f, (&v->code), indent + stdIndentG); fprintf (f,"\n"); Indent (f, indent); fprintf (f,"}"); } /* PrintTBLTag */ void FreeTBLTag PARAMS ((v), TBLTag *v) { if (v == NULL) return; FreeTBLTagClass ((&v->tclass)); FreeAsnInt ((&v->code)); } /* FreeTBLTag */ AsnLen BEncTBLTypeSeqOfContent PARAMS ((b, v), BUF_TYPE b _AND_ TBLTypeSeqOf *v) { AsnLen totalLen = 0; AsnLen itemLen; AsnLen listLen; void *component; listLen = 0; FOR_EACH_LIST_ELMT_RVS (component, v) { BEncEocIfNec (b); itemLen = BEncTBLTagContent (b, component); itemLen += BEncConsLen (b, itemLen); itemLen += BEncTag1 (b, UNIV, CONS, 16); listLen += itemLen; } return listLen; } /* BEncTBLTypeSeqOfContent */ void BDecTBLTypeSeqOfContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env), BUF_TYPE b _AND_ AsnTag tagId0 _AND_ AsnLen elmtLen0 _AND_ TBLTypeSeqOf *v _AND_ AsnLen *bytesDecoded _AND_ ENV_TYPE env) { int seqDone = FALSE; AsnLen totalElmtsLen1 = 0; AsnLen elmtLen1; AsnTag tagId1; int mandatoryElmtCount1 = 0; for (totalElmtsLen1 = 0; (totalElmtsLen1 < elmtLen0) || (elmtLen0 == INDEFINITE_LEN);) { TBLTag **tmpVar; tagId1 = BDecTag (b, &totalElmtsLen1, env); if ((tagId1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN)) { BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env) break; /* got EOC so can exit this SET OF/SEQ OF's for loop*/ } if ((tagId1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); tmpVar = (TBLTag**) AsnListAppend (v); (*tmpVar) = (TBLTag*) Asn1Alloc (sizeof (TBLTag)); CheckAsn1Alloc ((*tmpVar), env); BDecTBLTagContent (b, tagId1, elmtLen1, (*tmpVar), &totalElmtsLen1, env); } /* end of tag check if */ else /* wrong tag */ { Asn1Error ("Unexpected Tag\n"); longjmp (env, -117); } } /* end of for */ (*bytesDecoded) += totalElmtsLen1; } /* BDecTBLTypeSeqOfContent */ void PrintTBLTypeSeqOf PARAMS ((f, v, indent), FILE* f _AND_ TBLTypeSeqOf *v _AND_ unsigned short indent) { TBLTag *tmp; if (v == NULL) return; fprintf (f,"{ -- SEQUENCE OF -- \n"); FOR_EACH_LIST_ELMT (tmp, v) { Indent (f, indent+ stdIndentG); PrintTBLTag (f, tmp, indent + stdIndentG); if (tmp != (TBLTag*)LAST_LIST_ELMT (v)) fprintf (f,",\n"); } fprintf (f,"\n"); Indent (f, indent); fprintf (f,"}"); } /* PrintTBLTypeSeqOf */ void FreeTBLTypeSeqOf PARAMS ((v), TBLTypeSeqOf *v) { AsnListNode *l; AsnListNode *tmp; if (v == NULL) return; for (l = FIRST_LIST_NODE (v); l != NULL; ) { FreeTBLTag ((l->data)); tmp = l->next; Asn1Free (l->data); Asn1Free (l); l = tmp; } } /* FreeTBLTypeSeqOf */ AsnLen BEncTBLTypeContentSeqOfContent PARAMS ((b, v), BUF_TYPE b _AND_ TBLTypeContentSeqOf *v) { AsnLen totalLen = 0; AsnLen itemLen; AsnLen listLen; void *component; listLen = 0; FOR_EACH_LIST_ELMT_RVS (component, v) { BEncEocIfNec (b); itemLen = BEncTBLTypeContent (b, component); itemLen += BEncConsLen (b, itemLen); itemLen += BEncTag1 (b, UNIV, CONS, 16); listLen += itemLen; } return listLen; } /* BEncTBLTypeContentSeqOfContent */ void BDecTBLTypeContentSeqOfContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env), BUF_TYPE b _AND_ AsnTag tagId0 _AND_ AsnLen elmtLen0 _AND_ TBLTypeContentSeqOf *v _AND_ AsnLen *bytesDecoded _AND_ ENV_TYPE env) { int seqDone = FALSE; AsnLen totalElmtsLen1 = 0; AsnLen elmtLen1; AsnTag tagId1; int mandatoryElmtCount1 = 0; for (totalElmtsLen1 = 0; (totalElmtsLen1 < elmtLen0) || (elmtLen0 == INDEFINITE_LEN);) { TBLType **tmpVar; tagId1 = BDecTag (b, &totalElmtsLen1, env); if ((tagId1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN)) { BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env) break; /* got EOC so can exit this SET OF/SEQ OF's for loop*/ } if ((tagId1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); tmpVar = (TBLType**) AsnListAppend (v); (*tmpVar) = (TBLType*) Asn1Alloc (sizeof (TBLType)); CheckAsn1Alloc ((*tmpVar), env); BDecTBLTypeContent (b, tagId1, elmtLen1, (*tmpVar), &totalElmtsLen1, env); } /* end of tag check if */ else /* wrong tag */ { Asn1Error ("Unexpected Tag\n"); longjmp (env, -118); } } /* end of for */ (*bytesDecoded) += totalElmtsLen1; } /* BDecTBLTypeContentSeqOfContent */ void PrintTBLTypeContentSeqOf PARAMS ((f, v, indent), FILE* f _AND_ TBLTypeContentSeqOf *v _AND_ unsigned short indent) { TBLType *tmp; if (v == NULL) return; fprintf (f,"{ -- SEQUENCE OF -- \n"); FOR_EACH_LIST_ELMT (tmp, v) { Indent (f, indent+ stdIndentG); PrintTBLType (f, tmp, indent + stdIndentG); if (tmp != (TBLType*)LAST_LIST_ELMT (v)) fprintf (f,",\n"); } fprintf (f,"\n"); Indent (f, indent); fprintf (f,"}"); } /* PrintTBLTypeContentSeqOf */ void FreeTBLTypeContentSeqOf PARAMS ((v), TBLTypeContentSeqOf *v) { AsnListNode *l; AsnListNode *tmp; if (v == NULL) return; for (l = FIRST_LIST_NODE (v); l != NULL; ) { FreeTBLType ((l->data)); tmp = l->next; Asn1Free (l->data); Asn1Free (l); l = tmp; } } /* FreeTBLTypeContentSeqOf */ AsnLen BEncTBLTypeContent PARAMS ((b, v), BUF_TYPE b _AND_ TBLType *v) { AsnLen totalLen = 0; AsnLen itemLen; AsnLen listLen; void *component; if (NOT_NULL ((v->values))) { BEncEocIfNec (b); itemLen = BEncTBLNamedNumberListContent (b, (v->values)); itemLen += BEncConsLen (b, itemLen); itemLen += BEncTag1 (b, CNTX, CONS, 6); totalLen += itemLen; } if (NOT_NULL ((v->constraint))) { BEncEocIfNec (b); itemLen = BEncTBLRangeContent (b, (v->constraint)); itemLen += BEncConsLen (b, itemLen); itemLen += BEncTag1 (b, CNTX, CONS, 5); totalLen += itemLen; } if (ASNOCTS_PRESENT ((&v->fieldName))) { itemLen = BEncPrintableStringContent (b, (&v->fieldName)); itemLen += BEncDefLen (b, itemLen); itemLen += BEncTag1 (b, CNTX, PRIM, 4); totalLen += itemLen; } BEncEocIfNec (b); itemLen = BEncTBLTypeContentContent (b, (v->content)); itemLen += BEncConsLen (b, itemLen); itemLen += BEncTag1 (b, CNTX, CONS, 3); totalLen += itemLen; if (NOT_NULL ((v->tagList))) { BEncEocIfNec (b); itemLen = BEncTBLTypeSeqOfContent (b, (v->tagList)); itemLen += BEncConsLen (b, itemLen); itemLen += BEncTag1 (b, CNTX, CONS, 2); totalLen += itemLen; } itemLen = BEncAsnBoolContent (b, (&v->optional)); BEncDefLenTo127 (b, itemLen); itemLen++; itemLen += BEncTag1 (b, CNTX, PRIM, 1); totalLen += itemLen; itemLen = BEncTBLTypeIdContent (b, (&v->typeId)); BEncDefLenTo127 (b, itemLen); itemLen++; itemLen += BEncTag1 (b, CNTX, PRIM, 0); totalLen += itemLen; return totalLen; } /* BEncTBLTypeContent */ void BDecTBLTypeContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env), BUF_TYPE b _AND_ AsnTag tagId0 _AND_ AsnLen elmtLen0 _AND_ TBLType *v _AND_ AsnLen *bytesDecoded _AND_ ENV_TYPE env) { int seqDone = FALSE; AsnLen totalElmtsLen1 = 0; AsnLen elmtLen1; AsnTag tagId1; int mandatoryElmtCount1 = 0; AsnLen totalElmtsLen2 = 0; AsnLen elmtLen2; AsnTag tagId2; AsnLen totalElmtsLen3 = 0; AsnLen elmtLen3; AsnTag tagId3; tagId1 = BDecTag (b, &totalElmtsLen1, env); if (((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 0)))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); BDecTBLTypeIdContent (b, tagId1, elmtLen1, (&v->typeId), &totalElmtsLen1, env); tagId1 = BDecTag (b, &totalElmtsLen1, env); } else longjmp (env, -119); if (((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 1)))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); BDecAsnBoolContent (b, tagId1, elmtLen1, (&v->optional), &totalElmtsLen1, env); tagId1 = BDecTag (b, &totalElmtsLen1, env); } else longjmp (env, -120); if (((tagId1 == MAKE_TAG_ID (CNTX, CONS, 2)))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); (v->tagList) = AsnListNew (sizeof (char*)); CheckAsn1Alloc ((v->tagList), env); BDecTBLTypeSeqOfContent (b, tagId1, elmtLen1, (v->tagList), &totalElmtsLen1, env); tagId1 = BDecTag (b, &totalElmtsLen1, env); } if (((tagId1 == MAKE_TAG_ID (CNTX, CONS, 3)))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); (v->content) = (TBLTypeContent*) Asn1Alloc (sizeof (TBLTypeContent)); CheckAsn1Alloc ((v->content), env); tagId2 = BDecTag (b, &totalElmtsLen1, env); elmtLen2 = BDecLen (b, &totalElmtsLen1, env); BDecTBLTypeContentContent (b, tagId2, elmtLen2, (v->content), &totalElmtsLen1, env); if (elmtLen1 == INDEFINITE_LEN) BDecEoc(b, &totalElmtsLen1, env); if (elmtLen1 == INDEFINITE_LEN) BDecEoc (b, &totalElmtsLen1, env); if ((elmtLen0 != INDEFINITE_LEN) && (totalElmtsLen1 == elmtLen0)) seqDone = TRUE; else { tagId1 = BDecTag (b, &totalElmtsLen1, env); if ((elmtLen0 == INDEFINITE_LEN) && (tagId1 == EOC_TAG_ID)) { BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env) seqDone = TRUE; } } } else longjmp (env, -121); if ((!seqDone) && ((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 4)) || (tagId1 == MAKE_TAG_ID (CNTX, CONS, 4)))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); BDecPrintableStringContent (b, tagId1, elmtLen1, (&v->fieldName), &totalElmtsLen1, env); if ((elmtLen0 != INDEFINITE_LEN) && (totalElmtsLen1 == elmtLen0)) seqDone = TRUE; else { tagId1 = BDecTag (b, &totalElmtsLen1, env); if ((elmtLen0 == INDEFINITE_LEN) && (tagId1 == EOC_TAG_ID)) { BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env) seqDone = TRUE; } } } if ((!seqDone) && ((tagId1 == MAKE_TAG_ID (CNTX, CONS, 5)))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); (v->constraint) = (TBLRange*) Asn1Alloc (sizeof (TBLRange)); CheckAsn1Alloc ((v->constraint), env); BDecTBLRangeContent (b, tagId1, elmtLen1, (v->constraint), &totalElmtsLen1, env); if ((elmtLen0 != INDEFINITE_LEN) && (totalElmtsLen1 == elmtLen0)) seqDone = TRUE; else { tagId1 = BDecTag (b, &totalElmtsLen1, env); if ((elmtLen0 == INDEFINITE_LEN) && (tagId1 == EOC_TAG_ID)) { BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env) seqDone = TRUE; } } } if ((!seqDone) && ((tagId1 == MAKE_TAG_ID (CNTX, CONS, 6)))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); (v->values) = AsnListNew (sizeof (char*)); CheckAsn1Alloc ((v->values), env); BDecTBLNamedNumberListContent (b, tagId1, elmtLen1, (v->values), &totalElmtsLen1, env); seqDone = TRUE; if (elmtLen0 == INDEFINITE_LEN) BDecEoc (b, &totalElmtsLen1, env); else if (totalElmtsLen1 != elmtLen0) longjmp (env, -122); } if (!seqDone) longjmp (env, -123); (*bytesDecoded) += totalElmtsLen1; } /* BDecTBLTypeContent */ void PrintTBLType PARAMS ((f, v, indent), FILE* f _AND_ TBLType *v _AND_ unsigned short indent) { if (v == NULL) return; fprintf (f,"{ -- SEQUENCE --\n"); Indent (f, indent + stdIndentG); fprintf (f,"typeId "); PrintTBLTypeId (f, (&v->typeId), indent + stdIndentG); fprintf (f, ",\n"); Indent (f, indent + stdIndentG); fprintf (f,"optional "); PrintAsnBool (f, (&v->optional), indent + stdIndentG); fprintf (f, ",\n"); if (NOT_NULL ((v->tagList))) { Indent (f, indent + stdIndentG); fprintf (f,"tagList "); PrintTBLTypeSeqOf (f, (v->tagList), indent + stdIndentG); fprintf (f, ",\n"); } Indent (f, indent + stdIndentG); fprintf (f,"content "); PrintTBLTypeContent (f, (v->content), indent + stdIndentG); if (ASNOCTS_PRESENT ((&v->fieldName))) { fprintf (f,",\n"); Indent (f, indent + stdIndentG); fprintf (f,"fieldName "); PrintPrintableString (f, (&v->fieldName), indent + stdIndentG); } if (NOT_NULL ((v->constraint))) { fprintf (f,",\n"); Indent (f, indent + stdIndentG); fprintf (f,"constraint "); PrintTBLRange (f, (v->constraint), indent + stdIndentG); } if (NOT_NULL ((v->values))) { fprintf (f,",\n"); Indent (f, indent + stdIndentG); fprintf (f,"values "); PrintTBLNamedNumberList (f, (v->values), indent + stdIndentG); } fprintf (f,"\n"); Indent (f, indent); fprintf (f,"}"); } /* PrintTBLType */ void FreeTBLType PARAMS ((v), TBLType *v) { if (v == NULL) return; FreeTBLTypeId ((&v->typeId)); FreeAsnBool ((&v->optional)); if (NOT_NULL ((v->tagList))) { FreeTBLTypeSeqOf ((v->tagList)); Asn1Free ((v->tagList)); } FreeTBLTypeContent ((v->content)); Asn1Free ((v->content)); if (ASNOCTS_PRESENT ((&v->fieldName))) { FreePrintableString ((&v->fieldName)); } if (NOT_NULL ((v->constraint))) { FreeTBLRange ((v->constraint)); Asn1Free ((v->constraint)); } if (NOT_NULL ((v->values))) { FreeTBLNamedNumberList ((v->values)); Asn1Free ((v->values)); } } /* FreeTBLType */ AsnLen BEncTBLTypeContentContent PARAMS ((b, v), BUF_TYPE b _AND_ TBLTypeContent *v) { AsnLen totalLen = 0; AsnLen itemLen; AsnLen listLen; void *component; switch (v->choiceId) { case TBLTYPECONTENT_PRIMTYPE: itemLen = BEncAsnNullContent (b, (&v->a.primType)); BEncDefLenTo127 (b, itemLen); itemLen++; itemLen += BEncTag1 (b, CNTX, PRIM, 0); totalLen += itemLen; break; case TBLTYPECONTENT_ELMTS: BEncEocIfNec (b); itemLen = BEncTBLTypeContentSeqOfContent (b, (v->a.elmts)); itemLen += BEncConsLen (b, itemLen); itemLen += BEncTag1 (b, CNTX, CONS, 1); totalLen += itemLen; break; case TBLTYPECONTENT_TYPEREF: BEncEocIfNec (b); itemLen = BEncTBLTypeRefContent (b, (v->a.typeRef)); itemLen += BEncConsLen (b, itemLen); itemLen += BEncTag1 (b, CNTX, CONS, 2); totalLen += itemLen; break; } return totalLen; } /* BEncTBLTypeContentContent */ void BDecTBLTypeContentContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env), BUF_TYPE b _AND_ AsnTag tagId0 _AND_ AsnLen elmtLen0 _AND_ TBLTypeContent *v _AND_ AsnLen *bytesDecoded _AND_ ENV_TYPE env) { int seqDone = FALSE; AsnLen totalElmtsLen1 = 0; AsnLen elmtLen1; AsnTag tagId1; int mandatoryElmtCount1 = 0; switch (tagId0) { case MAKE_TAG_ID (CNTX, PRIM, 0): (v->choiceId) = TBLTYPECONTENT_PRIMTYPE; BDecAsnNullContent (b, tagId0, elmtLen0, (&v->a.primType), &totalElmtsLen1, env); break; case MAKE_TAG_ID (CNTX, CONS, 1): (v->choiceId) = TBLTYPECONTENT_ELMTS; (v->a.elmts) = AsnListNew (sizeof (char*)); CheckAsn1Alloc ((v->a.elmts), env); BDecTBLTypeContentSeqOfContent (b, tagId0, elmtLen0, (v->a.elmts), &totalElmtsLen1, env); break; case MAKE_TAG_ID (CNTX, CONS, 2): (v->choiceId) = TBLTYPECONTENT_TYPEREF; (v->a.typeRef) = (TBLTypeRef*) Asn1Alloc (sizeof (TBLTypeRef)); CheckAsn1Alloc ((v->a.typeRef), env); BDecTBLTypeRefContent (b, tagId0, elmtLen0, (v->a.typeRef), &totalElmtsLen1, env); break; default: Asn1Error ("ERROR - unexpected tag in CHOICE\n"); longjmp (env, -124); break; } /* end switch */ (*bytesDecoded) += totalElmtsLen1; } /* BDecTBLTypeContentContent */ void PrintTBLTypeContent PARAMS ((f, v, indent), FILE* f _AND_ TBLTypeContent *v _AND_ unsigned short indent) { switch (v->choiceId) { case TBLTYPECONTENT_PRIMTYPE: fprintf (f,"primType "); PrintAsnNull (f, (&v->a.primType), indent + stdIndentG); break; case TBLTYPECONTENT_ELMTS: fprintf (f,"elmts "); PrintTBLTypeContentSeqOf (f, (v->a.elmts), indent + stdIndentG); break; case TBLTYPECONTENT_TYPEREF: fprintf (f,"typeRef "); PrintTBLTypeRef (f, (v->a.typeRef), indent + stdIndentG); break; } } /* PrintTBLTypeContent */ void FreeTBLTypeContent PARAMS ((v), TBLTypeContent *v) { if (v == NULL) return; switch (v->choiceId) { case TBLTYPECONTENT_ELMTS: FreeTBLTypeContentSeqOf ((v->a.elmts)); Asn1Free ((v->a.elmts)); break; case TBLTYPECONTENT_TYPEREF: FreeTBLTypeRef ((v->a.typeRef)); Asn1Free ((v->a.typeRef)); break; } } /* FreeTBLTypeContent */ AsnLen BEncTBLTypeDefContent PARAMS ((b, v), BUF_TYPE b _AND_ TBLTypeDef *v) { AsnLen totalLen = 0; AsnLen itemLen; AsnLen listLen; void *component; if (NOT_NULL ((v->isPdu))) { itemLen = BEncAsnNullContent (b, (v->isPdu)); BEncDefLenTo127 (b, itemLen); itemLen++; itemLen += BEncTag1 (b, UNIV, PRIM, 5); totalLen += itemLen; } BEncEocIfNec (b); itemLen = BEncTBLTypeContent (b, (v->type)); itemLen += BEncConsLen (b, itemLen); itemLen += BEncTag1 (b, UNIV, CONS, 16); totalLen += itemLen; itemLen = BEncPrintableStringContent (b, (&v->typeName)); itemLen += BEncDefLen (b, itemLen); itemLen += BEncTag1 (b, UNIV, PRIM, 19); totalLen += itemLen; itemLen = BEncTBLTypeDefIdContent (b, (&v->typeDefId)); BEncDefLenTo127 (b, itemLen); itemLen++; itemLen += BEncTag1 (b, UNIV, PRIM, 2); totalLen += itemLen; return totalLen; } /* BEncTBLTypeDefContent */ void BDecTBLTypeDefContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env), BUF_TYPE b _AND_ AsnTag tagId0 _AND_ AsnLen elmtLen0 _AND_ TBLTypeDef *v _AND_ AsnLen *bytesDecoded _AND_ ENV_TYPE env) { int seqDone = FALSE; AsnLen totalElmtsLen1 = 0; AsnLen elmtLen1; AsnTag tagId1; int mandatoryElmtCount1 = 0; tagId1 = BDecTag (b, &totalElmtsLen1, env); if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); BDecTBLTypeDefIdContent (b, tagId1, elmtLen1, (&v->typeDefId), &totalElmtsLen1, env); tagId1 = BDecTag (b, &totalElmtsLen1, env); } else longjmp (env, -125); if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, PRINTABLESTRING_TAG_CODE)) || (tagId1 == MAKE_TAG_ID (UNIV, CONS, PRINTABLESTRING_TAG_CODE)))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); BDecPrintableStringContent (b, tagId1, elmtLen1, (&v->typeName), &totalElmtsLen1, env); tagId1 = BDecTag (b, &totalElmtsLen1, env); } else longjmp (env, -126); if (((tagId1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); (v->type) = (TBLType*) Asn1Alloc (sizeof (TBLType)); CheckAsn1Alloc ((v->type), env); BDecTBLTypeContent (b, tagId1, elmtLen1, (v->type), &totalElmtsLen1, env); if ((elmtLen0 != INDEFINITE_LEN) && (totalElmtsLen1 == elmtLen0)) seqDone = TRUE; else { tagId1 = BDecTag (b, &totalElmtsLen1, env); if ((elmtLen0 == INDEFINITE_LEN) && (tagId1 == EOC_TAG_ID)) { BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env) seqDone = TRUE; } } } else longjmp (env, -127); if ((!seqDone) && ((tagId1 == MAKE_TAG_ID (UNIV, PRIM, NULLTYPE_TAG_CODE)))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); (v->isPdu) = (AsnNull*) Asn1Alloc (sizeof (AsnNull)); CheckAsn1Alloc ((v->isPdu), env); BDecAsnNullContent (b, tagId1, elmtLen1, (v->isPdu), &totalElmtsLen1, env); seqDone = TRUE; if (elmtLen0 == INDEFINITE_LEN) BDecEoc (b, &totalElmtsLen1, env); else if (totalElmtsLen1 != elmtLen0) longjmp (env, -128); } if (!seqDone) longjmp (env, -129); (*bytesDecoded) += totalElmtsLen1; } /* BDecTBLTypeDefContent */ void PrintTBLTypeDef PARAMS ((f, v, indent), FILE* f _AND_ TBLTypeDef *v _AND_ unsigned short indent) { if (v == NULL) return; fprintf (f,"{ -- SEQUENCE --\n"); Indent (f, indent + stdIndentG); fprintf (f,"typeDefId "); PrintTBLTypeDefId (f, (&v->typeDefId), indent + stdIndentG); fprintf (f, ",\n"); Indent (f, indent + stdIndentG); fprintf (f,"typeName "); PrintPrintableString (f, (&v->typeName), indent + stdIndentG); fprintf (f, ",\n"); Indent (f, indent + stdIndentG); fprintf (f,"type "); PrintTBLType (f, (v->type), indent + stdIndentG); if (NOT_NULL ((v->isPdu))) { fprintf (f,",\n"); Indent (f, indent + stdIndentG); fprintf (f,"isPdu "); PrintAsnNull (f, (v->isPdu), indent + stdIndentG); } fprintf (f,"\n"); Indent (f, indent); fprintf (f,"}"); } /* PrintTBLTypeDef */ void FreeTBLTypeDef PARAMS ((v), TBLTypeDef *v) { if (v == NULL) return; FreeTBLTypeDefId ((&v->typeDefId)); FreePrintableString ((&v->typeName)); FreeTBLType ((v->type)); Asn1Free ((v->type)); if (NOT_NULL ((v->isPdu))) { FreeAsnNull ((v->isPdu)); Asn1Free ((v->isPdu)); } } /* FreeTBLTypeDef */ AsnLen BEncTBLModuleSeqOfContent PARAMS ((b, v), BUF_TYPE b _AND_ TBLModuleSeqOf *v) { AsnLen totalLen = 0; AsnLen itemLen; AsnLen listLen; void *component; listLen = 0; FOR_EACH_LIST_ELMT_RVS (component, v) { BEncEocIfNec (b); itemLen = BEncTBLTypeDefContent (b, component); itemLen += BEncConsLen (b, itemLen); itemLen += BEncTag1 (b, UNIV, CONS, 16); listLen += itemLen; } return listLen; } /* BEncTBLModuleSeqOfContent */ void BDecTBLModuleSeqOfContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env), BUF_TYPE b _AND_ AsnTag tagId0 _AND_ AsnLen elmtLen0 _AND_ TBLModuleSeqOf *v _AND_ AsnLen *bytesDecoded _AND_ ENV_TYPE env) { int seqDone = FALSE; AsnLen totalElmtsLen1 = 0; AsnLen elmtLen1; AsnTag tagId1; int mandatoryElmtCount1 = 0; for (totalElmtsLen1 = 0; (totalElmtsLen1 < elmtLen0) || (elmtLen0 == INDEFINITE_LEN);) { TBLTypeDef **tmpVar; tagId1 = BDecTag (b, &totalElmtsLen1, env); if ((tagId1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN)) { BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env) break; /* got EOC so can exit this SET OF/SEQ OF's for loop*/ } if ((tagId1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); tmpVar = (TBLTypeDef**) AsnListAppend (v); (*tmpVar) = (TBLTypeDef*) Asn1Alloc (sizeof (TBLTypeDef)); CheckAsn1Alloc ((*tmpVar), env); BDecTBLTypeDefContent (b, tagId1, elmtLen1, (*tmpVar), &totalElmtsLen1, env); } /* end of tag check if */ else /* wrong tag */ { Asn1Error ("Unexpected Tag\n"); longjmp (env, -130); } } /* end of for */ (*bytesDecoded) += totalElmtsLen1; } /* BDecTBLModuleSeqOfContent */ void PrintTBLModuleSeqOf PARAMS ((f, v, indent), FILE* f _AND_ TBLModuleSeqOf *v _AND_ unsigned short indent) { TBLTypeDef *tmp; if (v == NULL) return; fprintf (f,"{ -- SEQUENCE OF -- \n"); FOR_EACH_LIST_ELMT (tmp, v) { Indent (f, indent+ stdIndentG); PrintTBLTypeDef (f, tmp, indent + stdIndentG); if (tmp != (TBLTypeDef*)LAST_LIST_ELMT (v)) fprintf (f,",\n"); } fprintf (f,"\n"); Indent (f, indent); fprintf (f,"}"); } /* PrintTBLModuleSeqOf */ void FreeTBLModuleSeqOf PARAMS ((v), TBLModuleSeqOf *v) { AsnListNode *l; AsnListNode *tmp; if (v == NULL) return; for (l = FIRST_LIST_NODE (v); l != NULL; ) { FreeTBLTypeDef ((l->data)); tmp = l->next; Asn1Free (l->data); Asn1Free (l); l = tmp; } } /* FreeTBLModuleSeqOf */ AsnLen BEncTBLModuleContent PARAMS ((b, v), BUF_TYPE b _AND_ TBLModule *v) { AsnLen totalLen = 0; AsnLen itemLen; AsnLen listLen; void *component; BEncEocIfNec (b); itemLen = BEncTBLModuleSeqOfContent (b, (v->typeDefs)); itemLen += BEncConsLen (b, itemLen); itemLen += BEncTag1 (b, CNTX, CONS, 3); totalLen += itemLen; itemLen = BEncAsnBoolContent (b, (&v->isUseful)); BEncDefLenTo127 (b, itemLen); itemLen++; itemLen += BEncTag1 (b, CNTX, PRIM, 2); totalLen += itemLen; if (ASNOID_PRESENT ((&v->id))) { itemLen = BEncAsnOidContent (b, (&v->id)); itemLen += BEncDefLen (b, itemLen); itemLen += BEncTag1 (b, CNTX, PRIM, 1); totalLen += itemLen; } itemLen = BEncPrintableStringContent (b, (&v->name)); itemLen += BEncDefLen (b, itemLen); itemLen += BEncTag1 (b, CNTX, PRIM, 0); totalLen += itemLen; return totalLen; } /* BEncTBLModuleContent */ void BDecTBLModuleContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env), BUF_TYPE b _AND_ AsnTag tagId0 _AND_ AsnLen elmtLen0 _AND_ TBLModule *v _AND_ AsnLen *bytesDecoded _AND_ ENV_TYPE env) { int seqDone = FALSE; AsnLen totalElmtsLen1 = 0; AsnLen elmtLen1; AsnTag tagId1; int mandatoryElmtCount1 = 0; tagId1 = BDecTag (b, &totalElmtsLen1, env); if (((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 0)) || (tagId1 == MAKE_TAG_ID (CNTX, CONS, 0)))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); BDecPrintableStringContent (b, tagId1, elmtLen1, (&v->name), &totalElmtsLen1, env); tagId1 = BDecTag (b, &totalElmtsLen1, env); } else longjmp (env, -131); if (((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 1)))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); BDecAsnOidContent (b, tagId1, elmtLen1, (&v->id), &totalElmtsLen1, env); tagId1 = BDecTag (b, &totalElmtsLen1, env); } if (((tagId1 == MAKE_TAG_ID (CNTX, PRIM, 2)))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); BDecAsnBoolContent (b, tagId1, elmtLen1, (&v->isUseful), &totalElmtsLen1, env); tagId1 = BDecTag (b, &totalElmtsLen1, env); } else longjmp (env, -132); if (((tagId1 == MAKE_TAG_ID (CNTX, CONS, 3)))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); (v->typeDefs) = AsnListNew (sizeof (char*)); CheckAsn1Alloc ((v->typeDefs), env); BDecTBLModuleSeqOfContent (b, tagId1, elmtLen1, (v->typeDefs), &totalElmtsLen1, env); seqDone = TRUE; if (elmtLen0 == INDEFINITE_LEN) BDecEoc (b, &totalElmtsLen1, env); else if (totalElmtsLen1 != elmtLen0) longjmp (env, -133); } else longjmp (env, -134); if (!seqDone) longjmp (env, -135); (*bytesDecoded) += totalElmtsLen1; } /* BDecTBLModuleContent */ void PrintTBLModule PARAMS ((f, v, indent), FILE* f _AND_ TBLModule *v _AND_ unsigned short indent) { if (v == NULL) return; fprintf (f,"{ -- SEQUENCE --\n"); Indent (f, indent + stdIndentG); fprintf (f,"name "); PrintPrintableString (f, (&v->name), indent + stdIndentG); fprintf (f, ",\n"); if (ASNOID_PRESENT ((&v->id))) { Indent (f, indent + stdIndentG); fprintf (f,"id "); PrintAsnOid (f, (&v->id), indent + stdIndentG); fprintf (f, ",\n"); } Indent (f, indent + stdIndentG); fprintf (f,"isUseful "); PrintAsnBool (f, (&v->isUseful), indent + stdIndentG); fprintf (f, ",\n"); Indent (f, indent + stdIndentG); fprintf (f,"typeDefs "); PrintTBLModuleSeqOf (f, (v->typeDefs), indent + stdIndentG); fprintf (f,"\n"); Indent (f, indent); fprintf (f,"}"); } /* PrintTBLModule */ void FreeTBLModule PARAMS ((v), TBLModule *v) { if (v == NULL) return; FreePrintableString ((&v->name)); if (ASNOID_PRESENT ((&v->id))) { FreeAsnOid ((&v->id)); } FreeAsnBool ((&v->isUseful)); FreeTBLModuleSeqOf ((v->typeDefs)); Asn1Free ((v->typeDefs)); } /* FreeTBLModule */ AsnLen BEncTBLSeqOfContent PARAMS ((b, v), BUF_TYPE b _AND_ TBLSeqOf *v) { AsnLen totalLen = 0; AsnLen itemLen; AsnLen listLen; void *component; listLen = 0; FOR_EACH_LIST_ELMT_RVS (component, v) { BEncEocIfNec (b); itemLen = BEncTBLModuleContent (b, component); itemLen += BEncConsLen (b, itemLen); itemLen += BEncTag1 (b, UNIV, CONS, 16); listLen += itemLen; } return listLen; } /* BEncTBLSeqOfContent */ void BDecTBLSeqOfContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env), BUF_TYPE b _AND_ AsnTag tagId0 _AND_ AsnLen elmtLen0 _AND_ TBLSeqOf *v _AND_ AsnLen *bytesDecoded _AND_ ENV_TYPE env) { int seqDone = FALSE; AsnLen totalElmtsLen1 = 0; AsnLen elmtLen1; AsnTag tagId1; int mandatoryElmtCount1 = 0; for (totalElmtsLen1 = 0; (totalElmtsLen1 < elmtLen0) || (elmtLen0 == INDEFINITE_LEN);) { TBLModule **tmpVar; tagId1 = BDecTag (b, &totalElmtsLen1, env); if ((tagId1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN)) { BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env) break; /* got EOC so can exit this SET OF/SEQ OF's for loop*/ } if ((tagId1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); tmpVar = (TBLModule**) AsnListAppend (v); (*tmpVar) = (TBLModule*) Asn1Alloc (sizeof (TBLModule)); CheckAsn1Alloc ((*tmpVar), env); BDecTBLModuleContent (b, tagId1, elmtLen1, (*tmpVar), &totalElmtsLen1, env); } /* end of tag check if */ else /* wrong tag */ { Asn1Error ("Unexpected Tag\n"); longjmp (env, -136); } } /* end of for */ (*bytesDecoded) += totalElmtsLen1; } /* BDecTBLSeqOfContent */ void PrintTBLSeqOf PARAMS ((f, v, indent), FILE* f _AND_ TBLSeqOf *v _AND_ unsigned short indent) { TBLModule *tmp; if (v == NULL) return; fprintf (f,"{ -- SEQUENCE OF -- \n"); FOR_EACH_LIST_ELMT (tmp, v) { Indent (f, indent+ stdIndentG); PrintTBLModule (f, tmp, indent + stdIndentG); if (tmp != (TBLModule*)LAST_LIST_ELMT (v)) fprintf (f,",\n"); } fprintf (f,"\n"); Indent (f, indent); fprintf (f,"}"); } /* PrintTBLSeqOf */ void FreeTBLSeqOf PARAMS ((v), TBLSeqOf *v) { AsnListNode *l; AsnListNode *tmp; if (v == NULL) return; for (l = FIRST_LIST_NODE (v); l != NULL; ) { FreeTBLModule ((l->data)); tmp = l->next; Asn1Free (l->data); Asn1Free (l); l = tmp; } } /* FreeTBLSeqOf */ AsnLen BEncTBL PARAMS ((b, v), BUF_TYPE b _AND_ TBL *v) { AsnLen l; BEncEocIfNec (b); l = BEncTBLContent (b, v); l += BEncConsLen (b, l); l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE); return l; } /* BEncTBL */ void BDecTBL PARAMS ((b, result, bytesDecoded, env), BUF_TYPE b _AND_ TBL *result _AND_ AsnLen *bytesDecoded _AND_ ENV_TYPE env) { AsnTag tag; AsnLen elmtLen1; if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))) { Asn1Error ("BDecTBL: ERROR - wrong tag\n"); longjmp (env, -137); } elmtLen1 = BDecLen (b, bytesDecoded, env); BDecTBLContent (b, tag, elmtLen1, result, bytesDecoded, env); } /* BDecTBL */ AsnLen BEncTBLContent PARAMS ((b, v), BUF_TYPE b _AND_ TBL *v) { AsnLen totalLen = 0; AsnLen itemLen; AsnLen listLen; void *component; BEncEocIfNec (b); itemLen = BEncTBLSeqOfContent (b, (v->modules)); itemLen += BEncConsLen (b, itemLen); itemLen += BEncTag1 (b, UNIV, CONS, 16); totalLen += itemLen; itemLen = BEncAsnIntContent (b, (&v->totalLenStrings)); BEncDefLenTo127 (b, itemLen); itemLen++; itemLen += BEncTag1 (b, UNIV, PRIM, 2); totalLen += itemLen; itemLen = BEncAsnIntContent (b, (&v->totalNumStrings)); BEncDefLenTo127 (b, itemLen); itemLen++; itemLen += BEncTag1 (b, UNIV, PRIM, 2); totalLen += itemLen; itemLen = BEncAsnIntContent (b, (&v->totalNumTags)); BEncDefLenTo127 (b, itemLen); itemLen++; itemLen += BEncTag1 (b, UNIV, PRIM, 2); totalLen += itemLen; itemLen = BEncAsnIntContent (b, (&v->totalNumTypes)); BEncDefLenTo127 (b, itemLen); itemLen++; itemLen += BEncTag1 (b, UNIV, PRIM, 2); totalLen += itemLen; itemLen = BEncAsnIntContent (b, (&v->totalNumTypeDefs)); BEncDefLenTo127 (b, itemLen); itemLen++; itemLen += BEncTag1 (b, UNIV, PRIM, 2); totalLen += itemLen; itemLen = BEncAsnIntContent (b, (&v->totalNumModules)); BEncDefLenTo127 (b, itemLen); itemLen++; itemLen += BEncTag1 (b, UNIV, PRIM, 2); totalLen += itemLen; return totalLen; } /* BEncTBLContent */ void BDecTBLContent PARAMS ((b, tagId0, elmtLen0, v, bytesDecoded, env), BUF_TYPE b _AND_ AsnTag tagId0 _AND_ AsnLen elmtLen0 _AND_ TBL *v _AND_ AsnLen *bytesDecoded _AND_ ENV_TYPE env) { int seqDone = FALSE; AsnLen totalElmtsLen1 = 0; AsnLen elmtLen1; AsnTag tagId1; int mandatoryElmtCount1 = 0; tagId1 = BDecTag (b, &totalElmtsLen1, env); if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); BDecAsnIntContent (b, tagId1, elmtLen1, (&v->totalNumModules), &totalElmtsLen1, env); tagId1 = BDecTag (b, &totalElmtsLen1, env); } else longjmp (env, -138); if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); BDecAsnIntContent (b, tagId1, elmtLen1, (&v->totalNumTypeDefs), &totalElmtsLen1, env); tagId1 = BDecTag (b, &totalElmtsLen1, env); } else longjmp (env, -139); if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); BDecAsnIntContent (b, tagId1, elmtLen1, (&v->totalNumTypes), &totalElmtsLen1, env); tagId1 = BDecTag (b, &totalElmtsLen1, env); } else longjmp (env, -140); if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); BDecAsnIntContent (b, tagId1, elmtLen1, (&v->totalNumTags), &totalElmtsLen1, env); tagId1 = BDecTag (b, &totalElmtsLen1, env); } else longjmp (env, -141); if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); BDecAsnIntContent (b, tagId1, elmtLen1, (&v->totalNumStrings), &totalElmtsLen1, env); tagId1 = BDecTag (b, &totalElmtsLen1, env); } else longjmp (env, -142); if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); BDecAsnIntContent (b, tagId1, elmtLen1, (&v->totalLenStrings), &totalElmtsLen1, env); tagId1 = BDecTag (b, &totalElmtsLen1, env); } else longjmp (env, -143); if (((tagId1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))) { elmtLen1 = BDecLen (b, &totalElmtsLen1, env); (v->modules) = AsnListNew (sizeof (char*)); CheckAsn1Alloc ((v->modules), env); BDecTBLSeqOfContent (b, tagId1, elmtLen1, (v->modules), &totalElmtsLen1, env); seqDone = TRUE; if (elmtLen0 == INDEFINITE_LEN) BDecEoc (b, &totalElmtsLen1, env); else if (totalElmtsLen1 != elmtLen0) longjmp (env, -144); } else longjmp (env, -145); if (!seqDone) longjmp (env, -146); (*bytesDecoded) += totalElmtsLen1; } /* BDecTBLContent */ void PrintTBL PARAMS ((f, v, indent), FILE* f _AND_ TBL *v _AND_ unsigned short indent) { if (v == NULL) return; fprintf (f,"{ -- SEQUENCE --\n"); Indent (f, indent + stdIndentG); fprintf (f,"totalNumModules "); PrintAsnInt (f, (&v->totalNumModules), indent + stdIndentG); fprintf (f, ",\n"); Indent (f, indent + stdIndentG); fprintf (f,"totalNumTypeDefs "); PrintAsnInt (f, (&v->totalNumTypeDefs), indent + stdIndentG); fprintf (f, ",\n"); Indent (f, indent + stdIndentG); fprintf (f,"totalNumTypes "); PrintAsnInt (f, (&v->totalNumTypes), indent + stdIndentG); fprintf (f, ",\n"); Indent (f, indent + stdIndentG); fprintf (f,"totalNumTags "); PrintAsnInt (f, (&v->totalNumTags), indent + stdIndentG); fprintf (f, ",\n"); Indent (f, indent + stdIndentG); fprintf (f,"totalNumStrings "); PrintAsnInt (f, (&v->totalNumStrings), indent + stdIndentG); fprintf (f, ",\n"); Indent (f, indent + stdIndentG); fprintf (f,"totalLenStrings "); PrintAsnInt (f, (&v->totalLenStrings), indent + stdIndentG); fprintf (f, ",\n"); Indent (f, indent + stdIndentG); fprintf (f,"modules "); PrintTBLSeqOf (f, (v->modules), indent + stdIndentG); fprintf (f,"\n"); Indent (f, indent); fprintf (f,"}"); } /* PrintTBL */ void FreeTBL PARAMS ((v), TBL *v) { if (v == NULL) return; FreeAsnInt ((&v->totalNumModules)); FreeAsnInt ((&v->totalNumTypeDefs)); FreeAsnInt ((&v->totalNumTypes)); FreeAsnInt ((&v->totalNumTags)); FreeAsnInt ((&v->totalNumStrings)); FreeAsnInt ((&v->totalLenStrings)); FreeTBLSeqOf ((v->modules)); Asn1Free ((v->modules)); } /* FreeTBL */ #endif /* TTBL */ esnacc-ng-1.8.1/c-lib/boot/tbl.h000066400000000000000000000224501302010526100162330ustar00rootroot00000000000000/* * tbl.h * * "TBL" ASN.1 module C type definitions and prototypes * * This .h file was generated by snacc on Mon Jun 2 11:23:56 1997 * * UBC snacc written compiler by Mike Sample * * NOTE: This is a machine generated file--editing not recommended */ #ifndef _tbl_h_ #define _tbl_h_ typedef enum { TBL_BOOLEAN = 0, TBL_INTEGER = 1, TBL_BITSTRING = 2, TBL_OCTETSTRING = 3, TBL_NULL = 4, TBL_OID = 5, TBL_REAL = 6, TBL_ENUMERATED = 7, TBL_SEQUENCE = 8, TBL_SET = 9, TBL_SEQUENCEOF = 10, TBL_SETOF = 11, TBL_CHOICE = 12, TBL_TYPEREF = 13 } TBLTypeId; /* ENUMERATED { TBL_BOOLEAN (0), TBL_INTEGER (1), TBL_BITSTRING (2), TBL_OCTETSTRING (3), TBL_NULL (4), TBL_OID (5), TBL_REAL (6), TBL_ENUMERATED (7), TBL_SEQUENCE (8), TBL_SET (9), TBL_SEQUENCEOF (10), TBL_SETOF (11), TBL_CHOICE (12), TBL_TYPEREF (13) } */ #define BEncTBLTypeIdContent BEncAsnEnumContent #define BDecTBLTypeIdContent BDecAsnEnumContent #define PrintTBLTypeId PrintAsnEnum #define FreeTBLTypeId FreeAsnEnum typedef AsnInt TBLTypeDefId; /* INTEGER */ #define BEncTBLTypeDefIdContent BEncAsnIntContent #define BDecTBLTypeDefIdContent BDecAsnIntContent #define PrintTBLTypeDefId PrintAsnInt #define FreeTBLTypeDefId FreeAsnInt typedef enum { UNIVERSAL = 0, APPLICATION = 1, CONTEXT = 2, PRIVATE = 3 } TBLTagClass; /* ENUMERATED { UNIVERSAL (0), APPLICATION (1), CONTEXT (2), PRIVATE (3) } */ #define BEncTBLTagClassContent BEncAsnEnumContent #define BDecTBLTagClassContent BDecAsnEnumContent #define PrintTBLTagClass PrintAsnEnum #define FreeTBLTagClass FreeAsnEnum typedef struct TBLRange /* SEQUENCE */ { AsnInt from; /* [0] IMPLICIT INTEGER */ AsnInt to; /* [1] IMPLICIT INTEGER */ } TBLRange; AsnLen BEncTBLRangeContent PROTO ((BUF_TYPE b, TBLRange *v)); void BDecTBLRangeContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLRange *v, AsnLen *bytesDecoded, ENV_TYPE env)); void PrintTBLRange PROTO ((FILE* f, TBLRange *v, unsigned short indent)); void FreeTBLRange PROTO ((TBLRange *v)); typedef struct TBLNamedNumber /* SEQUENCE */ { PrintableString name; /* [0] IMPLICIT PrintableString */ AsnInt value; /* [1] IMPLICIT INTEGER */ } TBLNamedNumber; AsnLen BEncTBLNamedNumberContent PROTO ((BUF_TYPE b, TBLNamedNumber *v)); void BDecTBLNamedNumberContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLNamedNumber *v, AsnLen *bytesDecoded, ENV_TYPE env)); void PrintTBLNamedNumber PROTO ((FILE* f, TBLNamedNumber *v, unsigned short indent)); void FreeTBLNamedNumber PROTO ((TBLNamedNumber *v)); typedef AsnList TBLNamedNumberList; /* SEQUENCE OF TBLNamedNumber */ AsnLen BEncTBLNamedNumberListContent PROTO ((BUF_TYPE b, TBLNamedNumberList *v)); void BDecTBLNamedNumberListContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLNamedNumberList *v, AsnLen *bytesDecoded, ENV_TYPE env)); void PrintTBLNamedNumberList PROTO ((FILE* f, TBLNamedNumberList *v, unsigned short indent)); void FreeTBLNamedNumberList PROTO ((TBLNamedNumberList *v)); typedef struct TBLTypeRef /* SEQUENCE */ { TBLTypeDefId typeDef; /* TBLTypeDefId */ AsnBool implicit; /* BOOLEAN */ struct TBLTypeDef *typeDefPtr; /* Added by MS to hold resolved index */ } TBLTypeRef; AsnLen BEncTBLTypeRefContent PROTO ((BUF_TYPE b, TBLTypeRef *v)); void BDecTBLTypeRefContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLTypeRef *v, AsnLen *bytesDecoded, ENV_TYPE env)); void PrintTBLTypeRef PROTO ((FILE* f, TBLTypeRef *v, unsigned short indent)); void FreeTBLTypeRef PROTO ((TBLTypeRef *v)); typedef struct TBLTag /* SEQUENCE */ { TBLTagClass tclass; /* TBLTagClass */ AsnInt code; /* INTEGER (0..MAX) */ BER_FORM form; /* added by MS to simplify enc/dec */ AsnTag encTag; /* added by MS to simplify enc/dec */ } TBLTag; AsnLen BEncTBLTagContent PROTO ((BUF_TYPE b, TBLTag *v)); void BDecTBLTagContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLTag *v, AsnLen *bytesDecoded, ENV_TYPE env)); void PrintTBLTag PROTO ((FILE* f, TBLTag *v, unsigned short indent)); void FreeTBLTag PROTO ((TBLTag *v)); typedef AsnList TBLTypeSeqOf; /* SEQUENCE OF TBLTag */ AsnLen BEncTBLTypeSeqOfContent PROTO ((BUF_TYPE b, TBLTypeSeqOf *v)); void BDecTBLTypeSeqOfContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLTypeSeqOf *v, AsnLen *bytesDecoded, ENV_TYPE env)); void PrintTBLTypeSeqOf PROTO ((FILE* f, TBLTypeSeqOf *v, unsigned short indent)); void FreeTBLTypeSeqOf PROTO ((TBLTypeSeqOf *v)); typedef AsnList TBLTypeContentSeqOf; /* SEQUENCE OF TBLType */ AsnLen BEncTBLTypeContentSeqOfContent PROTO ((BUF_TYPE b, TBLTypeContentSeqOf *v)); void BDecTBLTypeContentSeqOfContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLTypeContentSeqOf *v, AsnLen *bytesDecoded, ENV_TYPE env)); void PrintTBLTypeContentSeqOf PROTO ((FILE* f, TBLTypeContentSeqOf *v, unsigned short indent)); void FreeTBLTypeContentSeqOf PROTO ((TBLTypeContentSeqOf *v)); typedef struct TBLType /* SEQUENCE */ { TBLTypeId typeId; /* [0] IMPLICIT TBLTypeId */ AsnBool optional; /* [1] IMPLICIT BOOLEAN */ TBLTypeSeqOf* tagList; /* [2] IMPLICIT TBLTypeSeqOf OPTIONAL */ struct TBLTypeContent* content; /* [3] TBLTypeContent */ PrintableString fieldName; /* [4] IMPLICIT PrintableString OPTIONAL */ struct TBLRange* constraint; /* [5] IMPLICIT TBLRange OPTIONAL */ TBLNamedNumberList* values; /* [6] IMPLICIT TBLNamedNumberList OPTIONAL */ } TBLType; AsnLen BEncTBLTypeContent PROTO ((BUF_TYPE b, TBLType *v)); void BDecTBLTypeContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLType *v, AsnLen *bytesDecoded, ENV_TYPE env)); void PrintTBLType PROTO ((FILE* f, TBLType *v, unsigned short indent)); void FreeTBLType PROTO ((TBLType *v)); typedef struct TBLTypeContent /* CHOICE */ { enum TBLTypeContentChoiceId { TBLTYPECONTENT_PRIMTYPE, TBLTYPECONTENT_ELMTS, TBLTYPECONTENT_TYPEREF } choiceId; union TBLTypeContentChoiceUnion { AsnNull primType; /* [0] IMPLICIT NULL */ TBLTypeContentSeqOf* elmts; /* [1] IMPLICIT TBLTypeContentSeqOf */ struct TBLTypeRef* typeRef; /* [2] IMPLICIT TBLTypeRef */ } a; } TBLTypeContent; AsnLen BEncTBLTypeContentContent PROTO ((BUF_TYPE b, TBLTypeContent *v)); void BDecTBLTypeContentContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLTypeContent *v, AsnLen *bytesDecoded, ENV_TYPE env)); void PrintTBLTypeContent PROTO ((FILE* f, TBLTypeContent *v, unsigned short indent)); void FreeTBLTypeContent PROTO ((TBLTypeContent *v)); typedef struct TBLTypeDef /* SEQUENCE */ { TBLTypeDefId typeDefId; /* TBLTypeDefId */ PrintableString typeName; /* PrintableString */ struct TBLType* type; /* TBLType */ AsnNull* isPdu; /* NULL OPTIONAL */ } TBLTypeDef; AsnLen BEncTBLTypeDefContent PROTO ((BUF_TYPE b, TBLTypeDef *v)); void BDecTBLTypeDefContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLTypeDef *v, AsnLen *bytesDecoded, ENV_TYPE env)); void PrintTBLTypeDef PROTO ((FILE* f, TBLTypeDef *v, unsigned short indent)); void FreeTBLTypeDef PROTO ((TBLTypeDef *v)); typedef AsnList TBLModuleSeqOf; /* SEQUENCE OF TBLTypeDef */ AsnLen BEncTBLModuleSeqOfContent PROTO ((BUF_TYPE b, TBLModuleSeqOf *v)); void BDecTBLModuleSeqOfContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLModuleSeqOf *v, AsnLen *bytesDecoded, ENV_TYPE env)); void PrintTBLModuleSeqOf PROTO ((FILE* f, TBLModuleSeqOf *v, unsigned short indent)); void FreeTBLModuleSeqOf PROTO ((TBLModuleSeqOf *v)); typedef struct TBLModule /* SEQUENCE */ { PrintableString name; /* [0] IMPLICIT PrintableString */ AsnOid id; /* [1] IMPLICIT OBJECT IDENTIFIER OPTIONAL */ AsnBool isUseful; /* [2] IMPLICIT BOOLEAN */ TBLModuleSeqOf* typeDefs; /* [3] IMPLICIT TBLModuleSeqOf */ } TBLModule; AsnLen BEncTBLModuleContent PROTO ((BUF_TYPE b, TBLModule *v)); void BDecTBLModuleContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLModule *v, AsnLen *bytesDecoded, ENV_TYPE env)); void PrintTBLModule PROTO ((FILE* f, TBLModule *v, unsigned short indent)); void FreeTBLModule PROTO ((TBLModule *v)); typedef AsnList TBLSeqOf; /* SEQUENCE OF TBLModule */ AsnLen BEncTBLSeqOfContent PROTO ((BUF_TYPE b, TBLSeqOf *v)); void BDecTBLSeqOfContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBLSeqOf *v, AsnLen *bytesDecoded, ENV_TYPE env)); void PrintTBLSeqOf PROTO ((FILE* f, TBLSeqOf *v, unsigned short indent)); void FreeTBLSeqOf PROTO ((TBLSeqOf *v)); typedef struct TBL /* SEQUENCE */ { AsnInt totalNumModules; /* INTEGER */ AsnInt totalNumTypeDefs; /* INTEGER */ AsnInt totalNumTypes; /* INTEGER */ AsnInt totalNumTags; /* INTEGER */ AsnInt totalNumStrings; /* INTEGER */ AsnInt totalLenStrings; /* INTEGER */ TBLSeqOf* modules; /* TBLSeqOf */ } TBL; AsnLen BEncTBL PROTO ((BUF_TYPE b, TBL *v)); void BDecTBL PROTO ((BUF_TYPE b, TBL *result, AsnLen *bytesDecoded, ENV_TYPE env)); AsnLen BEncTBLContent PROTO ((BUF_TYPE b, TBL *v)); void BDecTBLContent PROTO ((BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, TBL *v, AsnLen *bytesDecoded, ENV_TYPE env)); void PrintTBL PROTO ((FILE* f, TBL *v, unsigned short indent)); void FreeTBL PROTO ((TBL *v)); #endif /* conditional include of tbl.h */ esnacc-ng-1.8.1/c-lib/inc/000077500000000000000000000000001302010526100151045ustar00rootroot00000000000000esnacc-ng-1.8.1/c-lib/inc/asn-BMPString.h000066400000000000000000000012751302010526100176460ustar00rootroot00000000000000#ifndef _asn_BMPString_h_ #define _asn_BMPString_h_ #ifdef __cplusplus extern "C" { #endif typedef AsnOcts BMPString; /* [UNIVERSAL 30] IMPLICIT OCTET STRING */ AsnLen BEncBMPString PROTO ((GenBuf *b, BMPString *v)); AsnLen BEncBMPStringContent PROTO ((GenBuf *b, BMPString *octs)); void BDecBMPString PROTO ((GenBuf *b, BMPString *result, AsnLen *bytesDecoded, ENV_TYPE env)); void BDecBMPStringContent PROTO ((GenBuf *b, AsnTag tagId, AsnLen len, BMPString *result, AsnLen *bytesDecoded, ENV_TYPE env)); #define PrintBMPString PrintAsnOcts #define FreeBMPString FreeAsnOcts int CvtBMPString2wchar(BMPString *inOcts, wchar_t **outStr); #ifdef __cplusplus } #endif /* extern 'C' */ #endif esnacc-ng-1.8.1/c-lib/inc/asn-IA5String.h000066400000000000000000000012001302010526100175720ustar00rootroot00000000000000#ifndef _asn_IA5String_h_ #define _asn_IA5String_h_ #ifdef __cplusplus extern "C" { #endif typedef AsnOcts IA5String; /* [UNIVERSAL 22] IMPLICIT OCTET STRING */ AsnLen BEncIA5String PROTO ((GenBuf *b, IA5String *v)); AsnLen BEncIA5StringContent PROTO ((GenBuf *b, IA5String *octs)); void BDecIA5String PROTO ((GenBuf *b, IA5String *result, AsnLen *bytesDecoded, ENV_TYPE env)); void BDecIA5StringContent PROTO ((GenBuf *b, AsnTag tagId, AsnLen len, IA5String *result, AsnLen *bytesDecoded, ENV_TYPE env)); #define PrintIA5String PrintAsnOcts #define FreeIA5String FreeAsnOcts #ifdef __cplusplus } #endif /* __cplusplus */ #endif esnacc-ng-1.8.1/c-lib/inc/asn-NumericString.h000066400000000000000000000012621302010526100206260ustar00rootroot00000000000000#ifndef _asn_NumericString_h_ #define _asn_NumericString_h_ #ifdef __cplusplus extern "C" { #endif typedef AsnOcts NumericString; /* [UNIVERSAL 18] IMPLICIT OCTET STRING */ AsnLen BEncNumericString PROTO ((GenBuf *b, NumericString *v)); AsnLen BEncNumericStringContent PROTO ((GenBuf *b, NumericString *octs)); void BDecNumericString PROTO ((GenBuf *b, NumericString *result, AsnLen *bytesDecoded, ENV_TYPE env)); void BDecNumericStringContent PROTO ((GenBuf *b, AsnTag tagId, AsnLen len, NumericString *result, AsnLen *bytesDecoded, ENV_TYPE env)); #define PrintNumericString PrintAsnOcts #define FreeNumericString FreeAsnOcts #ifdef __cplusplus } #endif /* __cplusplus */ #endif esnacc-ng-1.8.1/c-lib/inc/asn-PrintableStr.h000066400000000000000000000013151302010526100204450ustar00rootroot00000000000000#ifndef _asn_PrintableString_h_ #define _asn_PrintableString_h_ #ifdef __cplusplus extern "C" { #endif typedef AsnOcts PrintableString; /* [UNIVERSAL 19] IMPLICIT OCTET STRING */ AsnLen BEncPrintableString PROTO ((GenBuf *b, PrintableString *v)); AsnLen BEncPrintableStringContent PROTO ((GenBuf *b, PrintableString *octs)); void BDecPrintableString PROTO ((GenBuf *b, PrintableString *result, AsnLen *bytesDecoded, ENV_TYPE env)); void BDecPrintableStringContent PROTO ((GenBuf *b, AsnTag tagId, AsnLen len, PrintableString *result, AsnLen *bytesDecoded, ENV_TYPE env)); #define PrintPrintableString PrintAsnOcts #define FreePrintableString FreeAsnOcts #ifdef __cplusplus } #endif /* __cplusplus */ #endif esnacc-ng-1.8.1/c-lib/inc/asn-TeletexString.h000066400000000000000000000012271302010526100206370ustar00rootroot00000000000000#ifndef _asn_TeletexString_h_ #define _asn_TeletexString_h_ #ifdef __cplusplus extern "C" { #endif typedef AsnOcts TeletexString; /* [UNIVERSAL 20] IMPLICIT OCTET STRING */ AsnLen BEncTeletexString PROTO ((GenBuf *b, TeletexString *v)); void BDecTeletexString PROTO ((GenBuf *b, TeletexString *result, AsnLen *bytesDecoded, ENV_TYPE env)); AsnLen BEncTeletexStringContent PROTO ((GenBuf *b, AsnOcts *octs)); void BDecTeletexStringContent PROTO ((GenBuf *b, AsnTag tagId, AsnLen len, AsnOcts *result, AsnLen *bytesDecoded, ENV_TYPE env)); #define PrintTeletexString PrintAsnOcts #define FreeTeletexString FreeAsnOcts #ifdef __cplusplus } #endif #endif esnacc-ng-1.8.1/c-lib/inc/asn-UTF8String.h000066400000000000000000000014431302010526100177530ustar00rootroot00000000000000#ifndef _asn_UTF8String_h_ #define _asn_UTF8String_h_ #ifdef __cplusplus extern "C" { #endif typedef AsnOcts UTF8String; /* [UNIVERSAL 12] IMPLICIT OCTET STRING */ AsnLen BEncUTF8String PROTO ((GenBuf *b, UTF8String *v)); AsnLen BEncUTF8StringContent PROTO ((GenBuf *b, UTF8String *octs)); void BDecUTF8String PROTO ((GenBuf *b, UTF8String *result, AsnLen *bytesDecoded, ENV_TYPE env)); void BDecUTF8StringContent PROTO ((GenBuf *b, AsnTag tagId, AsnLen len, UTF8String *result, AsnLen *bytesDecoded, ENV_TYPE env)); #define PrintUTF8String PrintAsnOcts #define FreeUTF8String FreeAsnOcts int CvtUTF8String2wchar(UTF8String *inOcts, wchar_t **outStr); int CvtUTF8towchar(char *utf8Str, wchar_t **outStr); int CvtWchar2UTF8(wchar_t *inStr, char **utf8Str); #ifdef __cplusplus } #endif #endif esnacc-ng-1.8.1/c-lib/inc/asn-UniversalString.h000066400000000000000000000014061302010526100211740ustar00rootroot00000000000000#ifndef _asn_UniversalString_h_ #define _asn_UniversalString_h_ #ifdef __cplusplus extern "C" { #endif typedef AsnOcts UniversalString; /* [UNIVERSAL 28] IMPLICIT OCTET STRING */ AsnLen BEncUniversalString PROTO ((GenBuf *b, UniversalString *v)); AsnLen BEncUniversalStringContent PROTO ((GenBuf *b, UniversalString *octs)); void BDecUniversalString PROTO ((GenBuf *b, UniversalString *result, AsnLen *bytesDecoded, ENV_TYPE env)); void BDecUniversalStringContent PROTO ((GenBuf *b, AsnTag tagId, AsnLen len, UniversalString *result, AsnLen *bytesDecoded, ENV_TYPE env)); #define PrintUniversalString PrintAsnOcts #define FreeUniversalString FreeAsnOcts int CvtUniversalString2wchar(UniversalString *inOcts, wchar_t **outStr); #ifdef __cplusplus } #endif #endif esnacc-ng-1.8.1/c-lib/inc/asn-VisibleString.h000066400000000000000000000012651302010526100206240ustar00rootroot00000000000000#ifndef _asn_VisibleString_h_ #define _asn_VisibleString_h_ #ifdef __cplusplus extern "C" { #endif typedef AsnOcts VisibleString; /* [UNIVERSAL 26] IMPLICIT OCTET STRING */ AsnLen BEncVisibleString PROTO ((GenBuf *b, VisibleString *v)); AsnLen BEncVisibleStringContent PROTO ((GenBuf *b, VisibleString *octs)); void BDecVisibleString PROTO ((GenBuf *b, VisibleString *result, AsnLen *bytesDecoded, ENV_TYPE env)); void BDecVisibleStringContent PROTO ((GenBuf *b, AsnTag tagId, AsnLen len, VisibleString *result, AsnLen *bytesDecoded, ENV_TYPE env)); #define PrintVisibleString PrintAsnOcts #define FreeVisibleString FreeAsnOcts #ifdef __cplusplus } #endif /* __cplusplus */ #endif esnacc-ng-1.8.1/c-lib/inc/asn-any.h000066400000000000000000000072221302010526100166260ustar00rootroot00000000000000/* * asn_any.h * * MS 92 * Copyright (C) 1992 Michael Sample and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/inc/asn-any.h,v 1.8 2004/01/22 20:02:58 nicholar Exp $ */ #ifndef _asn_any_h_ #define _asn_any_h_ #include "hash.h" #ifdef __cplusplus extern "C" { #endif /* * 1 hash table for integer keys * 1 hash table for oid keys */ extern Table *anyOidHashTblG; extern Table *anyIntHashTblG; typedef AsnLen (*EncodeFcn) PROTO ((GenBuf *b, void *value)); typedef void (*DecodeFcn) PROTO ((GenBuf *b, void *value, AsnLen *bytesDecoded, ENV_TYPE env)); typedef void (*FreeFcn) PROTO ((void *v)); typedef void (*PrintFcn) PROTO ((FILE *f, void *v, unsigned int indent)); /* * this is put into the hash table with the * int or oid as the key */ typedef struct AnyInfo { int anyId; /* will be a value from the AnyId enum */ AsnOid oid; /* will be zero len/null if intId is valid */ AsnInt intId; unsigned int size; /* size of the C data type (ie as ret'd by sizeof) */ EncodeFcn Encode; DecodeFcn Decode; FreeFcn Free; PrintFcn Print; } AnyInfo; typedef struct AsnAny { AnyInfo *ai; /* point to entry in hash tbl that has routine ptrs */ void *value; /* points to the value */ } AsnAny; #define ASN_ANY_PRESENT(any) ((any)->value) /* * Returns anyId value for the given ANY type. * Use this to determine to the type of an ANY after decoding * it. Returns -1 if the ANY info is not available */ #define GetAsnAnyId( a) (((a)->ai)? (a)->ai->anyId: -1) /* * This ID is used for those any by oid types for which * we have to use our unknown any handlers to decode/encode. * The data pointed at by the value field will basically * be the ASN.1 encoded value contained in an octs type * structure. * * NOTE: we don't use -1 here since that is used for the * GetAsnAnyId() macro. * */ #define kUnknownAnyObjectID -7 /* * used before encoding or decoding a type so the proper * encode or decode routine is used. */ void SetAnyTypeByInt PROTO ((AsnAny *v, AsnInt id)); void SetAnyTypeByOid PROTO ((AsnAny *v, AsnOid *id)); void SetAnyTypeUnknown PROTO ((AsnAny *v)); /* * used to initialize the hash table (s) */ void InstallAnyByInt PROTO ((int anyId, AsnInt intId, unsigned int size, EncodeFcn encode, DecodeFcn decode, FreeFcn free, PrintFcn print)); void InstallAnyByOid PROTO ((int anyId, AsnOid *oid, unsigned int size, EncodeFcn encode, DecodeFcn decode, FreeFcn free, PrintFcn print)); /* * Standard enc, dec, free, & print routines * for the AsnAny type. * These call the routines referenced from the * given value's hash table entry. */ void FreeAsnAny PROTO ((AsnAny *v)); AsnLen BEncAsnAny PROTO ((GenBuf *b, AsnAny *v)); void BDecAsnAny PROTO ((GenBuf *b, AsnAny *result, AsnLen *bytesDecoded, ENV_TYPE env)); #define DEncAsnAny BEncAsnAny #define DDecAsnAny BDecAsnAny void PrintAsnAny PROTO ((FILE *f, AsnAny *v, unsigned int indent)); /* AnyDefinedBy is currently the same as AsnAny */ typedef AsnAny AsnAnyDefinedBy; #define FreeAsnAnyDefinedBy FreeAsnAny #define BEncAsnAnyDefinedBy BEncAsnAny #define BDecAsnAnyDefinedBy BDecAsnAny #define PrintAsnAnyDefinedBy PrintAsnAny #ifdef __cplusplus } /* extern 'C' */ #endif /* extern 'C' */ #endif /* conditional include */ esnacc-ng-1.8.1/c-lib/inc/asn-bits.h000066400000000000000000000040071302010526100167760ustar00rootroot00000000000000/* * asn_bits.h * * MS 92 * Copyright (C) 1992 Michael Sample and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/inc/asn-bits.h,v 1.9 2004/01/22 20:02:58 nicholar Exp $ */ #ifndef _asn_bits_h_ #define _asn_bits_h_ #ifdef __cplusplus extern "C" { #endif typedef struct AsnBits { int bitLen; char *bits; } AsnBits; extern const char numToHexCharTblG[]; /* * BER encode/decode routines */ AsnLen BEncAsnBits PROTO ((GenBuf *b, AsnBits *data)); void BDecAsnBits PROTO ((GenBuf *b, AsnBits *result, AsnLen *bytesDecoded, ENV_TYPE env)); AsnLen BEncAsnBitsContent PROTO ((GenBuf *b, AsnBits *bits)); void BDecAsnBitsContent PROTO ((GenBuf *b, AsnTag tagId, AsnLen len, AsnBits *result, AsnLen *bytesDecoded, ENV_TYPE env)); /* * DER encode/decode routines * * Same as BER except that the bits are zero padded (however BEncxx does this) */ #define DEncAsnBits BEncAsnBits #define DDecAsnBits BDecAsnBits #define DEncAsnBitsContent BEncAsnBitsContent #define DDecAsnBitsContent BDecAsnBitsContent /* Print and Free routines */ void FreeAsnBits PROTO ((AsnBits *v)); void PrintAsnBits PROTO ((FILE *f, AsnBits *b, unsigned int indent)); /* Utility routines */ #define TO_HEX( fourBits) (numToHexCharTblG[(fourBits) & 0x0f]) #define ASNBITS_PRESENT( abits) ((abits)->bits != NULL) int AsnBitsEquiv PROTO ((AsnBits *b1, AsnBits *b2)); void SetAsnBit PROTO ((AsnBits *b1, size_t bit)); void ClrAsnBit PROTO ((AsnBits *b1, size_t bit)); int GetAsnBit PROTO ((AsnBits *b1, size_t bit)); #ifdef __cplusplus } #endif /* extern 'C' */ #endif /* conditional include */ esnacc-ng-1.8.1/c-lib/inc/asn-bool.h000066400000000000000000000024141302010526100167700ustar00rootroot00000000000000/* * asn_bool.h * * MS 92 * Copyright (C) 1992 Michael Sample and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/inc/asn-bool.h,v 1.9 2004/04/21 13:26:24 gronej Exp $ */ #ifndef _asn_bool_h_ #define _asn_bool_h_ #ifdef __cplusplus extern "C" { #endif typedef unsigned char AsnBool; AsnLen BEncAsnBool PROTO ((GenBuf *b, AsnBool *data)); void BDecAsnBool PROTO ((GenBuf *b, AsnBool *result, AsnLen *bytesDecoded, ENV_TYPE env)); AsnLen BEncAsnBoolContent PROTO ((GenBuf *b, AsnBool *data)); void BDecAsnBoolContent PROTO ((GenBuf *b, AsnTag tag, AsnLen len, AsnBool *result, AsnLen *bytesDecoded, ENV_TYPE env)); /* do nothing */ void FreeAsnBool PROTO ((AsnBool *b)); #define FreeAsnBool( v) void PrintAsnBool PROTO ((FILE *f, AsnBool *b, unsigned int indent)); #ifdef __cplusplus } #endif /* extern 'C' */ #endif esnacc-ng-1.8.1/c-lib/inc/asn-config.h000066400000000000000000000147651302010526100173160ustar00rootroot00000000000000/* * asn_config.h - configures the ANSI/non ansi, defines * decoder alloc routines and buffer routines * * MS 91 * Copyright (C) 1992 Michael Sample and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/inc/asn-config.h,v 1.15 2003/12/17 19:05:03 gronej Exp $ * $Log: asn-config.h,v $ * Revision 1.15 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.14.2.1 2003/11/05 14:58:55 gronej * working PER code merged with esnacc_1_6 * * Revision 1.14 2003/02/20 21:07:59 leonberp * added #ifdef __cplusplus extern "C" to headers * * Revision 1.13 2002/11/01 15:35:37 mcphersc * Modified to fix SetWriteError * * Revision 1.12 2002/10/23 10:23:51 mcphersc * Changed BUF_TYPE to AsnBuf * * Revision 1.11 2002/10/22 15:49:42 mcphersc * Mods for gen-buf usage * * Revision 1.10 2002/10/15 17:32:41 mcphersc * ExpBuf and GenBuf chagnes * * Revision 1.9 2002/10/01 14:02:39 mcphersc * ASN "C" Buf modifications * * Revision 1.8 2002/08/30 19:11:34 vracarl * got rid of c++ comments * * Revision 1.7 2002/07/25 10:52:05 sfl * Added ifdef's around pragma statement to avoid warnings on unix boxes * * Revision 1.5 2002/01/16 17:25:40 vracarl * added more defs * * Revision 1.4 2001/07/12 19:34:01 leonberp * Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. * * Revision 1.3 2001/03/05 19:36:21 nicholar * no message * * Revision 1.2 2000/10/24 14:54:41 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:35:54 leonberp * First CVS Version of SNACC. * * Revision 1.6 1997/03/13 09:15:16 wan * Improved dependency generation for stupid makedepends. * Corrected PeekTag to peek into buffer only as far as necessary. * Added installable error handler. * Fixed small glitch in idl-code generator (Markku Savela ). * * Revision 1.5 1995/07/24 21:01:11 rj * changed `_' to `-' in file names. * * Revision 1.4 1995/02/13 14:47:33 rj * settings for IEEE_REAL_FMT/IEEE_REAL_LIB moved from {c_lib,c++_lib}/inc/asn_config.h to acconfig.h. * * Revision 1.3 1994/10/08 04:46:20 rj * config.h -> snacc.h, which now is the toplevel config file. * * Revision 1.2 1994/08/31 23:53:05 rj * redundant code moved into ../../config.h.bot * * Revision 1.1 1994/08/28 09:21:25 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #ifndef _asn_config_h_ #define _asn_config_h_ #include #include /* for jmp_buf type, setjmp and longjmp */ #include #include #include #define ENV_TYPE jmp_buf /* for pow() used in asn_real.c - must include to avoid casting err on pow */ /* #include */ #include "snacc.h" /* used to test if optionals are present */ #define NOT_NULL( ptr) ((ptr) != NULL) #ifdef __cplusplus extern "C" { #endif /* * Asn1Error (char *str) - configure error handler */ void Asn1Error PROTO ((char* str)); /* * Asn1Warning (char *str) - configure warning mechanism * (currently never called) */ void Asn1Warning PROTO ((char* str)); /* * Asn1ErrorHandler - procedure to call upon Asn1Warning (severity 0) * and Asn1Error (severity 1). */ typedef void (*Asn1ErrorHandler) PROTO ((char* str, int severity)); /* * Asn1InstallErrorHandler - installs new error handler, returns former one */ Asn1ErrorHandler Asn1InstallErrorHandler PROTO ((Asn1ErrorHandler handler)); /* * configure memory scheme used by decoder to allocate memory * for the decoded value. * The Asn1Free will be called in the optionally generated * hierachical free routines. * * nibble_alloc allocs from a single buffer and EVERYTHING * is freed by a single fcn call. Individual elmts cannot be freed */ #ifdef __cplusplus } #endif /* __cplusplus */ #ifdef USE_NIBBLE_MEMORY #include "nibble-alloc.h" #define Asn1Alloc( size) NibbleAlloc (size) #define Asn1Free( ptr) /* empty */ #define CheckAsn1Alloc( ptr, env) \ if ((ptr) == NULL)\ longjmp (env, -27) #else /* !USE_NIBBLE_MEMORY */ #include "mem.h" #define Asn1Alloc( size) Malloc (size) #define Asn1Free( ptr) Free (ptr) #define CheckAsn1Alloc( ptr, env) \ if ((ptr) == NULL)\ longjmp (env, -27) #endif /* USE_NIBBLE_MEMORY */ /* * NOTE: for use with tables, I defined the (slower) * GenBuf type that is more flexible (à la ISODE and XDR). * This allows the encode/decode libs to support other * buffer types dynamically instead of having different * libs for each buffer type. * The GenBufs are not provided for the compiled code * (ie the c_lib directory) but could easily be added * (I don't have time, tho). Tables tools are * around 4x slower than the compiled version so a * the GenBufs aren't such a big performance hit for table stuff. * */ #include "gen-buf.h" //#define BUF_TYPE GenBuf * #define BufGetByte( b) GenBufGetByte (b) #define BufGetSeg( b, lenPtr) GenBufGetSeg (b, lenPtr) #define BufCopy( dst, b, len) GenBufCopy (dst, b, len) #define BufSkip( b, len) GenBufSkip (b, len) #define BufPeekByte( b) GenBufPeekByte (b) #define BufPeekSeg( b, lenPtr) GenBufPeekSeg (b, lenPtr) #define BufPeekCopy( dst, b, len) GenBufPeekCopy (dst, b, len) #define BufPutByteRvs( b, byte) GenBufPutByteRvs (b, byte) #define BufPutSegRvs( b, data, len) GenBufPutSegRvs (b, data, len) #define BufReadError( b) GenBufReadError (b) #define BufWriteError( b) GenBufWriteError (b) #define BufFreeBufAndData( b) GenBufFreeBufAndData(*(b)) #define BufResetInWriteRvsMode( b) GenBufResetInWriteRvsMode(*(b)) #define BufResetInReadMode( b) GenBufResetInReadMode((b)) #define BufSetWriteError(b, value) GenBufSetWriteError(b, value) #include "print.h" /* for printing set up */ #ifdef WIN32 #pragma warning( disable : 4127 ) /* IGNORE constant conditional expression. */ #endif #endif /* conditional include */ esnacc-ng-1.8.1/c-lib/inc/asn-der.h000066400000000000000000000033441302010526100166120ustar00rootroot00000000000000/* * asn-der.h * * Dean Povey 97/08 * Copyright (C) 1997 Dean Povey and the Distributed Systems Technology Centre * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/inc/asn-der.h,v 1.6 2003/12/17 19:05:03 gronej Exp $ * $Log: asn-der.h,v $ * Revision 1.6 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.5.2.1 2003/11/05 14:58:55 gronej * working PER code merged with esnacc_1_6 * * Revision 1.5 2003/02/20 21:07:59 leonberp * added #ifdef __cplusplus extern "C" to headers * * Revision 1.4 2002/10/18 13:10:32 mcphersc * took out long int to unsigned long * * Revision 1.3 2002/10/15 17:37:34 mcphersc * no message * * Revision 1.2 2001/07/12 19:34:01 leonberp * Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. * * Revision 1.1.1.1 2000/08/21 20:35:54 leonberp * First CVS Version of SNACC. * * Revision 1.1 1997/08/28 07:25:50 povey * Changes to support DER encoding/decoding * * */ #ifndef _asn_der_h #define _asn_der_h #include "exp-buf.h" #include "gen-buf.h" #ifdef __cplusplus extern "C" { #endif typedef struct EncodedElmt { GenBuf *b; unsigned long len; } EncodedElmt; int EncodedElmtCmp PROTO((const void* a1, const void* b)); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* _asn_der_h */ esnacc-ng-1.8.1/c-lib/inc/asn-enum.h000066400000000000000000000044301302010526100170010ustar00rootroot00000000000000/* * asn_enum.h * * MS 92 * Copyright (C) 1992 Michael Sample and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/inc/asn-enum.h,v 1.5 2003/12/17 19:05:03 gronej Exp $ * $Log: asn-enum.h,v $ * Revision 1.5 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.4.2.1 2003/11/05 14:58:55 gronej * working PER code merged with esnacc_1_6 * * Revision 1.4 2003/02/20 21:07:59 leonberp * added #ifdef __cplusplus extern "C" to headers * * Revision 1.3 2002/10/23 10:23:51 mcphersc * Changed BUF_TYPE to AsnBuf * * Revision 1.2 2001/07/12 19:34:01 leonberp * Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. * * Revision 1.1.1.1 2000/08/21 20:35:54 leonberp * First CVS Version of SNACC. * * Revision 1.2 1995/07/24 21:01:12 rj * changed `_' to `-' in file names. * * Revision 1.1 1994/08/28 09:21:26 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #ifndef _asn_enum_h_ #define _asn_enum_h_ #ifdef __cplusplus extern "C" { #endif typedef AsnInt AsnEnum; /* * ENUMERATED have a UNIVERSAL tag that is diff from INTEGERS * so need diff encoding routine tho content stuff is the same */ AsnLen BEncAsnEnum PROTO ((GenBuf *b, AsnEnum *data)); void BDecAsnEnum PROTO ((GenBuf *b, AsnEnum *result, AsnLen *bytesDecoded, ENV_TYPE env)); /* DAD - modified the two defines here so that enum Ptr's can * be resolved to the same size dest as what AsnInt gets * defined to be. */ #define BEncAsnEnumContent(a,b) BEncAsnIntContent((a),((AsnInt *) (b))) #define BDecAsnEnumContent(a,b,c,d,e,f) BDecAsnIntContent((a),(b),(c),((AsnInt*)(d)),(e),(f)) #define FreeAsnEnum FreeAsnInt #define PrintAsnEnum PrintAsnInt #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* conditional include */ esnacc-ng-1.8.1/c-lib/inc/asn-incl.h000066400000000000000000000072751302010526100167740ustar00rootroot00000000000000/* * asn_incl.h * includes hdr files nec for a user prg that calls the generated * encoding/decoding routines. * * Copyright (C) 1992 Michael Sample and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/inc/asn-incl.h,v 1.17 2004/03/09 16:38:43 gronej Exp $ * $Log: asn-incl.h,v $ * Revision 1.17 2004/03/09 16:38:43 gronej * Updated check for visible string, and created it's own .c and .h files, * commented out for now but did not remove old visible string code * * Revision 1.16 2004/01/16 15:23:31 gronej * Updated Compiler to accept and process relative-oid's * * Revision 1.15 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.14.2.1 2003/11/05 14:58:55 gronej * working PER code merged with esnacc_1_6 * * Revision 1.14 2003/02/20 21:07:59 leonberp * added #ifdef __cplusplus extern "C" to headers * * Revision 1.13 2002/11/01 15:36:11 mcphersc * Fixed SetWriteError * * Revision 1.12 2002/10/23 13:33:47 mcphersc * Redo include references placement * * Revision 1.11 2002/10/22 15:49:36 mcphersc * Mods for gen-buf usage * * Revision 1.10 2002/10/22 14:40:11 mcphersc * added exp-buf include reference * * Revision 1.9 2002/10/18 13:10:32 mcphersc * took out long int to unsigned long * * Revision 1.8 2002/10/01 14:11:39 mcphersc * ASN "C" Buf modifications * * Revision 1.7 2002/05/10 16:39:37 leonberp * latest changes for release 2.2 * includes integrating asn-useful into C & C++ runtime library, the compiler changes that go along with that, SnaccException changes for C++ runtime and compiler * * Revision 1.6 2002/02/13 18:04:11 sfl * Added EOL to avoid Linux compile warning. * * Revision 1.5 2002/01/16 17:26:24 vracarl * added new file - snaccCder.h and define for MAX_BUF * * Revision 1.4 2001/07/12 19:34:01 leonberp * Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. * * Revision 1.3 2001/03/05 19:36:21 nicholar * no message * * Revision 1.2 2000/10/24 14:54:41 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:35:54 leonberp * First CVS Version of SNACC. * * Revision 1.2 1995/07/24 21:01:13 rj * changed `_' to `-' in file names. * * Revision 1.1 1994/08/28 09:21:27 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include "asn-config.h" #include "gen-buf.h" /* #include "exp-buf.h" #include "sbuf.h" */ #include "asn-len.h" #include "asn-tag.h" #include "asn-bool.h" #include "asn-int.h" #include "asn-enum.h" #include "asn-real.h" #include "asn-octs.h" #include "asn-bits.h" #include "asn-oid.h" #include "asn-relative-oid.h" #include "asn-null.h" #include "asn-any.h" #include "asn-list.h" #include "asn-der.h" #include "asn-PrintableStr.h" #include "asn-UniversalString.h" #include "asn-BMPString.h" #include "asn-UTF8String.h" #include "asn-VisibleString.h" #include "asn-IA5String.h" #include "asn-NumericString.h" #include "asn-TeletexString.h" #include "snaccCder.h" #include "print.h" #define MAX_BUF 4096 esnacc-ng-1.8.1/c-lib/inc/asn-int.h000066400000000000000000000033621302010526100166320ustar00rootroot00000000000000/* * asn_int.h * * MS 92 * Copyright (C) 1992 Michael Sample and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/inc/asn-int.h,v 1.9 2004/04/21 13:27:09 gronej Exp $ */ #ifndef _asn_int_h_ #define _asn_int_h_ #include typedef int32_t I; typedef I AsnInt; typedef uint32_t UAsnInt; #ifdef __cplusplus extern "C" { #endif AsnLen BEncAsnInt PROTO ((GenBuf *b, AsnInt *data)); void BDecAsnInt PROTO ((GenBuf *b, AsnInt *result, AsnLen *bytesDecoded, ENV_TYPE env)); AsnLen BEncAsnIntContent PROTO ((GenBuf *b, AsnInt *data)); void BDecAsnIntContent PROTO ((GenBuf *b, AsnTag tag, AsnLen elmtLen, AsnInt *result, AsnLen *bytesDecoded, ENV_TYPE env)); /* do nothing */ #define FreeAsnInt( v) void PrintAsnInt PROTO ((FILE *f, AsnInt *v, unsigned int indent)); AsnLen BEncUAsnInt PROTO ((GenBuf *b, UAsnInt *data)); void BDecUAsnInt PROTO ((GenBuf *b, UAsnInt *result, AsnLen *bytesDecoded, ENV_TYPE env)); AsnLen BEncUAsnIntContent PROTO ((GenBuf *b, UAsnInt *data)); void BDecUAsnIntContent PROTO ((GenBuf *b, AsnTag tagId, AsnLen len, UAsnInt *result, AsnLen *bytesDecoded, ENV_TYPE env)); /* do nothing */ #define FreeUAsnInt( v) void PrintUAsnInt PROTO ((FILE *f, UAsnInt *v, unsigned int indent)); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* conditional include */ esnacc-ng-1.8.1/c-lib/inc/asn-len.h000066400000000000000000000111531302010526100166130ustar00rootroot00000000000000/* * asn_len.h * * Warning: many of these routines are MACROs for performance reasons * - be carful where you use them. Don't use more than one per * assignment statement - * (eg itemLen += BEncEoc (b) + BEncFoo (b) ..; this * will break the code) * * MS 92 * Copyright (C) 1992 Michael Sample and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/inc/asn-len.h,v 1.7 2003/12/17 19:05:03 gronej Exp $ * $Log: asn-len.h,v $ * Revision 1.7 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.6.2.1 2003/11/05 14:58:55 gronej * working PER code merged with esnacc_1_6 * * Revision 1.6 2003/02/20 21:07:59 leonberp * added #ifdef __cplusplus extern "C" to headers * * Revision 1.5 2002/10/23 10:23:51 mcphersc * Changed BUF_TYPE to AsnBuf * * Revision 1.4 2002/10/21 17:13:24 mcphersc * fixed long int * * Revision 1.3 2002/10/01 14:13:34 mcphersc * ASN "C" Buf modifications * * Revision 1.2 2001/07/12 19:34:02 leonberp * Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. * * Revision 1.1.1.1 2000/08/21 20:35:54 leonberp * First CVS Version of SNACC. * * Revision 1.4 1997/08/28 07:25:52 povey * Changes to support DER encoding/decoding * * Revision 1.3.1.1 1997/08/20 23:14:43 povey * * Revision 1.2 1995/07/27 08:42:40 rj * cpp macro TBL changed to TTBL since some type table code uses TBL as a type name. * * changed `_' to `-' in file names. * * Revision 1.1 1994/08/28 09:21:29 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #ifndef _asn_len_h_ #define _asn_len_h_ #ifdef __cplusplus extern "C" { #endif typedef unsigned long AsnLen; /* * BER Encoding/Decoding routines */ /* max unsigned value - used for internal rep of indef len */ #define INDEFINITE_LEN ~0UL #ifdef USE_INDEF_LEN #define BEncEocIfNec( b) BEncEoc (b) /* * include len for EOC (2 must be first due to BEncIndefLen * - ack! ugly macros!) */ #define BEncConsLen( b, len) 2 + BEncIndefLen(b) #else /* use definite length - faster?/smaller encodings */ /* do nothing since only using definite lens */ #define BEncEocIfNec( b) #define BEncConsLen( b, len) BEncDefLen(b, len) #endif /* * writes indefinite length byte to buffer. 'returns' encoded len (1) */ #define BEncIndefLen( b)\ 1;\ BufPutByteRvs (b, 0x80); #ifndef _DEBUG #define BEncEoc( b)\ 2;\ BufPutByteRvs (b, 0);\ BufPutByteRvs (b, 0); #endif /* * use if you know the encoded length will be 0 >= len <= 127 * Eg for booleans, nulls, any resonable integers and reals * * NOTE: this particular Encode Routine does NOT return the length * encoded (1). */ #define BEncDefLenTo127( b, len)\ BufPutByteRvs (b, (unsigned char) len) #define BDEC_2ND_EOC_OCTET( b, bytesDecoded, env)\ {\ if ((BufGetByte (b) != 0) || BufReadError (b)) {\ Asn1Error ("ERROR - second octet of EOC not zero\n");\ longjmp (env, -28);}\ (*bytesDecoded)++;\ } AsnLen BEncDefLen PROTO ((GenBuf *b, AsnLen len)); AsnLen BEncDefLen2 PROTO ((GenBuf *b, long len)); AsnLen BDecLen PROTO ((GenBuf *b, AsnLen *bytesDecoded, ENV_TYPE env)); #ifdef _DEBUG AsnLen BEncEoc PROTO ((GenBuf *b)); #endif void BDecEoc PROTO ((GenBuf *b, AsnLen *bytesDecoded, ENV_TYPE env)); #if TTBL int PeekEoc PROTO ((GenBuf *b)); #endif /* * DER Encoding/Decoding routines */ /* We always use Definite length encoders */ /* do nothing since only using definite lens */ #define DEncEocIfNec( b) #define DEncConsLen DEncDefLen /* * use if you know the encoded length will be 0 >= len <= 127 * Eg for booleans, nulls, any resonable integers and reals * * NOTE: this particular Encode Routine does NOT return the length * encoded (1). */ #define DEncDefLenTo127( b, len)\ BufPutByteRvs (b, (unsigned char) len) #define DEncDefLen BEncDefLen AsnLen DDecLen PROTO ((GenBuf *b, AsnLen *bytesDecoded, ENV_TYPE env)); /* Error conditions */ #define DDecEoc(a, b, env) longjmp(env, -666) /* Should never happen */ #define DDEC_2ND_EOC_OCTET(a, b, env) #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* conditional include */ esnacc-ng-1.8.1/c-lib/inc/asn-list.h000066400000000000000000000130351302010526100170110ustar00rootroot00000000000000/* * asn_list.h * * --------- * | AsnList | * | last |-------------------------------------------| * | curr |--------------------------| | * | first|--------| | | * --------- | | | * V V V * --------- --------- --------- * |AsnListNode |AsnListNode |AsnListNode * | next |---...->| next |--...-->| next |-----|i. * .i|----| prev |<--...--| prev |<--...--| prev | * | data | | data | | data | * --------- --------- --------- * * Originally by Murray Goldberg * Modified for ASN.1 use. * MS 92 * Copyright (C) 1992 the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/inc/asn-list.h,v 1.7 2003/12/17 19:05:03 gronej Exp $ * $Log: asn-list.h,v $ * Revision 1.7 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.6.2.1 2003/11/05 14:58:55 gronej * working PER code merged with esnacc_1_6 * * Revision 1.6 2003/02/20 21:07:59 leonberp * added #ifdef __cplusplus extern "C" to headers * * Revision 1.5 2002/10/21 17:13:24 mcphersc * fixed long int * * Revision 1.4 2002/10/18 13:10:32 mcphersc * took out long int to unsigned long * * Revision 1.3 2001/07/12 19:34:02 leonberp * Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. * * Revision 1.2 2001/03/05 19:36:21 nicholar * no message * * Revision 1.1.1.1 2000/08/21 20:35:54 leonberp * First CVS Version of SNACC. * * Revision 1.4 1997/08/28 07:25:52 povey * Changes to support DER encoding/decoding * * Revision 1.3.1.1 1997/08/20 23:14:43 povey * * Revision 1.3 1995/07/24 21:01:14 rj * changed `_' to `-' in file names. * * Revision 1.2 1994/10/08 01:40:22 rj * it is unwise to #define unbalanced if()s! (fixed.) * three declarations added. * * Revision 1.1 1994/08/28 09:21:30 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #ifndef _asn_list_h_ #define _asn_list_h_ #ifdef __cplusplus extern "C" { #endif typedef struct AsnListNode { struct AsnListNode *prev; struct AsnListNode *next; void *data; /* this must be the last field of this structure */ } AsnListNode; typedef struct AsnList { AsnListNode *first; AsnListNode *last; AsnListNode *curr; int count; /* number of elements in list */ int dataSize; /* space required in each node for the data */ } AsnList; #define FOR_EACH_LIST_ELMT( elmt, al)\ if (!(al))\ ;\ else\ for ((al)->curr = (al)->first; (al)->curr && (((elmt) = (al)->curr->data) != NULL); (al)->curr = (al)->curr->next) #define FOR_EACH_LIST_ELMT_RVS( elmt, al)\ if (!(al))\ ;\ else\ for ((al)->curr = (al)->last; (al)->curr && (((elmt) = (al)->curr->data) != NULL); (al)->curr = (al)->curr->prev) #define FOR_REST_LIST_ELMT( elmt, al)\ if (!(al))\ ;\ else\ for (; (al)->curr && (((elmt) = (al)->curr->data) != NULL); (al)->curr = (al)->curr->next) #define FOR_REST_LIST_ELMT_RVS( elmt, al)\ if (!(al))\ ;\ else\ for (; ((al)->curr && (((elmt) = (al)->curr->data) != NULL); (al)->curr = (al)->curr->prev) /* * The following macros return the pointer stored in the * data part of the listNode. The do not change the current * list pointer. */ #define CURR_LIST_ELMT( al) ((al)->curr->data) #define NEXT_LIST_ELMT( al) ((al)->curr->next->data) #define PREV_LIST_ELMT( al) ((al)->curr->prev->data) #define LAST_LIST_ELMT( al) ((al)->last->data) #define FIRST_LIST_ELMT( al) ((al)->first->data) #define LIST_EMPTY( al) ((al)->count == 0) #define LIST_COUNT( al) ((al)->count) /* * list nodes are the parts of the list that contain ptrs/data * to/of the list elmts. */ #define CURR_LIST_NODE( al) ((al)->curr) #define FIRST_LIST_NODE( al) ((al)->first) #define LAST_LIST_NODE( al) ((al)->last) #define PREV_LIST_NODE( al) ((al)->curr->prev) #define NEXT_LIST_NODE( al) ((al)->curr->next) #define SET_CURR_LIST_NODE( al, listNode) ((al)->curr = (listNode)) void AsnListRemove PROTO ((AsnList *)); void *AsnListAdd PROTO ((AsnList *)); void *AsnListInsert PROTO ((AsnList *)); void AsnListInit PROTO ((AsnList *list, int dataSize)); AsnList *AsnListNew PROTO ((int)); void *AsnListPrev PROTO ((AsnList *)); void *AsnListNext PROTO ((AsnList *)); void *AsnListLast PROTO ((AsnList *)); void *AsnListFirst PROTO ((AsnList *)); void *AsnListPrepend PROTO ((AsnList *)); void *AsnListAppend PROTO ((AsnList *)); void *AsnListCurr PROTO ((AsnList *)); AsnList *AsnListSort PROTO ((AsnList *list, int ((*cmp)(const void *, const void *)))); int AsnListCount PROTO ((AsnList *)); AsnList *AsnListConcat PROTO ((AsnList *, AsnList *)); long GetAsnListElmtIndex PROTO ((void *elmt,AsnList *list)); void AsnListFree PROTO (( AsnList *)); void *GetAsnListElmt PROTO ((AsnList *list, unsigned int index)); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* conditional include */ esnacc-ng-1.8.1/c-lib/inc/asn-null.h000066400000000000000000000024661302010526100170160ustar00rootroot00000000000000/* * asn_null.h * * MS 92 * Copyright (C) 1992 Michael Sample and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/inc/asn-null.h,v 1.9 2004/04/21 13:27:33 gronej Exp $ */ #ifndef _asn_null_h_ #define _asn_null_h_ #ifdef __cplusplus extern "C" { #endif typedef char AsnNull; AsnLen BEncAsnNull PROTO ((GenBuf *b, AsnNull *data)); void BDecAsnNull PROTO ((GenBuf *b, AsnNull *result, AsnLen *bytesDecoded, ENV_TYPE env)); /* 'return' length of encoded NULL value, 0 */ #define BEncAsnNullContent(b, data) 0 void BDecAsnNullContent PROTO ((GenBuf *b, AsnTag tag, AsnLen len, AsnNull *result, AsnLen *bytesDecoded, ENV_TYPE env)); /* do nothing */ void FreeAsnNull PROTO ((AsnNull *b)); #define FreeAsnNull( v) void PrintAsnNull PROTO ((FILE *f, AsnNull * b, unsigned int indent)); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* conditional include */ esnacc-ng-1.8.1/c-lib/inc/asn-octs.h000066400000000000000000000026351302010526100170120ustar00rootroot00000000000000/* * asn_octs.h * * MS 92 * Copyright (C) 1992 Michael Sample and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/inc/asn-octs.h,v 1.8 2004/01/22 20:02:58 nicholar Exp $ */ #ifndef _asn_octs_h_ #define _asn_octs_h_ #ifdef __cplusplus extern "C" { #endif typedef struct AsnOcts { unsigned long octetLen; char *octs; } AsnOcts; #define ASNOCTS_PRESENT( aocts) ((aocts)->octs != NULL) AsnLen BEncAsnOcts PROTO ((GenBuf *b, AsnOcts *data)); void BDecAsnOcts PROTO ((GenBuf *b, AsnOcts *result, AsnLen *bytesDecoded, ENV_TYPE env)); AsnLen BEncAsnOctsContent PROTO ((GenBuf *b, AsnOcts *octs)); void BDecAsnOctsContent PROTO ((GenBuf *b, AsnTag tagId, AsnLen len, AsnOcts *result, AsnLen *bytesDecoded, ENV_TYPE env)); void FreeAsnOcts PROTO ((AsnOcts *o)); void PrintAsnOcts PROTO ((FILE *f, AsnOcts *o, unsigned int indent)); int AsnOctsEquiv PROTO ((AsnOcts *o1, AsnOcts *o2)); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* conditional include */ esnacc-ng-1.8.1/c-lib/inc/asn-oid.h000066400000000000000000000034411302010526100166110ustar00rootroot00000000000000/* * asn_oid.h * * this file depends on asn_octs.h * MS 92 * Copyright (C) 1992 Michael Sample and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/inc/asn-oid.h,v 1.10 2004/01/22 20:02:58 nicholar Exp $ */ #ifndef _asn_oid_h_ #define _asn_oid_h_ #include "asn-octs.h" #ifdef __cplusplus extern "C" { #endif typedef AsnOcts AsnOid; /* standard oid type */ #define ASNOID_PRESENT( aoid) ASNOCTS_PRESENT (aoid) AsnLen BEncAsnOid PROTO ((GenBuf *b, AsnOid *data)); void BDecAsnOid PROTO ((GenBuf *b, AsnOid *result, AsnLen *bytesDecoded, ENV_TYPE env)); #define BEncAsnOidContent( b, oid) BEncAsnOctsContent (b, oid) void BDecAsnOidContent PROTO ((GenBuf *b, AsnTag tag, AsnLen len, AsnOid *result, AsnLen *bytesDecoded, ENV_TYPE env)); #define FreeAsnOid FreeAsnOcts void PrintAsnOid PROTO ((FILE *f, AsnOid *b, unsigned int indent)); #define AsnOidsEquiv( o1, o2) AsnOctsEquiv (o1, o2) /* linked oid type that may be easier to use in some circumstances */ #define NULL_OID_ARCNUM -1 typedef struct OID { struct OID *next; long arcNum; #if COMPILER || TTBL struct Value *valueRef; #endif } OID; AsnLen EncodedOidLen PROTO ((OID *oid)); void BuildEncodedOid PROTO ((OID *oid, AsnOid *result)); void UnbuildEncodedOid PROTO ((AsnOid *eoid, OID **result)); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* conditional include */ esnacc-ng-1.8.1/c-lib/inc/asn-real.h000066400000000000000000000025551302010526100167660ustar00rootroot00000000000000/* * asn_real.h * * MS 92 * Copyright (C) 1992 Michael Sample and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/inc/asn-real.h,v 1.9 2004/01/22 20:02:58 nicholar Exp $ */ #ifndef _asn_real_h_ #define _asn_real_h_ #ifdef __cplusplus extern "C" { #endif typedef double AsnReal; extern AsnReal PLUS_INFINITY; extern AsnReal MINUS_INFINITY; void InitAsnInfinity(); unsigned long SignedIntOctetLen PROTO ((long val)); AsnLen BEncAsnReal PROTO ((GenBuf *b, AsnReal *data)); void BDecAsnReal PROTO ((GenBuf *b, AsnReal *result, AsnLen *bytesDecoded, ENV_TYPE env)); AsnLen BEncAsnRealContent PROTO ((GenBuf *b, AsnReal *data)); void BDecAsnRealContent PROTO ((GenBuf *b, AsnTag tag, AsnLen len, AsnReal *result, AsnLen *bytesDecoded, ENV_TYPE env)); /* do nothing */ #define FreeAsnReal( v) void PrintAsnReal PROTO ((FILE *f, AsnReal *b, unsigned int indent)); #ifdef __cplusplus } #endif /* __cplusplus */ #endif esnacc-ng-1.8.1/c-lib/inc/asn-relative-oid.h000066400000000000000000000037641302010526100204320ustar00rootroot00000000000000/* * asn_relative_RELATIVE_RELATIVE_OID.h * * this file depends on asn_octs.h * * Joseph Grone * 15/01/2004 * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/inc/asn-relative-oid.h,v 1.2 2004/01/22 20:03:07 nicholar Exp $ */ #ifndef _asn_relative_oid_h_ #define _asn_relative_oid_h_ #include "asn-octs.h" #ifdef __cplusplus extern "C" { #endif typedef AsnOcts AsnRelativeOid; /* standard oid type */ #define ASNRELATIVE_OID_PRESENT( aoid) ASNOCTS_PRESENT (aoid) AsnLen BEncAsnRelativeOid PROTO ((GenBuf *b, AsnRelativeOid *data)); void BDecAsnRelativeOid PROTO ((GenBuf *b, AsnRelativeOid *result, AsnLen *bytesDecoded, ENV_TYPE env)); #define BEncAsnRelativeOidContent( b, oid) BEncAsnOctsContent (b, oid) void BDecAsnRelativeOidContent PROTO ((GenBuf *b, AsnTag tag, AsnLen len, AsnRelativeOid *result, AsnLen *bytesDecoded, ENV_TYPE env)); #define FreeAsnRelativeOid FreeAsnOcts void PrintAsnRelativeOid PROTO ((FILE *f, AsnRelativeOid *b, unsigned int indent)); #define AsnRelativeOidsEquiv( o1, o2) AsnOctsEquiv (o1, o2) /* linked oid type that may be easier to use in some circumstances */ #define NULL_RELATIVE_OID_ARCNUM -1 typedef struct RELATIVE_OID { struct RELATIVE_OID *next; long arcNum; #if COMPILER || TTBL struct Value *valueRef; #endif } RELATIVE_OID; AsnLen EncodedRelativeOidLen PROTO ((RELATIVE_OID *oid)); void BuildEncodedRelativeOid PROTO ((RELATIVE_OID *oid, AsnRelativeOid *result)); void UnbuildEncodedRelativeOid PROTO ((AsnRelativeOid *eoid, RELATIVE_OID **result)); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* conditional include */ esnacc-ng-1.8.1/c-lib/inc/asn-tag.h000066400000000000000000000200401302010526100166030ustar00rootroot00000000000000/* * asn_tag.h * * MS 92 * Copyright (C) 1992 Michael Sample and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * * ------------------------------------------------------------------------ * - J.G. Van Dyke & Associates, Inc. Modification History of SNACC 1.3 - * ------------------------------------------------------------------------ * * All modification are relative to the v1.3 of SNACC. We used SunOS 4.1.3's * SCCS. The revision #'s start at 1.1, which is the original version from * SNACC 1.3. * * * ../SCCS/s.asn-tag.h: * * D 1.2 98/04/24 22:38:58 pleonber 2 1 00012/00000/00221 * added INSERT_VDA_COMMENTS for script that adds SCCS history. Also added support for UniversalString and BMPString. * * D 1.1 98/04/23 12:11:09 pleonber 1 0 00221/00000/00000 * date and time created 98/04/23 12:11:09 by pleonber * * ----------------------- End of VDA Modifications --------------------------- * * * * $Header: /baseline/SNACC/c-lib/inc/asn-tag.h,v 1.9 2004/03/22 20:04:18 gronej Exp $ * $Log: asn-tag.h,v $ * Revision 1.9 2004/03/22 20:04:18 gronej * took IBM references out of the code (to the best of our knowledge, we don't use any of it anymore) * * Revision 1.8 2004/01/14 19:07:52 gronej * Updated Compiler to accept and process relative-oid's * * Revision 1.7 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.6.2.1 2003/11/05 14:58:55 gronej * working PER code merged with esnacc_1_6 * * Revision 1.6 2003/02/20 21:07:59 leonberp * added #ifdef __cplusplus extern "C" to headers * * Revision 1.5 2002/10/23 10:23:51 mcphersc * Changed BUF_TYPE to AsnBuf * * Revision 1.4 2002/05/15 17:00:57 leonberp * added support for new basicTypes to compiler * * Revision 1.3 2001/07/12 19:34:04 leonberp * Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. * * Revision 1.2 2000/09/19 14:16:15 rwc * Updated UTF8String for proper tag (12, instead of 11th position in enum). * * Revision 1.1.1.1 2000/08/21 20:35:54 leonberp * First CVS Version of SNACC. * * Revision 1.3 1995/07/27 08:44:15 rj * cpp macro TBL changed to TTBL since some type table code uses TBL as a type name. * * changed `_' to `-' in file names. * * Revision 1.2 1995/02/18 16:22:23 rj * let cpp choose a 32 bit integer type. * * Revision 1.1 1994/08/28 09:21:37 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #ifndef _asn_tag_h_ #define _asn_tag_h_ #ifdef __cplusplus extern "C" { #endif #include typedef uint32_t UL; typedef UL AsnTag; /* Tag Id's byte length */ #define TB sizeof (AsnTag) /* * The MAKE_TAG_ID macro generates the TAG_ID rep for the * the given class/form/code (rep'd in long integer form) * if the class/form/code are constants the compiler (should) * calculate the tag completely --> zero runtime overhead. * This is good for efficiently comparing tags in switch statements * (decoding) etc. because run-time bit fiddling (eliminated) minimized */ #define MAKE_TAG_ID( cl, fm, cd)\ ((((UL)(cl)) << ((TB -1) * 8)) | (((UL)(fm)) << ((TB -1) * 8)) | (MAKE_TAG_ID_CODE (((UL)(cd))))) #define MAKE_TAG_ID_CODE(cd)\ ( (cd < 31) ? (MAKE_TAG_ID_CODE1 (cd)):\ ((cd < 128)? (MAKE_TAG_ID_CODE2 (cd)):\ ((cd < 16384)? (MAKE_TAG_ID_CODE3 (cd)):\ (MAKE_TAG_ID_CODE4 (cd))))) #define MAKE_TAG_ID_CODE1(cd) (cd << ((TB -1) * 8)) #define MAKE_TAG_ID_CODE2(cd) ((31 << ((TB -1) * 8)) | (cd << ((TB-2) * 8))) #define MAKE_TAG_ID_CODE3(cd) ((31 << ((TB -1) * 8))\ | ((cd & 0x3f80) << 9)\ | ( 0x0080 << ((TB-2) * 8))\ | ((cd & 0x007F) << ((TB-3)* 8))) #define MAKE_TAG_ID_CODE4(cd) ((31 << ((TB -1) * 8))\ | ((cd & 0x1fc000) << 2)\ | ( 0x0080 << ((TB-2) * 8))\ | ((cd & 0x3f80) << 1)\ | ( 0x0080 << ((TB-3) * 8))\ | ((cd & 0x007F) << ((TB-4)*8))) typedef enum { ANY_CLASS = -2, NULL_CLASS = -1, UNIV = 0, APPL = (1 << 6), CNTX = (2 << 6), PRIV = (3 << 6) } BER_CLASS; typedef enum { ANY_FORM = -2, NULL_FORM = -1, PRIM = 0, CONS = (1 << 5) } BER_FORM; typedef enum { NO_TAG_CODE = 0, BOOLEAN_TAG_CODE = 1, INTEGER_TAG_CODE, BITSTRING_TAG_CODE, OCTETSTRING_TAG_CODE, NULLTYPE_TAG_CODE, OID_TAG_CODE, OD_TAG_CODE, EXTERNAL_TAG_CODE, REAL_TAG_CODE, ENUM_TAG_CODE, UTF8STRING_TAG_CODE=12, RELATIVE_OID_TAG_CODE=13, SEQ_TAG_CODE = 16, SET_TAG_CODE, NUMERICSTRING_TAG_CODE, PRINTABLESTRING_TAG_CODE, TELETEXSTRING_TAG_CODE, VIDEOTEXSTRING_TAG_CODE, IA5STRING_TAG_CODE, UTCTIME_TAG_CODE, GENERALIZEDTIME_TAG_CODE, GRAPHICSTRING_TAG_CODE, VISIBLESTRING_TAG_CODE, GENERALSTRING_TAG_CODE, UNIVERSALSTRING_TAG_CODE = 28, BMPSTRING_TAG_CODE = 30 } BER_UNIV_CODE; #define TT61STRING_TAG_CODE TELETEXSTRING_TAG_CODE #define ISO646STRING_TAG_CODE VISIBLESTRING_TAG_CODE /* * the TAG_ID_[CLASS/FORM/CODE] macros are not * super fast - try not to use during encoding/decoding */ #define TAG_ID_CLASS( tid) ((tid & (0xC0 << ((TB-1) *8))) >> ((TB -1) * 8)) #define TAG_ID_FORM( tid) ((tid & (0x20 << ((TB-1) *8))) >> ((TB -1) * 8)) /* * TAG_IS_CONS evaluates to true if the given AsnTag type * tag has the constructed bit set. */ #define TAG_IS_CONS( tag) ((tag) & (CONS << ((TB-1) *8))) #define CONSIFY( tag) (tag | (CONS << ((TB-1) *8))) #define DECONSIFY( tag) (tag & ~(CONS << ((TB-1) *8))) /* not a valid tag - usually the first EOC octet */ #define EOC_TAG_ID 0 /* * tag encoders. given constant values for class form & * code in the source, these can be optimized by the compiler * (e.g. do the shifts and bitwise ands & ors etc) * * This is the prototype that the following BEncTag routines * would use if they were routines. They return the number of * octets written to the buffer. * * *AsnLen BEncTag PROTO ((GenBuf *b, BER_CLASS class, BER_FORM form, int code)); * * WARNING: these are FRAGILE macros (What people will do for performance!) * Be careful of situations like: * if (foo) * encLen += BEncTag1 (...); * Use {}'s to enclose any ASN.1 related routine that you are * treating as a single statement in your code. */ #define BEncTag1( b, class, form, code)\ 1;\ BufPutByteRvs (b, (class) | (form) | (code)); #define BEncTag2( b, class, form, code)\ 2;\ BufPutByteRvs (b, code);\ BufPutByteRvs (b, (class) | (form) | 31); #define BEncTag3( b, class, form, code)\ 3;\ BufPutByteRvs (b, (code) & 0x7F);\ BufPutByteRvs (b, 0x80 | ((code) >> 7));\ BufPutByteRvs (b, (class) | (form) | 31); #define BEncTag4( b, class, form, code)\ 4;\ BufPutByteRvs (b, (code) & 0x7F);\ BufPutByteRvs (b, 0x80 | ((code) >> 7));\ BufPutByteRvs (b, 0x80 | ((code) >> 14));\ BufPutByteRvs (b, (class) | (form) | 31); #define BEncTag5( b, class, form, code)\ 5;\ BufPutByteRvs (b, (code) & 0x7F);\ BufPutByteRvs (b, 0x80 | ((code) >> 7));\ BufPutByteRvs (b, 0x80 | ((code) >> 14));\ BufPutByteRvs (b, 0x80 | ((code) >> 21));\ BufPutByteRvs (b, (class) | (form) | 31); /* the following are protos for routines ins asn_tag.c */ AsnTag BDecTag PROTO ((GenBuf *b, AsnLen *bytesDecoded, ENV_TYPE env)); #if TTBL AsnTag PeekTag PROTO ((GenBuf *b, ENV_TYPE env)); #endif #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* conditional include */ esnacc-ng-1.8.1/c-lib/inc/exp-buf.h000066400000000000000000000127361302010526100166340ustar00rootroot00000000000000/* * exp_buf.h - read/write/alloc/free routines for a simple buffer structure * * MACROS are gross but execution speed is important * * NOTE: replacing the malloc and free with a allocs/frees * from/to buffer pools or similar tuned/fixed size * mem mgmt will improve performance. * * You should tune the buffer management to your environment * for best results * * MS 91 * Copyright (C) 1992 Michael Sample and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/inc/exp-buf.h,v 1.10 2003/12/17 19:05:03 gronej Exp $ * $Log: exp-buf.h,v $ * Revision 1.10 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.9.2.1 2003/11/05 14:58:55 gronej * working PER code merged with esnacc_1_6 * * Revision 1.9 2003/08/04 10:34:17 colestor * Updated several improperly referenced "b" buffer parameters when dealing with * ANY load/unloads (encode/decodes). This code has never been tested in the * "C" library. * Also, added DEnc[Dec]AsnAny references to be BEnc[Dec]AsnAny. * * Revision 1.8 2003/02/20 21:07:59 leonberp * added #ifdef __cplusplus extern "C" to headers * * Revision 1.7 2002/10/23 13:33:23 mcphersc * Took GenBuf defines out * * Revision 1.6 2002/10/22 15:49:25 mcphersc * Mods for gen-buf usage * * Revision 1.5 2002/10/18 13:10:32 mcphersc * took out long int to unsigned long * * Revision 1.4 2002/10/15 17:33:34 mcphersc * Changed der structure to accept GenBufs * * Revision 1.3 2002/10/01 14:18:08 mcphersc * ASN "C" Buf modifications * * Revision 1.2 2001/07/12 19:34:04 leonberp * Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. * * Revision 1.1.1.1 2000/08/21 20:35:54 leonberp * First CVS Version of SNACC. * * Revision 1.2 1995/07/27 08:54:45 rj * functions used by gen-bufs or type tables merged. * * changed `_' to `-' in file names. * * Revision 1.1 1994/08/28 09:21:40 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #ifndef _exp_buf_h_ #define _exp_buf_h_ #ifdef __cplusplus extern "C" { #endif typedef struct ExpBuf { char *dataStart; /* points to first valid data byte */ /* when empty, 1 byte past blk end (rvs write)*/ char *dataEnd; /* pts to first byte AFTER last valid data byte*/ char *curr; /* current location to read form */ /* points to next byte to read */ struct ExpBuf *next; /* next buf (NULL if no next buffer)*/ struct ExpBuf *prev; /* prev buf (NULL if no prev buffer)*/ char *blkStart; /* points to first byte of the blk */ char *blkEnd; /* points the first byte AFTER blks last byte */ int readError; /* non-zero is attempt to read past end of data*/ int writeError;/* non-zero is attempt write fails (no mor bufs)*/ } ExpBuf; /* init, alloc and free routines */ void PutExpBufInGenBuf PROTO ((ExpBuf *eb,GenBuf *gb)); void ExpBuftoGenBuf PROTO ((ExpBuf *eb,GenBuf **gb)); void ExpBufInit PROTO ((unsigned long dataBlkSize)); ExpBuf *ExpBufAllocBuf(); void ExpBufFreeBuf PROTO ((ExpBuf *ptr)); char *ExpBufAllocData(); void ExpBufFreeData PROTO ((char *ptr)); void ExpBufFreeBufAndData PROTO (( ExpBuf *b)); ExpBuf *ExpBufNext PROTO ((ExpBuf *b)); ExpBuf *ExpBufPrev PROTO ((ExpBuf *b)); void ExpBufResetInReadMode PROTO ((ExpBuf **b)); void ExpBufResetInWriteRvsMode PROTO ((ExpBuf *b)); int ExpBufAtEod PROTO ((ExpBuf *b)); int ExpBufFull PROTO ((ExpBuf *b)); int ExpBufHasNoData PROTO ((ExpBuf *b)); unsigned long ExpBufDataSize PROTO ((ExpBuf *b)); unsigned long ExpBufDataBlkSize PROTO ((ExpBuf *b)); char *ExpBufDataPtr PROTO ((ExpBuf *b)); extern unsigned long expBufDataBlkSizeG; int ExpBufReadError PROTO ((ExpBuf **b)); int ExpBufWriteError PROTO ((ExpBuf **b)); int ExpBufSetWriteError PROTO ((ExpBuf *b, unsigned short Value)); ExpBuf *ExpBufAllocBufAndData(); void ExpBufInstallDataInBuf PROTO ((ExpBuf *b, char *data, unsigned long len)); void ExpBufFreeBufAndDataList PROTO (( ExpBuf *b)); ExpBuf *ExpBufListLastBuf PROTO ((ExpBuf *b)); ExpBuf *ExpBufListFirstBuf PROTO ((ExpBuf *b)); void ExpBufCopyToFile PROTO ((ExpBuf *b, FILE *f)); /* reading and writing routines */ int ExpBufCopyAny PROTO ((ExpBuf **b,void *value, unsigned long *bytesDecoded, ENV_TYPE env)); void ExpBufSkip PROTO (( ExpBuf**, unsigned long len)); int ExpBufCopy PROTO (( char *dst, ExpBuf **b, unsigned long len)); unsigned char ExpBufPeekByte PROTO (( ExpBuf **b)); int ExpBufPeekCopy PROTO ((char *dst, ExpBuf **b, unsigned long len)); char *ExpBufPeekSeg PROTO ((ExpBuf **b, unsigned long *len)); char *ExpBufGetSeg PROTO ((ExpBuf **b, unsigned long *len)); void ExpBufPutSegRvs PROTO ((ExpBuf **b, char *data, unsigned long len)); unsigned char ExpBufGetByte PROTO ((ExpBuf **b)); void ExpBufPutByteRvs PROTO ((ExpBuf **b, unsigned char byte)); #ifdef __cplusplus } #endif #endif /* conditional include */ esnacc-ng-1.8.1/c-lib/inc/gen-buf.h000066400000000000000000000112031302010526100165750ustar00rootroot00000000000000/* * gen_buf.h - flexible (runtime configurable) buffer mgmt stuff. * * These are somewhat slower than the direct approach used in * the compiled stuff. Since tables are around 4x slower, * the flexibility of the GenBufs can be justified. This * also allows one enc/dec library to support all buffer types. * * MS 93 * * Copyright (C) 1993 Michael Sample * and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef _gen_buf_h_ #define _gen_buf_h_ #ifdef __cplusplus extern "C" { #endif /* * These are the standard buffer routines that the lib * routines need. Note that the Peek routines have be * added to the standard list - they are necessary * to nicely support the table oriented decoder. * The "void *b" param's real type will be the buffer * type that is used inside the GenBuf * (ie ExpBuf ** have been defined). * * Note that macros can not be used for these standard functions * because the GenBuf keeps a pointer to these routines. * Thus the exp_buf.[ch] and files are somewhat * differnt than those in snacc/c_lib and snacc/c_include * */ typedef int (*BufCopyAnyFcn) PROTO ((void *b, void *value, unsigned long *bytesDecoded, ENV_TYPE env)); typedef unsigned char (*BufGetByteFcn) PROTO ((void *b)); typedef unsigned char *(*BufGetSegFcn) PROTO ((void *b, unsigned long *lenPtr)); typedef long (*BufCopyFcn) PROTO ((char *dst, void *b, unsigned long len)); typedef void (*BufSkipFcn) PROTO ((void *b, unsigned long len)); typedef unsigned char (*BufPeekByteFcn) PROTO ((void *b)); typedef unsigned char *(*BufPeekSegFcn) PROTO ((void *b, unsigned long *lenPtr)); typedef long (*BufPeekCopyFcn) PROTO ((char *dst, void *b, unsigned long len)); typedef void (*BufPutByteRvsFcn) PROTO ((void *b, unsigned char byte)); typedef void (*BufPutSegRvsFcn) PROTO ((void *b, char *data, unsigned long len)); typedef int (*BufReadErrorFcn) PROTO ((void *b)); typedef int (*BufWriteErrorFcn) PROTO ((void *b)); typedef int (*BufSetWriteErrorFcn) PROTO ((void *b, unsigned short Value)); typedef void (*BufResetInReadModeFcn) PROTO ((void *b)); typedef struct GenBuf { BufCopyAnyFcn copyAny; BufGetByteFcn getByte; BufGetSegFcn getSeg; BufCopyFcn copy; BufSkipFcn skip; BufPeekByteFcn peekByte; BufPeekSegFcn peekSeg; BufPeekCopyFcn peekCopy; BufPutByteRvsFcn putByteRvs; BufPutSegRvsFcn putSegRvs; BufReadErrorFcn readError; BufSetWriteErrorFcn setWriteError; BufWriteErrorFcn writeError; BufResetInReadModeFcn resetInReadMode; void *bufInfo; void *spare; /* hack to save space for ExpBuf ** type */ } GenBuf; static inline int GenBufCopyAny(GenBuf *b, void *value, unsigned long *bytesDecoded, ENV_TYPE env) { return b->copyAny(b->bufInfo, value, bytesDecoded, env); } static inline unsigned char GenBufGetByte(GenBuf *b) { return b->getByte(b->bufInfo); } static inline unsigned char * GenBufGetSeg(GenBuf *b, unsigned long *lenPtr) { return b->getSeg(b->bufInfo, lenPtr); } static inline long GenBufCopy(char *dst, GenBuf *b, unsigned long len) { return b->copy(dst, b->bufInfo, len); } static inline void GenBufSkip(GenBuf *b, unsigned long len) { b->skip(b->bufInfo, len); } static inline unsigned char GenBufPeekByte(GenBuf *b) { return b->peekByte(b->bufInfo); } static inline unsigned char * GenBufPeekSeg(GenBuf *b, unsigned long *lenPtr) { return b->peekSeg(b->bufInfo, lenPtr); } static inline long GenBufPeekCopy(char *dst, GenBuf *b, unsigned long len) { return b->peekCopy(dst, b->bufInfo, len); } static inline void GenBufPutByteRvs(GenBuf *b, unsigned char byte) { b->putByteRvs(b->bufInfo, byte); } static inline void GenBufPutSegRvs(GenBuf *b, char *data, unsigned long len) { b->putSegRvs(b->bufInfo, data, len); } static inline int GenBufReadError(GenBuf *b) { return b->readError(b->bufInfo); } static inline int GenBufWriteError(GenBuf *b) { return b->writeError(b->bufInfo); } static inline int GenBufSetWriteError(GenBuf *b, unsigned short value) { return b->setWriteError(b->bufInfo, value); } static inline void GenBufResetInReadMode(GenBuf *b) { b->resetInReadMode(b->bufInfo); } #define GenBufFree(b) free(b) #ifdef __cplusplus } #endif #endif /* _gen_buf_h_ conditional include */ esnacc-ng-1.8.1/c-lib/inc/hash.h000066400000000000000000000043321302010526100162020ustar00rootroot00000000000000/* * hash.h * * Based on hashing stuff from UBC Raven Code (Terry Coatta & Don Acton) * * MS 92 * Copyright (C) 1992 the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/inc/hash.h,v 1.5 2003/12/17 19:05:03 gronej Exp $ * $Log: hash.h,v $ * Revision 1.5 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.4.2.1 2003/11/05 14:58:55 gronej * working PER code merged with esnacc_1_6 * * Revision 1.4 2003/02/20 21:07:59 leonberp * added #ifdef __cplusplus extern "C" to headers * * Revision 1.3 2002/10/21 17:13:24 mcphersc * fixed long int * * Revision 1.2 2001/07/12 19:34:05 leonberp * Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. * * Revision 1.1.1.1 2000/08/21 20:35:54 leonberp * First CVS Version of SNACC. * * Revision 1.3 1997/02/28 13:39:49 wan * Modifications collected for new version 1.3: Bug fixes, tk4.2. * * Revision 1.2 1995/07/24 21:01:19 rj * changed `_' to `-' in file names. * * Revision 1.1 1994/08/28 09:21:41 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #ifndef _asn_hash_h_ #define _asn_hash_h_ #ifdef __cplusplus extern "C" { #endif #define TABLESIZE 256 #define INDEXMASK 0xFF #define INDEXSHIFT 8 typedef void *Table[TABLESIZE]; typedef unsigned int Hash; typedef struct HashSlot { int leaf; Hash hash; void *value; Table *table; } HashSlot; Hash MakeHash PROTO ((char *str, unsigned long len)); Table *InitHash(); int Insert PROTO ((Table *table, void *element, Hash hash)); int CheckFor PROTO ((Table *table, Hash hash)); int CheckForAndReturnValue PROTO ((Table *table, Hash hash, void **value)); #ifdef __cplusplus } #endif #endif /* conditional include */ esnacc-ng-1.8.1/c-lib/inc/mem.h000066400000000000000000000035711302010526100160410ustar00rootroot00000000000000/* * compiler/core/mem.h * * MS 91/08/03 * * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/c-lib/inc/mem.h,v 1.3 2003/12/17 19:05:03 gronej Exp $ * $Log: mem.h,v $ * Revision 1.3 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.2.2.1 2003/11/05 14:58:55 gronej * working PER code merged with esnacc_1_6 * * Revision 1.2 2003/02/20 21:07:59 leonberp * added #ifdef __cplusplus extern "C" to headers * * Revision 1.1 2002/05/10 17:22:26 leonberp * latest changes for release 2.2 * includes integrating asn-useful into C & C++ runtime library, the compiler changes that go along with that, SnaccException changes for C++ runtime and compiler * * Revision 1.2 2001/07/12 19:34:30 leonberp * Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. * * Revision 1.1.1.1 2000/08/21 20:36:00 leonberp * First CVS Version of SNACC. * * Revision 1.2 1994/09/01 00:40:32 rj * snacc_config.h's last macro, MT ( ) got here. * * Revision 1.1 1994/08/28 09:49:22 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #ifndef _snacc_mem_h_ #define _snacc_mem_h_ #ifdef __cplusplus extern "C" { #endif #include "snacc.h" #include "asn-incl.h" void *Malloc PROTO ((int size)); void *Realloc PROTO ((void *ptr, int newsize)); void Free PROTO ((void *ptr)); char *Strdup PROTO ((const char *istring)); /* malloc type */ #define MT( type) (type *)Malloc (sizeof (type)) #ifdef __cplusplus } #endif #endif esnacc-ng-1.8.1/c-lib/inc/min-buf.h000066400000000000000000000053001302010526100166100ustar00rootroot00000000000000/* * .../c-lib/inc/min-buf.h - trivial buffer routines. * only use these for * encoding - if you know you 'buffer' is big enough * to hold the encoded value * * decoding - if you know that the encoding is error * free. * * * The minimal buffer is simply a block of mem referenced * by a char **(ie BUF_TYPE char**). These are very efficient * but should only be used when it is safe (see above) or you're * willing to risk reading past the end of the buffer or writing * 'past' the beginning (segmentation faults/bus errors etc). * * No checks for reading or writing past the buffer are done. * every operation is assumed to succeed. * MS 92 * * Copyright (C) 1992 Michael Sample and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/inc/min-buf.h,v 1.3 2003/12/17 19:05:03 gronej Exp $ * $Log: min-buf.h,v $ * Revision 1.3 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.2.2.1 2003/11/05 14:58:55 gronej * working PER code merged with esnacc_1_6 * * Revision 1.2 2001/07/12 19:34:05 leonberp * Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. * * Revision 1.1.1.1 2000/08/21 20:35:54 leonberp * First CVS Version of SNACC. * * Revision 1.2 1995/07/24 21:01:21 rj * changed `_' to `-' in file names. * * Revision 1.1 1994/08/28 09:21:42 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #ifndef MIN_BUF_H_ #define MIN_BUF_H_ struct GenBuf; #define MinBufGetByte(b)\ (unsigned char)(*((*(b))++)) #define MinBufGetSeg( b, lenPtr)\ *(b);\ (*b) += *lenPtr; #define MinBufCopy( dst, b, len)\ memcpy ((dst), *(b), (len));\ (*(b)) += (len); #define MinBufSkip( b, len) ((*(b)) += len) #define MinBufPeekByte( b) (**(b)) #define MinBufPutByteRvs( b, byte)\ (*(--(*(b))) = (byte)) #define MinBufPutSegRvs( b, data, len)\ ((*(b)) = (*(b)) - (len));\ memcpy (*(b), (data), (len)); #define MinBufReadError( b) 0 /* always false */ #define MinBufWriteError( b) 0 /* always false */ void GenBufFromMinBuf PROTO ((struct GenBuf *, void *)); #endif /* conditional include */ esnacc-ng-1.8.1/c-lib/inc/nibble-alloc.h000066400000000000000000000043131302010526100176010ustar00rootroot00000000000000/* * nibble_alloc.h - handles buffer allocation * MS 91 * * Copyright (C) 1992 Michael Sample and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/inc/nibble-alloc.h,v 1.6 2003/12/17 19:05:03 gronej Exp $ * $Log: nibble-alloc.h,v $ * Revision 1.6 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.5.2.1 2003/11/05 14:58:55 gronej * working PER code merged with esnacc_1_6 * * Revision 1.5 2003/02/20 21:07:59 leonberp * added #ifdef __cplusplus extern "C" to headers * * Revision 1.4 2002/10/21 17:13:24 mcphersc * fixed long int * * Revision 1.3 2002/10/18 13:10:32 mcphersc * took out long int to unsigned long * * Revision 1.2 2001/07/12 19:34:06 leonberp * Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. * * Revision 1.1.1.1 2000/08/21 20:35:54 leonberp * First CVS Version of SNACC. * * Revision 1.2 1995/07/24 21:01:22 rj * changed `_' to `-' in file names. * * Revision 1.1 1994/08/28 09:21:43 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #ifndef _nibble_alloc_h_ #define _nibble_alloc_h_ #ifdef __cplusplus extern "C" { #endif typedef struct NibbleBuf { char *start; char *end; char *curr; struct NibbleBuf *next; } NibbleBuf; typedef struct NibbleMem { NibbleBuf *firstNibbleBuf; NibbleBuf *currNibbleBuf; unsigned long incrementSize; } NibbleMem; void InitNibbleMem PROTO ((unsigned long initialSize, unsigned long incrementSize)); void ShutdownNibbleMem(); void ServiceNibbleFault PROTO ((unsigned long size)); void *NibbleAlloc PROTO ((unsigned long size)); void ResetNibbleMem(); #ifdef __cplusplus } #endif #endif /* conditional include */ esnacc-ng-1.8.1/c-lib/inc/print.h000066400000000000000000000015771302010526100164230ustar00rootroot00000000000000/* * print.h * * MS 92 * Copyright (C) 1992 Michael Sample and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/inc/print.h,v 1.7 2004/01/22 20:02:58 nicholar Exp $ */ #ifndef _snaccc_print_h_ #define _snaccc_print_h_ #ifdef __cplusplus extern "C" { #endif void Indent PROTO ((FILE *f, unsigned int i)); void Asn1DefaultErrorHandler PROTO ((char* str,int severity)); #ifdef __cplusplus } #endif #endif /* conditional include */ esnacc-ng-1.8.1/c-lib/inc/sbuf.h000066400000000000000000000073651302010526100162270ustar00rootroot00000000000000/* * sbuf.h - a buffer consisting of one contiguous block * that checks for read and write range errors. * MS 92 * Copyright (C) 1992 Michael Sample and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/inc/sbuf.h,v 1.10 2003/12/17 19:05:03 gronej Exp $ * $Log: sbuf.h,v $ * Revision 1.10 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.9.2.1 2003/11/05 14:58:55 gronej * working PER code merged with esnacc_1_6 * * Revision 1.9 2003/02/20 21:07:59 leonberp * added #ifdef __cplusplus extern "C" to headers * * Revision 1.8 2002/10/24 14:51:56 mcphersc * fixed SBufCopy prototype * * Revision 1.7 2002/10/24 12:02:37 mcphersc * Modified prototypes * * Revision 1.6 2002/10/23 17:55:33 mcphersc * Bug fixes * * Revision 1.5 2002/10/22 17:46:59 mcphersc * fixed prototypes * * Revision 1.4 2002/10/22 15:49:08 mcphersc * Mods for gen-buf usage * * Revision 1.3 2002/10/21 17:13:24 mcphersc * fixed long int * * Revision 1.2 2001/07/12 19:34:06 leonberp * Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. * * Revision 1.1.1.1 2000/08/21 20:35:54 leonberp * First CVS Version of SNACC. * * Revision 1.2 1995/07/27 08:54:46 rj * functions used by gen-bufs or type tables merged. * * changed `_' to `-' in file names. * * Revision 1.1 1994/08/28 09:45:39 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #ifndef _sbuf_h_ #define _sbuf_h_ #ifdef __cplusplus extern "C" { #endif typedef struct SBuf { char *dataStart; /* byte last written (or end) */ char *dataEnd; /* ptr to first byte after last valid data byte */ char *blkStart; /* ptr to first byte of the buffer */ char *blkEnd; /* ptr to first byte past end of the buffer */ char *readLoc; /* next byte to read (or end) */ int writeError; /* whether write error occurred */ int readError; /* whether read error occurred */ } SBuf; void SBuftoGenBuf PROTO ((SBuf *eb,GenBuf **gb)); int SBufPeekCopy PROTO ((char *dst, SBuf **b, unsigned long copyLen)); void PutSBufInGenBuf PROTO ((SBuf *sb, GenBuf *gb)); void SBufInit PROTO ((SBuf *b, char *data, long dataLen)); void SBufResetInReadMode PROTO ((SBuf **b)); void SBufResetInWriteRvsMode PROTO ((SBuf *b)); void SBufInstallData PROTO ((SBuf *b, char *data, long dataLen)); long SBufDataLen PROTO ((SBuf *b)); char *SBufDataPtr PROTO ((SBuf *b)); long SBufBlkLen PROTO ((SBuf *b)); char *SBufBlkPtr PROTO ((SBuf *b)); int SBufEod PROTO ((SBuf *b)); int SBufReadError PROTO ((SBuf **b)); int SBufWriteError PROTO ((SBuf **b)); void SBufSkip PROTO ((SBuf **b, long skipLen)); void SBufCopy PROTO ((char *dst, SBuf **b, long copyLen)); unsigned char SBufPeekByte PROTO ((SBuf **b)); char *SBufGetSeg PROTO ((SBuf **b,long *lenPtr)); void SBufPutSegRvs PROTO ((SBuf **b, char *seg, long segLen)); unsigned char SBufGetByte PROTO ((SBuf **b)); char *SBufPeekSeg PROTO ((SBuf **b, long *lenPtr)); void SBufPutByteRvs PROTO ((SBuf **b, unsigned char byte)); int SBufSetWriteError PROTO ((SBuf *b, unsigned short Value)); int SBufCopyAny PROTO ((SBuf *b, void *value, unsigned long *bytesDecoded, ENV_TYPE env)); #ifdef __cplusplus } #endif #endif /* conditional include */ esnacc-ng-1.8.1/c-lib/inc/snaccCder.h000066400000000000000000000025231302010526100171440ustar00rootroot00000000000000 #ifndef _snaccCder_h_ #define _snaccCder_h_ #define DEncTag1 BEncTag1 #define DEncAsnOidContent BEncAsnOidContent #define DDecAsnOidContent BDecAsnOidContent #define DDecTag BDecTag #define DEncAsnOctsContent BEncAsnOctsContent #define DEncAsnBoolContent BEncAsnBoolContent #define DDecAsnBoolContent BDecAsnBoolContent #define DDecAsnOctsContent BDecAsnOctsContent #define DEncAsnIntContent BEncAsnIntContent #define DDecAsnIntContent BDecAsnIntContent #define DEncAsnEnumContent BEncAsnEnumContent #define DDecAsnEnumContent BDecAsnEnumContent #define DEncAsnRealContent BEncAsnRealContent #define DEncAsnNullContent BEncAsnNullContent #define DDecAsnNullContent BDecAsnNullContent #define DDecAsnRealContent BDecAsnRealContent #define DEncAsnAnyDefinedBy BEncAsnAny #define DDecAsnAnyDefinedBy BDecAsnAny #define DEncBMPStringContent DEncAsnOctsContent #define DEncUTF8StringContent DEncAsnOctsContent #define DEncUniversalStringContent DEncAsnOctsContent #define DEncPrintableStringContent DEncAsnOctsContent #define DEncTeletexStringContent DEncAsnOctsContent #define DDecBMPStringContent DDecAsnOctsContent #define DDecUTF8StringContent DDecAsnOctsContent #define DDecUniversalStringContent DDecAsnOctsContent #define DDecPrintableStringContent DDecAsnOctsContent #define DDecTeletexStringContent DDecAsnOctsContent #endif /* conditional include */ esnacc-ng-1.8.1/c-lib/inc/str-stk.h000066400000000000000000000106761302010526100166760ustar00rootroot00000000000000/* * str_stk.h - maintains a stack of the components of a bit string * or octet string so they can be copied into a single chunk * * * CONSTRUCTED BIT AND OCTET STRINGS SUCK. They should be * specified in the application's ASN.1 spec as SEQUENCE OF OCTET STRING * * this stack stuff is for decoding constructed bit/octet strings * so the user gets a single contiguous bit/octet str instead of * irritating little pieces. This does not cost a lot more than * a linked octet/bit string type since we're copying from the * buffer anyway, not referencing it directly (even in simple case). * It will cost more if the string stk overflows and * needs to be enlarged via realloc - set the values of * initialStkSizeG, and stkGrowSize carefully for your application. * Once the StkSize grows, it doesn't shrink back ever. * * Only three routine use/deal with this stack garbage * BDecConsAsnOcts * BDecConsAsnBits * SetupConsBitsOctsStringStk * * Copyright (C) 1992 Michael Sample and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/inc/str-stk.h,v 1.6 2004/03/25 19:20:16 gronej Exp $ * $Log: str-stk.h,v $ * Revision 1.6 2004/03/25 19:20:16 gronej * fixed some linux warnings * * Revision 1.5 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.4.2.1 2003/11/05 14:58:55 gronej * working PER code merged with esnacc_1_6 * * Revision 1.4 2003/02/20 21:07:59 leonberp * added #ifdef __cplusplus extern "C" to headers * * Revision 1.3 2002/10/18 13:10:32 mcphersc * took out long int to unsigned long * * Revision 1.2 2001/07/12 19:34:06 leonberp * Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. * * Revision 1.1.1.1 2000/08/21 20:35:55 leonberp * First CVS Version of SNACC. * * Revision 1.2 1995/07/24 21:01:24 rj * changed `_' to `-' in file names. * * Revision 1.1 1994/08/28 09:45:41 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #ifndef _str_stk_h #ifdef __cpluscplus extern "C" { #endif typedef struct StrStkElmt { char *str; unsigned long len; } StrStkElmt; typedef struct StrStk { StrStkElmt *stk; /* ptr to array of SSElmts with 'size' elmts */ unsigned long initialNumElmts; unsigned long numElmts; /* total # of elements in str stk */ unsigned long growElmts; /* # elmts to increase size by when nec */ unsigned long nextFreeElmt; /* index of next free element */ unsigned long totalByteLen; /* octet len of string stored in stk */ } StrStk; extern StrStk strStkG; /* * initializes stk (Allocates if nec.) * once stk is enlarged, it doesn't shrink */ #define RESET_STR_STK()\ {\ strStkG.nextFreeElmt = 0;\ strStkG.totalByteLen = 0;\ if (strStkG.stk == NULL){\ strStkG.stk = (StrStkElmt*) malloc ((strStkG.initialNumElmts) *sizeof (StrStkElmt));\ strStkG.numElmts = strStkG.initialNumElmts;}\ } /* * add a char*,len pair to top of stack. * grows stack if necessary using realloc (!) */ #define PUSH_STR(strPtr, strsLen, env)\ {\ if (strStkG.nextFreeElmt >= strStkG.numElmts)\ {\ strStkG.stk = (StrStkElmt*) realloc (strStkG.stk, (strStkG.numElmts + strStkG.growElmts) *sizeof (StrStkElmt));\ strStkG.numElmts += strStkG.growElmts;\ }\ strStkG.totalByteLen += strsLen;\ strStkG.stk[strStkG.nextFreeElmt].str = strPtr;\ strStkG.stk[strStkG.nextFreeElmt].len = strsLen;\ strStkG.nextFreeElmt++;\ } /* * Set up size values for the stack that is used for merging constructed * octet or bit string into single strings. * **** Call this before decoding anything. ***** * Note: you don't have to call this if the default values * for initialStkSizeG and stkGrowSizeG are acceptable */ #define SetupConsBitsOctsStringStk (initialNumberOfElmts, numberOfElmtsToGrowBy)\ {\ strStkG.initialNumElmts = initialNumberOfElmts; \ strStkG.growElmts = numberOfElmtsToGrowBy;\ } #ifdef __cplusplus } #endif /* extern "C" */ #endif /* _str_stk__h */ esnacc-ng-1.8.1/c-lib/inc/tbl-dbg.h000066400000000000000000000005021302010526100165650ustar00rootroot00000000000000#ifndef TBL_DBG_H #define TBL_DBG_H #include "tbl-gen.h" extern TdeExceptionCode DBGMinCode; /* Defaults to TDEINFO */ int DBGSimple PROTO ((AsnTag tag, AsnOcts* v, int begin)); int DBGType PROTO ((TBLType* type, AVal* val, int begin)); int DBGExc PROTO ((TdeExceptionCode code, void* p1, void* p2, void* p3)); #endif esnacc-ng-1.8.1/c-lib/inc/tbl-dec.h000066400000000000000000000031131302010526100165650ustar00rootroot00000000000000/* * tbl-util.h - type table utilities. * * * Mike Sample * * Copyright (C) 1993 Michael Sample * and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/inc/tbl-dec.h,v 1.5 2003/12/17 19:05:03 gronej Exp $ * $Log: tbl-dec.h,v $ * Revision 1.5 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.4.2.1 2003/11/05 14:58:55 gronej * working PER code merged with esnacc_1_6 * * Revision 1.4 2002/10/23 10:23:51 mcphersc * Changed BUF_TYPE to AsnBuf * * Revision 1.3 2002/10/18 13:10:32 mcphersc * took out long int to unsigned long * * Revision 1.2 2001/07/12 19:34:07 leonberp * Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. * * Revision 1.1.1.1 2000/08/21 20:35:55 leonberp * First CVS Version of SNACC. * * Revision 1.1 1995/07/27 08:55:52 rj * first check-in after being merged into .../c-lib/. * */ AVal *TblDecode PROTO ((TBL *tbl, char *modName, char *typeName, GenBuf *b, unsigned long *bytesDecoded)); AVal *TblDecodeType PROTO ((TBLType *tblT, GenBuf *b, int implicit, unsigned long *bytesDecoded, ENV_TYPE env)); esnacc-ng-1.8.1/c-lib/inc/tbl-enc.h000066400000000000000000000031041302010526100165770ustar00rootroot00000000000000/* * tbl-enc.h - type table encoder * * * Mike Sample * * Copyright (C) 1993 Michael Sample * and the University of British Columbia * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/inc/tbl-enc.h,v 1.5 2003/12/17 19:05:03 gronej Exp $ * $Log: tbl-enc.h,v $ * Revision 1.5 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.4.2.1 2003/11/05 14:58:55 gronej * working PER code merged with esnacc_1_6 * * Revision 1.4 2002/10/23 10:23:51 mcphersc * Changed BUF_TYPE to AsnBuf * * Revision 1.3 2002/10/18 13:10:32 mcphersc * took out long int to unsigned long * * Revision 1.2 2001/07/12 19:34:07 leonberp * Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. * * Revision 1.1.1.1 2000/08/21 20:35:55 leonberp * First CVS Version of SNACC. * * Revision 1.1 1995/07/27 08:55:54 rj * first check-in after being merged into .../c-lib/. * */ int TblEncode PROTO ((TBL *tbl, char *modName, char *typeName, GenBuf *b, AVal *v, unsigned long *bytesEncoded)); int TblEncodeType PROTO ((TBLType *tblT, GenBuf *b, AVal *v, int implicit, unsigned long *bytesEncoded)); esnacc-ng-1.8.1/c-lib/inc/tbl-free.h000066400000000000000000000025511302010526100167600ustar00rootroot00000000000000/* * tbl-free.h - frees data structs returned by type table driven decoder. * * * Mike Sample * * Copyright (C) 1993 Michael Sample * and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/inc/tbl-free.h,v 1.3 2003/12/17 19:05:03 gronej Exp $ * $Log: tbl-free.h,v $ * Revision 1.3 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.2.2.1 2003/11/05 14:58:55 gronej * working PER code merged with esnacc_1_6 * * Revision 1.2 2001/07/12 19:34:07 leonberp * Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. * * Revision 1.1.1.1 2000/08/21 20:35:55 leonberp * First CVS Version of SNACC. * * Revision 1.1 1995/07/27 08:55:55 rj * first check-in after being merged into .../c-lib/. * */ void TblFree PROTO ((TBL *tbl, char *modName, char *typeName, AVal *v)); void TblFreeType PROTO ((TBLType *tblT, AVal *v)); esnacc-ng-1.8.1/c-lib/inc/tbl-gen-c-hdr.h000066400000000000000000000025221302010526100176010ustar00rootroot00000000000000/* * tbl-gen-c-hdr.h - prints C type defs for vals * tbl decoder will return for the given type table. * * * Mike Sample * * Copyright (C) 1993 Michael Sample * and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/inc/tbl-gen-c-hdr.h,v 1.3 2003/12/17 19:05:03 gronej Exp $ * $Log: tbl-gen-c-hdr.h,v $ * Revision 1.3 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.2.2.1 2003/11/05 14:58:55 gronej * working PER code merged with esnacc_1_6 * * Revision 1.2 2001/07/12 19:34:08 leonberp * Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. * * Revision 1.1.1.1 2000/08/21 20:35:55 leonberp * First CVS Version of SNACC. * * Revision 1.1 1995/07/27 08:55:56 rj * first check-in after being merged into .../c-lib/. * */ void TblPrintCHdr PROTO ((TBL *tbl, FILE *f)); esnacc-ng-1.8.1/c-lib/inc/tbl-gen.h000066400000000000000000000015071302010526100166100ustar00rootroot00000000000000#ifndef TBL_GEN_H #define TBL_GEN_H #define USE_GEN_BUF 1 #include "tbl-incl.h" typedef enum {TDEINFO, TDEEOC=TDEINFO, TDEPEEKTAG, TDEPUSHTAG, TDEWARNING, TDEUNEXPECTED=TDEWARNING, TDENONOPTIONAL, TDEMANDATORY, TDECONSTRAINT, TDENOMATCH, TDEERROR} TdeExceptionCode; typedef int (*TdeTypeProc) PROTO ((TBLType* type, AVal* val, int begin)); typedef int (*TdeSimpleProc) PROTO ((AsnTag tag, AsnOcts* val, int begin)); typedef int (*TdeExcProc) PROTO ((TdeExceptionCode code, void* p1, void* p2, void* p3)); int TdeDecode PROTO ((TBL* tbl, GenBuf *b, unsigned long* bytesDecoded, TdeTypeProc typeproc, TdeSimpleProc simpleproc, TdeExcProc excproc)); int TdeDecodeSpecific PROTO ((TBL* tbl, GenBuf *b, TBLType* type, unsigned long* bytesDecoded, TdeTypeProc typeproc, TdeSimpleProc simpleproc, TdeExcProc excproc)); #endif esnacc-ng-1.8.1/c-lib/inc/tbl-incl.h000066400000000000000000000034011302010526100167570ustar00rootroot00000000000000/* * tbl-incl.h - wraps all nec tbl stuff in one file * * Copyright (C) 1993 Michael Sample * and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/inc/tbl-incl.h,v 1.3 2003/12/17 19:05:03 gronej Exp $ * $Log: tbl-incl.h,v $ * Revision 1.3 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.2.2.1 2003/11/05 14:58:55 gronej * working PER code merged with esnacc_1_6 * * Revision 1.2 2001/07/12 19:34:08 leonberp * Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. * * Revision 1.1.1.1 2000/08/21 20:35:55 leonberp * First CVS Version of SNACC. * * Revision 1.2 1997/05/07 15:18:34 wan * Added (limited) size constraints, bitstring and enumeration names to tables * * Revision 1.1 1995/07/27 08:55:57 rj * first check-in after being merged into .../c-lib/. * */ #define TTBL 3 #include "asn-incl.h" #include "tbl.h" typedef void AVal; typedef AVal *AStructVal; /* an array of AVal ptrs */ typedef struct AChoiceVal { enum { achoiceval_notused } choiceId; AVal *val; } AChoiceVal; #include "tbl-util.h" #include "tbl-enc.h" #include "tbl-dec.h" #include "tbl-print.h" #include "tbl-free.h" /* * TblError (char *str) - configure error handler */ #define TblError( str) fprintf (stderr, "%s", str) esnacc-ng-1.8.1/c-lib/inc/tbl-print.h000066400000000000000000000027161302010526100171760ustar00rootroot00000000000000/* * tbl-print.h - type table value printer * * * Mike Sample * * Copyright (C) 1993 Michael Sample * and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/inc/tbl-print.h,v 1.4 2003/12/17 19:05:03 gronej Exp $ * $Log: tbl-print.h,v $ * Revision 1.4 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.3.2.1 2003/11/05 14:58:55 gronej * working PER code merged with esnacc_1_6 * * Revision 1.3 2002/10/21 17:01:21 mcphersc * fixed unsigned short int * * Revision 1.2 2001/07/12 19:34:08 leonberp * Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. * * Revision 1.1.1.1 2000/08/21 20:35:55 leonberp * First CVS Version of SNACC. * * Revision 1.1 1995/07/27 08:55:58 rj * first check-in after being merged into .../c-lib/. * */ void TblPrintValue PROTO ((TBL *tbl, char *modName, char *typeName, FILE *f, AVal *v)); void TblPrintTypeValue PROTO ((TBLType *tblT, FILE *f, AVal *v, unsigned short indent)); esnacc-ng-1.8.1/c-lib/inc/tbl-util.h000066400000000000000000000041051302010526100170110ustar00rootroot00000000000000/* * tbl-util.h - type table utilities. * * * Mike Sample * * Copyright (C) 1993 Michael Sample * and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/inc/tbl-util.h,v 1.4 2003/12/17 19:05:03 gronej Exp $ * $Log: tbl-util.h,v $ * Revision 1.4 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.3.2.1 2003/11/05 14:58:55 gronej * working PER code merged with esnacc_1_6 * * Revision 1.3 2002/10/21 17:13:24 mcphersc * fixed long int * * Revision 1.2 2001/07/12 19:34:09 leonberp * Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. * * Revision 1.1.1.1 2000/08/21 20:35:55 leonberp * First CVS Version of SNACC. * * Revision 1.1 1995/07/27 08:55:59 rj * first check-in after being merged into .../c-lib/. * */ /* * these rely on the TBLTagClass enum starting at zero * and being in the order: UNIVERSAL, APPLICATION, CONTEXT, PRIVATE */ #define TblTagClassToBer(tblClass) (tblClass << 6) #define BerTagClassToTbl(berClass) (berClass >> 6) #define TagsEquiv(asnTag, tblTag) (((tblTag)->encTag == (asnTag)) ||\ (((tblTag)->form == ANY_FORM) &&\ ((tblTag)->encTag == DECONSIFY (asnTag)))) char *LoadFile PROTO ((char *tblFileName, unsigned long *size)); TBL *LoadTblFile PROTO ((char *tblFileName)); TBLTypeDef *TblFindTypeDef PROTO ((TBL *tbl, char *moduleName, char *typeName, TBLModule **tblModHndl)); TBLTypeDef *TblFindTypeDefInMod PROTO ((TBLModule *tbl, char *typeName)); TBLTypeDef *TblFindTypeDefByIndex PROTO ((TBL *tbl,TBLTypeDefId id)); TBLModule *TblFindModule PROTO ((TBL *tbl, char *modName)); esnacc-ng-1.8.1/c-lib/libesnacc.pc.in000066400000000000000000000004701302010526100172100ustar00rootroot00000000000000# Enhanced SNACC pkg-config source file PREFIX=@prefix@ EXEC_PREFIX=@exec_prefix@ LIBDIR=@libdir@ INCLUDEDIR=@includedir@ Name: libesnacc Description: Enhanced SNACC Compiler development support and libs for C Version: @VERSION@ Requires: Conflicts: Libs: -L${LIBDIR} -lcasn1 Cflags: -I${INCLUDEDIR}/c-lib/inc esnacc-ng-1.8.1/c-lib/readme000066400000000000000000000025641302010526100155220ustar00rootroot00000000000000(RCS control information is at the end of this file.) C ASN.1 library README ---------------------- This directory contains the type definitions and the encode, decode, free and print routines for all of the built-in ASN.1 types. It also contains the code for three different buffer types. The makefile will produce 3 different libraries, one for each buffer type. Each buffer types requires a different library because many of the buffer routine calls made from the encode and decode library routines are macros (for performance reasons). The 3 libararies are: libasn1cebuf.a - uses the ExpBufs libasn1cmbuf.a - uses the MinBufs libasn1csbuf.a - uses the SBufs See the documentation for a full descriptions of the buffer types. You must link your code with proper library (i.e. if you use SBufs, link with libasn1csbuf.a). #------------------------------------------------------------------------------- # $Header: /baseline/SNACC/c-lib/readme,v 1.2 2003/12/17 19:05:03 gronej Exp $ # $Log: readme,v $ # Revision 1.2 2003/12/17 19:05:03 gronej # SNACC baseline merged with PER v1_7 tag # # Revision 1.1.2.1 2003/11/05 14:59:00 gronej # working PER code merged with esnacc_1_6 # # Revision 1.1.1.1 2000/08/21 20:35:51 leonberp # First CVS Version of SNACC. # # Revision 1.2 1994/08/31 23:50:07 rj # textual change to adapt to change of directory tree. # esnacc-ng-1.8.1/c-lib/src/000077500000000000000000000000001302010526100151225ustar00rootroot00000000000000esnacc-ng-1.8.1/c-lib/src/asn-BMPString.c000066400000000000000000000036041302010526100176550ustar00rootroot00000000000000 /* Include Files */ #include "asn-incl.h" #include "gen-buf.h" AsnLen BEncBMPStringContent(GenBuf *b, BMPString *octs) { if ((octs->octetLen % 2) != 0) { BufSetWriteError (b, TRUE); } return BEncAsnOctsContent(b, octs); } /* end of BEncBMPStringContent() */ AsnLen BEncBMPString(GenBuf *b, BMPString *v) { AsnLen l; l = BEncBMPStringContent (b, v); l += BEncDefLen (b, l); l += BEncTag1 (b, UNIV, PRIM, BMPSTRING_TAG_CODE); return l; } /* end of BEncBMPString() */ void BDecBMPStringContent(GenBuf *b, AsnTag tagId, AsnLen len, BMPString *result, AsnLen *bytesDecoded, ENV_TYPE env) { BDecAsnOctsContent(b, tagId, len, result, bytesDecoded, env); if ((result->octetLen % 2) != 0) { Asn1Error ("BDecBMPStringContent: ERROR - Invalid BMPString Format"); longjmp (env, -40); } } void BDecBMPString(GenBuf *b, BMPString *result, AsnLen *bytesDecoded, ENV_TYPE env) { AsnTag tag; AsnLen elmtLen1; if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, BMPSTRING_TAG_CODE)) && (tag != MAKE_TAG_ID (UNIV, CONS, BMPSTRING_TAG_CODE))) { Asn1Error ("BDecBMPString: ERROR - wrong tag\n"); longjmp (env, -113); } elmtLen1 = BDecLen (b, bytesDecoded, env); BDecBMPStringContent (b, tag, elmtLen1, result, bytesDecoded, env); } /* BDecBMPString */ /* Convert a BMPString to a wide character string */ int CvtBMPString2wchar(BMPString *inOcts, wchar_t **outStr) { unsigned int i, j; if ((inOcts == NULL) || (outStr == NULL)) return -1; if ((inOcts->octetLen % 2) != 0) return -2; *outStr = (wchar_t*)calloc(inOcts->octetLen / 2 + 1, sizeof(wchar_t)); if (*outStr == NULL) return -1; /* Transform the BMPString into wchar_t array */ for (i = 0, j = 0; i < (inOcts->octetLen / 2); i++, j += 2) (*outStr)[i] = (wchar_t)((inOcts->octs[j] << 8) | inOcts->octs[j + 1]); return 0; } /* end of CvtBMPAsnOcts2wchar() */ esnacc-ng-1.8.1/c-lib/src/asn-IA5String.c000066400000000000000000000033471302010526100176210ustar00rootroot00000000000000 /* Include Files */ #include "asn-incl.h" /* Function Prototypes */ static int checkIA5String(IA5String *octs); AsnLen BEncIA5StringContent(GenBuf *b, IA5String *octs) { if (checkIA5String(octs) != 0) { Asn1Error ("BEncIA5StringContent: ERROR - Invalid IA5String"); GenBufSetWriteError (b, TRUE); } return BEncAsnOctsContent (b, octs); } /* end of BEncIA5StringContent() */ AsnLen BEncIA5String(GenBuf *b, IA5String *v) { AsnLen l; l = BEncIA5StringContent (b, v); l += BEncDefLen (b, l); l += BEncTag1 (b, UNIV, PRIM, IA5STRING_TAG_CODE); return l; } /* end of BEncBMPString() */ void BDecIA5StringContent(GenBuf *b, AsnTag tagId, AsnLen len, IA5String *result, AsnLen *bytesDecoded, ENV_TYPE env) { BDecAsnOctsContent (b, tagId, len, result, bytesDecoded, env); if (checkIA5String(result) != 0) { Asn1Error ("BDecIA5StringContent: ERROR - Invalid IA5String"); longjmp (env, -40); } } /* end of BDecIA5StringContent() */ void BDecIA5String(GenBuf *b, IA5String *result, AsnLen *bytesDecoded, ENV_TYPE env) { AsnTag tag; AsnLen elmtLen1; if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, IA5STRING_TAG_CODE)) && (tag != MAKE_TAG_ID (UNIV, CONS, IA5STRING_TAG_CODE))) { Asn1Error ("BDecIA5String: ERROR - wrong tag\n"); longjmp (env, -105); } elmtLen1 = BDecLen (b, bytesDecoded, env); BDecIA5StringContent (b, tag, elmtLen1, result, bytesDecoded, env); } /* end of BDecIA5String() */ static int checkIA5String(IA5String *octs) { unsigned int i; if (octs == NULL) return -1; for (i = 0; i < octs->octetLen; i++) { if ((unsigned char)octs->octs[i] > 0x7F) return -1; } return 0; } esnacc-ng-1.8.1/c-lib/src/asn-NumericString.c000066400000000000000000000036471302010526100206500ustar00rootroot00000000000000 /* Include Files */ #include "asn-incl.h" /* Function Prototypes */ static int chkNumericString (NumericString *checkBuf); AsnLen BEncNumericStringContent(GenBuf *b, NumericString *octs) { if (chkNumericString (octs) < 0) { Asn1Error ("BEncNumericStringContent: ERROR - Format Error"); GenBufSetWriteError (b, TRUE); } return (BEncAsnOctsContent (b, octs)); } /* end of BEncNumericStringContent() */ AsnLen BEncNumericString(GenBuf *b, NumericString *v) { AsnLen l; l = BEncNumericStringContent (b, v); l += BEncDefLen (b, l); l += BEncTag1 (b, UNIV, PRIM, NUMERICSTRING_TAG_CODE); return l; } /* end of BEncNumericString() */ void BDecNumericStringContent(GenBuf *b, AsnTag tagId, AsnLen len, NumericString *result, AsnLen *bytesDecoded, ENV_TYPE env) { BDecAsnOctsContent (b, tagId, len, result, bytesDecoded, env); if (chkNumericString (result) < 0) { Asn1Error ("BDecNumericStringContent: ERROR - Format Error"); longjmp (env, -40); } } /* end of BDecNumericStringContent() */ void BDecNumericString(GenBuf *b, NumericString *result, AsnLen *bytesDecoded, ENV_TYPE env) { AsnTag tag; AsnLen elmtLen1; if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, NUMERICSTRING_TAG_CODE)) && (tag != MAKE_TAG_ID (UNIV, CONS, NUMERICSTRING_TAG_CODE))) { Asn1Error ("BDecNumericString: ERROR - wrong tag\n"); longjmp (env, -100); } elmtLen1 = BDecLen (b, bytesDecoded, env); BDecNumericStringContent (b, tag, elmtLen1, result, bytesDecoded, env); } /* end of BDecNumericString() */ static int chkNumericString(NumericString *checkBuf) { unsigned int i; if (checkBuf == NULL) return -1; for (i = 0; i < checkBuf->octetLen; i++) { if ((checkBuf->octs[i] != ' ') && ((checkBuf->octs[i] < '0') || (checkBuf->octs[i] > '9'))) return -1; } return 0; } /* end of chkNumericString() */ esnacc-ng-1.8.1/c-lib/src/asn-PrintableStr.c000066400000000000000000000050661302010526100204650ustar00rootroot00000000000000 /* Include Files */ #include "asn-incl.h" /* Function Prototypes */ static int chkPrintableString (PrintableString *checkBuf); AsnLen BEncPrintableStringContent(GenBuf *b, PrintableString *octs) { if (chkPrintableString (octs) < 0) { Asn1Error ("BEncPrintableStringContent: ERROR - Format Error"); GenBufSetWriteError (b, TRUE); } return BEncAsnOctsContent(b, octs); } /* end of BEncPrintableStringContent() */ AsnLen BEncPrintableString(GenBuf *b, PrintableString *v) { AsnLen l; l = BEncPrintableStringContent (b, v); l += BEncDefLen (b, l); l += BEncTag1 (b, UNIV, PRIM, PRINTABLESTRING_TAG_CODE); return l; } /* end of BEncPrintableString() */ void BDecPrintableStringContent(GenBuf *b, AsnTag tagId, AsnLen len, PrintableString *result, AsnLen *bytesDecoded, ENV_TYPE env) { BDecAsnOctsContent (b, tagId, len, result, bytesDecoded, env); if (chkPrintableString (result) < 0) { Asn1Error ("BDecPrintableStringContent: ERROR - Format Error"); longjmp (env, -40); } } /* end of BDecPrintableStringContent() */ void BDecPrintableString(GenBuf *b, PrintableString *result, AsnLen *bytesDecoded, ENV_TYPE env) { AsnTag tag; AsnLen elmtLen1; if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, PRINTABLESTRING_TAG_CODE)) && (tag != MAKE_TAG_ID (UNIV, CONS, PRINTABLESTRING_TAG_CODE))) { Asn1Error ("BDecPrintableString: ERROR - wrong tag\n"); longjmp (env, -101); } elmtLen1 = BDecLen (b, bytesDecoded, env); BDecPrintableStringContent (b, tag, elmtLen1, result, bytesDecoded, env); } /* end of BDecPrintableString() */ static int chkPrintableString(PrintableString *checkBuf) { unsigned int i; char temp; if (checkBuf == NULL) return -1; for (i = 0; i < checkBuf->octetLen; i++) { temp = checkBuf->octs[i]; /* Check A-Z */ if ((temp < 'A') || (temp > 'Z')) { /* Check for a-z */ if ((temp < 'a') || (temp > 'z')) { /* Check for 0-9 */ if ((temp < '0') || (temp > '9')) { switch (temp) { case ' ': /* space */ case '\'': /* apostrophe */ case '(': /* left parenthesis */ case ')': /* right parenthesis */ case '+': /* plus sign */ case ',': /* comma */ case '-': /* hyphen */ case '.': /* full stop (period) */ case '/': /* solidus */ case ':': /* colon */ case '=': /* equal sign */ case '?': /* question mark */ break; default: return -1; } } } } } return 0; } /* end of chkPrintableString() */ esnacc-ng-1.8.1/c-lib/src/asn-TeletexString.c000066400000000000000000000024141302010526100206470ustar00rootroot00000000000000#include "asn-incl.h" AsnLen BEncTeletexStringContent PARAMS ((b, octs), GenBuf *b _AND_ AsnOcts *octs) { return (BEncAsnOctsContent (b, octs)); } AsnLen BEncTeletexString PARAMS ((b, v), GenBuf *b _AND_ TeletexString *v) { AsnLen l; l = BEncTeletexStringContent (b, v); l += BEncDefLen (b, l); l += BEncTag1 (b, UNIV, PRIM, TELETEXSTRING_TAG_CODE); return l; } /* BEncTeletexString */ void BDecTeletexStringContent PARAMS ((b, tagId, len, result, bytesDecoded, env), GenBuf *b _AND_ AsnTag tagId _AND_ AsnLen len _AND_ AsnOcts *result _AND_ AsnLen *bytesDecoded _AND_ ENV_TYPE env) { BDecAsnOctsContent (b, tagId, len, result, bytesDecoded, env); } void BDecTeletexString PARAMS ((b, result, bytesDecoded, env), GenBuf *b _AND_ TeletexString *result _AND_ AsnLen *bytesDecoded _AND_ ENV_TYPE env) { AsnTag tag; AsnLen elmtLen1; if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, TELETEXSTRING_TAG_CODE))&& (tag != MAKE_TAG_ID (UNIV, CONS, TELETEXSTRING_TAG_CODE))) { Asn1Error ("BDecTeletexString: ERROR - wrong tag\n"); longjmp (env, -102); } elmtLen1 = BDecLen (b, bytesDecoded, env); BDecTeletexStringContent (b, tag, elmtLen1, result, bytesDecoded, env); } /* BDecTeletexString */ esnacc-ng-1.8.1/c-lib/src/asn-UTF8String.c000066400000000000000000000356461302010526100200000ustar00rootroot00000000000000 /* Include Files */ #ifndef WIN32 #include #endif #include #include "asn-incl.h" /* Type Definitions */ #ifndef bool typedef char bool; #endif #ifndef true #define true 1 #endif #ifndef false #define false 0 #endif typedef struct { unsigned char mask; unsigned char value; unsigned long maxCharValue; } MaskValue; /* Global Values */ #define MAX_UTF8_OCTS_PER_CHAR 6 const MaskValue gUTF8Masks[MAX_UTF8_OCTS_PER_CHAR] = { { 0x80, 0x00, 0x0000007F }, /* one-byte encoding */ { 0xE0, 0xC0, 0x000007FF }, /* two-byte encoding */ { 0xF0, 0xE0, 0x0000FFFF }, /* three-byte encoding */ { 0xF8, 0xF0, 0x0001FFFF }, /* four-byte encoding */ { 0xFC, 0xF8, 0x03FFFFFF }, /* five-byte encoding */ { 0xFE, 0xFC, 0x07FFFFFF } /* six-byte encoding */ }; /* Constants */ #define FOUR_BYTE_ENCODING 0xf0 #define THREE_BYTE_ENCODING 0xe0 #define TWO_BYTE_ENCODING 0xc0 /* Function Prototypes */ static bool IsValidUTF8String(UTF8String* octs); AsnLen BEncUTF8StringContent(GenBuf *b, UTF8String *octs) { if (IsValidUTF8String(octs) == false) { Asn1Error ("BEncUTF8StringContent: ERROR - Invalid UTF-8 Encoding"); GenBufSetWriteError (b, TRUE); } return (BEncAsnOctsContent (b, octs)); } /* end of BEncUTF8StringContent() */ AsnLen BEncUTF8String(GenBuf *b, UTF8String *v) { AsnLen l; l = BEncUTF8StringContent (b, v); l += BEncDefLen (b, l); l += BEncTag1 (b, UNIV, PRIM, UTF8STRING_TAG_CODE); return l; } /* end of BEncUTF8String() */ void BDecUTF8StringContent(GenBuf *b, AsnTag tagId, AsnLen len, UTF8String *result, AsnLen *bytesDecoded, ENV_TYPE env) { BDecAsnOctsContent (b, tagId, len, result, bytesDecoded, env); if (IsValidUTF8String(result) == false) { Asn1Error ("BDecUTF8StringContent: ERROR - Invalid UTF-8 Encoding"); longjmp (env, -40); } } /* end of BDecUTF8StringContent() */ void BDecUTF8String(GenBuf *b, UTF8String *result, AsnLen *bytesDecoded, ENV_TYPE env) { AsnTag tag; AsnLen elmtLen1; if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, UTF8STRING_TAG_CODE)) && (tag != MAKE_TAG_ID (UNIV, CONS, UTF8STRING_TAG_CODE))) { Asn1Error ("BDecUTF8String: ERROR - wrong tag\n"); longjmp (env, -113); } elmtLen1 = BDecLen (b, bytesDecoded, env); BDecUTF8StringContent (b, tag, elmtLen1, result, bytesDecoded, env); } static bool IsValidUTF8String(UTF8String* octs) { unsigned long i; unsigned int j; if (octs == NULL) return false; i = 0; while (i < octs->octetLen) { /* Determine the number of UTF-8 octets that follow the first */ for (j = 0; (j < MAX_UTF8_OCTS_PER_CHAR) && ((gUTF8Masks[j].mask & octs->octs[i]) != gUTF8Masks[j].value); j++) ; /* Return false if the first octet was invalid or if the number of subsequent octets exceeds the UTF8String length */ if ((j == MAX_UTF8_OCTS_PER_CHAR) || ((i + j) >= octs->octetLen)) return false; /* Skip over first octet */ i++; /* Check that each subsequent octet is properly formatted */ for (; j > 0; j--) { if ((octs->octs[i++] & 0xC0) != 0x80) return false; } } return true; } int CvtUTF8String2wchar(UTF8String *inOcts, wchar_t **outStr) { if ((inOcts == NULL) || (outStr == NULL)) return -1; if (inOcts->octetLen == 0) { *outStr = (wchar_t*)calloc(1, sizeof(wchar_t)); if (*outStr == NULL) return -2; return 0; } else return CvtUTF8towchar(inOcts->octs, outStr); } int CvtUTF8towchar(char *utf8Str, wchar_t **outStr) { unsigned int len, i, j, x; size_t wchar_size = sizeof(wchar_t); if ((utf8Str == NULL) || (outStr == NULL)) return -1; len = strlen(utf8Str); /* Allocate and clear the memory for a worst case result wchar_t string */ *outStr = (wchar_t*)calloc(len + 1, sizeof(wchar_t)); if (*outStr == NULL) return -2; /* Convert the UTF-8 string to a wchar_t string */ i = 0; x = 0; while (i < len) { /* Determine the number of UTF-8 octets that follow the first */ for (j = 0; (j < MAX_UTF8_OCTS_PER_CHAR) && ((gUTF8Masks[j].mask & utf8Str[i]) != gUTF8Masks[j].value); j++) ; /* Return an error if the first octet was invalid or if the number of subsequent octets exceeds the UTF-8 string length */ if ((j == MAX_UTF8_OCTS_PER_CHAR) || ((i + j) >= len)) { free(*outStr); *outStr = NULL; return -3; } /* Return an error if the size of the wchar_t doesn't support the size of this UTF-8 character */ if ((j > 2) && (wchar_size < 4)) { free(*outStr); *outStr = NULL; return -4; } /* Copy the bits from the first octet into the wide character */ (*outStr)[x] = (char)(~gUTF8Masks[j].mask & utf8Str[i++]); /* Add in the bits from each subsequent octet */ for (; j > 0; j--) { /* Return an error if a subsequent octet isn't properly formatted */ if ((utf8Str[i] & 0xC0) != 0x80) { free(*outStr); *outStr = NULL; return -3; } (*outStr)[x] <<= 6; (*outStr)[x] |= utf8Str[i++] & 0x3F; } x++; } /* Reallocate the wchar string memory to its correct size */ if (x < len) { *outStr = (wchar_t*)realloc(*outStr, (x + 1) * sizeof(wchar_t)); if (*outStr == NULL) return -2; } return 0; } int CvtWchar2UTF8(wchar_t *inStr, char **utf8Str) { size_t wLen; unsigned int i, j, x, y; size_t wchar_size = sizeof(wchar_t); wchar_t temp_wchar; /* Check parameters */ if ((inStr == NULL) || (utf8Str == NULL)) return -1; wLen = wcslen(inStr); /* Allocate and clear memory for a worst case UTF-8 string */ *utf8Str = (char*)calloc(wLen * (wchar_size / 2 * 3) + 1, sizeof(char)); if (*utf8Str == NULL) return -2; /* Convert each wide character into a UTF-8 char sequence */ for (i = 0, x = 0; i < wLen; i++) { temp_wchar = inStr[i]; /* Return an error if the wide character is invalid */ if (temp_wchar < 0) { free(*utf8Str); *utf8Str = NULL; return -3; } /* Determine the number of characters required to encode this wide character */ for (j = 0; (j < MAX_UTF8_OCTS_PER_CHAR) && (temp_wchar > gUTF8Masks[j].maxCharValue); j++) ; /* Return an error if the wide character is invalid */ if (j == MAX_UTF8_OCTS_PER_CHAR) { free(*utf8Str); *utf8Str = NULL; return -3; } /* Skip over the first UTF-8 octet and encode the remaining octets (if any) from right-to-left. Fill in the least significant six bits of each octet with the low-order bits from the wide character value */ for (y = j; y > 0; y--) { (*utf8Str)[x + y] = (char)(0x80 | (temp_wchar & 0x3F)); temp_wchar >>= 6; } /* Encode the first UTF-8 octet */ (*utf8Str)[x] = gUTF8Masks[j].value; (*utf8Str)[x++] |= ~gUTF8Masks[j].mask & temp_wchar; /* Update the UTF-8 string index (skipping over the subsequent octets already encoded */ x += j; } return 0; } /* end of CvtWchar2UTF8() */ #ifdef OLD_CODE_ /* * Convert a ISO10646 stream to UTF-8 wide character * Used only by UniversalStrings, BMPStrings, etc */ int CvtToUTFStr(AsnOcts *Octsinputstr, wchar_t **wchar_ptr) { int encodelen = Octsinputstr->octetLen; int newlen = 0; int flip = 1; wchar_t c = 0; char *inputstr = (char *)Octsinputstr->octs; int pos = encodelen; wchar_t *newbuf = (wchar_t *)calloc (1, encodelen*4); memset (newbuf, 0, encodelen*4); while (pos > 0) { memcpy ((wchar_t *)&c, inputstr, sizeof (wchar_t)); if(*(char *)&flip == 1) { c = (c << 8) | (c >> 8); } if (c < 0x80) { newbuf[newlen++] = c; } else if (c < 0x800) { /* Produce the 2 byte encoding */ newbuf[newlen++] = ((0xc0 | (c >>6))<<8) | (0x80 | (c & 0x3f)); } else if (c < 0x10000) { /* Produce the 3 byte encoding */ newbuf[newlen++] = ((0xe0 | (c >>12)) <<8) | (0x80 | ((c >>6) & 0x3f)); newbuf[newlen++] = (0x80 | (c & 0x3f)); } else if (c < 0x200000) { /* Not currently supported */ return (-1); } pos -= sizeof (wchar_t); inputstr += sizeof (wchar_t); } *wchar_ptr = (wchar_t *)newbuf; return (newlen); } /* * Converts a UTF-8 String into a ISO-10646 string */ int CvtUTFToISO (AsnOcts *utf_stringa, wchar_t **wchar_ptr) { int count; char *utf_string = (char *)utf_stringa->octs; int UTF8Len = utf_stringa->octetLen; wchar_t *work_buffer = (wchar_t *)calloc (1, UTF8Len*sizeof(wchar_t)); int newlen = 0; unsigned short enc_sequence; wchar_t enc_value = 0; int encoded_length = 0; /* memset (work_buffer, 0, (UTF8Len*sizeof(wchar_t))); */ count = UTF8Len; while (count > 0) { /* Analyze the UTF encodings */ enc_sequence = (unsigned char)(*utf_string); if (enc_sequence >= FOUR_BYTE_ENCODING) { free (work_buffer); return (-1); } else if (enc_sequence >= THREE_BYTE_ENCODING) { /* three bytes encoded, 16 bits */ enc_value = ((utf_string[0] & 0x3f)<<12) | ((utf_string[1] & 0x3f)<<6) | (utf_string[2] & 0x3f); utf_string += 3; count -= 3; encoded_length = 2; } else if (enc_sequence >= TWO_BYTE_ENCODING) { /* two bytes encoded, 11 bits */ enc_value = ((utf_string[0] & 0x3f)<<6) | (utf_string[1] & 0x3f); utf_string += 2; count -= 2; encoded_length = 2; } else { /* Simple - no encoding needed */ enc_value = enc_sequence; utf_string++; count--; encoded_length = 1; } work_buffer[newlen] = enc_value; newlen ++; } /* NULL Terminate it */\ work_buffer[newlen] = (wchar_t)NULL; /* Update the caller's pointer (may want to realloc it) */ *wchar_ptr = (wchar_t *)work_buffer; /* Return the length */ return (newlen); } /* Format char pointer to RFC 2253 * The flip argument specifies if you want to check for Endian-ness * such as on BMPStrings they are already checked for Endian-ness */ int cvt_WCStrtoLDAP (wchar_t *in_string, char **char_ptr, int flip) { bool quoted = false; /* Flag telling us if we are in a quoted string */ int hex_val = 0; /* Temporary hex value returned from sprintf */ int quote_count = 0; /* Quote counter */ int nullcount = 0; /* The terminating NULL Counter (related to the sizeof wchar_t) */ int count = 0; /* The input byte counter */ int to_count = 0; /* The destination counter */ int buf_len = 0; char *wrkbf = (char *)NULL; wchar_t *lptr = in_string; for (buf_len=0; in_string[buf_len] != (wchar_t)NULL; buf_len++); wrkbf = (char *)calloc (1, buf_len*6); while ((wchar_t)lptr[count] != (wchar_t)NULL) { wchar_t the_string = (wchar_t)lptr[count]; /* Make platform independent */ if(*(char *)&flip == 1) { the_string = (the_string << 8) | (the_string >> 8); } if (the_string != 0) { nullcount = 0; if ((to_count == 0) && (the_string == '#') || (the_string == ' ')) { /* A # or a Space in the first position must be escaped */ wrkbf[to_count] = '\\'; } /* Check the character for Quote */ if ((the_string == '\"') && (!quoted)) { memcpy ((char *)&wrkbf[to_count], (char *)"\\", 1); to_count += 1; quoted = true; } else if ((the_string == '\"') && (quoted)) { /* End the Quoted */ memcpy ((char *)&wrkbf[to_count], (char *)"\\", 1); to_count += 1; quoted = false; } /* Check non printable characters */ if ((the_string < ' ') || (the_string > 0x7E)) { int len = 0; int hex_val = 0; /* Temporary hex value returned from sprintf */ char csprintf[4]; /* Sprintf Buffer */ /* Check for non-ascii values SPACE and DEL */ /* Escape the value */ wrkbf[to_count] = '\\'; /* Backslash */ to_count++; hex_val = the_string; len = sprintf (csprintf,"%2x", hex_val); memcpy ((char *)&wrkbf[to_count], &csprintf[0], 2); to_count += 2; if (len == 4) { /* Check for "00" */ if (memcmp (&csprintf[2], "00", 2) != 0) { wrkbf[to_count] = '\\'; /* Backslash */ to_count++; memcpy ((char *)&wrkbf[to_count], &csprintf[2], 2); to_count += 2; } } } else { if (!quoted) { /* * Escape the following characters if not quoted */ if ((the_string == ',') || (the_string == '=') || (the_string == '+') || (the_string == '<') || (the_string == '>') || (the_string == '#') || (the_string == ';')) { /* Add the escape character to the work buffer */ wrkbf[to_count] = '\\'; to_count ++; } } wrkbf[to_count] = (char)the_string; to_count++; } } else { nullcount ++; } count ++; } /* Check the last character for a SPACE */ if (wrkbf[to_count-1] == ' ') { /* Must be escaped */ wrkbf[to_count] = wrkbf[to_count-1]; wrkbf[to_count-1] = '\\'; } *char_ptr = wrkbf; return (to_count); } /* Format char pointer with RFC 2253 to a char pointer */ int cvt_LDAPtoStr (char *in_string, char **char_ptr) { bool quoted = false; /* Flag telling us if we are in a quoted string */ int hex_val = 0; /* Temporary hex value returned from sprintf */ int quote_count = 0; /* Quote counter */ char hex_str[4]; /* Sprintf Buffer */ char *the_string; /* The character to parse */ char *wrkbf, *buf_ptr; /* Our work buffer */ int nullcount = 0; /* The terminating NULL Counter (related to the sizeof wchar_t) */ int count = 0; /* The input byte counter */ int to_count = 0; /* The destination counter */ int len = 0; int buf_len = 0; char *lptr = (char *)in_string; for (buf_len=0; in_string[buf_len] != (wchar_t)NULL; buf_len++); buf_ptr = (char *)calloc (1, buf_len*6); wrkbf = buf_ptr; the_string = lptr; while (nullcount < sizeof (wchar_t)) { if (the_string != NULL) { if (the_string == (char *)'\\') { if ((the_string >= (char *)'0') && (the_string <= (char *)'9')) { memset (&hex_str, 0, 4); memcpy (hex_str, (char *)&the_string+1, 2); /* Escaped hex value - convert */ hex_val = strtol (hex_str, NULL, 10); /* Copy then to the buffer */ memcpy ((char *)wrkbf[to_count], (char *)&hex_val, 2); the_string++; } else { /* Just skip over the backslash and add the data to the buffer */ wrkbf = (char *)&the_string+1; memcpy ((char *)wrkbf[to_count], (char *)the_string+1, 1); the_string ++; } } else { wrkbf = the_string; } the_string ++; wrkbf++; } } if (to_count < buf_len*6) realloc (wrkbf, to_count+1); *char_ptr = wrkbf; return (to_count); } #endif /* OLD_CODE_ */ esnacc-ng-1.8.1/c-lib/src/asn-UniversalString.c000066400000000000000000000051421302010526100212060ustar00rootroot00000000000000 /* Include Files */ #include "asn-incl.h" #include "gen-buf.h" AsnLen BEncUniversalStringContent(GenBuf *b, UniversalString *octs) { if ((octs->octetLen % 4) != 0) { Asn1Error ("BEncUniversalStringContent: ERROR - Invalid UniversalString Format"); GenBufSetWriteError (b, TRUE); } return BEncAsnOctsContent(b, octs); } /* end of BEncUniversalStringContent() */ AsnLen BEncUniversalString(GenBuf *b, UniversalString *v) { AsnLen l; l = BEncUniversalStringContent (b, v); l += BEncDefLen (b, l); l += BEncTag1 (b, UNIV, PRIM, UNIVERSALSTRING_TAG_CODE); return l; } /* end of BEncUniversalString() */ void BDecUniversalStringContent(GenBuf *b, AsnTag tagId, AsnLen len, UniversalString *result, AsnLen *bytesDecoded, ENV_TYPE env) { BDecAsnOctsContent (b, tagId, len, result, bytesDecoded, env); if ((result->octetLen % 4) != 0) { Asn1Error ("BDecUniversalStringContent: ERROR - Invalid UniversalString Format"); longjmp (env, -40); } } /* end of BDecUniversalStringContent() */ void BDecUniversalString(GenBuf *b, UniversalString *result, AsnLen *bytesDecoded, ENV_TYPE env) { AsnTag tag; AsnLen elmtLen1; if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, UNIVERSALSTRING_TAG_CODE)) && (tag != MAKE_TAG_ID (UNIV, CONS, UNIVERSALSTRING_TAG_CODE))) { Asn1Error ("BDecUniversalString: ERROR - wrong tag\n"); longjmp (env, -112); } elmtLen1 = BDecLen (b, bytesDecoded, env); BDecUniversalStringContent (b, tag, elmtLen1, result, bytesDecoded, env); } /* BDecUniversalString */ /* Convert a UniversalString to a wide character string */ int CvtUniversalString2wchar(UniversalString *inOcts, wchar_t **outStr) { unsigned int i, j; size_t wchar_size = sizeof(wchar_t); if ((inOcts == NULL) || (outStr == NULL)) return -1; if ((inOcts->octetLen % 4) != 0) return -2; if ((wchar_size != 2) && (wchar_size < 4)) return -3; *outStr = (wchar_t*)calloc(inOcts->octetLen / 4 + 1, wchar_size); if (*outStr == NULL) return -4; /* Transform the UniversalString into wchar_t array */ for (i = 0, j = 0; i < (inOcts->octetLen / 4); i++, j += 4) { if (wchar_size == 2) { /* Check that the first two bytes of the UniversalString character are zero */ if ((inOcts->octs[j] != 0) || (inOcts->octs[j + 1] != 0)) { free(*outStr); *outStr = NULL; return -5; } } else /* (wchar_size >= 4) */ (*outStr)[i] |= (inOcts->octs[j] << 24) | (inOcts->octs[j + 1] << 16); (*outStr)[i] |= (inOcts->octs[j + 2] << 8) | inOcts->octs[j + 3]; } return 0; } /* end of CvtUniversalAsnOcts2wchar() */ esnacc-ng-1.8.1/c-lib/src/asn-VisibleString.c000066400000000000000000000036731302010526100206420ustar00rootroot00000000000000 /* Include Files */ #include "asn-incl.h" /* Function Prototypes */ static int chkVisibleString (VisibleString *checkBuf); AsnLen BEncVisibleStringContent(GenBuf *b, VisibleString *octs) { if (chkVisibleString (octs) < 0) { Asn1Error ("BEncVisibleStringContent: ERROR - Format Error"); GenBufSetWriteError (b, TRUE); } return BEncAsnOctsContent(b, octs); } /* end of BEncVisibleStringContent() */ AsnLen BEncVisibleString(GenBuf *b, VisibleString *v) { AsnLen l; l = BEncVisibleStringContent (b, v); l += BEncDefLen (b, l); l += BEncTag1 (b, UNIV, PRIM, VISIBLESTRING_TAG_CODE); return l; } /* end of BEncVisibleString() */ void BDecVisibleStringContent(GenBuf *b, AsnTag tagId, AsnLen len, VisibleString *result, AsnLen *bytesDecoded, ENV_TYPE env) { BDecAsnOctsContent (b, tagId, len, result, bytesDecoded, env); if (chkVisibleString (result) < 0) { Asn1Error ("BDecVisibleStringContent: ERROR - Format Error"); longjmp (env, -40); } } /* end of BDecVisibleStringContent() */ void BDecVisibleString(GenBuf *b, VisibleString *result, AsnLen *bytesDecoded, ENV_TYPE env) { AsnTag tag; AsnLen elmtLen1; if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, VISIBLESTRING_TAG_CODE)) && (tag != MAKE_TAG_ID (UNIV, CONS, VISIBLESTRING_TAG_CODE))) { Asn1Error ("BDecVisibleString: ERROR - wrong tag\n"); longjmp (env, -101); } elmtLen1 = BDecLen (b, bytesDecoded, env); BDecVisibleStringContent (b, tag, elmtLen1, result, bytesDecoded, env); } /* end of BDecVisibleString() */ static int chkVisibleString(VisibleString *checkBuf) { unsigned int i; char temp; if (checkBuf == NULL) return -1; for (i = 0; i < checkBuf->octetLen; i++) { temp = checkBuf->octs[i]; /* Check A-Z */ if((unsigned int)temp > 128) { return -1; } } return 0; } /* end of chkVisibleString() */ esnacc-ng-1.8.1/c-lib/src/asn-any.c000066400000000000000000000267331302010526100166470ustar00rootroot00000000000000/* * asn_any.c - BER encode, decode, print, free, type set up and installation * routines for the ASN.1 ANY and ANY DEFINED BY types. * * MS 92 * Copyright (C) 1992 Michael Sample and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/src/asn-any.c,v 1.11 2004/01/22 20:03:12 nicholar Exp $ */ #include "asn-config.h" #include "asn-len.h" #include "asn-tag.h" #include "asn-oid.h" #include "asn-int.h" #include "asn-any.h" #include AsnLen BEncUnknownAsnAny(GenBuf *b,void *value); void BDecUnknownAsnAny(GenBuf *b,void *value, AsnLen *bytesDecoded, ENV_TYPE env); /* * 2 hash tables. 1 for INTEGER to type mappings the other * for OBJECT IDENTIFER to type mappings. */ Table *anyOidHashTblG = NULL; Table *anyIntHashTblG = NULL; /* * given an ANY type value and a integer hash key, this defines * this any values type (gets ptr to hash tbl entry from int key). * The hash table entry contains ptrs to the encode/decode etc. routines. */ void SetAnyTypeByInt PARAMS ((v, id), AsnAny *v _AND_ AsnInt id) { Hash hash; void *anyInfo; /* use int as hash string */ hash = MakeHash ((char*)&id, sizeof (id)); if (CheckForAndReturnValue (anyIntHashTblG, hash, &anyInfo)) v->ai = (AnyInfo*) anyInfo; else v->ai = NULL; /* indicates failure */ } /* SetAnyTypeByInt */ /* -------- ========== DAD =========== -------------- */ /* I added the following two routines for dealing with * the decode/encode of asn any's */ AsnLen BEncUnknownAsnAny(GenBuf *b,void *value) { AsnOcts *data; /* where we will store the stuff */ /* since the unknown type was just block copied into a oct's struct, we * only need copy it out.... you will need to change this if * you decide to stuff unknown any types for encoding in a * different way. */ data = (AsnOcts *) value; BufPutSegRvs(b, data->octs, data->octetLen); return(data->octetLen); } void BDecUnknownAsnAny(GenBuf *b,void *value, AsnLen *bytesDecoded, ENV_TYPE env) { int err = 0; /* we are going to try unknown items as blobs - we will * peek the tag and length, then record the whole thing * including the tag and length along with it's data * into a buffer which we will have to allocate. */ /* need to record the current read location in the buffer so * that we can copy out the tag+len+data later on. */ #ifdef OLD_CODE #ifdef USE_EXP_BUF loc = (**b).curr; /* for XBUF */ #endif #endif // Use the Memory Buffer Copy Any function err = GenBufCopyAny (b, value, bytesDecoded, env); if (err != 0) longjmp (env, -900); #ifdef OLD_CODE tagId1 = BDecTag(b, &totalElmtsLen1, env); /* item tag */ elmtLen1 = BDecLen (b, &totalElmtsLen1, env); /* len of item */ if (elmtLen1 == INDEFINITE_LEN) { /* can't deal with indef len unknown types here (at least for now) */ Asn1Error("BDecUnknownAsnAny: ERROR - indef length object found\n"); longjmp(env, -1600); } /* and now decode the contents */ data = (AsnOcts *) value; /* allocated by the any routine */ data->octetLen = elmtLen1 + totalElmtsLen1; /* tag+len+data lengths */ data->octs = Asn1Alloc(data->octetLen +1); CheckAsn1Alloc (data->octs, env); /* b was inc'd by our reading the tag - need to mem copy the data * ourselves. */ memcpy(data->octs, loc, totalElmtsLen1); /* use normal buffer reading to append the rest */ BufCopy(&data->octs[totalElmtsLen1] , b, elmtLen1); if (BufReadError(b)) { Asn1Error("BDecUnknownAsnAny: ERROR - decoded past end of data\n"); longjmp(env, -920); } /* add null terminator - this is not included in the str's len */ data->octs[data->octetLen] = '\0'; (*bytesDecoded) += data->octetLen; /* (*bytesDecoded) += totalElmtsLen1; just use the total blob length */ #endif } /* -------- ========== DAD =========== -------------- */ /* * Same as SetAnyTypeByInt except that the hash key is an OBJECT IDENTIFER. */ void SetAnyTypeByOid PARAMS ((v, id), AsnAny *v _AND_ AsnOid *id) { Hash hash; void *anyInfo; /* use encoded oid as hash string */ hash = MakeHash (id->octs, id->octetLen); if (CheckForAndReturnValue (anyOidHashTblG, hash, &anyInfo)) v->ai = (AnyInfo*) anyInfo; else v->ai = NULL; /* indicates failure */ /* DAD - 1/21/98 * Modification to deal with Unknown ANY's - we wish to * leave them in an octet chunk */ if(v->ai == NULL) /* no table entry */ { v->ai = (AnyInfo*) Asn1Alloc (sizeof(AnyInfo)); /* v->ai = (AnyInfo*) malloc(sizeof(AnyInfo)); */ /* fix2 */ /* CheckAsn1Alloc((v->ai), env); fix */ /* v->ai->anyId = (int) hash; need id numbers - use hash for now*/ /* mod for CM v1.2, we will place an unknown any constant into the * ID field so that our higher level code can detect an unknown any based * upon this id rather than assuming that it must scan a list of known * oids... */ v->ai->anyId = (int) kUnknownAnyObjectID; v->ai->oid.octs = id->octs; v->ai->oid.octetLen = id->octetLen; v->ai->size = sizeof(AsnOcts); /* store in octs struct, but diff coders */ v->ai->Encode = (EncodeFcn)BEncUnknownAsnAny; v->ai->Decode = (DecodeFcn)BDecUnknownAsnAny; v->ai->Free = (FreeFcn)FreeAsnOcts; #ifdef _USE_PRINTING_ v->ai->Print = (PrintFcn)PrintAsnOcts; #else v->ai->Print = (PrintFcn)NULL; #endif /* _USE_PRINTING_ */ /* Additional mod - for CM version 1.2 we will no longer place the Unknown * any handler into the table, intead catching the failed lookup each * time for a particular instance. */ #ifdef _OLDER_LIB_ /* after this is called with an oid we didn't have, from now on * this generic handler will be found for all further calls with * the given oid. */ if (anyOidHashTblG == NULL) anyOidHashTblG = InitHash(); if (anyOidHashTblG != NULL) { /* make sure we didn't fail */ Insert(anyOidHashTblG, v->ai, hash); } else { free(a); } #endif /* _OLDER_LIB_ */ } } /* SetAnyTypeByOid */ /* *RWC;ADDED this new "C" function to allow generic ANY's to be encoded/decoded. */ void SetAnyTypeUnknown PARAMS ((v), AsnAny *v) { if(v->ai == NULL) /* no table entry */ { v->ai = (AnyInfo*) Asn1Alloc (sizeof(AnyInfo)); v->ai->anyId = (int) kUnknownAnyObjectID; /*RWC;v->ai->oid.octs = id->octs; v->ai->oid.octetLen = id->octetLen;*RWC;*/ v->ai->size = sizeof(AsnOcts); /* store in octs struct, but diff coders */ v->ai->Encode = (EncodeFcn)BEncUnknownAsnAny; v->ai->Decode = (DecodeFcn)BDecUnknownAsnAny; v->ai->Free = (FreeFcn)FreeAsnOcts; #ifdef _USE_PRINTING_ v->ai->Print = (PrintFcn)PrintAsnOcts; #else v->ai->Print = (PrintFcn)NULL; #endif /* _USE_PRINTING_ */ } } /* SetAnyTypeByUnknown */ /* * Creates an entry in the hash table that contains the * type's size, encode, decode, free, and print routines and anyId. * The given intId is used as the hash key so future calls to * SetAnyTypeByInt with that intId as the id will reference this entry. * The anyId is stored in the hash tbl entry as well so the user can * figure out the type with a simple integer comparison. * * This routine is usually called from the AnyInit routine that * the compiler generates from MACRO info. Call this routine * once for each possible ANY type to set up the hash table. * Future calls to SetAnyTypeByInt/Oid will reference this table. */ void InstallAnyByInt PARAMS ((anyId, intId, size, Encode, Decode, Free, Print), int anyId _AND_ AsnInt intId _AND_ unsigned int size _AND_ EncodeFcn Encode _AND_ DecodeFcn Decode _AND_ FreeFcn Free _AND_ PrintFcn Print) { AnyInfo *a; Hash h; a = (AnyInfo*) malloc (sizeof (AnyInfo)); a->anyId = anyId; a->oid.octs = NULL; a->oid.octetLen = 0; a->intId = intId; a->size = size; a->Encode = Encode; a->Decode = Decode; a->Free = Free; a->Print = Print; if (anyIntHashTblG == NULL) anyIntHashTblG = InitHash(); h = MakeHash ((char*)&intId, sizeof (intId)); if(anyIntHashTblG != NULL) { /* make sure we didn't fail */ Insert(anyIntHashTblG, a, h); } else { free(a); } } /* InstallAnyByOid */ /* * Same as InstallAnyByInt except the oid is used as the hash key */ void InstallAnyByOid PARAMS ((anyId, oid, size, Encode, Decode, Free, Print), int anyId _AND_ AsnOid *oid _AND_ unsigned int size _AND_ EncodeFcn Encode _AND_ DecodeFcn Decode _AND_ FreeFcn Free _AND_ PrintFcn Print) { AnyInfo *a; Hash h; a = (AnyInfo*) malloc (sizeof (AnyInfo)); a->anyId = anyId; a->oid.octs = oid->octs; a->oid.octetLen = oid->octetLen; a->size = size; a->Encode = Encode; a->Decode = Decode; a->Free = Free; a->Print = Print; h = MakeHash (oid->octs, oid->octetLen); if (anyOidHashTblG == NULL) anyOidHashTblG = InitHash(); if(anyOidHashTblG != NULL) { /* make sure we didn't fail */ Insert(anyOidHashTblG, a, h); } else { free(a); } } /* InstallAnyByOid */ /* * Calls the free routine in this type's any info. * If the routine ptr is NULL, nothing is done * (This is the case for INTEGERs, BOOLEANs and other simple * values) */ void FreeAsnAny PARAMS ((v), AsnAny *v) { if ((v->ai != NULL) && (v->ai->Free != NULL)) { v->ai->Free (v->value); } else { Asn1Free(v->value); } if (v->ai && v->ai->anyId == kUnknownAnyObjectID) { Asn1Free(v->ai); } } /* FreeAsnAny */ /* * Calls the Encode routine pointed to in the given type's * Any Info. If the routine ptr is NULL nothing is encoded * (This should set some type of error). * Note: this calls the BEncFoo not BEncFooContent routine form * since the tags are needed too. */ AsnLen BEncAsnAny PARAMS ((b, v), GenBuf *b _AND_ AsnAny *v) { if ((v->ai != NULL) && (v->ai->Encode != NULL)) return v->ai->Encode (b, v->value); else return 0; } /* BEncAsnAny */ /* * Calls the Decode routine pointed to in the given type's * Any Info. If the routine ptr is NULL any error is flagged. * Note: this calls the BDecFoo not BDecFooContent routine form * since the tags are needed too. */ void BDecAsnAny PARAMS ((b, result, bytesDecoded, env), GenBuf *b _AND_ AsnAny *result _AND_ AsnLen *bytesDecoded _AND_ ENV_TYPE env) { if ((result->ai != NULL) && (result->ai->Decode != NULL)) { result->value = (void*) Asn1Alloc (result->ai->size); CheckAsn1Alloc (result->value, env); result->ai->Decode (b, result->value, bytesDecoded, env); } else { Asn1Error ("ERROR - ANY Decode routine is NULL\n"); longjmp (env, -44); } } /* * Calls the print routine pointed to from the given type's * Any Info. Prints an error if the type does not have * any 'AnyInfo' or if the AnyInfo has a NULL Print routine ptr. */ void PrintAsnAny PARAMS ((f, v, indent), FILE *f _AND_ AsnAny *v _AND_ unsigned int indent) { if ((v->ai != NULL) && (v->ai->Print != NULL)) v->ai->Print (f, v->value, indent); else fprintf (f," -- ERROR: malformed ANY value --"); } esnacc-ng-1.8.1/c-lib/src/asn-bits.c000066400000000000000000000260751302010526100170200ustar00rootroot00000000000000/* * .../c-lib/src/asn-bits.c - BER encode, decode, print and free routines for ASN.1 BIT STRING type * * MS 92 * Copyright (C) 1992 Michael Sample and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/src/asn-bits.c,v 1.15 2004/03/23 18:49:21 gronej Exp $ */ #include "asn-config.h" #if STDC_HEADERS || HAVE_STRING_H #include #else #include #endif #include "asn-len.h" #include "asn-tag.h" #include "str-stk.h" #include "asn-bits.h" static unsigned short unusedBitsG; const char numToHexCharTblG[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; /* * encodes universal TAG LENGTH and Contents of and ASN.1 BIT STRING */ AsnLen BEncAsnBits PARAMS ((b, data), GenBuf *b _AND_ AsnBits *data) { AsnLen len; len = BEncAsnBitsContent (b, data); len += BEncDefLen (b, len); len += BEncTag1 (b, UNIV, PRIM, BITSTRING_TAG_CODE); return len; } /* BEncAsnInt */ /* * decodes universal TAG LENGTH and Contents of and ASN.1 BIT STRING */ void BDecAsnBits PARAMS ((b, result, bytesDecoded, env), GenBuf *b _AND_ AsnBits *result _AND_ AsnLen *bytesDecoded _AND_ jmp_buf env) { AsnTag tag; AsnLen elmtLen; if (((tag =BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, BITSTRING_TAG_CODE)) && (tag != MAKE_TAG_ID (UNIV, CONS, BITSTRING_TAG_CODE))) { Asn1Error ("BDecAsnBits: ERROR - wrong tag on BIT STRING.\n"); longjmp (env, -40); } elmtLen = BDecLen (b, bytesDecoded, env); BDecAsnBitsContent (b, tag, elmtLen, result, bytesDecoded, env); } /* BDecAsnBits */ /* * Encodes the BIT STRING value (including the unused bits * byte) to the given buffer. */ AsnLen BEncAsnBitsContent PARAMS ((b, bits), GenBuf *b _AND_ AsnBits *bits) { unsigned long unusedBits; unsigned long byteLen; if (!b || !bits) return 0; /* Calculate number of bytes and number of unused bits */ byteLen = (bits->bitLen + 7) / 8; unusedBits = (unsigned char)(bits->bitLen % 8); if (unusedBits != 0) unusedBits = 8 - unusedBits; BufPutSegRvs(b, bits->bits, byteLen); BufPutByteRvs(b, unusedBits); return byteLen + 1; } /* BEncAsnBitsContent */ /* * Used when decoding to combine constructed pieces into one * contiguous block. * Fills string stack with references to the pieces of a * construced bit string. sets unusedBitsG appropriately. * and strStkG.totalByteLenG to bytelen needed to hold the bitstring */ static void FillBitStringStk PARAMS ((b, elmtLen0, bytesDecoded, env), GenBuf *b _AND_ AsnLen elmtLen0 _AND_ AsnLen *bytesDecoded _AND_ jmp_buf env) { unsigned long refdLen; char *strPtr; unsigned long totalElmtsLen1 = 0; unsigned long tagId1; unsigned long elmtLen1; unsigned long lenToRef; for (; (totalElmtsLen1 < elmtLen0) || (elmtLen0 == INDEFINITE_LEN); ) { tagId1 = BDecTag (b, &totalElmtsLen1, env); if ((tagId1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN)) { BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env); break; } elmtLen1 = BDecLen (b, &totalElmtsLen1, env); if (tagId1 == MAKE_TAG_ID (UNIV, PRIM, BITSTRING_TAG_CODE)) { /* * primitive part of string, put references to piece (s) in * str stack */ if (elmtLen1 == 0) { Asn1Error("BDecAsnBitsContent: ERROR - invalid length on " "primitive BIT STRING\n"); longjmp(env, -6); } /* * get unused bits octet */ if (unusedBitsG != 0) { /* * whoa - only allowed non-octet aligned bits on * on last piece of bits string */ Asn1Error ("FillBitStringStk: ERROR - a component of a constructed BIT STRING that is not the last has non-zero unused bits\n"); longjmp (env, -1); } unusedBitsG = BufGetByte(b); lenToRef =elmtLen1-1; /* remove one octet for the unused bits oct*/ while (lenToRef > 0) { refdLen = lenToRef; strPtr = (char *)BufGetSeg (b, &refdLen); if (refdLen == 0) { /* end of data */ Asn1Error( "FillBitStringStk: ERROR - expecting more data\n"); longjmp(env, -2); } PUSH_STR (strPtr, refdLen, env); lenToRef -= refdLen; } totalElmtsLen1 += elmtLen1; } else if (tagId1 == MAKE_TAG_ID (UNIV, CONS, BITSTRING_TAG_CODE)) { /* * constructed octets string embedding in this constructed * octet string. decode it. */ FillBitStringStk (b, elmtLen1, &totalElmtsLen1, env); } else /* wrong tag */ { Asn1Error ("FillBitStringStk: ERROR - decoded non-BIT STRING tag inside a constructed BIT STRING\n"); longjmp (env, -3); } } /* end of for */ *bytesDecoded += totalElmtsLen1; } /* FillBitStringStk */ /* * Decodes a seq of universally tagged bits until either EOC is * encountered or the given len decoded. Returns them in a * single concatenated bit string */ static void BDecConsAsnBits PARAMS ((b, len, result, bytesDecoded, env), GenBuf *b _AND_ AsnLen len _AND_ AsnBits *result _AND_ AsnLen *bytesDecoded _AND_ jmp_buf env) { char *bufCurr; unsigned long curr; RESET_STR_STK(); /* * decode each piece of the octet string, puting * an entry in the octet/bit string stack for each */ FillBitStringStk (b, len, bytesDecoded, env); /* alloc single str long enough for combined bitstring */ result->bitLen = strStkG.totalByteLen*8 - unusedBitsG; bufCurr = result->bits = Asn1Alloc (strStkG.totalByteLen); CheckAsn1Alloc (result->bits, env); /* copy bit string pieces (buffer refs) into single block */ for (curr = 0; curr < strStkG.nextFreeElmt; curr++) { memcpy (bufCurr, strStkG.stk[curr].str, strStkG.stk[curr].len); bufCurr += strStkG.stk[curr].len; } } /* BDecConsAsnBits */ /* * Decodes the content of a BIT STRING (including the unused bits octet) * Always returns a single contiguous bit string */ void BDecAsnBitsContent PARAMS ((b, tagId, len, result, bytesDecoded, env), GenBuf *b _AND_ AsnTag tagId _AND_ AsnLen len _AND_ AsnBits *result _AND_ AsnLen *bytesDecoded _AND_ jmp_buf env) { /* * tagId is encoded tag shifted into long int. * if CONS bit is set then constructed bit string */ if (TAG_IS_CONS (tagId)) BDecConsAsnBits (b, len, result, bytesDecoded, env); else /* primitive octet string */ { if (len == INDEFINITE_LEN) { Asn1Error( "BDecAsnBitsContent: ERROR - indefinite len on primitive\n"); longjmp(env, -5); } else if (len == 0) { Asn1Error( "BDecAsnBitsContent: ERROR - invalid len on primitive BIT STRING\n"); longjmp(env, -6); } (*bytesDecoded) += len; len--; result->bitLen = (len * 8) - (unsigned int)BufGetByte (b); result->bits = Asn1Alloc (len); CheckAsn1Alloc (result->bits, env); BufCopy (result->bits, b, len); if (BufReadError (b)) { Asn1Error( "BDecAsnBitsContent: ERROR - decoded past end of data\n"); longjmp(env, -4); } } } /* BDecAsnBitsContent */ /* * Frees the string part of a BIT STRING */ void FreeAsnBits PARAMS ((v), AsnBits *v) { Asn1Free (v->bits); } /* FreeAsnBits */ /* * Prints the contents of the given BIT STRING to the * given file. indent is ignored. Always uses ASN.1 Value Notaion * Hex format. (Should be binary versions in some cases) */ void PrintAsnBits PARAMS ((f,v, indent), FILE *f _AND_ AsnBits *v _AND_ unsigned int indent) { int i; unsigned long octetLen; if (v->bitLen == 0) octetLen = 0; else octetLen = (v->bitLen-1)/8 +1; fprintf (f,"'"); for (i = 0; i < (int)octetLen; i++) fprintf (f,"%c%c", TO_HEX (v->bits[i] >> 4), TO_HEX (v->bits[i])); fprintf (f,"'H"); indent=indent; /* referenced to avoid compiler warning. */ } /* PrintAsnBits */ /* * Returns TRUE if the given BIT STRINGs are identical. * Otherwise returns FALSE. */ int AsnBitsEquiv PARAMS ((b1, b2), AsnBits *b1 _AND_ AsnBits *b2) { int octetsLessOne; int unusedBits; if ((b1->bitLen == 0) && (b2->bitLen == 0)) return TRUE; octetsLessOne = (b1->bitLen-1)/8; unusedBits = b1->bitLen % 8; if (unusedBits != 0) unusedBits = 8 - unusedBits; /* trailing bits may not be significant */ return b1->bitLen == b2->bitLen && !memcmp(b1->bits, b2->bits, octetsLessOne) && ((b1->bits[octetsLessOne] & (0xFF << unusedBits)) == (b1->bits[octetsLessOne] & (0xFF << unusedBits))); } /* AsnBitsEquiv */ /* * Set given bit to 1. Most significant bit is bit 0, least significant * is bit (v1->bitLen -1) */ void SetAsnBit PARAMS ((b1, bit), AsnBits *b1 _AND_ size_t bit) { unsigned long octet; unsigned long octetsBit; if (bit < (unsigned long)b1->bitLen) { octet = bit/8; octetsBit = 7 - (bit % 8);/* bit zero is first/most sig bit in octet */ b1->bits[octet] |= 1 << octetsBit; } } /* SetAsnBit */ /* * Set given bit to 0. Most significant bit is bit 0, least significant * is bit (v1->bitLen -1) */ void ClrAsnBit PARAMS ((b1, bit), AsnBits *b1 _AND_ size_t bit) { unsigned long octet; unsigned long octetsBit; if (bit < (unsigned long)b1->bitLen) { octet = bit/8; octetsBit = 7 - (bit % 8);/* bit zero is first/most sig bit in octet */ b1->bits[octet] &= ~(1 << octetsBit); } } /* ClrAsnBit */ /* * Get given bit. Most significant bit is bit 0, least significant * is bit (v1->bitLen -1). Returns TRUE if the bit is 1. Returns FALSE * if the bit is 0. if the bit is out of range then returns 0. */ int GetAsnBit PARAMS ((b1, bit), AsnBits *b1 _AND_ size_t bit) { unsigned long octet; unsigned long octetsBit; if (bit < (unsigned long)b1->bitLen) { octet = bit/8; octetsBit = 7 - (bit % 8); /* bit zero is first/most sig bit in octet*/ return b1->bits[octet] & (1 << octetsBit); } return 0; } /* AsnBits::GetBit */ esnacc-ng-1.8.1/c-lib/src/asn-bool.c000066400000000000000000000107071302010526100170050ustar00rootroot00000000000000/* * asn_bool.c * * MS 92 * Copyright (C) 1992 Michael Sample and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/src/asn-bool.c,v 1.10 2004/04/21 13:28:42 gronej Exp $ * $Log: asn-bool.c,v $ * Revision 1.10 2004/04/21 13:28:42 gronej * v1_7 release fix * * Revision 1.9 2004/04/21 13:10:35 gronej * patch submitted by Oskar to fix free calls * * Revision 1.8 2004/01/22 20:03:12 nicholar * Changed indent variable to an unsigned int from an unsigned short. Indent is used in library print functions and generated print functions * * Revision 1.7 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.6.2.1 2003/11/05 14:58:53 gronej * working PER code merged with esnacc_1_6 * * Revision 1.6 2002/10/23 10:23:37 mcphersc * Changed BUF_TYPE to AsnBuf * * Revision 1.5 2002/10/21 17:01:29 mcphersc * fixed unsigned short int * * Revision 1.4 2002/09/03 19:33:20 vracarl * got rid of c++ comments * * Revision 1.3 2002/07/25 10:57:17 sfl * modified line 117 to be tagId=tagId and line 134 to be indent=indent to get rid of warnings * * Revision 1.1.1.1 2000/08/21 20:35:52 leonberp * First CVS Version of SNACC. * * Revision 1.3 1995/07/24 21:04:49 rj * changed `_' to `-' in file names. * * Revision 1.2 1994/09/01 00:05:57 rj * reduce the risk of unwanted surprises with macro expansion by properly separating the C tokens. * * Revision 1.1 1994/08/28 09:45:51 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include "asn-config.h" #include "asn-len.h" #include "asn-tag.h" #include "asn-bool.h" /* * encodes universal TAG LENGTH and Contents of and ASN.1 BOOLEAN */ AsnLen BEncAsnBool PARAMS ((b, data), GenBuf *b _AND_ AsnBool *data) { AsnLen len; len = BEncAsnBoolContent (b, data); len += BEncDefLen (b, len); len += BEncTag1 (b, UNIV, PRIM, BOOLEAN_TAG_CODE); return len; } /* BEncAsnBool */ /* * decodes universal TAG LENGTH and Contents of and ASN.1 BOOLEAN */ void BDecAsnBool PARAMS ((b, result, bytesDecoded, env), GenBuf *b _AND_ AsnBool *result _AND_ AsnLen *bytesDecoded _AND_ jmp_buf env) { AsnTag tag; AsnLen elmtLen; if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, BOOLEAN_TAG_CODE)) { Asn1Error ("BDecAsnBool: ERROR - wrong tag on BOOLEAN.\n"); longjmp (env, -40); } elmtLen = BDecLen (b, bytesDecoded, env); BDecAsnBoolContent (b, tag, elmtLen, result, bytesDecoded, env); } /* BDecAsnBool */ /* * Encodes just the content of the given BOOLEAN value to the given buffer. */ AsnLen BEncAsnBoolContent PARAMS ((b, data), GenBuf *b _AND_ AsnBool *data) { BufPutByteRvs (b, (unsigned char)(*data ? 0xFF : 0)); return 1; } /* BEncAsnBoolContent */ /* * Decodes just the content of an ASN.1 BOOLEAN from the given buffer. * longjmps if there is a buffer reading problem */ void BDecAsnBoolContent PARAMS ((b, tagId, len, result, bytesDecoded, env), GenBuf *b _AND_ AsnTag tagId _AND_ AsnLen len _AND_ AsnBool *result _AND_ AsnLen *bytesDecoded _AND_ jmp_buf env) { if (len != 1) { Asn1Error ("BDecAsnBoolContent: ERROR - BOOLEAN length must be 1\n"); longjmp (env,-5); } (*bytesDecoded)++; *result = (unsigned char)(BufGetByte (b) != 0); if (BufReadError (b)) { Asn1Error ("BDecAsnBoolContent: ERROR - decoded past end of data\n"); longjmp (env, -6); } tagId = tagId; /* referenced to avoid compiler warning. */ } /* BDecAsnBoolContent */ /* * Prints the given BOOLEAN to the given FILE * in ASN.1 Value notation. * Does not use the indent. */ void PrintAsnBool PARAMS ((f, v, indent), FILE *f _AND_ AsnBool *v _AND_ unsigned int indent) { if (*v) fprintf (f, "TRUE"); else fprintf (f, "FALSE"); indent = indent ; /* referenced to avoid compiler warning. */ } void FreeAsnBool PARAMS ((b), AsnBool* b) { b=b; } esnacc-ng-1.8.1/c-lib/src/asn-der.c000066400000000000000000000045741302010526100166310ustar00rootroot00000000000000/* * asn-der.c - These are used by DER encoders to sort the order of the * components in a SET OF * * Dean Povey 97/08 * Copyright (C) 1997 Dean Povey and the Distributed Systems Technology Centre * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/src/asn-der.c,v 1.7 2003/12/17 19:05:03 gronej Exp $ * $Log: asn-der.c,v $ * Revision 1.7 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.6.2.1 2003/11/05 14:58:53 gronej * working PER code merged with esnacc_1_6 * * Revision 1.6 2002/10/15 17:46:39 mcphersc * Compare mods * * Revision 1.4 2002/03/20 22:36:06 rwc * Fixed DER SET OF encoding rule failures; COMPILER code for these rules worked fine, * but the actual qsort handling routine did not return the * proper return code for sorting. Tested using the ./c-examples/vdatestC/vdatestC.c program. * * Revision 1.3 2002/03/20 22:09:28 vracarl * added 2 BufResetInReadMode calls * * Revision 1.2 2000/10/24 14:54:42 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:35:52 leonberp * First CVS Version of SNACC. * * Revision 1.1 1997/08/28 07:25:57 povey * Changes to support DER encoding/decoding * * */ #include "asn-config.h" #include "asn-der.h" #include // Simple Compare int EncodedElmtCmp(const void* a1, const void* b1) { int len = 0; int cmp = -1; unsigned char data1; unsigned char data2; EncodedElmt *a = (EncodedElmt *) a1; EncodedElmt *b = (EncodedElmt *) b1; /* Get minimum length */ len = (a->len > b->len)?b->len:a->len; while (len-- > 0) { data1 = BufGetByte (a->b); data2 = BufGetByte (b->b); if (data1++ != data2++) cmp = data1 < data2 ? -1 : 1; } BufResetInReadMode(a->b); BufResetInReadMode(b->b); return cmp; } esnacc-ng-1.8.1/c-lib/src/asn-enum.c000066400000000000000000000046501302010526100170160ustar00rootroot00000000000000/* * asn_enum.c - routines for the ASN.1 ENUMERATED type * * MS 92 * Copyright (C) 1992 Michael Sample and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/src/asn-enum.c,v 1.3 2003/12/17 19:05:03 gronej Exp $ * $Log: asn-enum.c,v $ * Revision 1.3 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.2.2.1 2003/11/05 14:58:53 gronej * working PER code merged with esnacc_1_6 * * Revision 1.2 2002/10/23 10:23:37 mcphersc * Changed BUF_TYPE to AsnBuf * * Revision 1.1.1.1 2000/08/21 20:35:52 leonberp * First CVS Version of SNACC. * * Revision 1.3 1995/07/24 21:04:50 rj * changed `_' to `-' in file names. * * Revision 1.2 1994/09/01 01:04:38 rj * reduce the risk of unwanted surprises with macro expansion by properly separating the C tokens. * * Revision 1.1 1994/08/28 09:45:52 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include "asn-config.h" #include "asn-len.h" #include "asn-tag.h" #include "asn-int.h" #include "asn-enum.h" /* * encodes universal TAG LENGTH and Contents of and ASN.1 ENUMERATED */ AsnLen BEncAsnEnum PARAMS ((b, data), GenBuf *b _AND_ AsnEnum *data) { AsnLen len; len = BEncAsnEnumContent (b, data); len += BEncDefLen (b, len); len += BEncTag1 (b, UNIV, PRIM, ENUM_TAG_CODE); return len; } /* BEncAsnEnum */ /* * decodes universal TAG LENGTH and Contents of and ASN.1 ENUMERATED */ void BDecAsnEnum PARAMS ((b, result, bytesDecoded, env), GenBuf *b _AND_ AsnEnum *result _AND_ AsnLen *bytesDecoded _AND_ jmp_buf env) { AsnTag tag; AsnLen elmtLen; if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, ENUM_TAG_CODE)) { Asn1Error ("BDecAsnInt: ERROR wrong tag on ENUMERATED.\n"); longjmp (env, -40); } elmtLen = BDecLen (b, bytesDecoded, env); BDecAsnEnumContent (b, tag, elmtLen, result, bytesDecoded, env); } /* BDecAsnEnum */ esnacc-ng-1.8.1/c-lib/src/asn-int.c000066400000000000000000000243201302010526100166400ustar00rootroot00000000000000/* * asn_int.c - BER encode, decode, print and free routines for the * ASN.1 INTEGER type * * MS 92 * Copyright (C) 1992 Michael Sample and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/src/asn-int.c,v 1.14 2004/04/21 13:29:16 gronej Exp $ * $Log: asn-int.c,v $ * Revision 1.14 2004/04/21 13:29:16 gronej * v1_7 release fix * * Revision 1.13 2004/04/21 13:10:35 gronej * patch submitted by Oskar to fix free calls * * Revision 1.12 2004/01/22 20:03:12 nicholar * Changed indent variable to an unsigned int from an unsigned short. Indent is used in library print functions and generated print functions * * Revision 1.11 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.10.2.1 2003/11/05 14:58:53 gronej * working PER code merged with esnacc_1_6 * * Revision 1.10 2002/10/23 10:23:37 mcphersc * Changed BUF_TYPE to AsnBuf * * Revision 1.9 2002/10/21 17:13:16 mcphersc * fixed long int * * Revision 1.8 2002/10/21 17:01:29 mcphersc * fixed unsigned short int * * Revision 1.7 2002/10/18 13:09:02 mcphersc * took out long int to unsigned long * * Revision 1.6 2002/09/03 19:43:11 vracarl * fixed a typo * * Revision 1.5 2002/09/03 19:33:19 vracarl * got rid of c++ comments * * Revision 1.4 2002/07/25 11:00:10 sfl * Modified: * Line 183 * tagId=tagId to get rid of warnings * Line 199 * indent=indent to get rid of warnings * Line 369 * tag=tag to get rid of warnings * Line 381 * indent=indent to get rid of warninsg * * Revision 1.2 2000/10/16 18:10:39 rwc * removed most warnings from C++-lib, some C-lib. * * Revision 1.1.1.1 2000/08/21 20:35:52 leonberp * First CVS Version of SNACC. * * Revision 1.3 1995/07/24 21:04:51 rj * changed `_' to `-' in file names. * * Revision 1.2 1994/09/01 00:05:05 rj * reduce the risk of unwanted surprises with macro expansion by properly separating the C tokens. * * Revision 1.1 1994/08/28 09:45:53 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include "asn-config.h" #include "asn-len.h" #include "asn-tag.h" #include "asn-int.h" /* * encodes universal TAG LENGTH and Contents of and ASN.1 INTEGER */ AsnLen BEncAsnInt PARAMS ((b, data), GenBuf *b _AND_ AsnInt *data) { AsnLen len; len = BEncAsnIntContent (b, data); len += BEncDefLen (b, len); len += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE); return len; } /* BEncAsnInt */ /* * decodes universal TAG LENGTH and Contents of and ASN.1 INTEGER */ void BDecAsnInt PARAMS ((b, result, bytesDecoded, env), GenBuf *b _AND_ AsnInt *result _AND_ AsnLen *bytesDecoded _AND_ jmp_buf env) { AsnTag tag; AsnLen elmtLen; if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)) { Asn1Error ("BDecAsnInt: ERROR wrong tag on INTEGER.\n"); longjmp (env, -40); } elmtLen = BDecLen (b, bytesDecoded, env); BDecAsnIntContent (b, tag, elmtLen, result, bytesDecoded, env); } /* BDecAsnInt */ /* * encodes signed long integer's contents */ AsnLen BEncAsnIntContent PARAMS ((b, data), GenBuf *b _AND_ AsnInt *data) { int len; int i; unsigned long mask; long dataCpy; #define INT_MASK (0x7f80 << ((sizeof(AsnInt) - 2) * 8)) dataCpy = *data; /* * calculate encoded length of the integer (content) */ mask = INT_MASK; if (dataCpy < 0) for (len = sizeof (AsnInt); len > 1; --len) { if ((dataCpy & mask) == mask) mask >>= 8; else break; } else for (len = sizeof (AsnInt); len > 1; --len) { if ((dataCpy & mask) == 0) mask >>= 8; else break; } /* * write the BER integer */ for (i = 0; i < len; i++) { BufPutByteRvs (b, (unsigned char)dataCpy); dataCpy >>= 8; } return len; } /* BEncAsnIntContent */ /* * Decodes content of BER a INTEGER value. The given tag is ignored. */ void BDecAsnIntContent PARAMS ((b, tagId, len, result, bytesDecoded, env), GenBuf *b _AND_ AsnTag tagId _AND_ AsnLen len _AND_ AsnInt *result _AND_ AsnLen *bytesDecoded _AND_ jmp_buf env) { int i; long retVal; unsigned long byte; if (len > sizeof (AsnInt)) { Asn1Error ("BDecAsnIntContent: ERROR - integer to big to decode.\n"); longjmp (env, -7); } /* * look at integer value */ byte = (unsigned long ) BufGetByte (b); if (byte & 0x80) /* top bit of first byte is sign bit */ retVal = (-1 << 8) | byte; else retVal = byte; /* * write from buffer into long int */ for (i = 1; i < (int)len; i++) retVal = (retVal << 8) | (unsigned long)(BufGetByte (b)); if (BufReadError (b)) { Asn1Error ("BDecAsnIntContent: ERROR - decoded past end of data \n"); longjmp (env, -8); } (*bytesDecoded) += len; *result = retVal; tagId=tagId; /* referenced to avoid compiler warning. */ } /* BDecAsnIntContent */ /* * Prints the given integer to the given FILE * in Value Notation. * indent is ignored. */ void PrintAsnInt PARAMS ((f, v, indent), FILE *f _AND_ AsnInt *v _AND_ unsigned int indent) { fprintf (f,"%d", *v); indent=indent; /* referenced to avoid compiler warning. */ } /* * The following deal with unsigned longs. * They do the same as the above routines for unsigned values. * * The compiler generated code does not call them. (It should * based on subtype info but it does not). */ /* * encodes universal TAG LENGTH and Contents of and ASN.1 INTEGER */ AsnLen BEncUAsnInt PARAMS ((b, data), GenBuf *b _AND_ UAsnInt *data) { AsnLen len; len = BEncUAsnIntContent (b, data); len += BEncDefLen (b, len); len += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE); return len; } /* BEncUAsnInt */ /* * decodes universal TAG LENGTH and Contents of and ASN.1 INTEGER */ void BDecUAsnInt PARAMS ((b, result, bytesDecoded, env), GenBuf *b _AND_ UAsnInt *result _AND_ AsnLen *bytesDecoded _AND_ jmp_buf env) { AsnTag tag; AsnLen elmtLen; if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)) { Asn1Error ("BDecAsnInt: ERROR wrong tag on INTGER.\n"); longjmp (env, -40); } elmtLen = BDecLen (b, bytesDecoded, env); BDecUAsnIntContent (b, tag, elmtLen, result, bytesDecoded, env); } /* BDecUAsnInt */ /* * encodes unsigned longeger. This allows you to correctly * handle unsiged values that used the most significant (sign) bit. */ AsnLen BEncUAsnIntContent PARAMS ((b, data), GenBuf *b _AND_ UAsnInt *data) { int len; int i; unsigned long mask; unsigned long dataCpy; dataCpy = *data; /* * calculate encoded length of the integer (content) */ mask = INT_MASK; if ((long)dataCpy < 0) { /*write integer as normal (remember writing in reverse) */ for (i = 0; i < sizeof (UAsnInt); i++) { BufPutByteRvs (b, (unsigned char)dataCpy); dataCpy >>= 8; } /* * write zero byte at beginning of int, since high bit * is set and need to differentiate between sign * bit and high bit in unsigned case. * (this code follows the prev for loop since writing * in reverse) */ BufPutByteRvs (b, 0); return sizeof (UAsnInt)+1; } else { for (len = sizeof (UAsnInt); len > 1; --len) { if ((dataCpy & mask) == 0) mask >>= 8; else break; } /* write the BER integer */ for (i = 0; i < len; i++) { BufPutByteRvs (b, (unsigned char)dataCpy); dataCpy >>= 8; } return len; } } /* BEncUAsnIntContent */ /* * decode integer portion - no tag or length expected or decoded * assumes unsigned integer - This routine is useful for * integer subtyped to > 0 eg Guage ::= INTEGER (0..4294967295) */ void BDecUAsnIntContent PARAMS ((b, tag, len, result, bytesDecoded, env), GenBuf *b _AND_ AsnTag tag _AND_ AsnLen len _AND_ UAsnInt *result _AND_ AsnLen *bytesDecoded _AND_ jmp_buf env) { int i; unsigned long retVal; retVal = (unsigned long) BufGetByte (b); if (len > (sizeof (UAsnInt)+1)) { Asn1Error ("BDecUAsnIntContent: ERROR - integer to big to decode.\n"); longjmp (env, -9); } else if (retVal & 0x80) /* top bit of first byte is sign bit */ { Asn1Error ("BDecUAsnIntContent: ERROR - integer is negative.\n"); longjmp (env, -10); } else if ((len == (sizeof (UAsnInt)+1)) && (retVal != 0)) { /* * first octet must be zero 5 octets long - extra 0 octet * at beginning is only used for value > 0 that need the * high bit */ Asn1Error ("BDecUAsnIntContent: ERROR - integer is negative.\n"); longjmp (env, -11); } /* * write from buffer into long int */ for (i = 1; i < (int)len; i++) retVal = (retVal << 8) | (unsigned long)(BufGetByte (b)); if (BufReadError (b)) { Asn1Error ("BDecUIntegerContent: ERROR - decoded past end of data\n"); longjmp (env, -12); } (*bytesDecoded) += len; *result = retVal; tag=tag; /* referenced to avoid compiler warning. */ } /* BDecUAsnIntContent */ void PrintUAsnInt PARAMS ((f, v, indent), FILE *f _AND_ UAsnInt *v _AND_ unsigned int indent) { fprintf (f, "%u", *v); indent=indent; } esnacc-ng-1.8.1/c-lib/src/asn-len.c000066400000000000000000000155531302010526100166340ustar00rootroot00000000000000/* * asn_len.c - BER encode, decode and utilities for ASN.1 lengths. * * indefinite lens are representd by the highest AsnLen * * MS 92 * Copyright (C) 1992 Michael Sample and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/src/asn-len.c,v 1.6 2003/12/17 19:05:03 gronej Exp $ * $Log: asn-len.c,v $ * Revision 1.6 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.5.2.1 2003/11/05 14:58:53 gronej * working PER code merged with esnacc_1_6 * * Revision 1.5 2002/10/23 10:23:37 mcphersc * Changed BUF_TYPE to AsnBuf * * Revision 1.4 2002/10/18 13:09:32 mcphersc * took out long int to unsigned long * * Revision 1.3 2002/10/01 14:13:29 mcphersc * ASN "C" Buf modifications * * Revision 1.2 2000/10/16 18:10:39 rwc * removed most warnings from C++-lib, some C-lib. * * Revision 1.1.1.1 2000/08/21 20:35:52 leonberp * First CVS Version of SNACC. * * Revision 1.4 1997/08/28 07:25:57 povey * Changes to support DER encoding/decoding * * Revision 1.3.1.1 1997/08/20 23:14:44 povey * * Revision 1.2 1995/07/27 08:58:36 rj * merged PeekEoc(), a function used only by the type table code. * * changed `_' to `-' in file names. * * Revision 1.1 1994/08/28 09:45:54 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include "asn-config.h" #include "asn-len.h" /* * BER encode/decode routines */ AsnLen BEncDefLen PARAMS ((b, len), GenBuf *b _AND_ AsnLen len) { /* * unrolled for efficiency * check each possibitlity of the 4 byte integer */ if (len < 128) { BufPutByteRvs (b, (unsigned char)len); return 1; } else if (len < 256) { BufPutByteRvs (b, (unsigned char)len); BufPutByteRvs (b, 0x81); return 2; } else if (len < 65536) { BufPutByteRvs (b, (unsigned char)len); BufPutByteRvs (b, (unsigned char)(len >> 8)); BufPutByteRvs (b, 0x82); return 3; } else if (len < 16777126) { BufPutByteRvs (b, (unsigned char)len); BufPutByteRvs (b, (unsigned char)(len >> 8)); BufPutByteRvs (b, (unsigned char)(len >> 16)); BufPutByteRvs (b, 0x83); return 4; } else { BufPutByteRvs (b, (unsigned char)len); BufPutByteRvs (b, (unsigned char)(len >> 8)); BufPutByteRvs (b, (unsigned char)(len >> 16)); BufPutByteRvs (b, (unsigned char)(len >> 24)); BufPutByteRvs (b, 0x84); return 5; } } /* BEncDefLen */ /* * non unrolled version */ AsnLen BEncDefLen2 PARAMS ((b, len), GenBuf *b _AND_ long len) { int i; unsigned long j; if (len < 128) { BufPutByteRvs (b, (unsigned char)len); return 1; } else { for (i = 0, j = len; j > 0; j >>= 8, i++) BufPutByteRvs (b, (unsigned char)j); BufPutByteRvs (b, (unsigned char)(0x80 | i)); return i + 1; } } /* BEncDefLen2 */ /* * decodes and returns an ASN.1 length */ AsnLen BDecLen PARAMS ((b, bytesDecoded, env), GenBuf *b _AND_ unsigned long *bytesDecoded _AND_ jmp_buf env) { AsnLen len; AsnLen byte; int lenBytes; byte = (unsigned long) BufGetByte (b); if (BufReadError (b)) { Asn1Error ("BDecLen: ERROR - decoded past end of data\n"); longjmp (env, -13); } (*bytesDecoded)++; if (byte < 128) /* short length */ return byte; else if (byte == (AsnLen) 0x080) /* indef len indicator */ return (unsigned long)INDEFINITE_LEN; else /* long len form */ { /* * strip high bit to get # bytes left in len */ lenBytes = byte & (AsnLen) 0x7f; if (lenBytes > sizeof (AsnLen)) { Asn1Error ("BDecLen: ERROR - length overflow\n"); longjmp (env, -14); } (*bytesDecoded) += lenBytes; for (len = 0; lenBytes > 0; lenBytes--) len = (len << 8) | (AsnLen) BufGetByte (b); if (BufReadError (b)) { Asn1Error ("BDecLen: ERROR - decoded past end of data\n"); longjmp (env, -15); } return len; } /* not reached */ } /* BDecLen */ #ifdef _DEBUG AsnLen BEncEoc PARAMS ((b), GenBuf *b) { BufPutByteRvs (b, 0); BufPutByteRvs (b, 0); return 2; } /* BEncEoc */ #endif /* * Decodes an End of Contents (EOC) marker from the given buffer. * Flags and error if the octets are non-zero or if a read error * occurs. Increments bytesDecoded by the length of the EOC marker. */ void BDecEoc PARAMS ((b, bytesDecoded, env), GenBuf *b _AND_ AsnLen *bytesDecoded _AND_ jmp_buf env) { if ((BufGetByte (b) != 0) || (BufGetByte (b) != 0) || BufReadError (b)) { Asn1Error ("BDecEoc: ERROR - non zero byte in EOC or end of data reached\n"); longjmp (env, -16); } (*bytesDecoded) += 2; } /* BDecEoc */ #if TTBL /* returns true if the next tag is actually and EOC */ int PeekEoc PARAMS ((b), GenBuf *b) { return BufPeekByte (b) == 0; } /* PeekEoc */ #endif /* * DER Encoding/Routines */ /* * decodes and returns a DER encoded ASN.1 length */ AsnLen DDecLen PARAMS ((b, bytesDecoded, env), GenBuf *b _AND_ unsigned long *bytesDecoded _AND_ jmp_buf env) { AsnLen len; AsnLen byte; int lenBytes; byte = (AsnLen) BufGetByte (b); if (BufReadError (b)) { Asn1Error ("DDecLen: ERROR - decoded past end of data\n"); longjmp (env, -13); } (*bytesDecoded)++; if (byte < 128) /* short length */ return byte; else if (byte == (AsnLen) 0x080) {/* indef len indicator */ Asn1Error("DDecLen: ERROR - Indefinite length decoded"); longjmp(env, -666); } else /* long len form */ { /* * strip high bit to get # bytes left in len */ lenBytes = byte & (AsnLen) 0x7f; if (lenBytes > sizeof (AsnLen)) { Asn1Error ("DDecLen: ERROR - length overflow\n"); longjmp (env, -14); } (*bytesDecoded) += lenBytes; for (len = 0; lenBytes > 0; lenBytes--) len = (len << 8) | (AsnLen) BufGetByte (b); if (BufReadError (b)) { Asn1Error ("DDecLen: ERROR - decoded past end of data\n"); longjmp (env, -15); } return len; } /* not reached */ } /* DDecLen */ esnacc-ng-1.8.1/c-lib/src/asn-list.c000066400000000000000000000264051302010526100170270ustar00rootroot00000000000000/* * asn_list.c - borrowed from Murray Goldberg * * the following routines implement the list data structure * * Copyright (C) 1992 the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/src/asn-list.c,v 1.7 2003/12/17 19:05:03 gronej Exp $ * $Log: asn-list.c,v $ * Revision 1.7 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.6.2.1 2003/11/05 14:58:53 gronej * working PER code merged with esnacc_1_6 * * Revision 1.6 2002/10/21 17:13:16 mcphersc * fixed long int * * Revision 1.5 2002/09/25 12:10:44 mcphersc * fixed warnings * * Revision 1.4 2002/09/03 19:33:19 vracarl * got rid of c++ comments * * Revision 1.3 2002/07/25 11:01:45 sfl * Added ifdef WIN32 around pragma to get rid of warnings * * Revision 1.1.1.1 2000/08/21 20:35:52 leonberp * First CVS Version of SNACC. * * Revision 1.4 1997/08/28 07:25:58 povey * Changes to support DER encoding/decoding * * Revision 1.3.1.1 1997/08/20 23:14:44 povey * * Revision 1.2 1995/07/27 08:59:36 rj * merged GetAsnListElmt(), a function used only by the type table code. * * changed `_' to `-' in file names. * * Revision 1.1 1994/08/28 09:45:55 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include "asn-config.h" #include "asn-list.h" #ifdef WIN32 #pragma warning( disable : 4706 ) /* IGNORE assign w/in conditional expression. */ #endif /* remove the entire list and all its nodes (not the actual list data elmts) */ /* this is set up for the snace compiler */ void AsnListFree PARAMS ((list), AsnList *list) { AsnListNode *node, *next; node = list->first; while (node) { next = node->next; Asn1Free (node); node = next; } Asn1Free (list); } /* AsnListFree */ /* * this routine removes the current node from the list. After removal the * current pointer will point to the next node in line, or NULL if the * removed item was at the tail of the list. */ void AsnListRemove PARAMS ((list), AsnList *list) { AsnListNode *node; if (list->curr) { if (list->curr->next) list->curr->next->prev = list->curr->prev; else list->last = list->curr->prev; if (list->curr->prev) list->curr->prev->next = list->curr->next; else list->first = list->curr->next; node = list->curr; list->curr = list->curr->next; list->count--; Asn1Free (node); } } /* * this creates a new node after the current node and returns the * address of the memory allocated for data. The current pointer is changed * to point to the newly added node in the list. If the current pointer is * initially off the list then this operation fails. */ void* AsnListAdd PARAMS ((list), AsnList *list) { AsnListNode *newNode; void *dataAddr; if (list->curr) { newNode = (AsnListNode *) Asn1Alloc (sizeof (AsnListNode) + list->dataSize); dataAddr = (void *) &(newNode->data); newNode->next = list->curr->next; newNode->prev = list->curr; if (list->curr->next) list->curr->next->prev = newNode; else list->last = newNode; list->curr->next = newNode; list->curr = newNode; list->count++; } else dataAddr = NULL; return dataAddr; } /* * this creates a new node before the current node and returns the * address of the memory allocated for data. The current pointer is changed * to point to the newly added node in the list. If the current pointer is * initially off the list then this operation fails. */ void* AsnListInsert PARAMS ((list), AsnList *list) { AsnListNode *newNode; void *dataAddr; if (list->curr) { newNode = (AsnListNode *) Asn1Alloc (sizeof (AsnListNode) + list->dataSize); dataAddr = (void *) &(newNode->data); newNode->next = list->curr; newNode->prev = list->curr->prev; if (list->curr->prev) list->curr->prev->next = newNode; else list->first = newNode; list->curr->prev = newNode; list->curr = newNode; list->count++; } else dataAddr = NULL; return dataAddr; } void AsnListInit PARAMS ((list, dataSize), AsnList *list _AND_ int dataSize) { list->first = list->last = list->curr = NULL; list->count = 0; list->dataSize = dataSize; } /* AsnListInit */ AsnList* AsnListNew PARAMS ((dataSize), int dataSize) { AsnList *list; list = (AsnList *) Asn1Alloc (sizeof (AsnList)); list->first = list->last = list->curr = NULL; list->count = 0; list->dataSize = dataSize; return list; } /* * backs up the current pointer by one and returns the data address of the new * current node. If the current pointer is off the list, the new current node * will be the last node of the list (unless the list is empty). */ void* AsnListPrev PARAMS ((list), AsnList *list) { void *retVal; if (list->curr == NULL) list->curr = list->last; else list->curr = list->curr->prev; if (list->curr == NULL) retVal = NULL; else retVal = (void *) &(list->curr->data); return retVal; } /* * advances the current pointer by one and returns the data address of the new * current node. If the current pointer is off the list, the new current node * will be the first node of the list (unless the list is empty). */ void* AsnListNext PARAMS ((list), AsnList *list) { void *retVal; if (list->curr == NULL) list->curr = list->first; else list->curr = list->curr->next; if (list->curr == NULL) retVal = NULL; else retVal = (void *) &(list->curr->data); return retVal; } /* * returns the data address of the last node (if there is one) and sets the * current pointer to this node. */ void* AsnListLast PARAMS ((list), AsnList *list) { void *retVal; list->curr = list->last; if (list->curr == NULL) retVal = NULL; else retVal = (void *) &(list->curr->data); return retVal; } /* * returns the data address of the first node (if there is one) and sets the * current pointer to this node. */ void* AsnListFirst PARAMS ((list), AsnList *list) { void *retVal; list->curr = list->first; if (list->curr == NULL) retVal = NULL; else retVal = (void *) &(list->curr->data); return retVal; } /* * this creates a new node at the beginning of the list and returns the * address of the memory allocated for data. The current pointer is changed * to point to the newly added node in the list. */ void* AsnListPrepend PARAMS ((list), AsnList *list) { AsnListNode *newNode; void *dataAddr; newNode = (AsnListNode *) Asn1Alloc (sizeof (AsnListNode) + list->dataSize); dataAddr = (void *) &(newNode->data); newNode->prev = NULL; if (list->first == NULL) { newNode->next = NULL; list->first = list->last = newNode; } else { newNode->next = list->first; list->first->prev = newNode; list->first = newNode; } list->curr = newNode; list->count++; return dataAddr; } /* * this creates a new node at the end of the list and returns the * address of the memory allocated for data. The current pointer is changed * to point to the newly added node in the list. */ void* AsnListAppend PARAMS ((list), AsnList *list) { AsnListNode *newNode; void *dataAddr; newNode = (AsnListNode *) Asn1Alloc (sizeof (AsnListNode) + list->dataSize); dataAddr = (void *) &(newNode->data); newNode->next = NULL; if (list->last == NULL) { newNode->prev = NULL; list->first = list->last = newNode; } else { newNode->prev = list->last; list->last->next = newNode; list->last = newNode; } list->curr = newNode; list->count++; return dataAddr; } void* AsnListCurr PARAMS ((list), AsnList *list) { void *retVal; if (list->curr) retVal = (void *) &(list->curr->data); else retVal = NULL; return retVal; } /* Sort the list in ascending order of content XXX: In-place sort in the future */ AsnList* AsnListSort PARAMS ((list, cmp), AsnList *list _AND_ int ((*cmp)(const void *, const void *))) { void **sortArray; void *elmt; int i; AsnList* ret; void** tmpVar; /* Make sure list is not null */ if (!(list)) { return NULL; } /* Create array of elements so we can qsort the list */ sortArray = (void **) Asn1Alloc(list->count * sizeof(void *)); /* Copy the elements from the list into the sort array */ for ((list)->curr = (list)->first, i=0; (list)->curr && ((elmt) = (void *)(list)->curr->data) && i < list->count; (list)->curr = (list)->curr->next, i++) { sortArray[i] = elmt; } /* Sort the array */ qsort(sortArray, list->count, sizeof(void *), cmp); /* Make a new list from the sorted Array */ ret = AsnListNew(list->dataSize); for (i=0; icount; i++) { tmpVar = AsnListAppend(ret); (*tmpVar) = sortArray[i]; } Asn1Free(sortArray); /* Return the sorted list */ return ret; } int AsnListCount PARAMS ((list), AsnList *list) { return list->count; } AsnList* AsnListConcat PARAMS ((l1,l2), AsnList *l1 _AND_ AsnList *l2) { if (l2->count == 0) return l1; if (l1->count == 0) { l1->count = l2->count; l1->last = l2->last; l1->first = l2->first; l1->curr = l1->first; } else { l1->count += l2->count; l1->last->next = l2->first; l2->first->prev = l1->last; l1->last = l2->last; } return l1; } /* * Returns the index (starting a 0 for the first elmt) * of the given elmt in the given list * returns -1 if the elmt is not in the list * Assumes that the list node contains a single pointer */ long GetAsnListElmtIndex PARAMS ((elmt, list), void *elmt _AND_ AsnList *list) { void *tmp; void *tmpElmt; long index; index = 0; tmp = (void*) CURR_LIST_NODE (list); FOR_EACH_LIST_ELMT (tmpElmt, list) { if (tmpElmt == elmt) { SET_CURR_LIST_NODE (list, tmp); return index; } else index++; } SET_CURR_LIST_NODE (list, tmp); return -1; } /* GetAsnListElmtIndex */ #if TTBL /* * Returns the element with the given index. * indexes start a 0 for the first elmt. * returns NULL if the index is too large. * Assumes that the list node contains a single pointer. */ void* GetAsnListElmt PARAMS ((list, index), AsnList *list _AND_ unsigned int index) { void *tmp; void *tmpElmt; unsigned long currIndex; if (index > (unsigned long)LIST_COUNT (list)) return NULL; currIndex = 0; tmp = (void*) CURR_LIST_NODE (list); FOR_EACH_LIST_ELMT (tmpElmt, list) { if (currIndex == index) { SET_CURR_LIST_NODE (list, tmp); return tmpElmt; } currIndex++; } SET_CURR_LIST_NODE (list, tmp); return NULL; } /* GetAsnListElmt */ #endif /* TTBL */ esnacc-ng-1.8.1/c-lib/src/asn-null.c000066400000000000000000000077351302010526100170330ustar00rootroot00000000000000/* * asn_null.c - BER encode, decode, print and free routines for the * ASN.1 NULL type. * * MS 92 * Copyright (C) 1992 Michael Sample and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/src/asn-null.c,v 1.12 2004/04/21 13:28:21 gronej Exp $ * $Log: asn-null.c,v $ * Revision 1.12 2004/04/21 13:28:21 gronej * v1_7 release fix * * Revision 1.11 2004/04/21 13:10:35 gronej * patch submitted by Oskar to fix free calls * * Revision 1.10 2004/01/22 20:03:12 nicholar * Changed indent variable to an unsigned int from an unsigned short. Indent is used in library print functions and generated print functions * * Revision 1.9 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.8.2.1 2003/11/05 14:58:53 gronej * working PER code merged with esnacc_1_6 * * Revision 1.8 2002/10/23 10:23:37 mcphersc * Changed BUF_TYPE to AsnBuf * * Revision 1.7 2002/10/21 17:01:29 mcphersc * fixed unsigned short int * * Revision 1.6 2002/09/03 19:43:11 vracarl * fixed a typo * * Revision 1.5 2002/09/03 19:33:19 vracarl * got rid of c++ comments * * Revision 1.4 2002/07/25 11:05:04 sfl * get rid of warnings * * Revision 1.1.1.1 2000/08/21 20:35:52 leonberp * First CVS Version of SNACC. * * Revision 1.3 1995/07/24 21:04:52 rj * changed `_' to `-' in file names. * * Revision 1.2 1994/09/01 00:06:08 rj * reduce the risk of unwanted surprises with macro expansion by properly separating the C tokens. * * Revision 1.1 1994/08/28 09:45:57 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include "asn-config.h" #include "asn-len.h" #include "asn-tag.h" #include "asn-null.h" /* * encodes universal TAG LENGTH and Contents of and ASN.1 NULL */ AsnLen BEncAsnNull PARAMS ((b, data), GenBuf *b _AND_ AsnNull *data) { AsnLen len; len = BEncAsnNullContent (b, data); len += BEncDefLen (b, len); len += BEncTag1 (b, UNIV, PRIM, NULLTYPE_TAG_CODE); data=data; /* referenced to avoid compiler warning. */ return len; } /* BEncAsnNull */ /* * decodes universal TAG LENGTH and Contents of and ASN.1 NULL */ void BDecAsnNull PARAMS ((b, result, bytesDecoded, env), GenBuf *b _AND_ AsnNull *result _AND_ AsnLen *bytesDecoded _AND_ jmp_buf env) { AsnTag tag; AsnLen elmtLen; if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, NULLTYPE_TAG_CODE)) { Asn1Error ("BDecAsnNull: ERROR wrong tag on NULL.\n"); longjmp (env, -40); } elmtLen = BDecLen (b, bytesDecoded, env); BDecAsnNullContent (b, tag, elmtLen, result, bytesDecoded, env); } /* BDecAsnNull */ void BDecAsnNullContent PARAMS ((b, tagId, len, result, bytesDecoded, env), GenBuf *b _AND_ AsnTag tagId _AND_ AsnLen len _AND_ AsnNull *result _AND_ AsnLen *bytesDecoded _AND_ jmp_buf env) { if (len != 0) { Asn1Error ("BDecAsnNullContent: ERROR - NULL type's len must be 0\n"); longjmp (env, -17); } bytesDecoded=bytesDecoded; /* referenced to avoid compiler warning. */ result=result; tagId=tagId; b=b; } /* BDecAsnNullContent */ /* * Prints the NULL value to the given FILE * in Value Notation. * ignores the indent. */ void PrintAsnNull PARAMS ((f,v, indent), FILE *f _AND_ AsnNull *v _AND_ unsigned int indent) { fprintf (f, "NULL"); indent=indent; /* referenced to avoid compiler warning. */ v=v; } void FreeAsnNull PARAMS ((b), AsnNull *b) { b=b; } esnacc-ng-1.8.1/c-lib/src/asn-octs.c000066400000000000000000000234711302010526100170240ustar00rootroot00000000000000/* * .../c-lib/src/asn-octs.c - BER encode, decode, print and free routines for the ASN.1 OCTET STRING type. * * MS 92 * Copyright (C) 1992 Michael Sample and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/src/asn-octs.c,v 1.13 2004/03/23 18:49:21 gronej Exp $ * $Log: asn-octs.c,v $ * Revision 1.13 2004/03/23 18:49:21 gronej * fixed linux warnings * * Revision 1.12 2004/01/22 20:03:12 nicholar * Changed indent variable to an unsigned int from an unsigned short. Indent is used in library print functions and generated print functions * * Revision 1.11 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.10.2.1 2003/11/05 14:58:53 gronej * working PER code merged with esnacc_1_6 * * Revision 1.10 2002/10/23 10:23:37 mcphersc * Changed BUF_TYPE to AsnBuf * * Revision 1.9 2002/10/18 13:09:32 mcphersc * took out long int to unsigned long * * Revision 1.8 2002/10/01 14:13:52 mcphersc * ASN "C" Buf modifications * * Revision 1.7 2002/09/03 19:43:10 vracarl * fixed a typo * * Revision 1.6 2002/09/03 19:33:19 vracarl * got rid of c++ comments * * Revision 1.5 2002/07/25 11:05:48 sfl * added indent=indent line 316 to get rid of warnings * * Revision 1.3 2002/03/05 18:34:15 vracarl * added CheckAsn1Alloc check and a check for INDEFINITE_LEN * * Revision 1.2 2000/10/16 18:10:40 rwc * removed most warnings from C++-lib, some C-lib. * * Revision 1.1.1.1 2000/08/21 20:35:52 leonberp * First CVS Version of SNACC. * * Revision 1.3 1995/07/27 09:00:32 rj * use memcmpeq that is defined in .../snacc.h to use either memcmp or bcmp. * * changed `_' to `-' in file names. * * Revision 1.2 1994/09/01 00:06:15 rj * reduce the risk of unwanted surprises with macro expansion by properly separating the C tokens. * * Revision 1.1 1994/08/28 09:45:58 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include #include "asn-config.h" #include "asn-len.h" #include "asn-tag.h" #include "str-stk.h" #include "asn-bits.h" /* for TO_HEX macro */ #include "asn-octs.h" #include /* * encodes universal TAG LENGTH and Contents of and ASN.1 OCTET STRING */ AsnLen BEncAsnOcts PARAMS ((b, data), GenBuf *b _AND_ AsnOcts *data) { AsnLen len; len = BEncAsnOctsContent (b, data); len += BEncDefLen (b, len); len += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE); return len; } /* BEncAsnOcts */ /* * decodes universal TAG LENGTH and Contents of and ASN.1 OCTET STRING */ void BDecAsnOcts PARAMS ((b, result, bytesDecoded, env), GenBuf *b _AND_ AsnOcts *result _AND_ AsnLen *bytesDecoded _AND_ jmp_buf env) { AsnTag tag; AsnLen elmtLen; if (((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE)) && (tag != MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE))) { Asn1Error ("BDecAsnOcts: ERROR - wrong tag on OCTET STRING.\n"); longjmp (env, -40); } elmtLen = BDecLen (b, bytesDecoded, env); BDecAsnOctsContent (b, tag, elmtLen, result, bytesDecoded, env); } /* BDecAsnOcts */ /* * BER encodes just the content of an OCTET STRING. */ AsnLen BEncAsnOctsContent PARAMS ((b, o), GenBuf *b _AND_ AsnOcts *o) { BufPutSegRvs (b, o->octs, o->octetLen); return o->octetLen; } /* BEncAsnOctsContent */ /* * Used for decoding constructed OCTET STRING values into * a contiguous local rep. * fills string stack with references to the pieces of a * construced octet string */ static void FillOctetStringStk PARAMS ((b, elmtLen0, bytesDecoded, env), GenBuf *b _AND_ AsnLen elmtLen0 _AND_ AsnLen *bytesDecoded _AND_ jmp_buf env) { unsigned long refdLen; unsigned long totalRefdLen; char *strPtr; unsigned long totalElmtsLen1 = 0; unsigned long tagId1; unsigned long elmtLen1; for (; (totalElmtsLen1 < elmtLen0) || (elmtLen0 == INDEFINITE_LEN); ) { tagId1 = BDecTag (b, &totalElmtsLen1, env); if ((tagId1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN)) { BDEC_2ND_EOC_OCTET (b, &totalElmtsLen1, env); break; } elmtLen1 = BDecLen (b, &totalElmtsLen1, env); if (tagId1 == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE)) { /* * primitive part of string, put references to piece (s) in * str stack */ totalRefdLen = 0; refdLen = elmtLen1; while (1) { strPtr = (char *)BufGetSeg (b, &refdLen); PUSH_STR (strPtr, refdLen, env); totalRefdLen += refdLen; if (totalRefdLen == elmtLen1) break; /* exit this while loop */ if (refdLen == 0) /* end of data */ { Asn1Error ("BDecConsOctetString: ERROR - attempt to decode past end of data\n"); longjmp (env, -18); } refdLen = elmtLen1 - totalRefdLen; } totalElmtsLen1 += elmtLen1; } else if (tagId1 == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)) { /* * constructed octets string embedding in this constructed * octet string. decode it. */ FillOctetStringStk (b, elmtLen1, &totalElmtsLen1, env); } else /* wrong tag */ { Asn1Error ("BDecConsOctetString: ERROR - decoded non-OCTET STRING tag inside a constructed OCTET STRING\n"); longjmp (env, -19); } } /* end of for */ (*bytesDecoded) += totalElmtsLen1; } /* FillOctetStringStk */ /* * Decodes a seq of universally tagged octets strings until either EOC is * encountered or the given len is decoded. Merges them into a single * string. puts a NULL terminator on the string but does not include * this in the length. */ static void BDecConsAsnOcts PARAMS ((b, len, result, bytesDecoded, env), GenBuf *b _AND_ AsnLen len _AND_ AsnOcts *result _AND_ AsnLen *bytesDecoded _AND_ jmp_buf env) { char *bufCurr; unsigned long curr; RESET_STR_STK(); /* * decode each piece of the octet string, puting * an entry in the octet string stack for each */ FillOctetStringStk (b, len, bytesDecoded, env); result->octetLen = strStkG.totalByteLen; /* alloc str for all octs pieces with extra byte for null terminator */ bufCurr = result->octs = Asn1Alloc (strStkG.totalByteLen +1); CheckAsn1Alloc (result->octs, env); /* copy octet str pieces into single blk */ for (curr = 0; curr < strStkG.nextFreeElmt; curr++) { memcpy (bufCurr, strStkG.stk[curr].str, strStkG.stk[curr].len); bufCurr += strStkG.stk[curr].len; } /* add null terminator - this is not included in the str's len */ *bufCurr = '\0'; } /* BDecConsAsnOcts */ /* * Decodes the content of a BER OCTET STRING value */ void BDecAsnOctsContent PARAMS ((b, tagId, len, result, bytesDecoded, env), GenBuf *b _AND_ AsnTag tagId _AND_ AsnLen len _AND_ AsnOcts *result _AND_ AsnLen *bytesDecoded _AND_ jmp_buf env) { /* * tagId is encoded tag shifted into long int. * if CONS bit is set then constructed octet string */ if (TAG_IS_CONS (tagId)) BDecConsAsnOcts (b, len, result, bytesDecoded, env); else /* primitive octet string */ { if (len == INDEFINITE_LEN) { Asn1Error ("BDecAsnOctsContent: ERROR - indefinite length on primitive\n"); longjmp (env, -67); } result->octetLen = len; result->octs = Asn1Alloc (len+1); CheckAsn1Alloc (result->octs, env); BufCopy (result->octs, b, len); if (BufReadError (b)) { Asn1Error ("BDecAsnOctsContent: ERROR - decoded past end of data\n"); longjmp (env, -20); } /* add null terminator - this is not included in the str's len */ result->octs[len] = '\0'; (*bytesDecoded) += len; } } /* BDecAsnOctsContent */ /* * Frees the string part of the given OCTET STRING */ void FreeAsnOcts PARAMS ((v), AsnOcts *v) { Asn1Free (v->octs); } /* FreeAsnOcts */ /* * Prints the given OCTET STRING value to the given FILE * in ASN.1 * Value Notation. Since the value notation uses the hard to read * hex format, the ASCII version is included in an ASN.1 comment. */ void PrintAsnOcts PARAMS ((f,v, indent), FILE *f _AND_ AsnOcts *v _AND_ unsigned int indent) { int i; /* print hstring value */ fprintf (f,"'"); for (i = 0; i < (int)(v->octetLen); i++) fprintf (f,"%c%c", TO_HEX (v->octs[i] >> 4), TO_HEX (v->octs[i])); fprintf (f,"'H"); /* show printable chars in comment */ fprintf (f," -- \""); for (i = 0; i < (int)(v->octetLen); i++) { /* if (isprint (v->octs[i])) DAD - temp removing for now*/ if(1) fprintf (f,"%c", v->octs[i]); else fprintf (f,"."); } fprintf (f,"\" --"); indent=indent; /* referenced to avoid compiler warning. */ } /* * Returns TRUE if the given OCTET STRING values are identical. * Returns FALSE otherwise. */ int AsnOctsEquiv PARAMS ((o1, o2), AsnOcts *o1 _AND_ AsnOcts *o2) { return o1->octetLen == o2->octetLen && !memcmp(o1->octs, o2->octs, o1->octetLen); } /* AsnOctsEquiv */ esnacc-ng-1.8.1/c-lib/src/asn-oid.c000066400000000000000000000220561302010526100166250ustar00rootroot00000000000000/* * asn_oid.c - BER encode, decode, print and free routines for the * ASN.1 OBJECT IDENTIFIER type. * * MS 92 * Copyright (C) 1992 Michael Sample and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/src/asn-oid.c,v 1.10 2004/01/22 20:03:12 nicholar Exp $ * $Log: asn-oid.c,v $ * Revision 1.10 2004/01/22 20:03:12 nicholar * Changed indent variable to an unsigned int from an unsigned short. Indent is used in library print functions and generated print functions * * Revision 1.9 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.8.2.1 2003/11/05 14:58:53 gronej * working PER code merged with esnacc_1_6 * * Revision 1.8 2002/10/23 10:23:37 mcphersc * Changed BUF_TYPE to AsnBuf * * Revision 1.7 2002/10/21 17:01:29 mcphersc * fixed unsigned short int * * Revision 1.6 2002/09/03 19:39:19 vracarl * got rid of c++ comments * * Revision 1.5 2002/07/25 11:15:52 sfl * got rid of warnings * * Revision 1.3 2001/12/18 20:56:48 vracarl * added set of octetLen in BuildEncodedOid * * Revision 1.2 2000/10/16 18:10:40 rwc * removed most warnings from C++-lib, some C-lib. * * Revision 1.1.1.1 2000/08/21 20:35:52 leonberp * First CVS Version of SNACC. * * Revision 1.3 1995/07/24 21:04:53 rj * changed `_' to `-' in file names. * * Revision 1.2 1994/09/01 00:06:21 rj * reduce the risk of unwanted surprises with macro expansion by properly separating the C tokens. * * Revision 1.1 1994/08/28 09:45:59 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include "asn-config.h" #include "asn-len.h" #include "asn-tag.h" #include "asn-octs.h" #include "asn-oid.h" /* * encodes universal TAG LENGTH and Contents of and ASN.1 OBJECT ID */ AsnLen BEncAsnOid PARAMS ((b, data), GenBuf *b _AND_ AsnOid *data) { AsnLen len; len = BEncAsnOidContent (b, data); len += BEncDefLen (b, len); len += BEncTag1 (b, UNIV, PRIM, OID_TAG_CODE); return len; } /* BEncAsnOid */ /* * decodes universal TAG LENGTH and Contents of and ASN.1 OBJECT ID */ void BDecAsnOid PARAMS ((b, result, bytesDecoded, env), GenBuf *b _AND_ AsnOid *result _AND_ AsnLen *bytesDecoded _AND_ jmp_buf env) { AsnTag tag; AsnLen elmtLen; if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE)) { Asn1Error ("BDecAsnOid: ERROR - wrong tag on OBJECT IDENTIFIER.\n"); longjmp (env, -40); } elmtLen = BDecLen (b, bytesDecoded, env); BDecAsnOidContent (b, tag, elmtLen, result, bytesDecoded, env); } /* BDecAsnOid */ /* * Decodes just the content of the OID. * AsnOid is handled the same as a primtive octet string */ void BDecAsnOidContent PARAMS ((b, tagId, len, result, bytesDecoded, env), GenBuf *b _AND_ AsnTag tagId _AND_ AsnLen len _AND_ AsnOid *result _AND_ AsnLen *bytesDecoded _AND_ jmp_buf env) { if (len == INDEFINITE_LEN) { Asn1Error ("BDecAsnOidContent: ERROR - indefinite length on primitive\n"); longjmp (env, -66); } result->octetLen = len; result->octs = Asn1Alloc (len); CheckAsn1Alloc (result->octs, env); BufCopy (result->octs, b, len); if (BufReadError (b)) { Asn1Error ("BDecAsnOidContent: ERROR - decoded past end of data\n"); longjmp (env, -21); } (*bytesDecoded) += len; tagId=tagId; /* referenced to avoid compiler warning. */ } /* BDecAsnOidContent */ /* * Prints the given OID to the given FILE * in ASN.1 Value Notation. * Since the internal rep of an OID is 'encoded', this routine * decodes each individual arc number to print it. */ void PrintAsnOid PARAMS ((f,v, indent), FILE *f _AND_ AsnOid *v _AND_ unsigned int indent) { unsigned int firstArcNum; unsigned int arcNum; int i; fprintf (f,"{"); /* un-munge first two arc numbers */ for (arcNum = 0, i=0; (i < (int)(v->octetLen)) && (v->octs[i] & 0x80);i++) arcNum = (arcNum << 7) + (v->octs[i] & 0x7f); arcNum = (arcNum << 7) + (v->octs[i] & 0x7f); i++; firstArcNum = (unsigned short)(arcNum/40); if (firstArcNum > 2) firstArcNum = 2; fprintf (f,"%u %u", (unsigned int)firstArcNum, arcNum - (firstArcNum * 40)); for (; i < (int)(v->octetLen); ) { for (arcNum = 0; (i < (int)(v->octetLen)) && (v->octs[i] & 0x80);i++) arcNum = (arcNum << 7) + (v->octs[i] & 0x7f); arcNum = (arcNum << 7) + (v->octs[i] & 0x7f); i++; fprintf (f," %u", arcNum); } fprintf (f,"}"); indent=indent; /* referenced to avoid compiler warning. */ } /* PrintAsnOid */ /* * given an OID, figures out the length for the encoded version */ AsnLen EncodedOidLen PARAMS ((oid), OID *oid) { AsnLen totalLen; unsigned long headArcNum; unsigned long tmpArcNum; OID *tmpOid; /* * oid must have at least 2 elmts */ if (oid->next == NULL) return 0; headArcNum = (oid->arcNum * 40) + oid->next->arcNum; /* * figure out total encoded length of oid */ tmpArcNum = headArcNum; for (totalLen = 1; (tmpArcNum >>= 7) != 0; totalLen++) ; for (tmpOid = oid->next->next; tmpOid != NULL; tmpOid = tmpOid->next) { totalLen++; tmpArcNum = tmpOid->arcNum; for (; (tmpArcNum >>= 7) != 0; totalLen++) ; } return totalLen; } /* EncodedOidLen */ /* * given an oid list and a pre-allocated ENC_OID * (use EncodedOidLen to figure out byte length needed) * fills the ENC_OID with a BER encoded version * of the oid. */ void BuildEncodedOid PARAMS ((oid, result), OID *oid _AND_ AsnOid *result) { unsigned long len; unsigned long headArcNum; unsigned long tmpArcNum; char *buf; int i; OID *tmpOid; buf = result->octs; /* * oid must have at least 2 elmts */ if (oid->next == NULL) return; /* * munge together first two arcNum * note first arcnum must be <= 2 * and second must be < 39 if first = 0 or 1 * see (X.209) for ref to this stupidity */ headArcNum = (oid->arcNum * 40) + oid->next->arcNum; tmpArcNum = headArcNum; /* * calc # bytes needed for head arc num */ for (len = 0; (tmpArcNum >>= 7) != 0; len++) ; /* * write more signifcant bytes (if any) of head arc num * with 'more' bit set */ for (i=0; i < (int)len; i++) *(buf++) = (char)(0x80 | (headArcNum >> ((len-i)*7))); /* * write least significant byte of head arc num */ *(buf++) = (char)(0x7f & headArcNum); /* * write following arc nums, if any */ for (tmpOid = oid->next->next; tmpOid != NULL; tmpOid = tmpOid->next) { /* * figure out encoded length -1 of this arcNum */ tmpArcNum = tmpOid->arcNum; for (len = 0; (tmpArcNum >>= 7) != 0; len++) ; /* * write more signifcant bytes (if any) * with 'more' bit set */ for (i=0; i < (int)len; i++) *(buf++) = (char)(0x80 | (tmpOid->arcNum >> ((len-i)*7))); /* * write least significant byte */ *(buf++) = (char)(0x7f & tmpOid->arcNum); } result->octetLen = (buf - result->octs); } /* BuildEncodedOid */ /* * convert an AsnOid into an OID (linked list) * NOT RECOMMENDED for use in protocol implementations */ void UnbuildEncodedOid PARAMS ((eoid, result), AsnOid *eoid _AND_ OID **result) { OID **nextOid; OID *headOid; int arcNum; int i; int firstArcNum; int secondArcNum; for (arcNum = 0, i=0; (i < (int)(eoid->octetLen)) && (eoid->octs[i] & 0x80);i++) arcNum = (arcNum << 7) + (eoid->octs[i] & 0x7f); arcNum = (arcNum << 7) + (eoid->octs[i] & 0x7f); i++; firstArcNum = arcNum / 40; if (firstArcNum > 2) firstArcNum = 2; secondArcNum = arcNum - (firstArcNum * 40); headOid = (OID*)malloc (sizeof (OID)); headOid->arcNum = firstArcNum; headOid->next = (OID*)malloc (sizeof (OID)); headOid->next->arcNum = secondArcNum; nextOid = &headOid->next->next; for (; i < (int)(eoid->octetLen); ) { for (arcNum = 0; (i < (int)(eoid->octetLen)) && (eoid->octs[i] & 0x80); i++) arcNum = (arcNum << 7) + (eoid->octs[i] & 0x7f); arcNum = (arcNum << 7) + (eoid->octs[i] & 0x7f); i++; *nextOid = (OID*)malloc (sizeof (OID)); (*nextOid)->arcNum = arcNum; (*nextOid)->next = NULL; nextOid = &(*nextOid)->next; } *result = headOid; } /* UnbuildEncodedOid */ esnacc-ng-1.8.1/c-lib/src/asn-real.c000066400000000000000000000617211302010526100167770ustar00rootroot00000000000000/* * asn_real.c - BER encode, decode, print and free routines for ASN.1 REAL type. * * MS 92 * Copyright (C) 1992 Michael Sample and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/src/asn-real.c,v 1.16 2004/01/22 20:03:12 nicholar Exp $ * $Log: asn-real.c,v $ * Revision 1.16 2004/01/22 20:03:12 nicholar * Changed indent variable to an unsigned int from an unsigned short. Indent is used in library print functions and generated print functions * * Revision 1.15 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.14.2.1 2003/11/05 14:58:53 gronej * working PER code merged with esnacc_1_6 * * Revision 1.14 2002/10/23 10:23:37 mcphersc * Changed BUF_TYPE to AsnBuf * * Revision 1.13 2002/10/21 17:13:16 mcphersc * fixed long int * * Revision 1.12 2002/10/21 17:05:56 mcphersc * fixed long int * * Revision 1.11 2002/10/21 17:01:29 mcphersc * fixed unsigned short int * * Revision 1.10 2002/10/18 13:09:32 mcphersc * took out long int to unsigned long * * Revision 1.9 2002/10/01 14:14:24 mcphersc * ASN "C" Buf modifications * * Revision 1.8 2002/09/25 12:11:00 mcphersc * fixed warnings * * Revision 1.7 2002/09/03 19:39:19 vracarl * got rid of c++ comments * * Revision 1.6 2002/07/25 10:51:28 sfl * Got rid of compiler warnings about indent and missint include reference to math.h * * Revision 1.4 2001/07/20 11:54:34 mcphersc * Get rid of compiler warning on windows for function prototype * extern double frexp( double x, int *expptr ) * * Revision 1.3 2000/10/24 14:54:43 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.2 2000/10/16 18:10:40 rwc * removed most warnings from C++-lib, some C-lib. * * Revision 1.1.1.1 2000/08/21 20:35:52 leonberp * First CVS Version of SNACC. * * Revision 1.5 1997/02/28 13:39:50 wan * Modifications collected for new version 1.3: Bug fixes, tk4.2. * * Revision 1.4 1995/07/24 21:04:54 rj * changed `_' to `-' in file names. * * Revision 1.3 1995/02/18 16:25:13 rj * added support for CPU/compiler combination presenting 64 bit little endian long integers * (in addition to the aforesupported 32 bit big endian long ints). * * Revision 1.2 1994/09/01 00:06:28 rj * reduce the risk of unwanted surprises with macro expansion by properly separating the C tokens. * * Revision 1.1 1994/08/28 09:46:00 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include "math.h" #include "asn-config.h" #include "asn-len.h" #include "asn-tag.h" #include "asn-real.h" double pow PROTO ((double base, double exp)); #ifdef WIN32 /* Get rid of frexp warning on windows */ //extern double frexp( double x, int *expptr ); #endif #ifdef IEEE_REAL_LIB /* ieee functions (in case not in math.h)*/ extern int iszero (double); extern int isinf (double); extern int signbit (double); extern int ilogb (double); extern double scalbn (double, int); #endif /* * You must call InitAsnInfinity() to initailize these values * (necessary if you deal with REAL values.) */ AsnReal PLUS_INFINITY; AsnReal MINUS_INFINITY; #define ENC_PLUS_INFINITY 0x40 #define ENC_MINUS_INFINITY 0x41 #define REAL_BINARY 0x80 #define REAL_SIGN 0x40 #define REAL_EXPLEN_MASK 0x03 #define REAL_EXPLEN_1 0x00 #define REAL_EXPLEN_2 0x01 #define REAL_EXPLEN_3 0x02 #define REAL_EXPLEN_LONG 0x03 #define REAL_FACTOR_MASK 0x0c #define REAL_BASE_MASK 0x30 #define REAL_BASE_2 0x00 #define REAL_BASE_8 0x10 #define REAL_BASE_16 0x20 /* * Returns the smallest octet length needed to * hold the given long int value */ unsigned long SignedIntOctetLen PARAMS ((val), long val) { unsigned long mask = (0x7f80L << ((sizeof (unsigned long ) - 2) * 8)); unsigned int retVal = sizeof (long); if (val < 0) val = val ^ (~0L); /* XOR val with all 1's */ while ((retVal > 1) && ((val & mask) == 0)) { mask >>= 8; retVal--; } return retVal; } /* SignedIntOctetLen */ /* * encodes universal TAG LENGTH and Contents of and ASN.1 REAL */ AsnLen BEncAsnReal PARAMS ((b, data), GenBuf *b _AND_ AsnReal *data) { AsnLen len; len = BEncAsnRealContent (b, data); len += BEncDefLen (b, len); len += BEncTag1 (b, UNIV, PRIM, REAL_TAG_CODE); return len; } /* BEncAsnReal */ /* * decodes universal TAG LENGTH and Contents of and ASN.1 REAL */ void BDecAsnReal PARAMS ((b, result, bytesDecoded, env), GenBuf *b _AND_ AsnReal *result _AND_ AsnLen *bytesDecoded _AND_ jmp_buf env) { AsnTag tag; AsnLen elmtLen; if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, REAL_TAG_CODE)) { Asn1Error ("BDecAsnReal: ERROR wrong tag on REAL.\n"); longjmp (env, -40); } elmtLen = BDecLen (b, bytesDecoded, env); BDecAsnRealContent (b, tag, elmtLen, result, bytesDecoded, env); } /* BDecAsnReal */ #ifdef IEEE_REAL_FMT /* * Inits the PLUS_INFINITY and MINUS_INFINITY globals assuming * that the double is an IEEE DOUBLE * The bits for MINUS_INFINITY are 0xfff0000000000000 * The bits for PLUS_INFINITY are 0x7ff0000000000000 */ void InitAsnInfinity() { unsigned char *c = (unsigned char *)&PLUS_INFINITY; int i; if (sizeof (double) != 8) Asn1Error ("InitAsnInfinity: ERROR expected sizeof (AsnReal) to be 8"); #if WORDS_BIGENDIAN /* Big endian */ c[0] = 0x7f; c[1] = 0xf0; for (i = 2; i < sizeof (double); i++) c[i] = 0; #else /* Little endian */ c[7] = 0x7f; c[6] = 0xf0; for (i = 0; i < 6; i++) c[i] = 0; #endif MINUS_INFINITY = -PLUS_INFINITY; } /* InitAsnInfinity */ /* * Encodes the content of an ASN.1 REAL value to the given buffer. * This version of the routine ASSUMES that the C rep. of a double * is the same as the IEEE std. */ AsnLen BEncAsnRealContent PARAMS ((b, value), GenBuf *b _AND_ AsnReal *value) { int exponent; int isNeg; #if SIZEOF_LONG == 4 unsigned char *dbl; unsigned long *first4; unsigned long *second4; #else #if SIZEOF_LONG == 8 unsigned long mantissa, val, *p; int i; #endif #endif /* no contents for 0.0 reals */ if (*value == 0.0) /* all bits zero, disregarding top/sign bit */ return 0; #if SIZEOF_LONG == 4 #if !WORDS_BIGENDIAN #error sorry! this 32 bit code requires big endianess. #endif /* this code is designed to work were longs are 32 bit wide and big endian */ dbl = (unsigned char *) value; first4 = (unsigned long *) dbl; second4 = (unsigned long *) (dbl + sizeof (long )); isNeg = dbl[0] & 0x80; /* special real values for +/- oo */ if (((*first4 & 0x7fffffff) == 0x7ff00000) && (*second4 == 0)) { if (isNeg) { BufPutByteRvs (b, ENC_MINUS_INFINITY); } else { BufPutByteRvs (b, ENC_PLUS_INFINITY); } return 1; } else /* encode a binary real value */ { exponent = (((*first4) >> 20) & 0x07ff); /* write the mantissa (N value) */ BufPutSegRvs (b, (char *)(dbl+2), sizeof (double)-2); /* * The rightmost 4 bits of a double 2nd octet are the * most sig bits of the mantissa. * write the most signficant byte of the asn1 real mantissa, * adding implicit bit to 'left of decimal' if not de-normalized * (de normalized if exponent == 0) * * if the double is not in de-normalized form subtract 1023 * from the exponent to get proper signed exponent. * * for both the normalized and de-norm forms * correct the exponent by subtracting 52 since: * 1. mantissa is 52 bits in the double (56 in ASN.1 REAL form) * 2. implicit decimal at the beginning of double's mantissa * 3. ASN.1 REAL's implicit decimal is after its mantissa * so converting the double mantissa to the ASN.1 form has the * effect of multiplying it by 2^52. Subtracting 52 from the * exponent corrects this. */ if (exponent == 0) /* de-normalized - no implicit 1 to left of dec.*/ { BufPutByteRvs (b, dbl[1] & 0x0f); exponent -= 52; } else { BufPutByteRvs (b, (dbl[1] & 0x0f) | 0x10); /* 0x10 adds implicit bit */ exponent -= (1023 + 52); } #else #if SIZEOF_LONG == 8 #if WORDS_BIGENDIAN #error sorry! this 64 bit code requires little endianess. #endif /* this code is designed to work on Alpha under OSF/1 (64 bit longs, little endian) */ p = (unsigned long *) value; val = *p; isNeg = (val >> 63) & 1; /* special real values for +/- oo */ if (!finite (*value)) { if (isNeg) { BufPutByteRvs (b, ENC_MINUS_INFINITY); } else { BufPutByteRvs (b, ENC_PLUS_INFINITY); } return 1; } else /* encode a binary real value */ { exponent = (val >> 52) & 0x7ff; mantissa = (val & 0xfffffffffffffL) | 0x10000000000000L; for (i = 0; i < 7; i++) { BufPutByteRvs (b, mantissa & 0xff); mantissa >>= 8; } exponent -= (1023 + 52); #else #error long neither 8 nor 4 bytes in size? #endif #endif /* write the exponent */ BufPutByteRvs (b, exponent & 0xff); BufPutByteRvs (b, exponent >> 8); /* write format octet */ /* bb is 00 since base is 2 so do nothing */ /* ff is 00 since no other shifting is nec */ if (isNeg) { BufPutByteRvs (b, REAL_BINARY | REAL_EXPLEN_2 | REAL_SIGN); } else { BufPutByteRvs (b, REAL_BINARY | REAL_EXPLEN_2); } return sizeof (double) + 2; } /* not reached */ } /* BEncAsnRealContent */ #else /* IEEE_REAL_FMT not def */ #ifdef IEEE_REAL_LIB /* * Inits the PLUS_INFINITY and MINUS_INFINITY globals assuming * that the ieee_values library is present */ void InitAsnInfinity() { PLUS_INFINITY = infinity(); MINUS_INFINITY = -PLUS_INFINITY; } /* InitAsnInfinity */ /* * Encodes the content of an ASN.1 REAL value to the given buffer. * This version of the routine does not assume an IEEE double rep. * ieee library conversion routine are used instead. */ AsnLen BEncAsnRealContent PARAMS ((b, value), GenBuf *b _AND_ AsnReal *value) { unsigned long encLen; double mantissa; double tmpMantissa; unsigned int truncatedMantissa; int exponent; unsigned int expLen; int sign; unsigned char buf[sizeof (double)]; int i, mantissaLen; unsigned char firstOctet; /* no contents for 0.0 reals */ if (iszero (*value)) return 0; /* special real values for +/- oo */ if (isinf (*value)) { if (signbit (*value)) /* neg */ BufPutByteRvs (b, ENC_MINUS_INFINITY); else BufPutByteRvs (b, ENC_PLUS_INFINITY); encLen = 1; } else /* encode a binary real value */ { if (signbit (*value)) sign = -1; else sign = 1; exponent = ilogb (*value); /* get the absolute value of the mantissa (subtract 1 to make < 1) */ mantissa = scalbn (fabs (*value), -exponent-1); tmpMantissa = mantissa; /* convert mantissa into an unsigned integer */ for (i = 0; i < sizeof (double); i++) { /* normalizied so shift 8 bits worth to the left of the decimal */ tmpMantissa *= (1<<8); /* grab only (octet sized) the integer part */ truncatedMantissa = (unsigned int) tmpMantissa; /* remove part to left of decimal now for next iteration */ tmpMantissa -= truncatedMantissa; /* write into tmp buffer */ buf[i] = truncatedMantissa; /* keep track of last non zero octet so can zap trailing zeros */ if (truncatedMantissa) mantissaLen = i+1; } /* * write format octet (first octet of content) * field 1 S bb ff ee * bit# 8 7 65 43 21 * * 1 in bit#1 means binary rep * 1 in bit#2 means the mantissa is neg, 0 pos * bb is the base: 65 base * 00 2 * 01 8 * 10 16 * 11 future ext. * * ff is the Value of F where Mantissa = sign x N x 2^F * FF can be one of 0 to 3 inclusive. (used to save re-alignment) * * ee is the length of the exponent: 21 length * 00 1 * 01 2 * 10 3 * 11 long form * * * encoded binary real value looks like * * fmt oct * -------------------------------------------------------- * |1Sbbffee| exponent (2's comp) | N (unsigned int) | * -------------------------------------------------------- * 87654321 */ firstOctet = REAL_BINARY; if (signbit (*value)) firstOctet |= REAL_SIGN; /* bb is 00 since base is 2 so do nothing */ /* ff is 00 since no other shifting is nec */ /* * get exponent calculate its encoded length * Note that the process of converting the mantissa * double to an int shifted the decimal mantissaLen * 8 * to the right - so correct that here */ exponent++; /* compensate for trick to put mantissa < 1 */ exponent -= (mantissaLen * 8); expLen = SignedIntOctetLen (exponent); switch (expLen) { case 1: firstOctet |= REAL_EXPLEN_1; break; case 2: firstOctet |= REAL_EXPLEN_2; break; case 3: firstOctet |= REAL_EXPLEN_3; break; default: firstOctet |= REAL_EXPLEN_LONG; break; } encLen = mantissaLen + expLen + 1; /* write the mantissa (N value) */ BufPutSegRvs (b, (char*)buf, mantissaLen); /* write the exponent */ for (i = expLen; i > 0; i--) { BufPutByteRvs (b, exponent); exponent >>= 8; } /* write the exponents length if nec */ if (expLen > 3) { encLen++; BufPutByteRvs (b, expLen); } /* write the format octet */ BufPutByteRvs (b, firstOctet); } return encLen; } /* BEncAsnRealContent */ #else /* neither IEEE_REAL_FMT or IEEE_REAL_LIB are def */ /* * Inits the PLUS_INFINITY and MINUS_INFINITY globals assuming * that the double is an IEEE DOUBLE. This should be changed * for the target architecture (if it is not IEEE) */ void InitAsnInfinity() { unsigned char *c; int i; if (sizeof (double) != 8) Asn1Error ("InitAsnInfinity: ERROR expected sizeof (AsnReal) to be 8"); c = (unsigned char*)&PLUS_INFINITY; c[0] = 0x7f; c[1] = 0xf0; for (i = 2; i < sizeof (double); i++) c[i] = 0; MINUS_INFINITY = -PLUS_INFINITY; } /* InitAsnInfinity */ /* * Encodes the content of an ASN.1 REAL value to the given buffer. * This version of the routine does not assume an IEEE double rep. * or the existence of the IEEE library routines. Uses old style * UNIX frexp etc. */ AsnLen BEncAsnRealContent PARAMS ((b, value), GenBuf *b _AND_ AsnReal *value) { unsigned long encLen; double mantissa; double tmpMantissa; unsigned int truncatedMantissa; int exponent; unsigned int expLen; int sign; unsigned char buf[sizeof (double)]; int i, mantissaLen=0; unsigned char firstOctet; /* no contents for 0.0 reals */ if (*value == 0.0) return 0; /* special real values for +/- oo */ if (*value == MINUS_INFINITY) { BufPutByteRvs (b, ENC_MINUS_INFINITY); encLen = 1; } else if (*value == PLUS_INFINITY) { BufPutByteRvs (b, ENC_PLUS_INFINITY); encLen = 1; } else /* encode a binary real value */ { /* * this is what frexp gets from *value * *value == mantissa * 2^exponent * where 0.5 <= |manitissa| < 1.0 */ mantissa = frexp (*value, &exponent); /* set sign and make mantissa = | mantissa | */ if (mantissa < 0.0) { sign = -1; mantissa *= -1; } else sign = 1; tmpMantissa = mantissa; /* convert mantissa into an unsigned integer */ for (i = 0; i < sizeof (double); i++) { /* normalizied so shift 8 bits worth to the left of the decimal */ tmpMantissa *= (1<<8); /* grab only (octet sized) the integer part */ truncatedMantissa = (unsigned int) tmpMantissa; /* remove part to left of decimal now for next iteration */ tmpMantissa -= truncatedMantissa; /* write into tmp buffer */ buf[i] = (unsigned char)truncatedMantissa; /* keep track of last non zero octet so can zap trailing zeros */ if (truncatedMantissa) mantissaLen = i+1; } /* * write format octet (first octet of content) * field 1 S bb ff ee * bit# 8 7 65 43 21 * * 1 in bit#1 means binary rep * 1 in bit#2 means the mantissa is neg, 0 pos * bb is the base: 65 base * 00 2 * 01 8 * 10 16 * 11 future ext. * * ff is the Value of F where Mantissa = sign x N x 2^F * FF can be one of 0 to 3 inclusive. (used to save re-alignment) * * ee is the length of the exponent: 21 length * 00 1 * 01 2 * 10 3 * 11 long form * * * encoded binary real value looks like * * fmt oct * -------------------------------------------------------- * |1Sbbffee| exponent (2's comp) | N (unsigned int) | * -------------------------------------------------------- * 87654321 */ firstOctet = REAL_BINARY; if (sign == -1) firstOctet |= REAL_SIGN; /* bb is 00 since base is 2 so do nothing */ /* ff is 00 since no other shifting is nec */ /* * get exponent calculate its encoded length * Note that the process of converting the mantissa * double to an int shifted the decimal mantissaLen * 8 * to the right - so correct that here */ exponent -= (mantissaLen * 8); expLen = SignedIntOctetLen (exponent); switch (expLen) { case 1: firstOctet |= REAL_EXPLEN_1; break; case 2: firstOctet |= REAL_EXPLEN_2; break; case 3: firstOctet |= REAL_EXPLEN_3; break; default: firstOctet |= REAL_EXPLEN_LONG; break; } encLen = mantissaLen + expLen + 1; /* write the mantissa (N value) */ GenBufPutSegRvs (b, (char*)buf, mantissaLen); /* write the exponent */ for (i = expLen; i > 0; i--) { BufPutByteRvs (b, (unsigned char)exponent); exponent >>= 8; } /* write the exponents length if nec */ if (expLen > 3) { encLen++; BufPutByteRvs (b, (unsigned char)expLen); } /* write the format octet */ BufPutByteRvs (b, firstOctet); } return encLen; } /* BEncAsnRealContent */ #endif /* IEEE_REAL_LIB */ #endif /* IEEE_REAL_FMT */ /* * Decodes the content of a BER REAL value. * This only supports the binary REAL encoding. The decimal encoding * is left as an exercise to the reader. */ void BDecAsnRealContent PARAMS ((b, tagId, len, result, bytesDecoded, env), GenBuf *b _AND_ AsnTag tagId _AND_ AsnLen len _AND_ AsnReal *result _AND_ AsnLen *bytesDecoded _AND_ jmp_buf env) { unsigned char firstOctet; unsigned char firstExpOctet; int i; unsigned int expLen; double mantissa; unsigned short base; long exponent = 0; if (len == 0) { *result = 0.0; return; } else if (len == INDEFINITE_LEN) { Asn1Error ("BDecAsnRealContent: ERROR - indefinite length on primitive.\n"); longjmp (env, -67); } firstOctet = BufGetByte (b); if (len == 1) { (*bytesDecoded) += 1; if (firstOctet == ENC_PLUS_INFINITY) *result = PLUS_INFINITY; else if (firstOctet == ENC_MINUS_INFINITY) *result = MINUS_INFINITY; else { Asn1Error ("BDecAsnRealContent: ERROR - unrecognized real number of length 1 octet.\n"); longjmp (env, -22); } } else { if (firstOctet & REAL_BINARY) { firstExpOctet = BufGetByte (b); if (firstExpOctet & 0x80) exponent = -1; switch (firstOctet & REAL_EXPLEN_MASK) { case REAL_EXPLEN_1: expLen = 1; exponent = (exponent << 8)| firstExpOctet; break; case REAL_EXPLEN_2: expLen = 2; exponent = (exponent << 16) | (((unsigned long) firstExpOctet) << 8) | BufGetByte (b); break; case REAL_EXPLEN_3: expLen = 3; exponent = (exponent << 16) | (((unsigned long) firstExpOctet) << 8) | BufGetByte (b); exponent = (exponent << 8) | BufGetByte (b); break; default: /* long form */ expLen = firstExpOctet +1; i = firstExpOctet-1; firstExpOctet = BufGetByte (b); if (firstExpOctet & 0x80) exponent = (-1 <<8) | firstExpOctet; else exponent = firstExpOctet; for (;i > 0; firstExpOctet--) exponent = (exponent << 8) | BufGetByte (b); break; } mantissa = 0.0; for (i = 1 + expLen; i < (int)len; i++) { mantissa *= (1<<8); mantissa += BufGetByte (b); } /* adjust N by scaling factor */ mantissa *= (1<<((firstOctet & REAL_FACTOR_MASK) >> 2)); switch (firstOctet & REAL_BASE_MASK) { case REAL_BASE_2: base = 2; break; case REAL_BASE_8: base = 8; break; case REAL_BASE_16: base = 16; break; default: Asn1Error ("BDecAsnRealContent: ERROR - unsupported base for a binary real number.\n"); longjmp (env, -23); break; } *result = mantissa * pow ((double)base, (double)exponent); if (firstOctet & REAL_SIGN) *result = -*result; (*bytesDecoded) += len; } else /* decimal version */ { Asn1Error ("BDecAsnRealContent: ERROR - decimal REAL form is not currently supported\n"); longjmp (env, -24); } } tagId = tagId; /* referenced to avoid compiler warning. */ } /* BDecAsnRealContent */ /* * Prints given REAL value to the given FILE * in ASN.1 Value Notation. * indent is ignored. */ void PrintAsnReal PARAMS ((f, v, indent), FILE *f _AND_ AsnReal *v _AND_ unsigned int indent) { fprintf (f, "%.17E", *v); indent = indent; /* referenced to avoid compiler warning. */ } esnacc-ng-1.8.1/c-lib/src/asn-relative-oid.c000066400000000000000000000150431302010526100204340ustar00rootroot00000000000000/* * asn_relative_oid.c - BER encode, decode, print and free routines for the * ASN.1 RELATIVE OBJECT IDENTIFIER type. * * Joseph Grone * 15/01/2004 * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ #include "asn-config.h" #include "asn-len.h" #include "asn-tag.h" #include "asn-octs.h" #include "asn-relative-oid.h" /* * encodes universal TAG LENGTH and Contents of and ASN.1 OBJECT ID */ AsnLen BEncAsnRelativeOid PARAMS ((b, data), GenBuf *b _AND_ AsnRelativeOid *data) { AsnLen len; len = BEncAsnRelativeOidContent (b, data); len += BEncDefLen (b, len); len += BEncTag1 (b, UNIV, PRIM, RELATIVE_OID_TAG_CODE); return len; } /* BEncAsnRelativeOid */ /* * decodes universal TAG LENGTH and Contents of and ASN.1 OBJECT ID */ void BDecAsnRelativeOid PARAMS ((b, result, bytesDecoded, env), GenBuf *b _AND_ AsnRelativeOid *result _AND_ AsnLen *bytesDecoded _AND_ jmp_buf env) { AsnTag tag; AsnLen elmtLen; if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, RELATIVE_OID_TAG_CODE)) { Asn1Error ("BDecAsnRelativeOid: ERROR - wrong tag on OBJECT IDENTIFIER.\n"); longjmp (env, -40); } elmtLen = BDecLen (b, bytesDecoded, env); BDecAsnRelativeOidContent (b, tag, elmtLen, result, bytesDecoded, env); } /* BDecAsnRelativeOid */ /* * Decodes just the content of the RELATIVE_OID. * AsnRelativeOid is handled the same as a primtive octet string */ void BDecAsnRelativeOidContent PARAMS ((b, tagId, len, result, bytesDecoded, env), GenBuf *b _AND_ AsnTag tagId _AND_ AsnLen len _AND_ AsnRelativeOid *result _AND_ AsnLen *bytesDecoded _AND_ jmp_buf env) { if (len == INDEFINITE_LEN) { Asn1Error ("BDecAsnRelativeOidContent: ERROR - indefinite length on primitive\n"); longjmp (env, -66); } result->octetLen = len; result->octs = Asn1Alloc (len); CheckAsn1Alloc (result->octs, env); BufCopy (result->octs, b, len); if (BufReadError (b)) { Asn1Error ("BDecAsnRelativeOidContent: ERROR - decoded past end of data\n"); longjmp (env, -21); } (*bytesDecoded) += len; tagId=tagId; /* referenced to avoid compiler warning. */ } /* BDecAsnRelativeOidContent */ /* * Prints the given RELATIVE_OID to the given FILE * in ASN.1 Value Notation. * Since the internal rep of an RELATIVE_OID is 'encoded', this routine * decodes each individual arc number to print it. */ void PrintAsnRelativeOid PARAMS ((f,v, indent), FILE *f _AND_ AsnRelativeOid *v _AND_ unsigned int indent) { unsigned int arcNum; int i; fprintf (f,"{"); for (i = 0; i < (int)(v->octetLen); ) { for (arcNum = 0; (i < (int)(v->octetLen)) && (v->octs[i] & 0x80);i++) arcNum = (arcNum << 7) + (v->octs[i] & 0x7f); arcNum = (arcNum << 7) + (v->octs[i] & 0x7f); i++; fprintf (f," %u", arcNum); } fprintf (f,"}"); indent=indent; /* referenced to avoid compiler warning. */ } /* PrintAsnRelativeOid */ /* * given an RELATIVE_OID, figures out the length for the encoded version */ AsnLen EncodedRelativeOidLen PARAMS ((oid), RELATIVE_OID *oid) { AsnLen totalLen; unsigned long tmpArcNum; RELATIVE_OID *tmpOid; totalLen = 0; /* * oid must have at least 2 elmts */ if (oid == NULL) return 0; for (tmpOid = oid; tmpOid != NULL; tmpOid = tmpOid->next) { totalLen++; tmpArcNum = tmpOid->arcNum; for (; (tmpArcNum >>= 7) != 0; totalLen++) ; } return totalLen; } /* EncodedOidLen */ /* * given an oid list and a pre-allocated ENC_RELATIVE_OID * (use EncodedOidLen to figure out byte length needed) * fills the ENC_RELATIVE_OID with a BER encoded version * of the oid. */ void BuildEncodedRelativeOid PARAMS ((oid, result), RELATIVE_OID *oid _AND_ AsnRelativeOid *result) { unsigned long len; char *buf; int i; unsigned long tmpArcNum; RELATIVE_OID *tmpOid; buf = result->octs; /* * oid must have at least 2 elmts */ if (oid->next == NULL) return; /* * munge together first two arcNum * note first arcnum must be <= 2 * and second must be < 39 if first = 0 or 1 * see (X.209) for ref to this stupidity */ for (tmpOid = oid; tmpOid != NULL; tmpOid = tmpOid->next) { /* * figure out encoded length -1 of this arcNum */ tmpArcNum = tmpOid->arcNum; for (len = 0; (tmpArcNum >>= 7) != 0; len++) ; /* * write more signifcant bytes (if any) * with 'more' bit set */ for (i=0; i < (int)len; i++) *(buf++) = (char)(0x80 | (tmpOid->arcNum >> ((len-i)*7))); /* * write least significant byte */ *(buf++) = (char)(0x7f & tmpOid->arcNum); } result->octetLen = (buf - result->octs); } /* BuildEncodedOid */ /* * convert an AsnRelativeOid into an RELATIVE_OID (linked list) * NOT RECOMMENDED for use in protocol implementations */ void UnbuildEncodedRelativeOid PARAMS ((eoid, result), AsnRelativeOid *eoid _AND_ RELATIVE_OID **result) { RELATIVE_OID **nextOid; RELATIVE_OID *headOid; int arcNum; int i; for (arcNum = 0, i=0; (i < (int)(eoid->octetLen)) && (eoid->octs[i] & 0x80);i++) arcNum = (arcNum << 7) + (eoid->octs[i] & 0x7f); arcNum = (arcNum << 7) + (eoid->octs[i] & 0x7f); i++; headOid = (RELATIVE_OID*)malloc (sizeof (RELATIVE_OID)); headOid->arcNum = arcNum; headOid->next = (RELATIVE_OID*)malloc (sizeof (RELATIVE_OID)); nextOid = &headOid->next; for (i = 1; i < (int)(eoid->octetLen); ) { for (arcNum = 0; (i < (int)(eoid->octetLen)) && (eoid->octs[i] & 0x80); i++) arcNum = (arcNum << 7) + (eoid->octs[i] & 0x7f); arcNum = (arcNum << 7) + (eoid->octs[i] & 0x7f); i++; *nextOid = (RELATIVE_OID*)malloc (sizeof (RELATIVE_OID)); (*nextOid)->arcNum = arcNum; (*nextOid)->next = NULL; nextOid = &(*nextOid)->next; } *result = headOid; } /* UnbuildEncodedOid */ esnacc-ng-1.8.1/c-lib/src/asn-tag.c000066400000000000000000000111001302010526100166110ustar00rootroot00000000000000/* * asn_tag.c - BER encode, decode and untility routines for ASN.1 Tags. * * MS 92 * Copyright (C) 1992 Michael Sample and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/src/asn-tag.c,v 1.3 2003/12/17 19:05:03 gronej Exp $ * $Log: asn-tag.c,v $ * Revision 1.3 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.2.2.1 2003/11/05 14:58:53 gronej * working PER code merged with esnacc_1_6 * * Revision 1.2 2002/10/23 10:23:37 mcphersc * Changed BUF_TYPE to AsnBuf * * Revision 1.1.1.1 2000/08/21 20:35:52 leonberp * First CVS Version of SNACC. * * Revision 1.5 1997/09/03 12:11:41 wan * Patch to tag decoding for tags > 2^14 (thanks to Enrico Badella) * Patch to TblEncTag to emit final 0x00 if previous octet signals continuation * * Revision 1.4 1997/03/13 09:15:18 wan * Improved dependency generation for stupid makedepends. * Corrected PeekTag to peek into buffer only as far as necessary. * Added installable error handler. * Fixed small glitch in idl-code generator (Markku Savela ). * * Revision 1.3 1997/02/28 13:39:50 wan * Modifications collected for new version 1.3: Bug fixes, tk4.2. * * Revision 1.2 1995/07/27 09:01:25 rj * merged PeekTag(), a function used only by the type table code. * * changed `_' to `-' in file names. * * Revision 1.1 1994/08/28 09:46:01 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include "asn-config.h" #include "asn-len.h" #include "asn-tag.h" /* * Returns an AsnTag. An AsnTag is simply an encoded tag * shifted to fill up an unsigned long int (first tag byte * in most sig byte of long int) * This rep permits easy case stmt comparison of tags. * NOTE: The unsigned long rep for tag BREAKS if the * the tag's code is over 2^21 (very unlikely) * * RETURNS 0 if decoded a 0 byte (ie first byte of an EOC) */ AsnTag BDecTag PARAMS ((b, bytesDecoded, env), GenBuf * b _AND_ AsnLen *bytesDecoded _AND_ jmp_buf env) { AsnTag tagId; AsnTag tmpTagId; int i; tagId = ((AsnTag)BufGetByte (b)) << ((sizeof (AsnTag)-1)*8); (*bytesDecoded)++; /* check if long tag format (ie code > 31) */ if ((tagId & (((AsnTag) 0x1f) << ((sizeof (AsnTag)-1)*8))) == (((AsnTag)0x1f) << ((sizeof (AsnTag)-1)*8))) { i = 2; do { tmpTagId = (AsnTag) BufGetByte (b); tagId |= (tmpTagId << ((sizeof (AsnTag)-i)*8)); (*bytesDecoded)++; i++; } while ((tmpTagId & (AsnTag)0x80) && (i <= sizeof (AsnTag))); /* * check for tag that is too long */ if (i > (sizeof (AsnTag)+1)) { Asn1Error ("BDecTag: ERROR - tag value overflow\n"); longjmp (env, -25); } } if (BufReadError (b)) { Asn1Error ("BDecTag: ERROR - decoded past the end of data\n"); longjmp (env, -26); } return tagId; } /* BDecTag */ #if TTBL AsnTag PeekTag PARAMS ((b, env), GenBuf *b _AND_ ENV_TYPE env) { AsnTag tagId, tmpTagId; int i; unsigned char buf[sizeof(AsnTag)]; unsigned char* p = buf; /* * peek/copy the next (max size of tag) bytes * to get the tag info. The Peek buffer routines * were added to the standard set for this function. */ BufPeekCopy ((char*)buf, b, 1); tagId = ((AsnTag)*p++) << ((sizeof (AsnTag)-1)*8); /* check if long tag format (ie code > 31) */ if ((tagId & (((AsnTag) 0x1f) << ((sizeof (AsnTag)-1)*8))) == (((AsnTag)0x1f) << ((sizeof (AsnTag)-1)*8))) { i = 2; do { BufPeekCopy ((char*)buf, b, i); tmpTagId = (AsnTag) *p++; tagId |= (tmpTagId << ((sizeof (AsnTag)-i)*8)); i++; } while ((tmpTagId & (AsnTag)0x80) && (i <= sizeof (AsnTag))); /* * check for tag that is too long */ if (i > (sizeof (AsnTag)+1)) { Asn1Error ("BDecTag: ERROR - tag value overflow\n"); longjmp (env, -1004); } } return tagId; } /* PeekTag */ #endif /* TTBL */ esnacc-ng-1.8.1/c-lib/src/asn1init.c000066400000000000000000000020221302010526100170100ustar00rootroot00000000000000/* Included files */ #include "asn-incl.h" #include "nibble-alloc.h" void FreeHashTable(Table* pTable); void ASN1init() { ExpBufInit (1024); /* Should this be higher? */ /* decoding buffer init - use mem within buffer rather than allocating all * the time... I will initially alloc 4K since the certs are generally in * the 3k - 4k range */ InitNibbleMem(4096, 512); /* intially alloc 4096, inc by 512 as required */ } void ASN1Terminate() { /* Frees the existing hash tables */ FreeHashTable(anyOidHashTblG); anyOidHashTblG = NULL; FreeHashTable(anyIntHashTblG); anyIntHashTblG = NULL; /* Releases the nibble memory completely */ ShutdownNibbleMem(); } void FreeHashTable(Table* pTable) { unsigned int i; HashSlot* pSlot; if (pTable == NULL) return; for (i = 0; i < TABLESIZE; i++) { pSlot = (HashSlot*) (*pTable)[i]; if (pSlot != NULL) { if (pSlot->table != NULL) FreeHashTable(pSlot->table); else free(pSlot->value); free(pSlot); (*pTable)[i] = NULL; } } free(pTable); } esnacc-ng-1.8.1/c-lib/src/exp-buf.c000066400000000000000000000567351302010526100166540ustar00rootroot00000000000000/* * .../c-lib/src/exp-buf.c - buffer routines for the buffer structure * * * --------- ---------- * | ExpBuf |<------>| ExpBuf |<------> ...ExpBufs * | |--- | |--- * ---------- | ---------- | * V V * -------- -------- * | DATA | | DATA | * | BLK | | BLK | * -------- -------- * * * ExpBuf * -------------- * | readError | * | writeError | * | dataStart |----------- * | dataEnd |-------- | * | curr |------ | | * | next | | | | * | prev | | | | data * | blkStart |=====|=|==|==>-------------------------- * | blkEnd |--- | | | | | (each line * -------------- | | | | | | reps a byte * | | | |-->| - - - - - - - - - - - -| diff in addr) * | | | | valid | * | |-|----->| | * | | | data | * | | | | * | | | - - - - - - - - - - - -| * | |----->|(one byte after last valid data byte) * | | | * | -------------------------- * |-----------> (one byte after last byte in data blk) * * * readError - set to non-zero to indicate attempt to read past end of * of data * writeError- set to non-zero to indicate write error. * Set if Alloc of new buf fails * dataStart - pts to first VALID data byte ie *dataStart is first byte * dataEnd - pts to byte AFTER last VALID byte *dataEnd is not in the data * but *(dataEnd -1) is in the data * curr - used for current read ptr - points to next byte to be read * so *curr is the next byte to be read. * next - pts to next BUF in list, NULL for last BUF in list * prev - pts to prev BUF in list, NULL for first BUF in list * blkStart - pts to start of the data blk. *blkStart is first byte * in the buffer's data blk. * blkEnd - pts to byte AFTER last writable byte of the dataBlk. * *(blkEnd-1) is the last byte in the buffer's data blk. * * NOTES: * - dataEnd is currently always the same as blkEnd * - at End Of Data (EOD) (no more data to be read) * if (curr == dataEnd) * - buffer has no valid data if (dataStart == dataEnd) * - number of valid data bytes = (dataEnd - dataStart) * - size of the data block = (blkEnd - blkStart) * * - the write reverse routines modify dataStart * - the read routines modify the curr ptr. * - there are no 'forward' write routines at the moment * (if there were they would adjust dataEnd) * * * Copyright (C) 1992 Michael Sample and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/src/exp-buf.c,v 1.12 2003/12/17 19:05:03 gronej Exp $ * $Log: exp-buf.c,v $ * Revision 1.12 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.11.2.1 2003/11/05 14:58:54 gronej * working PER code merged with esnacc_1_6 * * Revision 1.11 2003/08/04 10:31:46 colestor * Updated several improperly referenced "b" buffer parameters when dealing with * ANY load/unloads (encode/decodes). This code has never been tested in the * "C" library. * * Revision 1.10 2002/12/05 15:21:41 nicholar * Eliminated duplicate code by having ExptBuftoGenBuf() call PutExpBufInGenBuf(). * * Revision 1.9 2002/10/23 13:32:40 mcphersc * Took GenBuf defines out * * Revision 1.8 2002/10/22 16:46:04 mcphersc * Mods for gen-buf usage * * Revision 1.7 2002/10/22 14:39:01 mcphersc * Fixed bug in resetinreadmode * * Revision 1.6 2002/10/18 13:09:32 mcphersc * took out long int to unsigned long * * Revision 1.5 2002/10/15 17:32:20 mcphersc * Added code to allocate a GenBuf from an ExpBuf. * Also modified ExpBufResetInReadMode * * Revision 1.4 2002/10/01 14:15:17 mcphersc * ASN "C" Buf modifications * * Revision 1.3 2002/09/25 12:11:08 mcphersc * fixed warnings * * Revision 1.2 2000/10/16 18:10:40 rwc * removed most warnings from C++-lib, some C-lib. * * Revision 1.1.1.1 2000/08/21 20:35:52 leonberp * First CVS Version of SNACC. * * Revision 1.2 1995/07/27 09:05:29 rj * merged type table routines and code used by its gen-bufs. * * changed `_' to `-' in file names. * * Revision 1.1 1994/08/28 09:46:05 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include "asn-config.h" #include "exp-buf.h" #include "gen-buf.h" #include "asn-incl.h" #include /* default buffer data block size (used when allocating) */ unsigned long expBufDataBlkSizeG = 1024; /* * casts are used to overcome void * - ExpBuf * conflict * be careful if you modify param lists etc. */ static struct GenBuf expBufOpsG = { (BufCopyAnyFcn) ExpBufCopyAny, (BufGetByteFcn) ExpBufGetByte, (BufGetSegFcn) ExpBufGetSeg, (BufCopyFcn) ExpBufCopy, (BufSkipFcn) ExpBufSkip, (BufPeekByteFcn) ExpBufPeekByte, (BufPeekSegFcn) ExpBufPeekSeg, (BufPeekCopyFcn) ExpBufPeekCopy, (BufPutByteRvsFcn) ExpBufPutByteRvs, (BufPutSegRvsFcn) ExpBufPutSegRvs, (BufReadErrorFcn) ExpBufReadError, (BufSetWriteErrorFcn) ExpBufSetWriteError, (BufWriteErrorFcn) ExpBufWriteError, (BufResetInReadModeFcn) ExpBufResetInReadMode, NULL, NULL }; /* * remember: ExpBufs are used via a handle (double ptr) * in the standardized buffer routines. This allows * the 'current' expbuf in the list of expbuf to be the arg. * The list is doubly linked so you can always find * the head or tail given any expbuf in the list */ void PutExpBufInGenBuf PARAMS ((eb, gb), ExpBuf *eb _AND_ GenBuf *gb) { *gb = expBufOpsG; /* structure assignemnt */ gb->bufInfo = &gb->spare; /* handle to expbuf */ gb->spare = eb; } /* PutExpBufInGenBuf */ /* * Allocate a GenBuf structure and copy in * the function pointers */ void ExpBuftoGenBuf PARAMS ((eb, gb), ExpBuf *eb _AND_ GenBuf **gb) { if (gb != NULL) { *gb = (struct GenBuf *) malloc (sizeof (struct GenBuf)); if (*gb != NULL) PutExpBufInGenBuf(eb, *gb); } } /* * sets the size of the data block to attach to * an ExpBuf when allocating a new one */ void ExpBufInit PARAMS ((dataBlkSize), unsigned long dataBlkSize) { expBufDataBlkSizeG = dataBlkSize; } /* InitBuffers */ /* * Allocates and returns an uninitialized ExpBuf with * no a data attached. */ ExpBuf* ExpBufAllocBuf() { return (ExpBuf*)malloc (sizeof (ExpBuf)); } void ExpBufFreeBuf PARAMS ((ptr), ExpBuf *ptr) { if (ptr != NULL) free (ptr); } char* ExpBufAllocData() { return (char*)malloc (expBufDataBlkSizeG); } void ExpBufFreeData PARAMS ((ptr), char *ptr) { if (ptr != NULL) free (ptr); } void ExpBufFreeBufAndData PARAMS ((b), ExpBuf *b) { ExpBufFreeData ((b)->blkStart); ExpBufFreeBuf (b); } /* ExpBufFreeBufAndData */ ExpBuf* ExpBufNext PARAMS ((b), ExpBuf *b) { return b->next; } ExpBuf* ExpBufPrev PARAMS ((b), ExpBuf *b) { return b->prev; } int ExpBufReadError PARAMS ((b), ExpBuf **b) { return (*b)->readError; } /* ExpBufReadError */ int ExpBufCopyAny PARAMS ((b, value, *bytesDecoded, env), ExpBuf **b _AND_ // RWC; ADDED 2nd "*" to work properly... void *value _AND_ AsnLen *bytesDecoded _AND_ ENV_TYPE env) { AsnLen totalElmtsLen1 = 0; AsnLen elmtLen1 = 0; AsnOcts *data = 0; /* where we will store the stuff */ GenBuf gb; // Our GenBuf char *loc = 0; if (!b) { return -1; } // Put the ExpBuf into a GenBuf so we can use BDecTag & BDecLen PutExpBufInGenBuf (*b, &gb); loc = (*b)->curr; // Get the buffer pointer elmtLen1 = BDecLen (&gb, &totalElmtsLen1, env); /* len of item */ if (elmtLen1 == INDEFINITE_LEN) { /* can't deal with indef len unknown types here (at least for now) */ Asn1Error("BDecUnknownAsnAny: ERROR - indef length object found\n"); longjmp(env, -910); } /* and now decode the contents */ data = (AsnOcts *) value; /* allocated by the any routine */ data->octetLen = elmtLen1 + totalElmtsLen1; /* tag+len+data lengths */ data->octs = Asn1Alloc(data->octetLen +1); CheckAsn1Alloc (data->octs, env); /* use normal buffer reading to copy the any */ /*RWC;RESET current pointer to be sure to get tag/length AND data.*/ (*b)->curr = loc; ExpBufCopy(&data->octs[0/*RWC;totalElmtsLen1*/] , b, totalElmtsLen1+elmtLen1); if (ExpBufReadError(b)) { Asn1Error("BDecUnknownAsnAny: ERROR - decoded past end of data\n"); longjmp(env, -920); } /* add null terminator - this is not included in the str's len */ data->octs[data->octetLen] = '\0'; (*bytesDecoded) += data->octetLen; /* (*bytesDecoded) += totalElmtsLen1; just use the total blob length */ return 0; } int ExpBufSetWriteError PARAMS ((b, Value), ExpBuf *b _AND_ unsigned short Value) { if (b == NULL) return -1; (b)->writeError = Value; return 0; } int ExpBufWriteError PARAMS ((b), ExpBuf **b) { if (b == NULL || *b == NULL) return -1; return (*b)->writeError; } /* ExpBufWriteError */ /* * set curr ptr used in reads to the first byte * to be read */ void ExpBufResetInReadMode PARAMS ((b), ExpBuf **b) { ExpBuf *nextPtr = (ExpBuf *)0; ExpBuf *retVal = (ExpBuf *)0; (*b)->curr = (*b)->dataStart; (*b)->readError = 0; (*b)->writeError = 1; /* catch wrong mode errors */ /* Get the Previous Pointer */ nextPtr = (*b)->next; if (nextPtr == NULL) retVal = (*b); else retVal = nextPtr; if (nextPtr != NULL) { while (nextPtr) { nextPtr->curr = nextPtr->dataStart; nextPtr->readError = 0; nextPtr->writeError = 1; /* catch wrong mode errors */ nextPtr = nextPtr->next; if (nextPtr) retVal = nextPtr; } } else { retVal->curr = retVal->dataStart; retVal->readError = 0; retVal->writeError = 1; } *b = retVal; } /* * sets dataStart to end of buffer * so following writes (backward) * over-write any existing data associated with * the buffer */ void ExpBufResetInWriteRvsMode PARAMS ((b), ExpBuf *b) { b->dataEnd = b->dataStart = b->blkEnd; b->writeError = 0; b->readError = 1; /* catch wrong mode errors */ } /* * returns true if no more data can be read from * the given buffer. only valid when buffer in read (fwd) * mode. */ int ExpBufAtEod PARAMS ((b), ExpBuf *b) { return b->curr == b->dataEnd; } /* * returns true if no more reverse writes can be done * to the buffer. Only valid when buffers in reverse * write mode */ int ExpBufFull PARAMS ((b), ExpBuf *b) { return (b)->dataStart == (b)->blkStart; } /* * returns true if the given buffer has no * valid data in it's data block */ int ExpBufHasNoData PARAMS ((b), ExpBuf *b) { return b->dataStart == b->dataEnd; } /* * returns the number of valid data bytes in the * given buffer's data block */ unsigned long ExpBufDataSize PARAMS ((b), ExpBuf *b) { return b->dataEnd - b->dataStart; } /* * returns size of data block that is attached to * the given buffer. */ unsigned long ExpBufDataBlkSize PARAMS ((b), ExpBuf *b) { return b->blkEnd - b->blkStart; } /* * returns a ptr the beginning of the valid data of * the given buffer. * returns NULL is there is no valid data. */ char* ExpBufDataPtr PARAMS ((b), ExpBuf *b) { if (ExpBufHasNoData (b)) return NULL; else return b->dataStart; } /* * returns last ExpBuf in a list of bufs. * The given buf can be any buf in the list. */ ExpBuf* ExpBufListLastBuf PARAMS ((b), ExpBuf *b) { for (; b->next != NULL; b = b->next) ; return b; } /* * returns first buf in a list of bufs . * The given buf can be any buf in the list */ ExpBuf* ExpBufListFirstBuf PARAMS ((b), ExpBuf *b) { for (; b->prev != NULL; b = b->prev) ; return b; } /* * Allocates a Buf and allocates an attaches a * data block of expBufDataBlkSizeG to that buffer. * sets up the blk for writing in that the data start * and data end point to the byte after the data blk. */ ExpBuf* ExpBufAllocBufAndData() { ExpBuf *retVal; retVal = ExpBufAllocBuf(); if (retVal == NULL) return NULL; retVal->readError = 0; retVal->writeError = 0; retVal->blkStart = ExpBufAllocData(); if (retVal->blkStart == NULL) { ExpBufFreeBuf (retVal); return NULL; } retVal->next = NULL; retVal->prev = NULL; retVal->curr = retVal->blkEnd = retVal->dataStart = retVal->dataEnd = retVal->blkStart + expBufDataBlkSizeG; return retVal; } /* ExpBufAllocBufAndData */ /* * Frees ExpBuf's and associated data blocks after * after (next ptr) and including the given buffer, b. */ void ExpBufFreeBufAndDataList PARAMS ((b), ExpBuf *b) { ExpBuf *tmp; for (; b != NULL;) { tmp = b->next; ExpBufFreeBufAndData (b); b = tmp; } } /* ExpBufFreeBufAndDataList */ /* * puts the given data in a buffer and sets it up for reading * the data. This results in a "full" buffer with a data * blk size of given data's len */ void ExpBufInstallDataInBuf PARAMS ((buf, data, len), ExpBuf *buf _AND_ char *data _AND_ unsigned long len) { buf->readError = 0; buf->writeError = 0; buf->blkStart = buf->dataStart = buf->curr = data; buf->next = NULL; buf->prev = NULL; buf->blkEnd = buf->dataEnd = data + len; } /* ExpBufInstallDataInBuf */ /* Buf reading and writing routines follow */ /* READ * returns the next byte to be read without * advancing the pointer. No check for end of * data - this is lame */ unsigned char ExpBufPeekByte PARAMS ((b), ExpBuf **b) { if ((*b)->curr == (*b)->dataEnd) (*b)->readError = 1; return *(*b)->curr; } /* ExpBufPeek */ /* READ * returns a ptr to the next "len" bytes (contiguous). * if "len" is greater than the available contiguous bytes * len is set the the number of contig. bytes the returned * ptr references. The next call to ExpBufGetSeg or other ExpBufGet * routines will return a ptrs to the SAME bytes (ie curr is NOT advanced). * * Does not change the buffer * * if the value returned in the len param is zero or the * returned char * is NULL then at end of data. * */ char* ExpBufPeekSeg PARAMS ((b, len), ExpBuf **b _AND_ unsigned long *len) { int bytesLeft = 0; if (ExpBufAtEod (*b)) { *len = 0; return NULL; } /* check for "buffer fault" and adjust "peeked" len */ bytesLeft = ((unsigned long)(*b)->dataEnd - (unsigned long)(*b)->curr); if (bytesLeft <= *len) *len = bytesLeft; return (*b)->curr; } /* ExpBufPeekSeg */ /* READ * copy the next len chars in the buffer to the given * dst char string. The curr ptr in the buffer is * NOT advanced so the next read will get the same bytes. */ int ExpBufPeekCopy PARAMS ((dst, b, len), char *dst _AND_ ExpBuf **b _AND_ unsigned long len) { unsigned long gotLen; unsigned long totalGotLen = 0; char *srcPtr; ExpBuf *origBuf; origBuf = *b; gotLen = len; while (1) /* optimize std path - eg only one ExpBufGetPeekSeg needed */ { srcPtr = ExpBufPeekSeg (b, &gotLen); memcpy (dst + totalGotLen, srcPtr, gotLen); totalGotLen += gotLen; if ((totalGotLen >= len) || ((*b)->next == NULL)) { *b = origBuf; return totalGotLen; } if (gotLen == 0) /* eod */ { (*b)->readError = 1; *b = origBuf; return totalGotLen; } *b = (*b)->next; /* get next buffer with valid data */ while (((*b)->next != NULL) && ExpBufHasNoData (*b)) *b = (*b)->next; /* reset current pointer to beggining of data if nec */ (*b)->curr = (*b)->dataStart; gotLen = len - totalGotLen; } /* not reached */ } /* ExpBufPeekCopy */ /* READ * copy the next len chars in the buffer to the given * dst char string. The curr ptr in the buffer is advanced * appropriately */ int ExpBufCopy PARAMS ((dst, b, len), char *dst _AND_ ExpBuf **b _AND_ unsigned long len) { unsigned long gotLen; int totalGotLen = 0; char *srcPtr; gotLen = len; while (1) /* optimize std path - eg only one ExpBufGetSeg needed */ { srcPtr = ExpBufGetSeg (b, &gotLen); memcpy (dst + totalGotLen, srcPtr, gotLen); totalGotLen += gotLen; if (totalGotLen >= (int)len) return totalGotLen; if (gotLen == 0) /* eod */ { (*b)->readError = 1; return totalGotLen; } gotLen = len - totalGotLen; } /* not reached */ } /* ExpBufCopy */ /* * advance the curr ptr in the given buffer over the next * len bytes */ void ExpBufSkip PARAMS ((b, len), ExpBuf **b _AND_ unsigned long len) { unsigned long lenRemaining; lenRemaining = len; while ((len > 0) && ExpBufGetSeg (b, &lenRemaining)) { len -= lenRemaining; if (lenRemaining == 0) { (*b)->readError = 1; return; } lenRemaining = len; } } /* ExpBufSkip */ /* READ * returns a ptr to the next "len" bytes (contiguous). * if "len" is greater than the available contiguous bytes * len is set the the number of contig. bytes the returned * ptr references. Subsequent call to ExpBufGetSeg or other ExpBufGet * routines will return ptrs to the following bytes (ie curr is advanced). * Changes *b to pt to the next buffer and sets curr for the * that buffer to dataStart if the current one has been totally read. * * if the value returned in the len param is zero or the * returned char * is NULL then at end of data (eod) * */ char* ExpBufGetSeg PARAMS ((b, len), ExpBuf **b _AND_ unsigned long *len) { int bytesLeft; char *retVal; if (ExpBufAtEod (*b)) { *len = 0; return NULL; } bytesLeft = (*b)->dataEnd - (*b)->curr; retVal = (*b)->curr; /* check for "buffer fault" */ if (bytesLeft <= (int)*len) { *len = bytesLeft; if ((*b)->next != NULL) { *b = (*b)->next; /* get next buffer with valid data */ while (((*b)->next != NULL) && ExpBufHasNoData (*b)) *b = (*b)->next; /* reset current pointer to beggining of data if nec */ (*b)->curr = (*b)->dataStart; } else (*b)->curr += *len; } else (*b)->curr += *len; return retVal; } /* ExpBufGetSeg */ /* * WRITE * Copies len bytes from the data pointer into the given buffer * * FILLS EXP_BUFFERS BACKWARDS! from the end of the data to the beginning * LINKS BUFFERS BACKWARDS! if a buf is full it allocs another an * puts it at the HEAD of the buffer list * * changes *b to pt to the new "prev" buffer if the current one * has been totally filled * Rvs is for REVERSE! * * modifies the dataStart pointer to reflect the new data */ void ExpBufPutSegRvs PARAMS ((b, data, len), ExpBuf **b _AND_ char *data _AND_ unsigned long len) { int bytesLeft; ExpBuf *buf; char *dataPtr; buf = *b; if (buf->writeError) return; bytesLeft = buf->dataStart - buf->blkStart; dataPtr = data + len; /* pts to end of data to be written */ /* optimize fast path */ do { if (bytesLeft > (int)len) /* enough room in this buffer for write */ { buf->dataStart -= len; memcpy (buf->dataStart, data, len); break; /* this is the normal exit from this loop */ } else { /* * going to fill this buffer completely, * so alloc other one (only if one is not * already linked in) */ dataPtr = dataPtr - bytesLeft; buf->dataStart = buf->blkStart; memcpy (buf->dataStart, dataPtr, bytesLeft); len -= bytesLeft; if (buf->prev == NULL) { /* alloc & insert new buf at head of buffer list */ buf = ExpBufAllocBufAndData(); if (buf == NULL) { (*b)->writeError = 1; return; } buf->next = *b; (*b)->prev = buf; } else buf = buf->prev; *b = buf; /* update head of list */ bytesLeft = buf->dataStart - buf->blkStart; } } while (1); /* not reached */ } /* ExpBufPutSegRvs */ /* * returns the next byte and advances the curr ptr by one. * sets the readError flag if there is no byte to read * (ie at end of data) */ unsigned char ExpBufGetByte PARAMS ((b), ExpBuf **b) { unsigned char retVal; if (ExpBufAtEod (*b)) { (*b)->readError = 1; return (unsigned char)0; } retVal = *(*b)->curr++; /* "buffer fault" - if end of this buf, go on to next, if any */ if (ExpBufAtEod (*b) && ((*b)->next != NULL)) { *b = (*b)->next; /* get next buffer with valid data */ while (((*b)->next != NULL) && ExpBufHasNoData (*b)) *b = (*b)->next; /* reset current pointer to beggining of data if nec */ (*b)->curr = (*b)->dataStart; } return retVal; } /* ExpBufGetByte */ /* WRITE * Puts a single octet into the buffer * writes in reverse. * allocates new buffers as nec - may change * (*b) to new buffer since writing backwards */ void ExpBufPutByteRvs PARAMS ((b, byte), ExpBuf **b _AND_ unsigned char byte) { ExpBuf *new; if ((*b)->writeError) return; *(--(*b)->dataStart) = byte; /* * check if buffer is full and alloc new one if nec * and insert it before this one since writing backwards */ if (ExpBufFull (*b)) { if ((*b)->prev == NULL) { /* * no prev buf so alloc & insert * new buf as head of buffer list */ new = ExpBufAllocBufAndData(); if (new == NULL) { (*b)->writeError = 1; return; } new->next = *b; (*b)->prev = new; *b = new; } else { (*b) = (*b)->prev; ExpBufResetInWriteRvsMode (*b); } } } /* ExpBufPutByteRvs */ void ExpBufCopyToFile PARAMS ((b, f), ExpBuf *b _AND_ FILE *f) { unsigned long writeLen; b = ExpBufListFirstBuf (b); for ( ; b != NULL; b = ExpBufNext (b)) { writeLen = fwrite (ExpBufDataPtr (b), sizeof (char), ExpBufDataSize (b), f); if (writeLen != ExpBufDataSize (b)) fprintf (stderr, "ExpBufCopyToFile: error during writing\n"); } } esnacc-ng-1.8.1/c-lib/src/hash.c000066400000000000000000000157361302010526100162250ustar00rootroot00000000000000/* * This was borrowed from Don Acton and Terry Coatta's Raven Code. * It has been modified somewhat. * - Mike Sample 92 * * This is a set or routines that implements an extensible hashing * algorithm. At the moment it assumes that all the hash codes are unique * (ie. there are no collisions). For the way hash codes are currently being * supplied this is not a bad assumption. * The extensible hashing routine used is based on a multiway tree with * each node in the tree being a fixed array of (2^n) size. At a given * level, i, in the tree with the first level being level 0, bits * i*n through i*n through (i+1)*n-1 are used as the index into the table. * Each entry in the table is either NULL (unused) or a pointer to an * object of type entry. The entry contains all the information about a * hash entry. The entry also contains a field indicating whether or not this * is a leaf node. If an entry isn't a leaf node then it references a table at * at the next level and not a value. With the current implementation * a 32 hash value is used and table sizes are 256. The algorithm used * here is the same as the one used in the Set class of the Raven * class system. * * Copyright (C) 1992 University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/src/hash.c,v 1.4 2003/12/17 19:05:03 gronej Exp $ * $Log: hash.c,v $ * Revision 1.4 2003/12/17 19:05:03 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.3.2.1 2003/11/05 14:58:54 gronej * working PER code merged with esnacc_1_6 * * Revision 1.3 2002/10/21 17:13:16 mcphersc * fixed long int * * Revision 1.2 2000/10/16 18:10:40 rwc * removed most warnings from C++-lib, some C-lib. * * Revision 1.1.1.1 2000/08/21 20:35:52 leonberp * First CVS Version of SNACC. * * Revision 1.3 1997/02/28 13:39:51 wan * Modifications collected for new version 1.3: Bug fixes, tk4.2. * * Revision 1.2 1995/07/27 09:05:54 rj * use memzero that is defined in .../snacc.h to use either memset or bzero. * * changed `_' to `-' in file names. * * Revision 1.1 1994/08/28 09:46:06 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include "asn-config.h" #include "hash.h" #include /* * * From sdbm, an ndbm work-alike hashed database library * Author: oz@nexus.yorku.ca * Status: public domain. * * polynomial conversion ignoring overflows * [this seems to work remarkably well, in fact better * then the ndbm hash function. Replace at your own risk] * use: 65599 nice. * 65587 even better. * * [In one experiment, this function hashed 84165 symbols (English words * plus symbol table values) with no collisions. -bjb] * */ Hash MakeHash PARAMS ((str, len), char *str _AND_ unsigned long len) { register Hash n; n = 0; #define HASHC n = *str++ + 65587 * n if (len > 0) { int loop; loop = (len + 8 - 1) >> 3; switch (len & (8 - 1)) { case 0: do { HASHC; case 7: HASHC; case 6: HASHC; case 5: HASHC; case 4: HASHC; case 3: HASHC; case 2: HASHC; case 1: HASHC; } while (--loop); } } return n; } /* Creates and clears a new hash slot */ static HashSlot* NewHashSlot() { HashSlot *foo; foo = (HashSlot *) malloc (sizeof (HashSlot)); if (foo == NULL) return NULL; memzero (foo, sizeof (HashSlot)); return foo; } /* Create a new cleared hash table */ static Table* NewTable() { Table *new_table; new_table = (Table *) malloc (sizeof (Table)); if (new_table == NULL) return NULL; memzero (new_table, sizeof (Table)); return new_table; } /* This routine is used to initialize the hash tables. When it is called * it returns a value which is used to identify which hash table * a particular request is to operate on. */ Table* InitHash() { Table *table; table = NewTable(); if (table == NULL) return 0; else return table; } /* When a hash collision occurs at a leaf slot this routine is called to * split the entry and add a new level to the tree at this point. */ static int SplitAndInsert PARAMS ((entry, element, hash_value), HashSlot *entry _AND_ void *element _AND_ Hash hash_value) { if (((entry->table = NewTable()) == NULL) || !Insert (entry->table, entry->value, entry->hash >> INDEXSHIFT) || !Insert (entry->table, element, hash_value >> INDEXSHIFT)) return FALSE; entry->leaf = FALSE; return TRUE; } /* This routine takes a hash table identifier, an element (value) and the * coresponding hash value for that element and enters it into the table * assuming it isn't already there. */ int Insert PARAMS ((table, element, hash_value), Table *table _AND_ void *element _AND_ Hash hash_value) { HashSlot *entry; entry = (HashSlot *) (*table)[hash_value & INDEXMASK]; if (entry == NULL) { /* Need to add this element here */ entry = NewHashSlot(); if (entry == NULL) return FALSE; entry->leaf = TRUE; entry->value = element; entry->hash = hash_value; (*table)[hash_value & INDEXMASK] = (void *)entry; return TRUE; } if (hash_value == entry->hash) return TRUE; if (entry->leaf) return SplitAndInsert (entry, element, hash_value); return Insert (entry->table, element, hash_value >> INDEXSHIFT); } /* This routine looks to see if a particular hash value is already stored in * the table. It returns true if it is and false otherwise. */ int CheckFor PARAMS ((table, hash), Table *table _AND_ Hash hash) { HashSlot *entry; entry = (HashSlot *) &(*table)[hash & INDEXMASK]; if (entry == NULL) return FALSE; if (entry->leaf) return entry->hash == hash; return CheckFor (entry->table, hash >> INDEXSHIFT); } /* In addition to checking for a hash value in the tree this function also * returns the coresponding element value into the space pointed to by * the value parameter. If the hash value isn't found FALSE is returned * the the space pointed to by value is not changed. */ int CheckForAndReturnValue PARAMS ((table, hash, value), Table *table _AND_ Hash hash _AND_ void **value) { HashSlot *entry; entry = (HashSlot *) (*table)[hash & INDEXMASK]; if (entry == NULL) return FALSE; if (entry->leaf) { if (entry->hash == hash) { *value = entry->value; return TRUE; } else return FALSE; } return CheckForAndReturnValue (entry->table, hash >> INDEXSHIFT, value); } esnacc-ng-1.8.1/c-lib/src/mem.c000066400000000000000000000067471302010526100160620ustar00rootroot00000000000000/* * compiler/core/mem.c - used for allocating the components of the Module * data structure. The program expects 0'ed memory * to be returned by Malloc - this initializes ptrs * to NULL. * * If there is not enough memory the Malloc exits * (Callers of Malloc will never get a NULL return value) * * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/c-lib/src/mem.c,v 1.2 2003/12/17 19:05:04 gronej Exp $ * $Log: mem.c,v $ * Revision 1.2 2003/12/17 19:05:04 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.1.2.1 2003/11/05 14:58:54 gronej * working PER code merged with esnacc_1_6 * * Revision 1.1 2002/05/10 17:32:16 leonberp * latest changes for release 2.2 * includes integrating asn-useful into C & C++ runtime library, the compiler changes that go along with that, SnaccException changes for C++ runtime and compiler * * Revision 1.2 2000/10/24 14:54:53 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:36:00 leonberp * First CVS Version of SNACC. * * Revision 1.4 1995/07/25 19:11:50 rj * use memzero that is defined in .../snacc.h to use either memset or bzero. * * Realloc() now checks realloc(3)'s return value. * * Revision 1.3 1994/10/08 03:48:49 rj * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long. * * Revision 1.2 1994/09/01 00:39:27 rj * snacc_config.h removed; more portable .h file inclusion. * * Revision 1.1 1994/08/28 09:49:21 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. */ #include "snacc.h" #if STDC_HEADERS #include #else #if HAVE_STRING_H #include #else #include #endif #if HAVE_MALLOC_H #include #endif #endif #include #include "mem.h" #include void* Malloc PARAMS ((size), int size) { void *retVal = malloc (size); if (retVal == NULL) { fprintf (stderr, "out of memory! bye!\n"); fprintf (stderr, "tried to allocate %d byes\n", size); exit (1); } memzero (retVal, size); return retVal; } /* Malloc */ void *Realloc PARAMS ((ptr, newsize), void *ptr _AND_ int newsize) { void *retval = realloc (ptr, newsize); if (retval == NULL) { fprintf (stderr, "out of memory! bye!\n"); fprintf (stderr, "tried to reallocate %d byes\n", newsize); exit (1); } return retval; } void Free PARAMS ((ptr), void *ptr) { free (ptr); } char * Strdup PARAMS ((istring), const char *istring) { char *ret = strdup(istring); if (ret == NULL) { fprintf (stderr, "out of memory! bye!\n"); fprintf (stderr, "tried to strdup too many bytes\n"); exit (1); } return ret; } esnacc-ng-1.8.1/c-lib/src/min-buf.c000066400000000000000000000060471302010526100166320ustar00rootroot00000000000000#include "config.h" #include "snacc.h" #include "asn-config.h" #include "min-buf.h" #include "gen-buf.h" #include static unsigned char * MinBufGetSeg__(void *b, unsigned long *len) { unsigned char *i = (unsigned char *)(*(unsigned char **)b); *(unsigned char **)b = i + *len; return i; } static unsigned char MinBufGetByte__(void *b) { unsigned long l = 1; return *MinBufGetSeg__(b, &l); } static long MinBufCopy__(char *dst, void *b, unsigned long len) { char *src = (char *)MinBufGetSeg__(b, &len); memcpy(dst, src, len); return len; } static void MinBufSkip__(void *b, unsigned long len) { MinBufGetSeg__(b, &len); } static unsigned char * MinBufPeekSeg__(void *b, unsigned long *len ESNACC_UNUSED) { return (unsigned char *)(*(unsigned char **)b); } static unsigned char MinBufPeekByte__(void *b) { unsigned long i = 1; return *MinBufPeekSeg__(b, &i); } static long MinBufPeekCopy__(char *dst, void *b, unsigned long len) { unsigned char *src = MinBufPeekSeg__(b, &len); memcpy(dst, src, len); return len; } static void MinBufPutSegRvs__(void *b, char *src, unsigned long len) { unsigned char *dst = (unsigned char *)(*(unsigned char **)b); dst -= len; memcpy(dst, src, len); } static void MinBufPutByteRvs__(void *b, unsigned char byte) { MinBufPutSegRvs__(b, (char *)&byte, 1); } static int MinBufIgnore__(void *b ESNACC_UNUSED) { return 0; } static int MinBufSetWriteError__(void *b ESNACC_UNUSED, unsigned short i ESNACC_UNUSED) { return 0; } static void MinBufReset__(void *b ESNACC_UNUSED) { } static int MinBufCopyAny__(void *b, void *value, unsigned long *bytesDecoded, ENV_TYPE env) { AsnLen elmtsLen, totalElmtsLen = 0; AsnOcts *data; GenBuf gb; char *loc = 0; GenBufFromMinBuf(&gb, b); loc = (char *)GenBufPeekSeg(&gb, 0); elmtsLen = BDecLen (&gb, &totalElmtsLen, env); /* len of item */ if (elmtsLen == INDEFINITE_LEN) { Asn1Error("BDecUnknownAsnAny: ERROR - indef length object found\n"); longjmp(env, -910); } data = (AsnOcts *) value; /* allocated by the any routine */ data->octetLen = elmtsLen + totalElmtsLen; /* tag+len+data lengths */ data->octs = Asn1Alloc(data->octetLen +1); gb.spare = loc; MinBufCopy__(data->octs, gb.bufInfo, totalElmtsLen+elmtsLen); /* add null terminator - this is not included in the str's len */ data->octs[data->octetLen] = '\0'; (*bytesDecoded) += data->octetLen; return 0; } static struct GenBuf minBufOpsG = { MinBufCopyAny__, MinBufGetByte__, MinBufGetSeg__, MinBufCopy__, MinBufSkip__, MinBufPeekByte__, MinBufPeekSeg__, MinBufPeekCopy__, MinBufPutByteRvs__, MinBufPutSegRvs__, MinBufIgnore__, MinBufSetWriteError__, MinBufIgnore__, MinBufReset__, NULL, NULL, }; void GenBufFromMinBuf PARAMS ((gb, data), GenBuf *gb _AND_ void *data) { *gb = minBufOpsG; gb->spare = data; gb->bufInfo = (void *) &gb->spare; } esnacc-ng-1.8.1/c-lib/src/nibble-alloc.c000066400000000000000000000141671302010526100176220ustar00rootroot00000000000000/* * .../c-lib/src/nibble-alloc.c - fast mem allocation for decoded values * * MS Dec 31/91 * * Copyright (C) 1992 Michael Sample and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/src/nibble-alloc.c,v 1.6 2003/12/17 19:05:04 gronej Exp $ * $Log: nibble-alloc.c,v $ * Revision 1.6 2003/12/17 19:05:04 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.5.2.1 2003/11/05 14:58:54 gronej * working PER code merged with esnacc_1_6 * * Revision 1.5 2002/10/18 13:09:32 mcphersc * took out long int to unsigned long * * Revision 1.4 2002/05/10 16:39:37 leonberp * latest changes for release 2.2 * includes integrating asn-useful into C & C++ runtime library, the compiler changes that go along with that, SnaccException changes for C++ runtime and compiler * * Revision 1.3 2001/03/12 14:52:12 mcphersc * Added check for nmG being null before goint in the for loop in ShutdownNibbleMem * function. * * Revision 1.2 2000/10/16 18:10:40 rwc * removed most warnings from C++-lib, some C-lib. * * Revision 1.1.1.1 2000/08/21 20:35:52 leonberp * First CVS Version of SNACC. * * Revision 1.4 1997/02/28 13:39:51 wan * Modifications collected for new version 1.3: Bug fixes, tk4.2. * * Revision 1.3 1995/07/27 09:06:37 rj * use memzero that is defined in .../snacc.h to use either memset or bzero. * * changed `_' to `-' in file names. * * Revision 1.2 1994/09/01 00:07:16 rj * more portable .h file inclusion. * * Revision 1.1 1994/08/28 09:46:07 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * * * Revision - 23 Jan 98 - DAD - * added a check to NibbleAlloc() for detecting requests for * "questionable" amounts of memory * */ #ifdef __APPLE__ #include #else #include #endif #include #include "asn-config.h" #include "nibble-alloc.h" NibbleMem *nmG = NULL; void InitNibbleMem PARAMS ((initialSize, incrementSize), unsigned long initialSize _AND_ unsigned long incrementSize) { NibbleMem *nm; nm = (NibbleMem*) malloc (sizeof (NibbleMem)); nm->incrementSize = incrementSize; nm->currNibbleBuf = nm->firstNibbleBuf = (NibbleBuf*)malloc (sizeof (NibbleBuf)); nm->firstNibbleBuf->curr = nm->firstNibbleBuf->start = (char*) malloc (initialSize); nm->firstNibbleBuf->end = nm->firstNibbleBuf->start + initialSize; nm->firstNibbleBuf->next = NULL; memzero (nm->currNibbleBuf->start, initialSize); nmG = nm;/* set global */ } /* InitNibbleAlloc */ /* * alloc new nibble buf, link in, reset to curr nibble buf */ void ServiceNibbleFault PARAMS ((size), unsigned long size) { NibbleMem *nm; unsigned long newBufSize; nm = nmG; if (size > nm->incrementSize) newBufSize = size; else newBufSize = nm->incrementSize; nm->currNibbleBuf->next = (NibbleBuf*) malloc (sizeof (NibbleBuf)); nm->currNibbleBuf = nm->currNibbleBuf->next; nm->currNibbleBuf->curr = nm->currNibbleBuf->start = (char*) malloc (newBufSize); nm->currNibbleBuf->end = nm->currNibbleBuf->start + newBufSize; nm->currNibbleBuf->next = NULL; memzero (nm->currNibbleBuf->start, newBufSize); } /* serviceNibbleFault */ /* * returns requested space filled with zeros */ void* NibbleAlloc PARAMS ((size), unsigned long size) { NibbleMem *nm; char *retVal; unsigned long ndiff; nm = nmG; /* DAD - although error checking on the mallocs during * ServiceNibbleFault could be more robust, for now i'm * just going to avoid allocating really huge amounts * of memory (which can occur if the ASN.1 data has * become corrupted, and you were trying to decode). */ if(size > 1024*1024) /* say roughly a meg for now */ return(0); if ((nm->currNibbleBuf->end - nm->currNibbleBuf->curr) < (int)size) ServiceNibbleFault (size); retVal = nm->currNibbleBuf->curr; /* * maintain word alignment */ ndiff = size % sizeof (long); if (ndiff != 0) { nm->currNibbleBuf->curr += size + sizeof (long) - ndiff; /* * this is a fix from Terry Sullivan * * makes sure curr does not go past the end ptr */ if (nm->currNibbleBuf->curr > nm->currNibbleBuf->end) nm->currNibbleBuf->curr = nm->currNibbleBuf->end; } else nm->currNibbleBuf->curr += size; return retVal; } /* NibbleAlloc */ /* * frees all nibble buffers except the first, * resets the first to empty and zero's it */ void ResetNibbleMem() { NibbleMem *nm; NibbleBuf *tmp; NibbleBuf *nextTmp; nm = nmG; /* * reset first nibble buf */ memzero (nm->firstNibbleBuf->start, nm->firstNibbleBuf->curr - nm->firstNibbleBuf->start); nm->firstNibbleBuf->curr = nm->firstNibbleBuf->start; /* * free incrementally added nibble bufs */ for (tmp = nm->firstNibbleBuf->next; tmp != NULL; ) { free (tmp->start); nextTmp = tmp->next; free (tmp); tmp = nextTmp; } /* From ftp://ftp.cs.ubc.ca/pub/local/src/snacc/bugs-in-1.1 */ nm->firstNibbleBuf->next = NULL; nm->currNibbleBuf = nm->firstNibbleBuf; } /* ResetNibbleMem */ /* * frees all nibble buffers, closing this * NibbleMem completely */ void ShutdownNibbleMem() { NibbleMem *nm; NibbleBuf *tmp; NibbleBuf *nextTmp; nm = nmG; nmG = NULL; /* * free nibble bufs */ if (nm == NULL) return; for (tmp = nm->firstNibbleBuf; tmp != NULL; ) { free (tmp->start); nextTmp = tmp->next; free (tmp); tmp = nextTmp; } free (nm); } /* ShutdownNibbleMem */ esnacc-ng-1.8.1/c-lib/src/print.c000066400000000000000000000027451302010526100164320ustar00rootroot00000000000000/* * print.c - library routines for printing ASN.1 values. * * Copyright (C) 1992 Michael Sample and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/src/print.c,v 1.8 2004/01/22 20:03:12 nicholar Exp $ * */ #include "asn-config.h" #include "print.h" void Indent PARAMS ((f, i), FILE *f _AND_ unsigned int i) { for (; i > 0; i--) fputs (" ", f); } void Asn1DefaultErrorHandler PARAMS ((str, severity), char* str _AND_ int severity) { /* fprintf(stderr,"%s",str); DAD - temp removing for now*/ severity=severity; /* referenced */ str=str; } static Asn1ErrorHandler asn1CurrentErrorHandler = Asn1DefaultErrorHandler; void Asn1Error PARAMS ((str), char* str) { (*asn1CurrentErrorHandler)(str,1); } void Asn1Warning PARAMS ((str), char* str) { (*asn1CurrentErrorHandler)(str,0); } Asn1ErrorHandler Asn1InstallErrorHandler PARAMS ((handler), Asn1ErrorHandler handler) { Asn1ErrorHandler former = asn1CurrentErrorHandler; asn1CurrentErrorHandler = handler; return former; } esnacc-ng-1.8.1/c-lib/src/sbuf.c000066400000000000000000000262311302010526100162310ustar00rootroot00000000000000/* * .../c-lib/src/sbuf.c * * Copyright (C) 1992 Michael Sample and the University of British Columbia * MS * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ #include "asn-config.h" #include "sbuf.h" #include "gen-buf.h" #include "asn-incl.h" #include /* * casts are used to overcome void * - SBuf * conflict * be careful if you modify param lists etc. */ static struct GenBuf sBufOpsG = { (BufCopyAnyFcn) SBufCopyAny, (BufGetByteFcn) SBufGetByte, (BufGetSegFcn) SBufGetSeg, (BufCopyFcn) SBufCopy, (BufSkipFcn) SBufSkip, (BufPeekByteFcn) SBufPeekByte, (BufPeekSegFcn) SBufPeekSeg, (BufPeekCopyFcn) SBufPeekCopy, (BufPutByteRvsFcn) SBufPutByteRvs, (BufPutSegRvsFcn) SBufPutSegRvs, (BufReadErrorFcn) SBufReadError, (BufSetWriteErrorFcn) SBufSetWriteError, (BufWriteErrorFcn) SBufWriteError, (BufResetInReadModeFcn) SBufResetInReadMode, NULL, NULL }; void PutSBufInGenBuf PARAMS ((sb, gb), SBuf *sb _AND_ GenBuf *gb) { *gb = sBufOpsG; /* structure assignemnt */ gb->bufInfo = &gb->spare; gb->spare = sb; } /* * Allocate a GenBuf structure and copy in * the function pointers */ void SBuftoGenBuf PARAMS ((eb, gb), SBuf *eb _AND_ GenBuf **gb) { struct GenBuf *retval; retval = (struct GenBuf *) malloc (sizeof (struct GenBuf)); if (retval != NULL) { memcpy (retval, &sBufOpsG, sizeof (struct GenBuf)); retval->bufInfo = &retval->spare; /* handle to expbuf */ retval->spare = eb; } *gb = retval; } /* * given an SBuf,b, and a block of data * and its length this initializes a the SBuf * to point to the data block. The data * block is assumed to contain no valid data- * ie it is empty and ready for writing */ void SBufInit PARAMS ((b, data, dataLen), SBuf *b _AND_ char *data _AND_ long dataLen) { b->readError = b->writeError = 1; b->blkStart = data; b->blkEnd = data + dataLen; b->dataStart = b->dataEnd = b->readLoc = b->blkEnd; } /* SBufInit */ /* * puts the given buffer in read mode and sets * the current read location to the beginning of * the buffer's data. * The read error flag is cleared. * The writeError flag is set so that attempted writes * will be fail and be detectable via a call to * SBufWriteError(). */ void SBufResetInReadMode PARAMS ((b), SBuf **b) { (*b)->readLoc = (*b)->dataStart; (*b)->readError = 0; (*b)->writeError = 1; } /* SBufResetInnReadMode */ /* * puts the given buffer in reverse writing mode and sets * the current write location to the end of the * buffer's data block. * The data start and end pointers are set to point to * the end of the block - ie no data. * The write error flag is cleared. * The readError flag is set so that attempted reads * will be fail and be detectable via a call to * SBufReadError(). */ void SBufResetInWriteRvsMode PARAMS ((b), SBuf *b) { b->dataStart = b->dataEnd = b->blkEnd; b->writeError = 0; b->readError = 1; } /* SBufResetInWriteRvsMode */ /* * installs given block of data into a buffer * and sets it up for reading */ void SBufInstallData PARAMS ((b, data, dataLen), SBuf *b _AND_ char *data _AND_ long dataLen) { SBufInit (b, data, dataLen); b->dataStart = b->blkStart; SBufResetInReadMode (&b); } /* SBufInstallData */ /* * returns the number of bytes in the data portion */ long SBufDataLen PARAMS ((b), SBuf *b) { return b->dataEnd - b->dataStart; } /* SBufDataLen */ /* * returns true if the given buffer has no * valid data in it's data block */ int SBufHasNoData PARAMS ((b), SBuf *b) { return b->dataStart == b->dataEnd; } /* * returns the pointer to the first data byte */ char* SBufDataPtr PARAMS ((b), SBuf *b) { if (SBufHasNoData (b)) return NULL; else return b->dataStart;} /* SBufDataPtr */ /* * returns the size of block, the maximum size for data * (does not look at how much data is present, just the * max size if the block were empty) */ long SBufBlkLen PARAMS ((b), SBuf *b) { return b->blkEnd - b->blkStart; } /* SBufBlkLen */ /* * returns a pointer to the first byte of the block */ char* SBufBlkPtr PARAMS ((b), SBuf *b) { return b->blkStart; } /* SBufBlkPtr */ /* * returns true if there is no more data * to be read in the SBuf */ int SBufEod PARAMS ((b), SBuf *b) { return b->readLoc >= b->dataEnd; } /* SBufEod */ /* returns true if you attempted to read past the end of data */ int SBufReadError PARAMS ((b), SBuf **b) { return (*b)->readError; } /* SBufReadError */ int SBufSetWriteError PARAMS ((b, Value), SBuf *b _AND_ unsigned short Value) { if (b == NULL) return -1; (b)->writeError = Value; return 0; } /* * returns true if you attempted to write past the end of the block * (remember SBufs do not expand like ExpBufs) */ int SBufWriteError PARAMS ((b), SBuf **b) { return (*b)->writeError; } /* SBufWriteError */ /* * Skips the next skipLen bytes for reading */ void SBufSkip PARAMS ((b, skipLen), SBuf **b _AND_ long skipLen) { if ((*b)->readLoc + skipLen > (*b)->dataEnd) { (*b)->readLoc = (*b)->dataEnd; (*b)->readError = 1; } else (*b)->readLoc += skipLen; } /* SBufSkip */ /* * copies copyLen bytes from buffer b into char *dst. * Advances the curr read loc by copyLen * Assumes dst is pre-allocated and is large enough. * Will set the read error flag is you attempt to copy * more than the number of unread bytes available. */ void SBufCopy PARAMS ((dst, b, copyLen), char *dst _AND_ SBuf **b _AND_ long copyLen) { if ((*b)->readLoc + copyLen > (*b)->dataEnd) { memcpy (dst, (*b)->readLoc, (*b)->dataEnd - (*b)->readLoc); (*b)->readLoc = (*b)->dataEnd; (*b)->readError = 1; } else { memcpy (dst, (*b)->readLoc, copyLen); (*b)->readLoc += copyLen; } } /* SBufCopy */ /* * returns the next byte from the buffer without advancing the * current read location. */ unsigned char SBufPeekByte PARAMS ((b), SBuf **b) { if (SBufEod ((*b))) { (*b)->readError = 1; return (unsigned char)0; } else return *(*b)->readLoc; } /* SBufPeekByte */ /* * returns a pointer into the buffer to the next bytes to be read. * If *lenPtr unread bytes are not available, *lenPtr will be set * to the number of bytes that are available. The current read location * is *NOT* advanced at all. The read error flag will NOT be set * by this routine. */ char* SBufPeekSeg PARAMS ((b, lenPtr), SBuf **b _AND_ long *lenPtr) { if ((*b)->readLoc + *lenPtr > (*b)->dataEnd) *lenPtr = (*b)->dataEnd - (*b)->readLoc; return (*b)->readLoc; } /* SBufPeekSeg */ /* * copies copyLen bytes from buffer b into char *dst. * Does NOT advance the curr read location. * assumes dst is pre-allocated and is large enough. * Will set the read error flag is you attempt to copy * more than the number of unread bytes available. */ int SBufPeekCopy PARAMS ((dst, b, copyLen), char *dst _AND_ SBuf **b _AND_ unsigned long copyLen) { if ((*b)->readLoc + copyLen > (*b)->dataEnd) { memcpy (dst,(*b)->readLoc, (*b)->dataEnd - (*b)->readLoc); (*b)->readError = 1; copyLen = (*b)->dataEnd - (*b)->readLoc; } else memcpy (dst, (*b)->readLoc, copyLen); return copyLen; } /* SBufPeekCopy */ /* * returns a pointer into the buffer to the next bytes to be read. * If *lenPtr unread bytes are not available, *lenPtr will be set * to the number of bytes that are available. The current read location * is advance by the number of bytes returned in *lenPtr. The read error * flag will NOT be set, ever, by this routine. */ char* SBufGetSeg PARAMS ((b, lenPtr), SBuf **b _AND_ long *lenPtr) { char *retVal; retVal =(*b)->readLoc; if ((*b)->readLoc + *lenPtr > (*b)->dataEnd) { *lenPtr = (*b)->dataEnd - (*b)->readLoc; (*b)->readLoc = (*b)->dataEnd; } else (*b)->readLoc += *lenPtr; return retVal; } /* SBufGetSeg */ /* * Write in reverse the char *seg of segLen bytes to the buffer b. * A reverse write of segement really just prepends the given seg * (in original order) to the buffers existing data. * If the SBuf does not have enough room for the segment, * the writeError flag is set and *NO* copying is done at all. */ void SBufPutSegRvs PARAMS ((b, seg, segLen), SBuf **b _AND_ char *seg _AND_ long segLen) { SBuf *buf = *b; long sLen = segLen; if (buf->dataStart - segLen < buf->blkStart) buf->writeError = 1; else { buf->dataStart -= segLen; memcpy (buf->dataStart, seg, sLen); } } /* SBufPutSegRvs */ /* * returns the next byte from buffer b's data and advances the * current read location by one byte. This will set the read error * flag if you attempt to read past the end of the SBuf */ unsigned char SBufGetByte PARAMS ((b), SBuf **b) { if (SBufEod ((*b))) { (*b)->readError = 1; return (unsigned char)0; } else return (unsigned char)(*((*b)->readLoc++)); } /* SBufGetByte */ int SBufCopyAny PARAMS ((b, value, *bytesDecoded, env), SBuf *b _AND_ void *value _AND_ unsigned long *bytesDecoded _AND_ ENV_TYPE env) { AsnLen totalElmtsLen1 = 0; AsnLen elmtLen1 = 0; AsnOcts *data = 0; /* where we will store the stuff */ GenBuf gb; // Our GenBuf if (b == 0) { SBufSetWriteError(b, TRUE); return -1; } // Put the ExpBuf into a GenBuf so we can use BDecTag & BDecLen PutSBufInGenBuf (b, &gb); elmtLen1 = BDecLen (&gb, &totalElmtsLen1, env); /* len of item */ if (elmtLen1 == INDEFINITE_LEN) { /* can't deal with indef len unknown types here (at least for now) */ Asn1Error("BDecUnknownAsnAny: ERROR - indef length object found\n"); longjmp(env, -910); } /* and now decode the contents */ data = (AsnOcts *) value; /* allocated by the any routine */ data->octetLen = elmtLen1 + totalElmtsLen1; /* tag+len+data lengths */ data->octs = Asn1Alloc(data->octetLen +1); CheckAsn1Alloc (data->octs, env); /* use normal buffer reading to copy the any */ SBufCopy(&data->octs[totalElmtsLen1] , &b, totalElmtsLen1+elmtLen1); if (SBufReadError(&b)) { Asn1Error("BDecUnknownAsnAny: ERROR - decoded past end of data\n"); longjmp(env, -920); } /* add null terminator - this is not included in the str's len */ data->octs[data->octetLen] = '\0'; (*bytesDecoded) += data->octetLen; /* (*bytesDecoded) += totalElmtsLen1; just use the total blob length */ return 0; } /* * writes (prepends) the given byte to buffer b's data */ void SBufPutByteRvs PARAMS ((b, byte), SBuf **b _AND_ unsigned char byte) { if ((*b)->dataStart <= (*b)->blkStart) (*b)->writeError = 1; else *--(*b)->dataStart = byte; } /* SBufPutByteRvs */ esnacc-ng-1.8.1/c-lib/src/str-stk.c000066400000000000000000000027061302010526100167020ustar00rootroot00000000000000/* * str_stk.c - maintains a stack of the components of a bit string * or octet string so they can be copied into a single chunk * * Copyright (C) 1992 Michael Sample and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Header: /baseline/SNACC/c-lib/src/str-stk.c,v 1.3 2004/03/23 18:49:21 gronej Exp $ * $Log: str-stk.c,v $ * Revision 1.3 2004/03/23 18:49:21 gronej * fixed linux warnings * * Revision 1.2 2003/12/17 19:05:04 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.1.2.1 2003/11/05 14:58:54 gronej * working PER code merged with esnacc_1_6 * * Revision 1.1.1.1 2000/08/21 20:35:53 leonberp * First CVS Version of SNACC. * * Revision 1.2 1995/07/24 21:04:57 rj * changed `_' to `-' in file names. * * Revision 1.1 1994/08/28 09:46:09 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include "asn-config.h" #include "str-stk.h" /* global for use by AsnBits and AsnOcts */ StrStk strStkG = { NULL, 128, 0, 64, 0, 0 }; esnacc-ng-1.8.1/c-lib/src/tbl-dbg.c000066400000000000000000000212161302010526100166030ustar00rootroot00000000000000#ifdef TTBL #include "tbl-dbg.h" TdeExceptionCode DBGMinCode = TDEINFO; void DBGOcts PARAMS ((v), AsnOcts* v) { int i; for (i = 0; i < v->octetLen; i++) fprintf (stdout, "%c", isprint(v->octs[i])?v->octs[i]:'.'); } char* Class2ClassStr PARAMS ((class), int class) { switch (class) { case UNIV: return "UNIV"; break; case APPL: return "APPL"; break; case CNTX: return "CNTX"; break; case PRIV: return "PRIV"; break; default: return "UNKNOWN"; break; } } char* Form2FormStr PARAMS ((form), BER_FORM form) { switch (form) { case PRIM: return "PRIM"; break; case CONS: return "CONS"; break; default: return "UNKNOWN"; break; } } char* Code2UnivCodeStr PARAMS ((code), BER_UNIV_CODE code) { switch (code) { case BOOLEAN_TAG_CODE: return "BOOLEAN"; break; case INTEGER_TAG_CODE: return "INTEGER"; break; case BITSTRING_TAG_CODE: return "BIT STRING"; break; case OCTETSTRING_TAG_CODE: return "OCTET STRING"; break; case NULLTYPE_TAG_CODE: return "NULL"; break; case OID_TAG_CODE: return "OBJECT IDENTIFIER"; break; case OD_TAG_CODE: return "OD"; break; case EXTERNAL_TAG_CODE: return "EXTERNAL"; break; case REAL_TAG_CODE: return "REAL"; break; case ENUM_TAG_CODE: return "ENUM"; break; case SEQ_TAG_CODE: return "SEQUENCE"; break; case SET_TAG_CODE: return "SET"; break; case NUMERICSTRING_TAG_CODE: return "NUMERICSTRING"; break; case PRINTABLESTRING_TAG_CODE: return "PRINTABLESTRING"; break; case TELETEXSTRING_TAG_CODE: return "TELETEXSTRING"; break; case VIDEOTEXSTRING_TAG_CODE: return "VIDEOTEXSTRING"; break; case IA5STRING_TAG_CODE: return "IA5STRING"; break; case UTCTIME_TAG_CODE: return "UTCTIME"; break; case GENERALIZEDTIME_TAG_CODE: return "GENERALIZEDTIME"; break; case GRAPHICSTRING_TAG_CODE: return "GRAPHICSTRING"; break; case VISIBLESTRING_TAG_CODE: return "VISIBLESTRING"; break; case GENERALSTRING_TAG_CODE: return "GENERALSTRING"; break; default: return "UNKNOWN"; } } /* Form2FormStr */ #define SOT 0 #define EOL 1 #define EOLINC 2 #define DECSOTEOL 3 #define SOTSPC 4 #define EOLIF 5 void DBGIndent PARAMS ((mode), int mode) { static int indent = 0; static int withinline = 0; int i; /*DEC*/ if (mode==DECSOTEOL) indent--; /*SPC*/ if (mode==SOTSPC && withinline) fprintf(stdout," "); /*SOT*/ if ((mode==SOT || mode==DECSOTEOL || mode==SOTSPC) && !withinline) { for (i=0; i>24; codename = Code2UnivCodeStr(bcode); } else { bcode = OCTETSTRING_TAG_CODE; codename = "NOT_UNIV"; } if (begin) { DBGIndent(SOTSPC); fprintf (stdout, "%s", codename); if (TAG_IS_CONS(tag)) { if (tclass==UNIV) { fprintf(stdout, " {\n"); DBGIndent(EOLINC); } } else { fprintf(stdout,": "); PrintAsnOcts(stdout,v,0); fprintf(stdout,"\n"); DBGIndent(EOL); } } else { if (TAG_IS_CONS(tag) && tclass==UNIV) { DBGIndent(DECSOTEOL); fprintf(stdout, "}\n"); } } return 0; } void DBGNamedValue PARAMS ((tnnl, val, mode), TBLNamedNumberList* tnnl _AND_ AsnInt val _AND_ int mode) { /* mode 0: Don't print if no named value. postfix print with -- */ /* mode 0|1: prefix with -- */ /* mode >1: prefix with , */ TBLNamedNumber* tnn; char* name = NULL; FOR_EACH_LIST_ELMT (tnn, tnnl) if (tnn->value == val) { name = tnn->name.octs; break; } if (!mode && !name) return; if (mode<=1) fprintf(stdout," -- "); else fprintf(stdout,", "); if (name) fprintf(stdout,"%s",name); fprintf(stdout,"(%d)",val); if (!mode) fprintf(stdout," --"); } void DBGPrintType PARAMS ((type), TBLType* type) { static char* TIN [] = { "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", "NULL", "OBJECT IDENTIFIER", "REAL", "ENUMERATED", "SEQUENCE", "SET", "SEQUENCE OF", "SET OF", "CHOICE", NULL }; if (type->typeId == TBL_TYPEREF) DBGOcts(&type->content->a.typeRef->typeDefPtr->typeName); else fprintf(stdout,TIN[type->typeId]); if (type->fieldName.octetLen) { fprintf(stdout," "); DBGOcts(&type->fieldName); } } typedef int (*Proc) PROTO (()); int DBGType PARAMS ((type, val, begin), TBLType* type _AND_ AVal* val _AND_ int begin) { static Proc printproc [] = {PrintAsnBool, PrintAsnInt, PrintAsnBits, PrintAsnOcts, PrintAsnNull, PrintAsnOid, PrintAsnReal, PrintAsnInt, NULL, NULL, NULL, NULL, NULL, NULL}; if (begin) { DBGIndent(SOTSPC); DBGPrintType(type); if (type->typeId >= TBL_SEQUENCE && type->typeId <= TBL_CHOICE) { fprintf(stdout," {\n"); DBGIndent(EOLINC); } } else { if (printproc[type->typeId]) { DBGIndent(SOT); fprintf(stdout,": "); (*printproc[type->typeId])(stdout,val,0); switch (type->typeId) { case TBL_BITSTRING: { AsnInt i; AsnBits* b = (AsnBits*)val; int mode = 1; for (i=0; ibitLen;i++) if (GetAsnBit(b,i)) DBGNamedValue(type->values,i,mode++); if (mode>1) fprintf(stdout," --"); } break; case TBL_ENUMERATED: DBGNamedValue(type->values,*(AsnInt*)val,0); break; default: break; } fprintf(stdout,"\n"); DBGIndent(EOL); } if (type->typeId >= TBL_SEQUENCE && type->typeId <= TBL_CHOICE) { DBGIndent(DECSOTEOL); fprintf(stdout,"}\n"); } } return 0; } int DBGExc PARAMS ((code, p1, p2, p3), TdeExceptionCode code _AND_ void* p1 _AND_ void* p2 _AND_ void* p3) { if (codefrom,((TBLRange*)p2)->to); DBGPrintType((TBLType*)p1); fprintf(stdout,".\n"); DBGIndent(EOL); break; case TDENOMATCH: DBGIndent(EOLIF); DBGIndent(SOT); fprintf(stdout,"WARNING: Tag [%08X] does not match tag [%08X] of type ", *(AsnTag*)p3,*(AsnTag*)p2); DBGPrintType((TBLType*)p1); fprintf(stdout,".\n"); DBGIndent(EOL); break; case TDEERROR: DBGIndent(EOLIF); DBGIndent(SOT); fprintf(stdout,"ERROR: %s.\n",(char*)p1); DBGIndent(EOL); break; } return 0; } #endif esnacc-ng-1.8.1/c-lib/src/tbl-dec.c000066400000000000000000000307621302010526100166100ustar00rootroot00000000000000#ifdef TTBL /* * tbl_dec.c - type table decoder. * * * Mike Sample * * Copyright (C) 1993 Michael Sample * and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "tbl-incl.h" int TagsMatch PROTO ((TBLType *tblT, AsnTag asnTag)); void TblPopTagsAndLens PROTO ((TBLType *tblT, GenBuf *b, int implicit, unsigned long *bytesDecoded, ENV_TYPE env)); void TblDecodeTagsAndLens PROTO ((TBLType *tblT, GenBuf *b, int implicit, ENV_TYPE env)); int CountMandatoryElmts PROTO ((TBLType *tblT)); typedef struct TagNLen { AsnTag tag; AsnLen len; unsigned int size; /* encoded len for this tag len pair */ } TagNLen; #define TL_STK_SIZE 128 static TagNLen tlStkG[TL_STK_SIZE]; static int nextFreeTLG = 0; #define PUSH_TL(t,l,sz, env)\ { if (nextFreeTLG >= TL_STK_SIZE)\ longjmp (env, -1000);\ tlStkG[nextFreeTLG].tag = t;\ tlStkG[nextFreeTLG].len = l;\ tlStkG[nextFreeTLG++].size = sz; } #define POP_TL(env)\ { nextFreeTLG--;\ if (nextFreeTLG < 0)\ longjmp (env, -1001);} #define LAST_TAG() (tlStkG[nextFreeTLG-1].tag) #define LAST_LEN() (tlStkG[nextFreeTLG-1].len) #define LAST_SIZE() (tlStkG[nextFreeTLG-1].size) AVal* TblDecode PARAMS ((tbl, modName, typeName, b, bytesDecoded), TBL *tbl _AND_ char *modName _AND_ char *typeName _AND_ GenBuf *b _AND_ unsigned long *bytesDecoded) { TBLModule *tblMod; TBLTypeDef *tblTd; ENV_TYPE env; AVal *retVal; int val; tblTd = TblFindTypeDef (tbl, modName, typeName, &tblMod); if (tblTd == NULL) { TblError ("TblDecode: Could not find a type definition with the given module and name"); return NULL; } *bytesDecoded = 0; if ((val = setjmp (env)) == 0) { retVal = TblDecodeType (tblTd->type, b, FALSE, bytesDecoded, env); } else retVal = NULL; if (val != 0) fprintf (stderr,"ack! longjmp error number: %d\n", val); return retVal; } /* TblDecode p*/ AVal* TblDecodeType PARAMS ((tblT, b, implicit, bytesDecoded, env), TBLType *tblT _AND_ GenBuf *b _AND_ int implicit _AND_ unsigned long *bytesDecoded _AND_ ENV_TYPE env) { AVal *elmtVPtr; unsigned long tmpBytesDecoded = 0; unsigned int currElmt; TBLType *listElmtType; TBLType *structElmtType; TBLType *choiceElmtType; AChoiceVal *cVal; AStructVal *sVal; AVal *retVal; AVal **tmpHndl; AsnTag asnTag; int i, mandatoryCount, mandatoryElmts; int implicitRef; void *tmp; TblDecodeTagsAndLens (tblT, b, implicit, env); switch (tblT->typeId) { case TBL_TYPEREF: /* * carry over implicit ref if goes * through typeref with no tags */ implicitRef = tblT->content->a.typeRef->implicit || (implicit && ((tblT->tagList == NULL) || LIST_EMPTY (tblT->tagList))); retVal = TblDecodeType (tblT->content->a.typeRef->typeDefPtr->type, b, implicitRef, &tmpBytesDecoded, env); break; case TBL_SEQUENCE: /* go fwd though elmt type list */ currElmt = 0; sVal = (AStructVal*) Asn1Alloc (sizeof (AVal*)* LIST_COUNT (tblT->content->a.elmts)); tmp = CURR_LIST_NODE (tblT->content->a.elmts); FOR_EACH_LIST_ELMT (structElmtType, tblT->content->a.elmts) { if (TagsMatch (structElmtType, PeekTag (b,env))) { sVal[currElmt] = TblDecodeType (structElmtType, b, FALSE, &tmpBytesDecoded, env); } else if (!structElmtType->optional) longjmp (env,-1008); currElmt++; } SET_CURR_LIST_NODE (tblT->content->a.elmts, tmp); retVal = (AVal*) sVal; break; case TBL_SET: sVal = (AStructVal*) Asn1Alloc (sizeof (AVal*)* LIST_COUNT (tblT->content->a.elmts)); mandatoryCount = 0; mandatoryElmts = CountMandatoryElmts (tblT); if (LAST_LEN() == INDEFINITE_LEN) while (!PeekEoc (b)) { asnTag = PeekTag (b,env); currElmt = 0; /* find elmt that matches the peeked tag */ FOR_EACH_LIST_ELMT (structElmtType, tblT->content->a.elmts) { if (TagsMatch (structElmtType, asnTag)) break; currElmt++; } /* didn't find a match */ if (currElmt >= LIST_COUNT (tblT->content->a.elmts)) longjmp (env,-1009); if (!structElmtType->optional) mandatoryCount++; sVal[currElmt] = TblDecodeType (structElmtType, b, FALSE, &tmpBytesDecoded, env); } else while (tmpBytesDecoded < LAST_LEN()) { asnTag = PeekTag (b,env); currElmt = 0; /* find elmt that matches the peeked tag */ FOR_EACH_LIST_ELMT (structElmtType, tblT->content->a.elmts) { if (TagsMatch (structElmtType, asnTag)) break; currElmt++; } if (currElmt >= LIST_COUNT (tblT->content->a.elmts)) longjmp (env, -1007); if (!structElmtType->optional) mandatoryCount++; sVal[currElmt] = TblDecodeType (structElmtType, b, FALSE, &tmpBytesDecoded, env); } if (mandatoryCount != mandatoryElmts) longjmp (env,-1006); else retVal = sVal; break; case TBL_SEQUENCEOF: case TBL_SETOF: retVal = (AsnList*)Asn1Alloc (sizeof (AsnList)); listElmtType = FIRST_LIST_ELMT (tblT->content->a.elmts); if (LAST_LEN() == INDEFINITE_LEN) while (!PeekEoc (b)) { elmtVPtr = TblDecodeType (listElmtType, b, FALSE, &tmpBytesDecoded, env); tmpHndl = AsnListAppend ((AsnList*)retVal); *tmpHndl = elmtVPtr; } else while (tmpBytesDecoded < LAST_LEN()) { elmtVPtr = TblDecodeType (listElmtType, b, FALSE, &tmpBytesDecoded, env); tmpHndl = AsnListAppend ((AsnList*)retVal); *tmpHndl = elmtVPtr; } break; case TBL_CHOICE: retVal = cVal = (AChoiceVal*) Asn1Alloc (sizeof (AChoiceVal)); asnTag = PeekTag (b,env); i = 0; /* find elmt that matches the peeked tag */ tmp = CURR_LIST_NODE (tblT->content->a.elmts); FOR_EACH_LIST_ELMT (choiceElmtType, tblT->content->a.elmts) { if (TagsMatch (choiceElmtType, asnTag)) { cVal->choiceId = i; break; } i++; } SET_CURR_LIST_NODE (tblT->content->a.elmts, tmp); cVal->val = TblDecodeType (choiceElmtType, b, FALSE, &tmpBytesDecoded, env); break; case TBL_BOOLEAN: retVal = Asn1Alloc (sizeof (AsnBool)); BDecAsnBoolContent (b, LAST_TAG(), LAST_LEN(), (AsnBool*) retVal, &tmpBytesDecoded, env); break; case TBL_INTEGER: case TBL_ENUMERATED: retVal = Asn1Alloc (sizeof (AsnInt)); BDecAsnIntContent (b, LAST_TAG(), LAST_LEN(), (AsnInt*) retVal, &tmpBytesDecoded, env); break; case TBL_BITSTRING: retVal = Asn1Alloc (sizeof (AsnBits)); BDecAsnBitsContent (b, LAST_TAG(), LAST_LEN(), (AsnBits*) retVal, &tmpBytesDecoded, env); break; case TBL_OCTETSTRING: retVal = Asn1Alloc (sizeof (AsnOcts)); BDecAsnOctsContent (b, LAST_TAG(), LAST_LEN(), (AsnOcts*) retVal, &tmpBytesDecoded, env); break; case TBL_NULL: retVal = Asn1Alloc (sizeof (AsnNull)); BDecAsnNullContent (b, LAST_TAG(), LAST_LEN(), (AsnNull*) retVal, &tmpBytesDecoded, env); break; case TBL_OID: retVal = Asn1Alloc (sizeof (AsnOid)); BDecAsnOidContent (b, LAST_TAG(), LAST_LEN(), (AsnOid*) retVal, &tmpBytesDecoded, env); break; case TBL_REAL: retVal = Asn1Alloc (sizeof (AsnReal)); BDecAsnRealContent (b, LAST_TAG(), LAST_LEN(), (AsnReal*) retVal, &tmpBytesDecoded, env); break; default: retVal = NULL; break; } TblPopTagsAndLens (tblT, b, implicit, &tmpBytesDecoded, env); (*bytesDecoded) += tmpBytesDecoded; return retVal; } /* TblDecodeType */ void TblDecodeTagsAndLens PARAMS ((tblT, b, implicit, env), TBLType *tblT _AND_ GenBuf *b _AND_ int implicit _AND_ ENV_TYPE env) { AsnTag tag; AsnLen len; AsnLen encSize; TBLTag *tblTag; if ((tblT->tagList == NULL) || (LIST_EMPTY (tblT->tagList))) return; SET_CURR_LIST_NODE (tblT->tagList, FIRST_LIST_NODE (tblT->tagList)); if (implicit) { SET_CURR_LIST_NODE (tblT->tagList, NEXT_LIST_NODE (tblT->tagList)); } FOR_REST_LIST_ELMT (tblTag, tblT->tagList) { encSize = 0; tag = BDecTag (b, &encSize, env); len = BDecLen (b, &encSize, env); if (!TagsEquiv (tag, tblTag)) longjmp (env, -1002); PUSH_TL (tag, len, encSize, env); } } /* TblDecodeTagsAndLens */ /* * bytesDecoded should hold the length of the content that * was just decoded. This verifies the lengths as it pops * them off the stack. Also decodes EOCs. */ void TblPopTagsAndLens PARAMS ((tblT, b, implicit, bytesDecoded, env), TBLType *tblT _AND_ GenBuf *b _AND_ int implicit _AND_ unsigned long *bytesDecoded _AND_ ENV_TYPE env) { TBLTag *tblTag; FOR_EACH_LIST_ELMT_RVS (tblTag, tblT->tagList) { if (implicit && (tblTag == FIRST_LIST_ELMT (tblT->tagList))) break; if (LAST_LEN() == INDEFINITE_LEN) BDecEoc (b, bytesDecoded, env); else if (*bytesDecoded != LAST_LEN()) longjmp (env, -1003); (*bytesDecoded) += LAST_SIZE(); POP_TL (env); } } /* TblPopTagsAndLens */ int TagsMatch PARAMS ((tblT, asnTag), TBLType *tblT _AND_ AsnTag asnTag) { TBLType *tmpTblT; TBLType *elmtTblT; TBLTag *tblTag; void *tmp; /* * skip through type refs until encounter first tag or * untagged CHOICE (only TYPEREFs and CHOICEs can * have empty tag lists). */ for (tmpTblT = tblT; ((tmpTblT->typeId == TBL_TYPEREF) && ((tmpTblT->tagList == NULL) || LIST_EMPTY (tmpTblT->tagList))); tmpTblT = tmpTblT->content->a.typeRef->typeDefPtr->type); /* * if untagged CHOICE must check for a match with the first tag * of each component of the CHOICE */ if ((tmpTblT->typeId == TBL_CHOICE) && ((tmpTblT->tagList == NULL) || LIST_EMPTY (tmpTblT->tagList))) { tmp = CURR_LIST_NODE (tmpTblT->content->a.elmts); FOR_EACH_LIST_ELMT (elmtTblT, tmpTblT->content->a.elmts) { /* * remember the elmt type can be an untagged choice too * so call TagsMatch again. */ if (TagsMatch (elmtTblT, asnTag)) { SET_CURR_LIST_NODE (tmpTblT->content->a.elmts, tmp); return TRUE; /* match in choice */ } } SET_CURR_LIST_NODE (tmpTblT->content->a.elmts, tmp); return FALSE; /* no match in choice */ } else /* is type other than untagged choice or type ref */ { tblTag = FIRST_LIST_ELMT (tmpTblT->tagList); return TagsEquiv (asnTag, tblTag); } } /* TagsMatch */ int CountMandatoryElmts PARAMS ((tblT), TBLType *tblT) { TBLType *tblElmtT; int count = 0; FOR_EACH_LIST_ELMT (tblElmtT, tblT->content->a.elmts) { if (!tblElmtT->optional) count++; } return count; } /* CountMandatoryElmts */ #endif /* TTBL */ esnacc-ng-1.8.1/c-lib/src/tbl-enc.c000066400000000000000000000206621302010526100166200ustar00rootroot00000000000000#ifdef TTBL /* * tbl_enc.c - type table encoder * * * Mike Sample * * Copyright (C) 1993 Michael Sample * and the University of British Columbia * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "tbl-incl.h" /* protos for non exported routines */ /* int TblEncodePrimTagsAndLens PROTO ((TBLType *tblT, GenBuf *b, int implicit, unsigned long *bytesEncoded)); int TblEncodeConsTagsAndLens PROTO ((TBLType *tblT, GenBuf *b, int implicit, unsigned long *bytesEncoded)); */ int TblEncodeTagsAndLens PROTO ((TBLType *tblT, GenBuf *b, int implicit, unsigned long *bytesEncoded)); AsnLen TblEncTag PROTO ((GenBuf *b, TBLTag *tag)); /* * Encode value v as though it is of type modName.typeName. * bytesEncoded is set the actual number of bytes in the * encode value. * returns less than zero if an error occurs otherwise * returns 0 for success. */ int TblEncode PARAMS ((tbl, modName, typeName, b, v, bytesEncoded), TBL *tbl _AND_ char *modName _AND_ char *typeName _AND_ GenBuf *b _AND_ AVal *v _AND_ unsigned long *bytesEncoded) { TBLModule *tblMod; TBLTypeDef *tblTd; int retVal; tblTd = TblFindTypeDef (tbl, modName, typeName, &tblMod); if (tblTd == NULL) { TblError ("TblEncode: Could not find a type definition with the given module and name"); return -1; } *bytesEncoded = 0; retVal = TblEncodeType (tblTd->type, b, v, FALSE, bytesEncoded); if (BufWriteError (b)) retVal = -1; return retVal; } /* TblEncode */ /* * returns less than zero if an error occurs */ int TblEncodeType PARAMS ((tblT, b, v, implicit, bytesEncoded), TBLType *tblT _AND_ GenBuf *b _AND_ AVal *v _AND_ int implicit _AND_ unsigned long *bytesEncoded) { AVal *elmtV; AsnList *lVal; int retVal = 0; unsigned long tmpBytesEncoded = 0; unsigned int currElmt; TBLType *listElmtType; TBLType *structElmtType; TBLType *choiceElmtType; AChoiceVal *cVal; AStructVal *sVal; int implicitRef; void *tmp; switch (tblT->typeId) { case TBL_TYPEREF: /* * carry over implicit ref if goes * through typeref with no tags */ implicitRef = tblT->content->a.typeRef->implicit || (implicit && ((tblT->tagList == NULL) || LIST_EMPTY (tblT->tagList))); retVal = TblEncodeType (tblT->content->a.typeRef->typeDefPtr->type, b, v, implicitRef, &tmpBytesEncoded); break; case TBL_SEQUENCE: case TBL_SET: /* rvs though list value and list type def */ currElmt = LIST_COUNT (tblT->content->a.elmts)-1; sVal = (AStructVal*)v; tmp = CURR_LIST_NODE (tblT->content->a.elmts); FOR_EACH_LIST_ELMT_RVS (structElmtType, tblT->content->a.elmts) { elmtV = sVal[currElmt--]; if (!(structElmtType->optional && (elmtV == NULL))) { retVal = TblEncodeType (structElmtType, b, elmtV, FALSE, &tmpBytesEncoded); if (retVal < 0) break; /* exit for loop */ } } /* restore list curr in case recursive type */ SET_CURR_LIST_NODE (tblT->content->a.elmts, tmp); break; case TBL_SEQUENCEOF: case TBL_SETOF: lVal = (AsnList*)v; listElmtType = FIRST_LIST_ELMT (tblT->content->a.elmts); FOR_EACH_LIST_ELMT_RVS (elmtV, lVal) { retVal = TblEncodeType (listElmtType, b, elmtV, FALSE, &tmpBytesEncoded); if (retVal < 0) break; /* exit for loop */ } break; case TBL_CHOICE: cVal = (AChoiceVal*) v; choiceElmtType = (TBLType*)GetAsnListElmt (tblT->content->a.elmts, cVal->choiceId); retVal = TblEncodeType (choiceElmtType, b, cVal->val, FALSE, &tmpBytesEncoded); break; case TBL_BOOLEAN: tmpBytesEncoded += BEncAsnBoolContent (b, (AsnBool*)v); break; case TBL_INTEGER: case TBL_ENUMERATED: tmpBytesEncoded += BEncAsnIntContent (b, (AsnInt*)v); break; case TBL_BITSTRING: tmpBytesEncoded += BEncAsnBitsContent (b, (AsnBits*)v); break; case TBL_OCTETSTRING: tmpBytesEncoded += BEncAsnOctsContent (b, (AsnOcts*)v); break; case TBL_NULL: tmpBytesEncoded += BEncAsnNullContent (b, (AsnNull*)v); break; case TBL_OID: tmpBytesEncoded += BEncAsnOidContent (b, (AsnOid*)v); break; case TBL_REAL: tmpBytesEncoded += BEncAsnRealContent (b, (AsnReal*)v); break; default: retVal = -1; } if (retVal >= 0) retVal = TblEncodeTagsAndLens (tblT, b, implicit, &tmpBytesEncoded); (*bytesEncoded) += tmpBytesEncoded; return retVal; } /* TblEncodeTd */ int TblEncodeTagsAndLens PARAMS ((tblT, b, implicit, bytesEncoded), TBLType *tblT _AND_ GenBuf *b _AND_ int implicit _AND_ unsigned long *bytesEncoded) { TBLTag *tag; FOR_EACH_LIST_ELMT_RVS (tag, tblT->tagList) { if (!(implicit && (tag == FIRST_LIST_ELMT (tblT->tagList)))) { if (tag->form == CONS) (*bytesEncoded) += BEncConsLen (b, *bytesEncoded); else /* ANY_FORM or PRIM */ (*bytesEncoded) += BEncDefLen (b, *bytesEncoded); (*bytesEncoded) += TblEncTag (b, tag); } } return 0; /* no errors */ } /* TblEncodeTagsAndLens */ /* int TblEncodePrimTagsAndLens PARAMS ((tblT, b, implicit, bytesEncoded), TBLType *tblT _AND_ GenBuf *b _AND_ int implicit _AND_ unsigned long *bytesEncoded) { TBLTag *tag; int tagsEncoded; int numTags; if ((tblT->tagList == NULL) ||(LIST_EMPTY (tblT->tagList))) untaggedPrimG = TRUE; else { numTags = LIST_COUNT (tblT->tagList); if ((numTags != 1) || !implicit) { untaggedPrimG = FALSE; tag = FIRST_LIST_ELMT (tblT->tagList); (*bytesEncoded) += BEncDefLen (b, *bytesEncoded); (*bytesEncoded) += TblEncTag (b, tag->tclass, PRIM, tag->code); tagsEncoded = 1; SET_CURR_LIST_NODE (tblT->tagList, LAST_LIST_NODE (tblT->tagList)->prev); FOR_REST_LIST_ELMT_RVS (tag, tblT->tagList) { if (implicit && (tagsEncoded == (numTags -1))) break; (*bytesEncoded) += BEncConsLen (b, *bytesEncoded); (*bytesEncoded) += TblEncTag (b, tag->tclass, CONS, tag->code); tagsEncoded++; } } else untaggedPrimG = TRUE; } return 0; } TblEncodeTagsAndLens */ /* * write encoded version of tag stored in the tag to * the bufer */ AsnLen TblEncTag PARAMS ((b, tag), GenBuf *b _AND_ TBLTag *tag) { AsnTag shifted; unsigned char octet; AsnLen encLen = 0; int i; for (i = 0; i < sizeof (AsnTag); i++) { shifted = (tag->encTag >> (i * 8)); octet = shifted & 0xff; if (octet || i #include "tbl-incl.h" void TblFree PARAMS ((tbl, modName, typeName, v), TBL *tbl _AND_ char *modName _AND_ char *typeName _AND_ AVal *v) { TBLModule *tblMod; TBLTypeDef *tblTd; tblTd = TblFindTypeDef (tbl, modName, typeName, &tblMod); if (tblTd == NULL) { TblError ("TblFree: Could not find a type definition with the given module and name"); } TblFreeType (tblTd->type, v); } /* TblDecode p*/ void TblFreeType PARAMS ((tblT, v), TBLType *tblT _AND_ AVal *v) { AVal *elmtVPtr; unsigned int currElmt; TBLType *listElmtType; TBLType *structElmtType; TBLType *choiceElmtType; AChoiceVal *cVal; AStructVal *sVal; AsnList *lVal; void *tmp; switch (tblT->typeId) { case TBL_TYPEREF: TblFreeType (tblT->content->a.typeRef->typeDefPtr->type, v); break; case TBL_SEQUENCE: case TBL_SET: sVal = (AStructVal*)v; currElmt = 0; tmp = CURR_LIST_NODE (tblT->content->a.elmts); FOR_EACH_LIST_ELMT (structElmtType, tblT->content->a.elmts) { if (!((structElmtType->optional) && (sVal[currElmt] == NULL))) TblFreeType (structElmtType, sVal[currElmt]); currElmt++; } SET_CURR_LIST_NODE (tblT->content->a.elmts, tmp); Asn1Free (v); break; case TBL_SEQUENCEOF: case TBL_SETOF: listElmtType = FIRST_LIST_ELMT (tblT->content->a.elmts); lVal = (AsnList*)v; FOR_EACH_LIST_ELMT (elmtVPtr, lVal) { TblFreeType (listElmtType, elmtVPtr); } AsnListFree (lVal); break; case TBL_CHOICE: cVal = (AChoiceVal*)v; choiceElmtType = (TBLType*)GetAsnListElmt (tblT->content->a.elmts, cVal->choiceId); TblFreeType (choiceElmtType, cVal->val); Asn1Free (cVal); break; case TBL_BOOLEAN: FreeAsnBool ((AsnBool*)v); Asn1Free (v); break; case TBL_INTEGER: case TBL_ENUMERATED: FreeAsnInt ((AsnInt*)v); Asn1Free (v); break; case TBL_BITSTRING: FreeAsnBits ((AsnBits*)v); Asn1Free (v); break; case TBL_OCTETSTRING: FreeAsnOcts ((AsnOcts*)v); Asn1Free (v); break; case TBL_NULL: FreeAsnNull ((AsnNull*)v); Asn1Free (v); break; case TBL_OID: FreeAsnOid ((AsnOid*)v); Asn1Free (v); break; case TBL_REAL: FreeAsnReal ((AsnReal*)v); Asn1Free (v); break; default: break; } } /* TblFreeType */ #endif /* TTBL */ esnacc-ng-1.8.1/c-lib/src/tbl-gen.c000066400000000000000000000446301302010526100166250ustar00rootroot00000000000000#ifdef TTBL #include #include "tbl-gen.h" typedef struct TagNLen { AsnTag tag; AsnLen len; unsigned int size; /* encoded len for this tag len pair */ } TagNLen; #define TL_STK_SIZE 128 typedef struct STDEDecoder { TBL* tbl; GenBuf *b; ENV_TYPE env; TagNLen tlStk[TL_STK_SIZE]; int nTlStk; int rewindsize; TdeTypeProc typeproc; TdeSimpleProc simpleproc; TdeExcProc excproc; } * TDEDecoder; #define TDEEXCEPTION(dec,code,p1,p2,p3) if ((dec)->excproc) if ((*(dec)->excproc)(code,p1,p2,p3)) longjmp((dec)->env,-236) #define TDEERRORMSG(dec,msg) TDEEXCEPTION(dec,TDEERROR,msg,NULL,NULL) #define TDEWARNUNEXPECTED(dec,type,elmtType) TDEEXCEPTION(dec,TDEUNEXPECTED,type,elmtType,NULL) #define TDEWARNNONOPTIONAL(dec,type,elmtType) TDEEXCEPTION(dec,TDENONOPTIONAL,type,elmtType,NULL) #define TDEWARNMANDATORY(dec,type) TDEEXCEPTION(dec,TDEMANDATORY,type,NULL,NULL) #define TDEWARNCONSTRAINT(dec,type,cons,val) TDEEXCEPTION(dec,TDECONSTRAINT,type,cons,&val) #define TDEWARNNOMATCH(dec,type,typetag,tag) TDEEXCEPTION(dec,TDENOMATCH,type,&typetag,&tag) #define TDEINFOEOC(dec) TDEEXCEPTION(dec,TDEEOC,NULL,NULL,NULL) #define TDEINFOPEEKTAG(dec,tag) TDEEXCEPTION(dec,TDEPEEKTAG,&tag,NULL,NULL) #define TDEINFOPUSHTAG(dec,tag,len,size) TDEEXCEPTION(dec,TDEPUSHTAG,&tag,&len,&size) #define TDETYPE(dec,type,val,begin) if (dec->typeproc) if ((*dec->typeproc)(type,val,begin)) longjmp(dec->env,-234) #define TDESIMPLE(dec,tag,octs,begin) if (dec->simpleproc) if ((*dec->simpleproc)(tag,octs,begin)) longjmp(dec->env,-235) #define LAST_TAG() (dec->tlStk[dec->nTlStk-1-dec->rewindsize].tag) #define LAST_LEN() (dec->tlStk[dec->nTlStk-1-dec->rewindsize].len) #define LAST_SIZE() (dec->tlStk[dec->nTlStk-1-dec->rewindsize].size) AsnTag TDEPeekTag PARAMS ((dec), TDEDecoder dec) { AsnTag tag; if (dec->rewindsize) tag = dec->tlStk[dec->nTlStk-dec->rewindsize].tag; else tag = PeekTag(dec->b,dec->env); TDEINFOPEEKTAG(dec,tag); return tag; } AsnTag TDEPushTag PARAMS ((dec), TDEDecoder dec) { if (dec->rewindsize) dec->rewindsize--; else { unsigned long encSize = 0; if (dec->nTlStk >= TL_STK_SIZE) longjmp (dec->env, -1000); dec->tlStk[dec->nTlStk].tag = BDecTag (dec->b, &encSize, dec->env); dec->tlStk[dec->nTlStk].len = BDecLen (dec->b, &encSize, dec->env); dec->tlStk[dec->nTlStk++].size = encSize; TDEINFOPUSHTAG(dec,LAST_TAG(),LAST_LEN(),LAST_SIZE()); } return LAST_TAG(); } void TDEDoPop PARAMS ((dec), TDEDecoder dec) { dec->nTlStk--; if (dec->nTlStk < 0) longjmp (dec->env, -1001); } void TDEPopTag PARAMS ((dec, bytesDecoded), TDEDecoder dec _AND_ unsigned long *bytesDecoded) { if (LAST_LEN()==INDEFINITE_LEN) { BDecEoc (dec->b, bytesDecoded, dec->env); TDEINFOEOC(dec); } else if (*bytesDecoded != LAST_LEN()) { TDEERRORMSG(dec,"Lost BER synchronisation"); longjmp (dec->env, -1003); } (*bytesDecoded) += LAST_SIZE(); TDEDoPop(dec); } void TDECheckConstraint PARAMS ((dec, type, constraint, value), TDEDecoder dec _AND_ TBLType* type _AND_ TBLRange* constraint _AND_ AsnInt value) { if (constraint && (valuefrom || value>constraint->to)) TDEWARNCONSTRAINT(dec,type,constraint,value); } int TDEInTag PARAMS ((dec, bytesDecodedInTag), TDEDecoder dec _AND_ unsigned long bytesDecodedInTag) { return LAST_LEN()==INDEFINITE_LEN? !PeekEoc(dec->b): (bytesDecodedInTagcontent->a.elmts) { if (!elmtType->optional) count++; } return count; } void TDESimpleDecode PARAMS ((dec, bytesDecoded), TDEDecoder dec _AND_ unsigned long *bytesDecoded) { AsnTag tag = TDEPushTag(dec); unsigned long bytesDecodedInTag = 0; BER_CLASS tclass = TAG_ID_CLASS(tag); BER_FORM form = TAG_ID_FORM(tag); unsigned long code = tag & 0x1FFFFFFF; BER_UNIV_CODE bcode; if (tclass==UNIV) bcode = code>>24; else bcode = OCTETSTRING_TAG_CODE; if (TAG_IS_CONS(tag)) { TDESIMPLE(dec,tag,NULL,1); while (TDEInTag(dec,bytesDecodedInTag)) { TDESimpleDecode (dec, &bytesDecodedInTag); } TDESIMPLE(dec,tag,NULL,0); } else { PrintableString v; switch (bcode) { case INTEGER_TAG_CODE: case OCTETSTRING_TAG_CODE: default: v.octetLen = LAST_LEN(); v.octs = Asn1Alloc(v.octetLen); BufCopy(v.octs,dec->b,v.octetLen); TDESIMPLE(dec,tag,&v,1); Asn1Free(v.octs); break; } bytesDecodedInTag += LAST_LEN(); } TDEPopTag(dec,&bytesDecodedInTag); *bytesDecoded += bytesDecodedInTag; } int TDEPushTagsAndLens PARAMS ((dec, type, implicit), TDEDecoder dec _AND_ TBLType *type _AND_ int implicit) { AsnTag tag; AsnLen len; AsnLen encSize; TBLTag *tblTag; int fullMatch = TRUE; int origTLG = dec->nTlStk; int origRewindsize = dec->rewindsize; if ((type->tagList == NULL) || (LIST_EMPTY (type->tagList))) return TRUE; SET_CURR_LIST_NODE (type->tagList, FIRST_LIST_NODE (type->tagList)); if (implicit) { SET_CURR_LIST_NODE (type->tagList, NEXT_LIST_NODE (type->tagList)); } FOR_REST_LIST_ELMT (tblTag, type->tagList) { tag = TDEPushTag(dec); if (!TagsEquiv (tag, tblTag)) { /* * Whoops! The expected tags do not completely fit! So what to do? * * This is a complicated situation since might have already read some * tags from the buffer (and pushed), but now we should return failure * AND REWIND TO THE STATE WE WERE IN WHEN CALLED, * so that future PeekTag and then TblDecodeTagsAndLens calls start * off there again! * * The idea is to modify PeekTag and this routine to first check * whether there is information pending that was read already. * * Luckily, this can not happen recursively, only in sequence: * ... -> ... * ... -> Tags fit -> Tags fit -> ... * ... -> Tags fit -> Tags fit -> ... * Tags fit -> ... * Tags don't fit -< * Tags don't fit -< * Complete subtype decoding remaining tags in simple manner * <- * Tags don't fit -< * Tags fit -> ... * Complete subtype decoding remaining tags in simple manner * <- * ... */ fullMatch = FALSE; dec->rewindsize = origRewindsize + dec->nTlStk - origTLG; TDEWARNNOMATCH(dec,type,tblTag->encTag,tag); break; } } if (fullMatch) dec->rewindsize = 0; return fullMatch; } void TDEPopTagsAndLens PARAMS ((dec, bytesDecoded, type, implicit), TDEDecoder dec _AND_ unsigned long *bytesDecoded _AND_ TBLType *type _AND_ int implicit) { TBLTag *tblTag; if (dec->rewindsize) TDEERRORMSG(dec,"Still rewinding at end of tag"); FOR_EACH_LIST_ELMT_RVS (tblTag, type->tagList) { if (implicit && (tblTag == FIRST_LIST_ELMT (type->tagList))) break; TDEPopTag(dec,bytesDecoded); } } int TDETagsMatch PARAMS ((type, asnTag), TBLType *type _AND_ AsnTag asnTag) { TBLType *tmpTblT; TBLType *elmtTblT; TBLTag *tblTag; void *tmp; /* * skip through type refs until encounter first tag or * untagged CHOICE (only TYPEREFs and CHOICEs can * have empty tag lists). */ for (tmpTblT = type; ((tmpTblT->typeId == TBL_TYPEREF) && ((tmpTblT->tagList == NULL) || LIST_EMPTY (tmpTblT->tagList))); ) tmpTblT = tmpTblT->content->a.typeRef->typeDefPtr->type; /* * if untagged CHOICE must check for a match with the first tag * of each component of the CHOICE */ if ((tmpTblT->typeId == TBL_CHOICE) && ((tmpTblT->tagList == NULL) || LIST_EMPTY (tmpTblT->tagList))) { tmp = CURR_LIST_NODE (tmpTblT->content->a.elmts); FOR_EACH_LIST_ELMT (elmtTblT, tmpTblT->content->a.elmts) { /* * remember the elmt type can be an untagged choice too * so call TagsMatch again. */ if (TagsMatch (elmtTblT, asnTag)) { SET_CURR_LIST_NODE (tmpTblT->content->a.elmts, tmp); return TRUE; /* match in choice */ } } SET_CURR_LIST_NODE (tmpTblT->content->a.elmts, tmp); return FALSE; /* no match in choice */ } else /* is type other than untagged choice or type ref */ { int result; tblTag = FIRST_LIST_ELMT (tmpTblT->tagList); result = TagsEquiv (asnTag, tblTag); return result; } } int TDEDecodeType PARAMS ((dec, bytesDecoded, type, implicit, constraint), TDEDecoder dec _AND_ unsigned long *bytesDecoded _AND_ TBLType *type _AND_ int implicit _AND_ TBLRange* constraint) { AVal *elmtVPtr; unsigned long tmpBytesDecoded = 0; unsigned int currElmt; TBLType *elmtType; AVal *retVal = NULL; AVal *eleVal; AVal **tmpHndl; AsnTag asnTag; int i, mandatoryCount, mandatoryElmts; int implicitRef; void *tmp; AsnInt value; char* constraintmsg = NULL; int elmtfound; int indefinite; if (!TDEPushTagsAndLens (dec, type, implicit)) return FALSE; #if TTBL>1 if (!constraint) constraint = type->constraint; #endif TDETYPE(dec,type,NULL,1); switch (type->typeId) { case TBL_TYPEREF: /* * carry over implicit ref if goes * through typeref with no tags */ implicitRef = type->content->a.typeRef->implicit || (implicit && ((type->tagList == NULL) || LIST_EMPTY (type->tagList))); if (!TDEDecodeType (dec, &tmpBytesDecoded, type->content->a.typeRef->typeDefPtr->type, implicitRef, constraint)) { TDEWARNUNEXPECTED(dec,type,type->content->a.typeRef->typeDefPtr->type); TDESimpleDecode(dec, &tmpBytesDecoded); } break; case TBL_SEQUENCE: /* go fwd though elmt type list */ tmp = CURR_LIST_NODE (type->content->a.elmts); FOR_EACH_LIST_ELMT (elmtType, type->content->a.elmts) { elmtfound = FALSE; while (!elmtfound && TDEInTag(dec,tmpBytesDecoded) && TDETagsMatch (elmtType, TDEPeekTag (dec))) elmtfound = TDEDecodeType (dec,&tmpBytesDecoded, elmtType, FALSE, NULL); if (!elmtfound && !elmtType->optional) TDEWARNNONOPTIONAL(dec,type,elmtType); } SET_CURR_LIST_NODE (type->content->a.elmts, tmp); /* process remaining stuff in sequence */ while (TDEInTag(dec,tmpBytesDecoded)) { TDEWARNUNEXPECTED(dec,type,NULL); TDESimpleDecode(dec, &tmpBytesDecoded); } break; case TBL_SET: mandatoryCount = 0; mandatoryElmts = TDECountMandatoryElmts (type); while (TDEInTag(dec,tmpBytesDecoded)) { asnTag = TDEPeekTag (dec); elmtfound = FALSE; /* find elmt that matches the peeked tag */ tmp = CURR_LIST_NODE (type->content->a.elmts); FOR_EACH_LIST_ELMT (elmtType, type->content->a.elmts) { if (TDETagsMatch (elmtType, asnTag)) { elmtfound = TRUE; break; } } SET_CURR_LIST_NODE (type->content->a.elmts, tmp); /* didn't find a match */ if (!elmtfound || !TDEDecodeType (dec, &tmpBytesDecoded, elmtType, FALSE, NULL)) { TDEWARNUNEXPECTED(dec,type,elmtfound?elmtType:NULL); TDESimpleDecode(dec, &tmpBytesDecoded); } else { if (!elmtType->optional) mandatoryCount++; } } if (mandatoryCount != mandatoryElmts) TDEWARNMANDATORY(dec,type); break; case TBL_SEQUENCEOF: case TBL_SETOF: elmtType = FIRST_LIST_ELMT (type->content->a.elmts); constraintmsg = "Size of SEQUENCE/SET OF"; value = 0; while (TDEInTag(dec,tmpBytesDecoded)) { if (!TDEDecodeType (dec, &tmpBytesDecoded, elmtType, FALSE,NULL)) { TDEWARNUNEXPECTED(dec,type,elmtType); TDESimpleDecode(dec, &tmpBytesDecoded); } else value++; } break; case TBL_CHOICE: elmtfound = FALSE; if (TDEInTag(dec,tmpBytesDecoded)) { asnTag = TDEPeekTag (dec); /* find elmt that matches the peeked tag */ tmp = CURR_LIST_NODE (type->content->a.elmts); FOR_EACH_LIST_ELMT (elmtType, type->content->a.elmts) { if (TDETagsMatch (elmtType, asnTag)) { elmtfound = TRUE; break; } } } SET_CURR_LIST_NODE (type->content->a.elmts, tmp); if (!elmtfound || !TDEDecodeType (dec, &tmpBytesDecoded, elmtType, FALSE, NULL)) { TDEWARNUNEXPECTED(dec,type,elmtfound?elmtType:NULL); TDESimpleDecode(dec, &tmpBytesDecoded); } break; case TBL_BOOLEAN: retVal = Asn1Alloc (sizeof (AsnBool)); BDecAsnBoolContent (dec->b, LAST_TAG(), LAST_LEN(), (AsnBool*) retVal, &tmpBytesDecoded, dec->env); break; case TBL_INTEGER: case TBL_ENUMERATED: retVal = Asn1Alloc (sizeof (AsnInt)); BDecAsnIntContent (dec->b, LAST_TAG(), LAST_LEN(), (AsnInt*) retVal, &tmpBytesDecoded, dec->env); constraintmsg = "INTEGER/ENUMERATED"; value = *(AsnInt*)retVal; break; case TBL_BITSTRING: retVal = Asn1Alloc (sizeof (AsnBits)); BDecAsnBitsContent (dec->b, LAST_TAG(), LAST_LEN(), (AsnBits*) retVal, &tmpBytesDecoded, dec->env); break; case TBL_OCTETSTRING: retVal = Asn1Alloc (sizeof (AsnOcts)); BDecAsnOctsContent (dec->b, LAST_TAG(), LAST_LEN(), (AsnOcts*) retVal, &tmpBytesDecoded, dec->env); constraintmsg = "Length of OCTET STRING"; value = ((AsnOcts*)retVal)->octetLen; break; case TBL_NULL: retVal = Asn1Alloc (sizeof (AsnNull)); BDecAsnNullContent (dec->b, LAST_TAG(), LAST_LEN(), (AsnNull*) retVal, &tmpBytesDecoded, dec->env); break; case TBL_OID: retVal = Asn1Alloc (sizeof (AsnOid)); BDecAsnOidContent (dec->b, LAST_TAG(), LAST_LEN(), (AsnOid*) retVal, &tmpBytesDecoded, dec->env); break; case TBL_REAL: retVal = Asn1Alloc (sizeof (AsnReal)); BDecAsnRealContent (dec->b, LAST_TAG(), LAST_LEN(), (AsnReal*) retVal, &tmpBytesDecoded, dec->env); break; default: retVal = NULL; break; } TDETYPE(dec,type,retVal,0); if (retVal) Asn1Free(retVal); if (constraintmsg) TDECheckConstraint(dec,type,constraint,value); TDEPopTagsAndLens (dec, &tmpBytesDecoded, type, implicit); (*bytesDecoded) += tmpBytesDecoded; return TRUE; } int TDEDecodeSpecific PARAMS ((dec, bytesDecoded, type), TDEDecoder dec _AND_ unsigned long *bytesDecoded _AND_ TBLType* type) { int val; *bytesDecoded = 0; dec->rewindsize = 0; dec->nTlStk = 0; if ((val = setjmp (dec->env)) == 0) { TDEDecodeType (dec, bytesDecoded, type, FALSE, NULL); return TRUE; } return FALSE; } int TDEDecodeUnknown PARAMS ((dec, bytesDecoded), TDEDecoder dec _AND_ unsigned long *bytesDecoded) { TBLModule *tblMod = NULL; TBLTypeDef *tblTd = NULL; *bytesDecoded = 0; FOR_EACH_LIST_ELMT (tblMod, dec->tbl->modules) break; if (!tblMod) { TDEERRORMSG (dec,"No module in grammar"); return FALSE; } FOR_EACH_LIST_ELMT_RVS (tblTd, tblMod->typeDefs) break; if (!tblTd) { TDEERRORMSG (dec,"No type in first module of grammar"); return FALSE; } return TDEDecodeSpecific (dec, bytesDecoded, tblTd->type); } struct STDEDecoder sdec; void TDEErrorHandler PARAMS ((str, severity), char* str _AND_ int severity) { TDEERRORMSG(&sdec,str); } int TdeDecodeSpecific PARAMS ((tbl, b, type, bytesDecoded, typeproc, simpleproc, excproc), TBL *tbl _AND_ GenBuf *b _AND_ TBLType* type _AND_ unsigned long *bytesDecoded _AND_ TdeTypeProc typeproc _AND_ TdeSimpleProc simpleproc _AND_ TdeExcProc excproc) { int result; Asn1ErrorHandler former = Asn1InstallErrorHandler(TDEErrorHandler); sdec.tbl = tbl; sdec.b = b; sdec.typeproc = typeproc; sdec.simpleproc = simpleproc; sdec.excproc = excproc; result = TDEDecodeSpecific(&sdec,bytesDecoded,type); Asn1InstallErrorHandler(former); return result; } int TdeDecode PARAMS ((tbl, b, bytesDecoded, typeproc, simpleproc, excproc), TBL *tbl _AND_ GenBuf *b _AND_ unsigned long *bytesDecoded _AND_ TdeTypeProc typeproc _AND_ TdeSimpleProc simpleproc _AND_ TdeExcProc excproc) { int result; Asn1ErrorHandler former = Asn1InstallErrorHandler(TDEErrorHandler); sdec.tbl = tbl; sdec.b = b; sdec.typeproc = typeproc; sdec.simpleproc = simpleproc; sdec.excproc = excproc; result = TDEDecodeUnknown(&sdec,bytesDecoded); Asn1InstallErrorHandler(former); return result; } #endif esnacc-ng-1.8.1/c-lib/src/tbl-print.c000066400000000000000000000113561302010526100172070ustar00rootroot00000000000000#ifdef TTBL /* * tbl_print.c - type table value printer * * * Mike Sample * * Copyright (C) 1993 Michael Sample * and the University of British Columbia * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "tbl-incl.h" static int indentIncrG = 2; /* * Print value v to file f as though it is of type modName.typeName in * table tbl. */ void TblPrintValue PARAMS ((tbl, modName, typeName, f, v), TBL *tbl _AND_ char *modName _AND_ char *typeName _AND_ FILE *f _AND_ AVal *v) { TBLTypeDef *tblTd; TBLModule *tblMod; tblTd = TblFindTypeDef (tbl, modName, typeName, &tblMod); if (tblTd == NULL) { TblError ("TblEncode: Could not find a type definition with the given module and name"); } else { fprintf (f, "value %s.%s ::= \n", tblMod->name.octs, typeName); TblPrintTypeValue (tblTd->type, f, v, 0); } } /* TblPrint */ /* * starts using indent after first newline printed by this routine */ void TblPrintTypeValue PARAMS ((tblT, f, v, indent), TBLType *tblT _AND_ FILE *f _AND_ AVal *v _AND_ unsigned short indent) { AVal *elmtV; AsnList *lVal; unsigned int currElmt; TBLType *listElmtType; TBLType *structElmtType; TBLType *choiceElmtType; AChoiceVal *cVal; AStructVal *sVal; void *tmp; switch (tblT->typeId) { case TBL_TYPEREF: TblPrintTypeValue (tblT->content->a.typeRef->typeDefPtr->type, f, v, indent); break; case TBL_SEQUENCE: case TBL_SET: fprintf (f,"{\n"); currElmt = 0; sVal = (AStructVal*)v; tmp = CURR_LIST_NODE (tblT->content->a.elmts); FOR_EACH_LIST_ELMT (structElmtType, tblT->content->a.elmts) { Indent (f, indent+indentIncrG); elmtV = sVal[currElmt++]; if (!(structElmtType->optional && (elmtV == NULL))) { if (structElmtType->fieldName.octs != NULL) fprintf (f,"%s ", structElmtType->fieldName.octs); TblPrintTypeValue (structElmtType, f, elmtV, indent+indentIncrG); if (structElmtType != LAST_LIST_ELMT (tblT->content->a.elmts)) fprintf (f,",\n"); else fprintf (f,"\n"); } } /* restore list curr in case recursive type */ SET_CURR_LIST_NODE (tblT->content->a.elmts, tmp); Indent (f,indent); fprintf (f,"}"); break; case TBL_SEQUENCEOF: case TBL_SETOF: fprintf (f,"{\n"); lVal = (AsnList*)v; listElmtType = FIRST_LIST_ELMT (tblT->content->a.elmts); tmp = CURR_LIST_NODE (tblT->content->a.elmts); FOR_EACH_LIST_ELMT (elmtV, lVal) { Indent (f, indent+indentIncrG); TblPrintTypeValue (listElmtType, f, elmtV, indent+indentIncrG); if (elmtV != LAST_LIST_ELMT (lVal)) fprintf (f,",\n"); else fprintf (f,"\n"); } /* restore old list curr ptr */ SET_CURR_LIST_NODE (tblT->content->a.elmts, tmp); Indent (f,indent); fprintf (f,"}"); break; case TBL_CHOICE: cVal = (AChoiceVal*) v; choiceElmtType = (TBLType*)GetAsnListElmt (tblT->content->a.elmts, cVal->choiceId); if (choiceElmtType->fieldName.octs != NULL) fprintf (f,"%s ", choiceElmtType->fieldName.octs); TblPrintTypeValue (choiceElmtType, f, cVal->val, indent+indentIncrG); break; case TBL_BOOLEAN: PrintAsnBool (f, (AsnBool*)v,indent); break; case TBL_INTEGER: case TBL_ENUMERATED: PrintAsnInt (f, (AsnInt*)v, indent); break; case TBL_BITSTRING: PrintAsnBits (f, (AsnBits*)v, indent); break; case TBL_OCTETSTRING: PrintAsnOcts (f, (AsnOcts*)v, indent); break; case TBL_NULL: PrintAsnNull (f, (AsnNull*)v, indent); break; case TBL_OID: PrintAsnOid (f, (AsnOid*)v, indent); break; case TBL_REAL: PrintAsnReal (f, (AsnReal*)v, indent); break; default: fprintf (f, ""); } } /* TblPrintTypeValue */ #endif /* TTBL */ esnacc-ng-1.8.1/c-lib/src/tbl-util.c000066400000000000000000000234751302010526100170350ustar00rootroot00000000000000#ifdef TTBL /* * tbl_util.c - type table utilities. * * Copyright (C) 1993 Michael Sample * and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ #include #include "tbl-incl.h" #include "sbuf.h" /* non -exported routine protos */ void TblLinkIndexes PROTO ((TBL *tbl)); void TblLinkTypeRefs PROTO ((TBL *tbl, TBLType *tblT)); void TblFixTags PROTO ((TBL *tbl)); void TblFixTypeTags PROTO ((TBLType *tblT)); void TblSetTagForms PROTO ((TBLType *t)); /* * opens given filename, determines its size, allocs a block * of that size and reads the file into it. returns a pointer * to this block. Prints an err msgs is something screwed up * and returns NULL. Sets the size param to the size of the file. */ char* LoadFile PARAMS ((fileName, size), char *fileName _AND_ unsigned long *size) { FILE *f; unsigned long fsize; char *fileData; f = fopen (fileName, "r"); if (f == NULL) { Asn1Error("Could not open file for reading.\n"); return NULL; } fseek (f, 0, 2); /* seek to end */ fsize = ftell (f); /* get size of file */ fseek (f, 0, 0); /* seek to beginning */ *size = fsize; fileData = (char *) malloc (fsize); if (fileData == NULL) { Asn1Error("Not enough memory to read in file.\n"); return NULL; } if (fread (fileData, sizeof (char), fsize, f) != fsize) { free (fileData); fileData = NULL; Asn1Error("Trouble reading file.\n"); } fclose (f); return fileData; } /* LoadFile */ TBL* LoadTblFile PARAMS ((tblFileName), char *tblFileName) { SBuf sb; SBuf *sbPtr; GenBuf gb; TBL *tbl; unsigned long fsize; char *fileData; AsnLen decodedLen; ENV_TYPE env; int val; fileData = LoadFile (tblFileName, &fsize); if (fileData == NULL) return NULL; SBufInstallData (&sb, fileData, fsize); SBufResetInReadMode (&sb); PutSBufInGenBuf (&sb, &gb); decodedLen = 0; tbl = (TBL*)Asn1Alloc (sizeof (TBL)); if ((val = setjmp (env)) == 0) BDecTBL (&gb, tbl, &decodedLen, env); else return NULL; /* convert the typeDefIndexes into real pointers */ TblLinkIndexes (tbl); TblFixTags (tbl); free (fileData); /* malloc'd in LoadFile */ return tbl; } /* * just use slow individual lookup instead of creating a table * (a conversion tbl could be built during decoding) */ void TblLinkIndexes PARAMS ((tbl), TBL *tbl) { TBLModule *tblMod; TBLTypeDef *tblTd; FOR_EACH_LIST_ELMT (tblMod, tbl->modules) { FOR_EACH_LIST_ELMT (tblTd, tblMod->typeDefs) { /* go through the types looking for TBLTypeRefs */ TblLinkTypeRefs (tbl, tblTd->type); } } } /* TBLLinkIndexes */ /* * set tags forms and include encoded version to improve * decoding and encoding performance. */ void TblFixTags PARAMS ((tbl), TBL *tbl) { TBLModule *tblMod; TBLTypeDef *tblTd; FOR_EACH_LIST_ELMT (tblMod, tbl->modules) { FOR_EACH_LIST_ELMT (tblTd, tblMod->typeDefs) { TblFixTypeTags (tblTd->type); } } } /* TBLFixTags */ /* * recursively descends type looking for typeDefIds in type refs * to convert to the type defs actual ptr * * Also sets the form field for each tag. (this speeds up enc/dec). * Note that the form bit is not in the encoded version of a TBLTag. */ void TblLinkTypeRefs PARAMS ((tbl, tblT), TBL *tbl _AND_ TBLType *tblT) { TBLType *tblElmtT; void *tmp; switch (tblT->typeId) { case TBL_BOOLEAN: case TBL_INTEGER: case TBL_BITSTRING: case TBL_OCTETSTRING: case TBL_NULL: case TBL_OID: case TBL_REAL: case TBL_ENUMERATED: /* not contained type refs so return */ break; case TBL_SEQUENCE: case TBL_SET: case TBL_SEQUENCEOF: case TBL_SETOF: case TBL_CHOICE: /* look for contained type refs */ tmp = CURR_LIST_NODE (tblT->content->a.elmts); FOR_EACH_LIST_ELMT (tblElmtT, tblT->content->a.elmts) { TblLinkTypeRefs (tbl, tblElmtT); } SET_CURR_LIST_NODE (tblT->content->a.elmts, tmp); break; case TBL_TYPEREF: /* convert type def index into a pointer to the type def */ tblT->content->a.typeRef->typeDefPtr = TblFindTypeDefByIndex (tbl, tblT->content->a.typeRef->typeDef); break; } } /* TblLinkTypeRefs */ void TblFixTypeTags PARAMS ((tblT), TBLType *tblT) { void *tmp; TBLType *tblElmtT; TblSetTagForms (tblT); switch (tblT->typeId) { case TBL_SEQUENCE: case TBL_SET: case TBL_SEQUENCEOF: case TBL_SETOF: case TBL_CHOICE: /* fix tags in elmt types */ tmp = CURR_LIST_NODE (tblT->content->a.elmts); FOR_EACH_LIST_ELMT (tblElmtT, tblT->content->a.elmts) { TblFixTypeTags (tblElmtT); } SET_CURR_LIST_NODE (tblT->content->a.elmts, tmp); break; default: break; } } void TblSetTagForms PARAMS ((tblT), TBLType *tblT) { TBLTag *tblTag; TBLType *tmpTblT; int numTags; TBLTypeId tid; BER_FORM form; if (tblT->tagList == NULL) return; numTags = LIST_COUNT (tblT->tagList); /* * get real type id (skip through type refs) * count total number of tags too. */ for (tmpTblT = tblT; tmpTblT->typeId == TBL_TYPEREF; tmpTblT = tmpTblT->content->a.typeRef->typeDefPtr->type) { if (tmpTblT->tagList) numTags += LIST_COUNT (tmpTblT->tagList); if (tmpTblT->content->a.typeRef->implicit) numTags--; } tid = tmpTblT->typeId; /* only traverse this types tags */ FOR_EACH_LIST_ELMT (tblTag, tblT->tagList) { if (numTags > 1) form = tblTag->form = CONS; else switch (tid) { case TBL_SEQUENCE: case TBL_SET: case TBL_SEQUENCEOF: case TBL_SETOF: case TBL_CHOICE: form = tblTag->form = CONS; break; case TBL_OCTETSTRING: case TBL_BITSTRING: tblTag->form = ANY_FORM; form = PRIM; /* store as prim (for encoder - always prim) */ break; default: form = tblTag->form = PRIM; break; } tblTag->encTag = MAKE_TAG_ID (TblTagClassToBer (tblTag->tclass), form, tblTag->code); numTags--; } } /* TblSetTagForms */ TBLTypeDef* TblFindTypeDef PARAMS ((tbl, modName, typeName, tblModHndl), TBL *tbl _AND_ char *modName _AND_ char *typeName _AND_ TBLModule **tblModHndl) { TBLModule *tblMod; TBLTypeDef *tblTd; void *tmp; /* look in named module only if given */ if (modName != NULL) { tblMod = TblFindModule (tbl, modName); *tblModHndl = tblMod; if (tblMod == NULL) return NULL; return TblFindTypeDefInMod (tblMod, typeName); } else /* look in all modules and return first instance */ { tmp = CURR_LIST_NODE (tbl->modules); FOR_EACH_LIST_ELMT (tblMod, tbl->modules) { tblTd = TblFindTypeDefInMod (tblMod, typeName); if (tblTd != NULL) { *tblModHndl = tblMod; SET_CURR_LIST_NODE (tbl->modules, tmp); return tblTd; } } SET_CURR_LIST_NODE (tbl->modules, tmp); } return NULL; /* not found */ } /* TblFindTypeDef */ TBLTypeDef* TblFindTypeDefInMod PARAMS ((tblMod, typeName), TBLModule *tblMod _AND_ char *typeName) { TBLTypeDef *tblTd; void *tmp; tmp = CURR_LIST_NODE (tblMod->typeDefs); FOR_EACH_LIST_ELMT (tblTd, tblMod->typeDefs) { if (strcmp (tblTd->typeName.octs, typeName) == 0) { SET_CURR_LIST_NODE (tblMod->typeDefs, tmp); return tblTd; } } SET_CURR_LIST_NODE (tblMod->typeDefs, tmp); return NULL; } /* TblFindTypeDefInMod */ TBLTypeDef* TblFindTypeDefByIndex PARAMS ((tbl, id), TBL *tbl _AND_ TBLTypeDefId id) { TBLModule *tblMod; TBLTypeDef *tblTd; void *tmp1; void *tmp2; /* look in all modules and return typedef with given id */ tmp1 = CURR_LIST_NODE (tbl->modules); FOR_EACH_LIST_ELMT (tblMod, tbl->modules) { tmp2 = CURR_LIST_NODE (tblMod->typeDefs); FOR_EACH_LIST_ELMT (tblTd, tblMod->typeDefs) { if (tblTd->typeDefId == id) { SET_CURR_LIST_NODE (tblMod->typeDefs, tmp2); SET_CURR_LIST_NODE (tbl->modules, tmp1); return tblTd; } } SET_CURR_LIST_NODE (tblMod->typeDefs, tmp2); } SET_CURR_LIST_NODE (tbl->modules, tmp1); return NULL; } /* TblFindTypeDefByIndex */ TBLModule* TblFindModule PARAMS ((tbl, modName), TBL *tbl _AND_ char *modName) { TBLModule *tblMod; void *tmp; tmp = CURR_LIST_NODE (tbl->modules); FOR_EACH_LIST_ELMT (tblMod, tbl->modules) { if (strcmp (tblMod->name.octs, modName) == 0) { SET_CURR_LIST_NODE (tbl->modules, tmp); return tblMod; } } SET_CURR_LIST_NODE (tbl->modules, tmp); return NULL; } /* TblFindModule */ #endif /* TTBL */ esnacc-ng-1.8.1/changelog000066400000000000000000000727661302010526100152410ustar00rootroot00000000000000Tue Sep 16 15:05:10 1997 Sebastian Wangnick * tbl-tools/berdecode/berdecode.c: Changed default value of strip to 0. * entry.html: Documented current situation Tue Sep 16 14:57:59 1997 Sebastian Wangnick * README: Proper description of last-minute changes * asn1specs/p-rec.asn1, tbl-example/p-rec.ber: Added test for "tag dividable by 128" case. * c-lib/src/tbl-enc.c, c-lib/src/tbl-gen.c: Fixed "tag dividable by 128" case. Fixed problem of peeking beyond tag size. Fri Sep 5 07:15:06 1997 Sebastian Wangnick * tcl-asn/asnwish.c: Picky compiler mods Thu Sep 4 13:54:10 1997 Sebastian Wangnick * tbl-tools/berdecode/berdecode.c, c++-lib/src/asn-list.C, configure.in: A little more portability Wed Sep 3 12:50:33 1997 Sebastian Wangnick * compiler/makefile: Shifted parse and lex * tcl-asn/makefile, tcl-asn/asnwish.c: Reworked asnwish to neither strip nor encapsulate; instead, buffer reads during decoding incrementally Tcl_Read the channel. * c-lib/src/tbl-enc.c, c-lib/src/asn-tag.c: Patch to tag decoding for tags > 2^14 (thanks to Enrico Badella) Patch to TblEncTag to emit final 0x00 if previous octet signals continuation * c++-lib/src/asn-tag.C: Patch to tag decoding for tags > 2^14 (thanks to Enrico Badella) Mon Sep 1 14:21:03 1997 Sebastian Wangnick * compiler/core/err-chk.c: Improved error output in certain cases. Thu Aug 28 09:48:08 1997 Sebastian Wangnick * README, entry.html, ChangeLog: Added description of changes * compiler/core/lex-asn1.l, compiler/core/parse-asn1.y: Reworked number range checking, only gives warning now. Wed Aug 27 15:56:09 1997 Sebastian Wangnick * tcl-asn/README, tcl-asn/asnwish.c, tcl-asn/makefile, tbl-tools/berdecode/berdecode.c, tbl-tools/berdecode/makefile, tbl-tools/berdecode/README, tbl-tools/makefile, c-lib/src/tbl-dbg.c, c-lib/src/tbl-gen.c, c-lib/inc/tbl-dbg.h, c-lib/inc/tbl-gen.h, c-lib/makefile: Added generic table decoding, debug routines, berdecode, and asnwish. * c++-lib/src/asn-bits.C: GetBit now returns 0 or 1, not 0 or <#bit>, even if bool type is emulated. * version.h, makefile: Added generic table decoding, debug routines, berdecode, and asnwish. Thu Jun 19 09:32:22 1997 Sebastian Wangnick * README: Added 1.3b3 change description * doc/makefile: Disabled making new doc due to new version string. * compiler/boot/tbl.h, compiler/boot/tbl.c, c-lib/boot/tbl.h, c-lib/boot/tbl.c: Remade by make tar * version.h: Fixed release date. * tbl-tools/ptbl/pasn1.c, compiler/core/lex-asn1.l, compiler/core/parse-asn1.y, compiler/boot/tbl.c, compiler/boot/tbl.h, compiler/core/gen-tbls.c, c-lib/boot/tbl.h, c-lib/src/tbl-util.c, c-lib/boot/tbl.c, asn1specs/tbl.asn1, version.h: Added isPdu flag to tables. Added value range checks during parsing. Wed May 7 15:20:57 1997 Sebastian Wangnick * README, tbl-tools/ptbl/pasn1.c, compiler/core/gen-tbls.h, compiler/core/snacc.c, c-lib/inc/tbl-incl.h, compiler/core/gen-tbls.c, asn1specs/tbl.asn1, version.h: Added (limited) size constraints, bitstring and enumeration names to tables * compiler/back-ends/c-gen/gen-vals.c: Fixed bug in C value string generation. Mon Apr 7 13:14:16 1997 Sebastian Wangnick * README: Final README for 1.3b1 * snacc.h: Made more C++ readable (credits to Steve Walker) Thu Mar 20 15:50:25 1997 Sebastian Wangnick * version.h, README: Push to 1.3b1. Thu Mar 13 14:48:28 1997 Sebastian Wangnick * compiler/core/parse-asn1.y: Parsed SEQUENCE SIZE(..) OF as SET, corrected. * compiler/boot/tbl.h, compiler/boot/tbl.c, compiler/back-ends/idl-gen/gen-code.c, c-lib/src/print.c, c-lib/src/asn-tag.c, c-lib/inc/asn-config.h, c-lib/boot/tbl.h, c-lib/boot/tbl.c, c-lib/boot/asn-useful.h, c-lib/boot/asn-useful.c, c-lib/makefile, c++-lib/makefile, version.h: Improved dependency generation for stupid makedepends. Corrected PeekTag to peek into buffer only as far as necessary. Added installable error handler. Fixed small glitch in idl-code generator (Markku Savela ). Mon Mar 3 11:58:34 1997 Sebastian Wangnick * compiler/core/parse-asn1.y, compiler/boot/tbl.c, compiler/boot/tbl.h, compiler/makefile, c-lib/boot/tbl.c, c-lib/boot/tbl.h, c-lib/boot/asn-useful.c, c-lib/boot/asn-useful.h, c++-examples/test-lib/makefile, acconfig.h, makefile, ChangeLog: Final pre-delivery stuff (I hope). Fri Feb 28 13:43:53 1997 Sebastian Wangnick * version.h: New version #. * .cvsignore: Added config.cache * tcl-lib/snacced.tcl, tcl-example/edex1.asn1, tcl-lib/selbox.tcl, compiler/core/parse-asn1.y, compiler/core/print.c, compiler/back-ends/c-gen/gen-dec.c, compiler/back-ends/c++-gen/gen-code.c, c-lib/src/tbl-util.c, compiler/makefile, c-lib/src/hash.c, c-lib/src/nibble-alloc.c, c-lib/src/tbl-free.c, c-lib/src/asn-real.c, c-lib/src/asn-tag.c, c-lib/inc/asn-any.h, c-lib/inc/hash.h, c-lib/src/asn-any.c, c++-lib/src/tkAppInit.c, c-lib/tbl.h.patch, c++-lib/src/meta.C, c++-lib/src/tcl-if.C, c++-lib/src/asn-oid.C, c++-lib/src/asn-real.C, c++-lib/src/hash.C, c++-lib/src/asn-int.C, c++-lib/src/asn-octs.C, c++-lib/src/asn-bits.C, c++-lib/src/asn-bool.C, c++-lib/src/asn-enum.C, c++-lib/inc/meta.h, c++-lib/src/asn-any.C, c++-examples/test-lib/test-lib.C, c++-lib/inc/hash.h, c++-examples/test-lib/makefile, configure.in, snacc.h, acconfig.h: Modifications collected for new version 1.3: Bug fixes, tk4.2. Sun Feb 16 22:26:40 1997 rj * README: url corrected * c-examples/test-lib/README, c-examples/any/example.c, c-examples/any/README, c++-lib/src/str-stk.C, c++-lib/src/print.C, c++-lib/src/hash.C, c++-lib/src/asn-tag.C, c++-lib/src/asn-len.C, c++-lib/src/asn-bool.C, c++-lib/src/asn-any.C, c++-lib/inc/str-stk.h, c++-lib/inc/print.h, c++-lib/inc/hash.h, c++-lib/inc/asn-type.h, c++-lib/inc/asn-tag.h, c++-lib/inc/asn-real.h, c++-lib/inc/asn-octs.h, c++-lib/inc/asn-list.h, c++-lib/inc/asn-incl.h, c++-lib/inc/asn-buf.h, c++-lib/inc/asn-bits.h, c++-examples/test-lib/README, c++-examples/any/README, asn1specs/ex1.asn1, asn1specs/any.asn1: check-in of a few cosmetic changes * README, ChangeLog, version.h: final release of snacc 1.2rj * makefile: remove tcl-p when making clobber * INITIAL: first check-in * tcl-example/.cvsignore: ignore yet two more generated files * doc/makefile: typo fixed * c++-examples/any/.cvsignore, c-examples/any/.cvsignore: ignore more generated files and directories * c++-examples/simple/.cvsignore, c-examples/simple/.cvsignore: ignore generated directories * c-examples/test-lib/.cvsignore: ignore yet another generated file * tbl-example/.cvsignore: ignore two more generated files * tbl-tools/pval/.cvsignore, tbl-tools/ptbl/.cvsignore, tbl-tools/mkchdr/.cvsignore: ignore yet another generated file * makefile: correct path to configure script * compiler/makefile: snacc is needed to generate the distfiles * tcl-example/.cvsignore: ignore more generated files * tbl-tools/mkchdr/.cvsignore: ignore yet another generated file * tbl-example/.cvsignore, doc/.cvsignore: ignore yet two more generated files * doc/.cvsignore: ignore yet another generated file * tcl-example/.cvsignore, tbl-tools/pval/.cvsignore, tbl-tools/ptbl/.cvsignore, tbl-tools/mkchdr/.cvsignore, tbl-example/.cvsignore, c-examples/test-lib/.cvsignore: ignore the dependencies file * c-examples/snmp/.cvsignore, c-examples/simple/.cvsignore, c-examples/any/.cvsignore, c++-examples/test-lib/.cvsignore, c++-examples/snmp/.cvsignore, c++-examples/simple/.cvsignore, c++-examples/any/.cvsignore: ignore yet another file * c++-lib/.cvsignore: ignore generated directories * c++-lib/.cvsignore, compiler/.cvsignore: ignore yet another generated file * c-lib/.cvsignore: ignore more generated files and directories * doc/thisnextafter.tex, doc/misc-defs.tex, doc/list-popup.eps, doc/str-popup.eps, doc/struct.eps, doc/simple.eps, doc/selbox.eps, doc/recur.eps, doc/example.eps, c-lib/tbl.h.patch: first check-in * makefile: generate tcl-p before it is needed... * configure.in, doc/intro-1.2.tex, c++-lib/makefile, c++-examples/snmp/makefile, c++-examples/simple/makefile, c++-examples/any/makefile: made return *this after calling abort()'' a compile time option. * maketail: rule to generate $(TCL-P) added * makehead.in, doc/snacc.1, compiler/back-ends/c++-gen/gen-code.h, compiler/back-ends/c++-gen/gen-code.c: made return *this after calling abort()'' a compile time option. * compiler/core/snacc.c: made ``return *this after calling abort()'' a compile time option. * c++-lib/inc/asn-oid.h: construct in the order the members are defined * tcl-example/makefile: remove more generated files * compiler/back-ends/c++-gen/gen-code.c: use the TIME_WITH_SYS_TIME flag (checked and generated by configure). return *this after calling abort() for compilers that don't know about this volatile function. comment out unused parameters, the compiler otherwise may complain. * compiler/makefile: let make clobber remove the link to install-sh that make made let make clean remove more created files * c-lib/makefile: let make clobber remove the link to install-sh that make made * c++-lib/src/asn-oid.C: name lookup of \for' scoping * c++-lib/inc/asn-null.h: comment out an unused argument * c++-lib/inc/asn-len.h: make the unsigned value unsigned :-) Sun Feb 16 05:22:42 1997 Robert Joop * ***** this is the end, my last words on my final snacc release, 1.2rj.10. ***** * lots of files and directories added to the various .cvsignore files. * added a file INITIAL to explain the first steps necessary after an initial cvs checkout. * made ``return *this after calling abort()'' a compile time option. * compiler/back-ends/c++-gen/gen-code.c: comment out unused parameters, the compiler otherwise may complain. * compiler/back-ends/c++-gen/gen-code.c: return *this after calling abort() for compilers that don't know about this volatile function. * compiler/back-ends/c++-gen/gen-code.c: use the TIME_WITH_SYS_TIME flag (checked and generated by configure) * changes for new ANSI `for' scoping Sat Feb 15 19:09:43 1997 Robert Joop * configure.in and acconfig.h: check whether the compiler supports volatile functions (and whether abort() is volatile). In member functions, return *this after calling abort() for those stupid compilers (they would otherwise abort with an error). * tbl-tools/ and tbl-example/ directoies added. * compiler/core/snacc.c: do not silently ignore the -tcl option if not compiled for tcl code generation * compiler/core/snacc.c: use the TIME_WITH_SYS_TIME flag (checked and generated by configure) * c++-lib/src/asn-list.C: names of Tcl*-functions fixed (obviously they weren't needed :-) * c++-lib/inc/tcl-if.h, c++-lib/src/tcl-if.C: `typename' appears to be a reserved word in gcc 2.7, so prefix it with `_' * c++-lib/src/asn-bits.C: dereferencing pointer to member function is neither necessary nor allowed * c++-lib/src/asn-type.C: "virtual" removed from functions. (fix due to changed C++ language.) Thu Sep 7 20:21:39 1995 Robert Joop (rj@rainbow.in-berlin.de) * deep copying code added to C++ backend generated assignment operators. * c-lib/makefile and c++-lib/makefile: asn-useful.asn1 is compiled with the -l 50 option, as recommended by MS in the documentation. * compiler/back-ends/c++-gen/kwd.c: bool, true and false are reserved words in new C++ (supported by gcc since version 2.6). * new options -mA and -mC for snacc(1) that switch the names used between those defined in the ASN.1 files and those used in the generated C++ code. enum type MetaNameStyle introduced. * c++-lib/src/tcl-if.C: duplicate code merged into a new function SnaccTcl::gettypedesc(). * c++-lib/*: long int replaced by AsnIntType at a lot of places. It shall provide a 32 bit integer type on all platforms. new type introduced: AsnUIntType (32 bit unsigned integer type). Thu Aug 17 17:01:59 1995 Robert Joop (rj@rainbow.in-berlin.de) * c++-lib/*/asn-real.[hC]: recognize and return "±inf" for PLUS-INFINITY/MINUS-INFINITY * c++-lib/*/asn-enum.[hC]: AsnEnumTypeDesc gets its own TclGetVal and TclSetVal functions. * c++-lib/*/meta.[hC]: introduce an AsnEnumTypeDesc class with its own TclGetDesc2 function that returns the value names but omits the numeric values. * c++-lib/src/tcl-if.C &al.: set Tcl's errorCode variable * c++-lib/{inc,src}: snacced.[hC] renamed to tcl-if.[hC]. class SnaccEd renamed to SnaccTcl. * the PDU flag belongs to the metacode, not only to the tcl interface. (type and variable named adjusted) Thu Jul 27 10:27:07 1995 Robert Joop (rj@rainbow.in-berlin.de) * cpp macro TBL changed to TTBL since some type table code uses TBL as a type name. * c++-lib/makefile: make $(TCL-P) if necessary. * c++-lib/makefile: actions for stamp-useful rule: call diff only if both input files exist. * rfc1155-smi.asn1, rfc1157-snmp.asn1 and rfc1213-mib2.asn1 renamed from 1155-smi.asn1, 1157-snmp.asn1 and 1213-mib2.asn1 to accomodate to snacc's new file name generation scheme. Tue Jul 25 13:35:58 1995 Robert Joop (rj@rainbow.in-berlin.de) * policy.h: added switch for (en|dis)abling the compilation of the idl code generator. * compiler: PrintConditionalIncludeOpen() and PrintConditionalIncludeClose() moved from back-ends/c-gen/gen-code.[ch] to back-ends/cond.[ch]. * .../compiler/back-ends/c++-gen/gen-vals.c: use true/false instead of AsnBool::true/false. * the compiler is compiled from two files, tbl.h and tbl.c, it generates itself. for bootstrapping purposes, initial versions are supplied with the distribution. Mon Jul 24 14:26:16 1995 Robert Joop (rj@rainbow.in-berlin.de) * .../c++-lib: code extracted from AsnOcts::TclGetVal and AsnOcts::TclSetVal (src/asn-octs.C) into ::debinify and ::binify (src/meta.C). * Clone() added to AsnEnum. * various C++ files: ``#error "..."'' instead of ``#error ...'' * c++-lib/*/asn-list.?: operator == and != return bool instead of int. * .../maketail: the .C.o default rule now uses CXXFLAGS instead of CFLAGS for compilation. * .../c-lib and c++-lib call make recursively to generate the different depencies for all the different makefiles. * .../configure looks for tclsh(1)---the tcl-lib uses it to construct the tclIndex file. .../configure doesn't look for Tcl/Tk if the tclsh is absent. * .../configure looks for patch(1)---the c-lib uses it to patch tbl.h. * .../configure searches for tree-3.6's libtktree.a and sets TREELIBS in .../makehead accordingly. * type table tools and the example merged into the distribution: .../tbl-tools/ and .../tbl-example. * dummy action added to config.h.in and config.h rules to trick many makes' overoptimization. * snacc -h now prints the usage to stdout. * bug report address changed to protect an innocent's mailbox :-) * .../version.h contains the snacc version---it is included in the compiler source and is used by the .../makefile upon tar-file generation. * configure checks for memset(3), memcpy(3) and memcmp(3) and .../snac.h defines replacements using bzero(3), bcopy(3) and bcmp(3) if necessary. * .../compiler/core/mem.c: Realloc() now checks realloc(3)'s return value. * changed `_' to `-' in file names. * file names in .../compiler/back-ends/ have been shortened for redundant parts (e.g. c_gen/gen_c_code -> c_gen/gen_code or c++_gen/c++_kwd -> c++_gen/kwd). Sun Jul 23 12:51:24 1995 Robert Joop (rj@rainbow.in-berlin.de) * an additional type description, AsnAliasTypeDesc, for type definitions of the form ``TypeB ::= TypeA''. see the documentation for further details. * allow for more than one PDU per .asn1 file set: - each type description gets a bool flag, pdu. - each type description gets accompanied with a create function that returns a newly allocated object of its mirror type. the type description contains a pointer to this function. the getTclPDU() function is deleted. - compiler/core/meta.h: struct TclPDU becomes a linked list. it gets a flag `used' to detect invalid command line arguments. * additional function TclUnsetVal() to delete OPTIONAL members and SEQUENCE OF and SET OF list elements. *_getref() gets an additional optional argument, bool create=false, to faciliate the different member access semantics of TclGetVal() and TclSetVal(). * to accomodate to snacc's new file name generation scheme: - useful.asn1 renamed to asn-useful.asn1 - any-test.[hC] renamed to any.[hC] * by default, snacc now derives output file names from the .asn1 input file name instead of the module name. a global variable, `keepbaseG', is used to toggle between old and new behaviour. Sat Jul 22 22:49:25 1995 Robert Joop (rj@rainbow.in-berlin.de) * use install-sh instead of install.sh, to prevent `make' implicit rules from creating a file called install from it when there is no makefile. Mon Feb 20 12:38:00 1995 Robert Joop (rj@rainbow.in-berlin.de) * c{,++}_lib/makefile: remove stamp-useful before removing asn_useful.[hcC]. Sun Feb 19 19:13:50 1995 Robert Joop (rj@rainbow.in-berlin.de) * some c{,++}_examples/*/makefile: some make(1)s leave a trailing `/' on $(@D). since some mkdir(1)s deny their cooperation with such arguments, this slash has got to be stripped. Sat Feb 18 14:12:23 1995 Robert Joop (rj@rainbow.in-berlin.de) * in a lot of makefiles: dirname(1) and basename(1) do not exist on every system. so we're using $(@D) and $(@F) instead. * the code partially relied on big endianess. autoconf is used to (un)define WORDS_BIGENDIAN accordingly and the byte order dependent code parts have been fixed. * instead of relying on (sizeof (int) == 4), autoconf now checks some integer sizes and cpp is used to select appropiatly sized integer types. * c++_lib/{inc/asn_list.h,src/asn_list.C}: #pragma interface/implementation are GNU specific and need to be wrapped (by #ifdef __GNUG__). * configure.in, acconfig.h, misc .C files: added #define HAVE_VARIABLE_SIZED_AUTOMATIC_ARRAYS (we need to check for this since not every C++ compiler provides them.) * snacc.h: added #defines GLASS and KHO for wrapping and enabling of project and user specific code, resp. Fri Feb 17 15:27:31 1995 Robert Joop (rj@rainbow.in-berlin.de) * c_examples/simple/README: reflect the test script's integration into the makefile. * makehead.in, maketail: added a small hack to find gcc's hidden include directory to pass it to makedepend. this shall enable X11's makedepend to find .h files a little more the way gcc does. * configure.in, changes for autoconf 2.x Mon Feb 13 15:43:10 1995 Robert Joop (rj@rainbow.in-berlin.de) * miscelleanous makefiles: make depend builds snacc if and where necessary. * makefiles changed to augment CPPFLAGS instead of overriding them. * CFLAGS, CXXFLAGS and LDFLAGS moved from the various makefiles to makehead(.in). * settings for IEEE_REAL_FMT/IEEE_REAL_LIB moved from {c_lib,c++_lib}/inc/asn_config.h to acconfig.h. Mon Oct 10 01:59:50 1994 Robert Joop (rj@rainbow.in-berlin.de) * compiler/back_ends/c++_gen/gen_c++_code.c: the list functions Append(), Prepend(), InsertBefore() and InsertAfter() now set the current element to the element just inserted. Sat Oct 8 02:20:20 1994 Robert Joop (rj@rainbow.in-berlin.de) * since autoconf substitutes in config.h.bot as well, we can't use it. therefore it has been renamed to snacc.h and it includes the config.h (generated by autoconf/configure) and policy.h (edited by the person who wishes to compile/install/use snacc). * the compiler is generated with a file it generates itself. for bootstraping purposes, an initial version is supplied in the distribution (c_lib/boot/asn_useful.[hc]). * to complement the destructors, T::T (const T&) and T &T::operator = (const T &) have been added to override the defaults supplied by the compiler. reason: simple pointer duplication may lead to unreferenced objects and to objects referenced more than once (on which the destructors delete may choke). * three bugs in compiler/back_ends/c++_gen/gen_c++_code.c's list functions fixed (IBM ENC detected and fixed it at only place only). * at the same places as the below two points: code for a Tcl interface added. * c++_lib/*: meta code for the basic types added. (and a little glue code in compiler/core/snacc.c) * compiler/back_ends/c++_gen/gen_c++_code.c: code added that (on request) added meta information to the C++ classes generated. * compiler/back_ends/c++_gen/gen_c++_code.c: turned character pointers into constant character arrays. * several `unsigned long int' turned into `size_t' (C++ code only). Thu Oct 6 19:25:31 1994 Robert Joop (rj@rainbow.in-berlin.de) * c++_lib/*: virtual inline functions (the destructor and the Clone() function) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included. Wed Sep 28 12:17:50 1994 Robert Joop (rj@rainbow.in-berlin.de) * c++_lib/inc/asn_buf.h: fixed both Copy()'s name and implementation to CopyOut() that always returns the number of bytes copied out instead of 0 in case less than the requested amount is available. Sat Sep 17 20:07:29 1994 Robert Joop (rj@rainbow.in-berlin.de) * compiler/back_ends/c++_gen/gen_c++_code.c: reordered the functions to get rid of their annoying declarations. Wed Sep 14 00:59:36 1994 Robert Joop (rj@rainbow.in-berlin.de) * the constructors should initialize all pointers or else the destructor may delete bogus pointers. * c_lib/inc/asn_list.h: is unwise to #define unbalanced if()s! * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long. * made Print() const (and some other, mainly comparison functions). Thu Sep 1 01:11:17 1994 Robert Joop (rj@rainbow.in-berlin.de) * compiler/core/snacc_config.h dissolved into mem.h and snacc_util.h. * the empty statement in a for (...; ...; ...); has often been overseen; the equivalent for (...; ...; ...) ; has proven to be less error prone. * off-topic: cvs and rcs fixed to recognize .C and .asn1 as suffices for C++ and ASN.1 code, respectively. Wed Aug 31 00:03:22 1994 Robert Joop (rj@rainbow.in-berlin.de) * it is a good idea to have every .c file include its corresponding .h file were its functions are declared, because it's a very effictive way to let an ANSI compiler assert that every function is defined with the same number and types of arguments as it is declared with. proof: ParseValues() was declared different than defined (different return type and arguments reversed). * for reasons unknown, the compiler files included two of the various almost identical config.h files. * compiler/back_ends/c++_gen/gen_c++_code.c: turned the huge inline funtions into normal functions. (the change was actually made by IBM ENC, but wasn't properly marked.) due to their size, these inlines wouldn't get inlined anyway. due to their size they wouldn't offer any speed advantage (the function call overhead diminishes). instead, the compiler generated static functions in every .C file were the .h file is included! this inflates the .o files and executables real quick (i'm speaking of MBytes per executable). * integrating c{,++}_examples: .../simple: test csh-script integrated into makefile. Mon Aug 29 11:18:11 1994 Robert Joop (rj@rainbow.in-berlin.de) * the dependencies have been moved into a separate file that is not under cvs control. otherwise, the makefiles would inflate the repository unnecessarily. Sun Aug 28 11:18:23 1994 Robert Joop (rj@rainbow.in-berlin.de) * config.h defines TRUE/FALSE for C only. for C++, the built-in bool type accompanied by true/false is used. for C++ compilers that don't have bool built-in, an equivalent enum is defined. * merged .../tbl_{lib,include}/ with .../c_lib/. changes detected were: - asn_any.h present in c_lib only. - asn_bits.c ... - tbl_*/asn_len.[ch] has an additional function PeekEoc(). - tbl_include/asn_list.h has an additonal macro FOR_REST_LIST_ELMT_RVS() and three additional functions, GetAsnListElmtIndex(), AsnListFree() and GetAsnListElmt(). tbl_lib/asn_list.c defines only one additional function, GetAsnListElmt(). - asn_oid.h has the same extension as the compiler version. - asn_real.c: the tbl version at two places has exponent >>= 8; where the c_lib has exponent >> 8; since the latter is a statement without any effect, that's probably the buggy version... - tbl_*/asn_tag.[hc]: two additional macros, CONSIFY() and DECONSIFY(), and an additional function, PeekTag(). - asn_useful.c: the c_lib version contains two dozen used variables, so why not use the tbl version? - exp_buf.h ... - files only found in tbl_include: gen_buf.h, tbl{,_dec,_enc,_free,_gen_c_hdr,_incl,_print,_util}.h. - files only found in tbl_lib: gen_buf.c, tbl{,_dec,_enc,_free,_print,_util}.c. - sbuf.[hc]: tbl uses functions, c_lib defines cpp macros. * modified the makefiles to include depend, install, clean and clobber phony targets following the usual conventions. * INSTALL, mkinstalldirs and install.sh copied from autoconf-1.11. * 1.0-to-1.1-changes renamed to NEWS. README.changes that starts with a line reading ``Changes between 1.0 and 1.1'' merged into NEWS. * collected common code from compiler/core/snacc_config.h, c_lib/inc/asn_config.h and c++_lib/inc/asn_config.h into config.h.bot. * adding support for configuration via GNU autoconf: - writing a configure.in, acconfig.h, makehead.in. - replace a lot of macros in the makefiles with an inclusion of a makehead file generated by configure. since file inclusion has been a feature supported since UNIX System III, i consider it pretty portable. * first cvs import. * inserting RCS keywords as a preparation for cvs import. Sat Aug 27 11:59:08 1994 Robert Joop (rj@rainbow.in-berlin.de) * fixed the developer's nightmare that for every tiny change, virtually everything was remade. * -DFLEX ain't necessary since flex defines FLEX_SCANNER already. * renamed asn1.lex to lex-asn1.l and asn1.yacc to parse-asn1.y to take advantage of make's default rules. * collision of #define Free() in the compiler's mem.h and a member called Free in c_lib's struct AnyInfo in asn_any.h resolved. * changed the directory structure. the content of .../c_lib/ + .../c_include/ was almost identical to that of .../src/c_lib/, so i merged them. .../src/ isn't the only directory containing source, so i renamed it to compiler. to sum it up: old: new: .../src/back_ends .../compiler/back_ends .../src .../compiler/core .../src/c_lib -> merged with .../c_{lib,include} .../c_lib .../c_lib/src .../c_include .../c_lib/inc .../c++_lib .../c++_lib/src .../c++_include .../c++_lib/inc the differences found between .../src/c_lib/ and .../c_{lib,include}/: - Malloc()/Free() vs. NibbleAlloc() - snacc_config.h partially copied to asn_config.h - for the compiler, struct OID in asn_oid.h contains an additional member. - the functions AsnListConcat(), AsnListFree() and GetAsnListElmtIndex() existed in the compiler version only. the mixture of Asn1Alloc() in combination with Free() and free() has been unified to using Asn1Free(). yet another almost identical copy of c_lib/ can be found in .../tbl_{lib,include}/. * since the code was quite inconsistent in respect of where lines were broken (many short lines that unbroken are shorter than 72 columns were broken, and many long lines were broken into pieces that were much longer than 80 columns), i took the liberty to unify the layout. * some international rules of typography: - put a space before an opening parenthesis, and one after a closing one. - no space after an opening parenthesis, or before a closing one. - no space before punctuation. - one space after punctuation (in some countries two after a full stop). * a space somewhere between function name and first argument helps to see that there are actually two words, not just one. for me, AlongFunctionName(andanArgument, ...) looks too much like AlongFunctionNameCandanArgument, ...) and thus i prefer AlongFunctionName (andanArgument, ...) * moved `*' and `&' from the type to the value. that's where C and C++ bind them to! people are often mislead by this and generate bugs like char* p1, p2; instead of char *p1, *p2; which they really meant. blame K&R, not me :-) * removed trailing blank lines. they simply produce blank pages when the file is printed out. some files had got a dozen of them! * trailing white space removed. noted here because it might cause problems when someone wants to integrate patches; but vi users hate empty lines that aren't empty because of white space, since it keeps some movement commands from working. * one of IBM ENC's changes is the addition of C++ destructors. this change was clearly marked and therefore i removed the #defines. * i took the official snacc-1.1 distribution and made a diff(1) to another version modified by IBM ENC. this diff has been merged with the official version using `patch -D _IBM_ENC_`. esnacc-ng-1.8.1/compiler/000077500000000000000000000000001302010526100151575ustar00rootroot00000000000000esnacc-ng-1.8.1/compiler/.gitignore000066400000000000000000000001521302010526100171450ustar00rootroot00000000000000.dirstamp .libs .deps esnacc esnacc.1 esnacc.xml core/y.output core/y.tab.c core/y.tab.h core/lex-asn1.c esnacc-ng-1.8.1/compiler/automake.mk000066400000000000000000000063651302010526100173300ustar00rootroot00000000000000bin_PROGRAMS += compiler/esnacc compiler_esnacc_SOURCES = \ compiler/core/asn1module.h \ compiler/core/y.tab.y \ compiler/core/define.c \ compiler/core/define.h \ compiler/core/dependency.c \ compiler/core/do-macros.c \ compiler/core/enc-rules.c \ compiler/core/enc-rules.h \ compiler/core/err-chk.c \ compiler/core/exports.c \ compiler/core/exports.h \ compiler/core/gen-tbls.c \ compiler/core/lex-asn1.l \ compiler/core/lex-stuff.h \ compiler/core/lib-types.c \ compiler/core/lib-types.h \ compiler/core/link-types.c \ compiler/core/link-values.c \ compiler/core/meta.c \ compiler/core/meta.h \ compiler/core/normalize.c \ compiler/core/oid.c \ compiler/core/print.c \ compiler/core/print.h \ compiler/core/recursive.c \ compiler/core/snacc.c \ compiler/core/snacc-util.c \ compiler/core/snacc-util.h \ compiler/core/tbl.c \ compiler/core/tbl.h \ compiler/core/val-parser.c \ compiler/core/gfsi.c \ compiler/back-ends/cond.c \ compiler/back-ends/str-util.c \ compiler/back-ends/str-util.h \ compiler/back-ends/tag-util.c \ compiler/back-ends/tag-util.h \ compiler/back-ends/c-gen/gen-any.c \ compiler/back-ends/c-gen/gen-type.c \ compiler/back-ends/c-gen/gen-code.c \ compiler/back-ends/c-gen/gen-vals.c \ compiler/back-ends/c-gen/gen-dec.c \ compiler/back-ends/c-gen/kwd.c \ compiler/back-ends/c-gen/gen-enc.c \ compiler/back-ends/c-gen/rules.c \ compiler/back-ends/c-gen/rules.h \ compiler/back-ends/c-gen/gen-free.c \ compiler/back-ends/c-gen/type-info.c \ compiler/back-ends/c-gen/type-info.h \ compiler/back-ends/c-gen/gen-print.c \ compiler/back-ends/c-gen/util.c \ compiler/back-ends/c-gen/util.h \ compiler/back-ends/c++-gen/cxxconstraints.c \ compiler/back-ends/c++-gen/cxxconstraints.h \ compiler/back-ends/c++-gen/cxxmultipleconstraints.c \ compiler/back-ends/c++-gen/cxxmultipleconstraints.h \ compiler/back-ends/c++-gen/gen-any.c \ compiler/back-ends/c++-gen/gen-code.c \ compiler/back-ends/c++-gen/gen-vals.c \ compiler/back-ends/c++-gen/kwd.c \ compiler/back-ends/c++-gen/rules.c \ compiler/back-ends/c++-gen/rules.h \ compiler/back-ends/c++-gen/types.c \ compiler/back-ends/idl-gen/gen-any.c \ compiler/back-ends/idl-gen/rules.c \ compiler/back-ends/idl-gen/rules.h \ compiler/back-ends/idl-gen/gen-code.c \ compiler/back-ends/idl-gen/types.c \ compiler/back-ends/idl-gen/gen-vals.c \ policy.h \ version.h compiler/core/y.tab.c compiler/core/y.tab.h: compiler/core/y.tab.y $(YACC) -v -t -d -r all -o compiler/core/y.tab.c $(srcdir)/compiler/core/y.tab.y compiler/core/lex-asn1.c: compiler/core/lex-asn1.l compiler/core/y.tab.c compiler/core/y.tab.h $(LEX) -t $< | $(SED) -e 's@#include @@g' > $@ EXTRA_DIST += compiler/esnacc.xml.in if !WIN32 man_MANS += compiler/esnacc.1 DISTCLEANFILES += compiler/esnacc.1 endif compiler/esnacc.1: compiler/esnacc.xml $(XSLTPROC) --novalid -o $@ http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $< CLEANFILES += compiler/core/lex-asn1.c \ compiler/core/y.output \ compiler/core/y.tab.c \ compiler/core/y.tab.h \ compiler/esnacc.xml compiler_esnacc_CFLAGS = \ -I$(top_srcdir)/compiler/core \ -I$(top_srcdir)/c-lib/inc \ -I$(top_srcdir)/compiler/back-ends \ -I$(top_srcdir) \ -DCOMPILER compiler_esnacc_LDADD = \ c-lib/libcasn1.la esnacc-ng-1.8.1/compiler/back-ends/000077500000000000000000000000001302010526100170065ustar00rootroot00000000000000esnacc-ng-1.8.1/compiler/back-ends/c++-gen/000077500000000000000000000000001302010526100201255ustar00rootroot00000000000000esnacc-ng-1.8.1/compiler/back-ends/c++-gen/cxxconstraints.c000066400000000000000000000262121302010526100233660ustar00rootroot00000000000000/* JKG -- 7/31/03 -- */ /* ../SNACC/compiler/back-ends/c++-gen/cxxconstraints.c */ /* This file contains implementations of functions for */ /* checking constraints and converting .asn1 */ /* primitives (with constraints) into valid C++ code */ /* Their respective prototypes are in: */ /* 'cxxconstraints.h' in the pwd */ #include "cxxconstraints.h" #include /* Prints the default instantiation for a typedefined object */ void PrintTypeDefDefault PARAMS((hdr, src, td), FILE* hdr _AND_ FILE* src _AND_ TypeDef* td) { src=src; fprintf (hdr, "typedef %s %s;\n\n", td->type->cxxTypeRefInfo->className, td->cxxTypeDefInfo->className); } void PrintCxxSetOfSizeConstraint(FILE* hdr, SubtypeValue* sizeConstraint, Module* m, Type* type) { long lBound = 0; long uBound = 0; int ubExists = 0; Value* pValue; switch (sizeConstraint->choiceId) { case SUBTYPEVALUE_SINGLEVALUE: pValue = GetValue(sizeConstraint->a.singleValue); if (pValue->basicValue->choiceId == BASICTYPE_INTEGER) lBound = pValue->basicValue->a.integer; else { PrintErrLoc(m->asn1SrcFileName, (long)type->lineNo); fprintf(errFileG, "ERROR - unsupported value in size constraint\n"); return; } break; case SUBTYPEVALUE_VALUERANGE: // Get the lower end value pValue = GetValue(sizeConstraint->a.valueRange->lowerEndValue->endValue); if (pValue->basicValue->choiceId == BASICTYPE_INTEGER) { lBound = pValue->basicValue->a.integer; if (!sizeConstraint->a.valueRange->lowerEndValue->valueInclusive) ++lBound; } else { PrintErrLoc(m->asn1SrcFileName, (long)type->lineNo); fprintf(errFileG, "ERROR - unsupported value in size constraint\n"); return; } // Get the upper end value pValue = GetValue(sizeConstraint->a.valueRange->upperEndValue->endValue); if (pValue->basicValue->choiceId == BASICTYPE_INTEGER) { uBound = pValue->basicValue->a.integer; if (!sizeConstraint->a.valueRange->upperEndValue->valueInclusive) --uBound; ubExists = 1; } else if ((pValue->basicValue->choiceId == BASICVALUE_SPECIALINTEGER) && (pValue->basicValue->a.specialInteger == MAX_INT)) { uBound = 0; ubExists = 2; } else { PrintErrLoc(m->asn1SrcFileName, (long)type->lineNo); fprintf(errFileG, "ERROR - unsupported value in size constraint\n"); return; } break; default: PrintErrLoc(m->asn1SrcFileName, (long)type->lineNo); fprintf(errFileG, "ERROR - unsupported size constraint\n"); return; } // Check that the size constraint is valid if ((lBound < 0) || ((ubExists == 1) && (lBound > uBound))) { PrintErrLoc(m->asn1SrcFileName, (long)type->lineNo); fprintf(errFileG, "ERROR - invalid size constraint\n"); return; } // Print the size constraints fprintf(hdr, "\tSizeConstraint* SizeConstraints() const {\n"); fprintf(hdr, "\t\tstatic SizeConstraint s = { %ld, %ld, %d }; return &s; }\n", lBound, uBound, ubExists); } /* Function generates the checkconstraints function for */ /* a setOf or seqOf with size constraints set */ void PrintCxxSetOfSizeValRangeConstraints PARAMS((hdr, src, td), FILE* hdr _AND_ FILE* src _AND_ TypeDef* td) { Subtype* s_type; long lboundLower = 0; long lboundUpper = 0; int ubExists = 2; hdr=hdr; src=src; td=td; s_type = (Subtype*)td->type->subtypes->a.single->a.sizeConstraint->a.or->last->data; if(s_type->a.single->a.valueRange->lowerEndValue->endValue->basicValue->choiceId == BASICTYPE_INTEGER) { if(s_type->a.single->a.valueRange->lowerEndValue->valueInclusive) { lboundLower = s_type->a.single->a.valueRange->lowerEndValue->endValue->basicValue->a.integer; } else { lboundLower = s_type->a.single->a.valueRange->lowerEndValue->endValue->basicValue->a.integer+1; } if(s_type->a.single->a.valueRange->upperEndValue->endValue->basicValue->choiceId == BASICTYPE_INTEGER) { if(s_type->a.single->a.valueRange->upperEndValue->valueInclusive) { lboundUpper = s_type->a.single->a.valueRange->upperEndValue->endValue->basicValue->a.integer; ubExists = 1; } else { lboundUpper = s_type->a.single->a.valueRange->upperEndValue->endValue->basicValue->a.integer-1; ubExists = 1; } } } if(lboundUpper > 65536) { ubExists = 2; } if(ubExists == 2) { lboundUpper = 0; } if(lboundLower >= 0 && ((lboundUpper >= 0 && (lboundUpper >= lboundLower)) || ubExists == 2)) { fprintf (hdr, " SizeConstraint* SizeConstraints()const{\n"); fprintf (hdr, " static SizeConstraint s = {%ld, %ld, %d}; SizeConstraint * ps = &s; return ps;}\n", lboundLower, lboundUpper, ubExists); //fprintf (hdr, " SizeConstraint* SizeConstraints(){\n"); //fprintf (hdr, " static SizeConstraint s = {%d, %d, %d}; SizeConstraint * ps = &s; return ps;}\n", lboundLower, lboundUpper, ubExists); /* fprintf (hdr, " AsnLen PEnc(AsnBufBits &b)const;\n"); fprintf (src, "AsnLen %s::PEnc(AsnBufBits &b)const\n", td->definedName); fprintf (src, "{\n"); fprintf (src, " AsnLen len = 0;\n"); fprintf (src, " return len;\n}\n"); fprintf (hdr, " void PDec(AsnBufBits &b, AsnLen &bitsDecoded);\n"); fprintf (src, "void %s::PDec(AsnBufBits &b, AsnLen &bitsDecoded)\n", td->definedName); fprintf (src, "{\n"); fprintf (src, "}\n"); */ /* fprintf(hdr, " virtual int checkConstraints(ConstraintFailList* pConstraintFails)const;\n"); fprintf(src, "int %s::checkConstraints(ConstraintFailList* pConstraintFails)const\n{\n", td->cxxTypeDefInfo->className); fprintf (src, " std::string * pTmpError;\n"); if(ubExists == 1) { fprintf (src, " char* ptr = checkSOfValRange(%d, %d);\n\n", lboundLower, lboundUpper); } else { fprintf (src, " char* ptr = checkSOfValRange(%d, 65535/\*TBD-fix check to check for unconstrainted UB*//*);\n\n", lboundLower);*/ /* } fprintf (src, " if(ptr)\n {\n"); fprintf (src, " if(pConstraintFails!=NULL)\n {\n"); fprintf (src, " pTmpError=pConstraintFails->Append();\n"); fprintf (src, " *pTmpError += ptr;\n"); fprintf (src, " *pTmpError += \"In function call: %s::checkConstraints(...)\\n\";\n", td->cxxTypeDefInfo->className); fprintf (src, " }\n"); fprintf (src, " }\n else\n {\n"); fprintf (src, " return checkListConstraints(pConstraintFails);\n"); fprintf (src, " }\n\n"); fprintf (src, " return checkListConstraints(pConstraintFails);\n"); fprintf(src, "\n}\n"); } else { fprintf(hdr, " int checkConstraints(ConstraintFailList* pConstraintFails)const;\n"); fprintf(src, "int %s::checkConstraints(ConstraintFailList* pConstraintFails)const\n{\n", td->cxxTypeDefInfo->className); fprintf(src, " return checkListConstraints(pConstraintFails);\n"); fprintf(src, "}\n\n"); */ } } void PrintCxxSetOfSizeSingleValConstraints PARAMS((hdr, src, td), FILE* hdr _AND_ FILE* src _AND_ TypeDef* td) { Subtype* s_type; long lbound = 0; hdr=hdr; src=src; td=td; s_type = (Subtype*)td->type->subtypes->a.single->a.sizeConstraint->a.or->last->data; if(s_type->a.single->a.singleValue->basicValue->choiceId == BASICTYPE_INTEGER) { lbound = s_type->a.single->a.singleValue->basicValue->a.integer; } if(lbound >= 0) { fprintf (hdr, " SizeConstraint* SizeConstraints()const{\n"); fprintf (hdr, " SizeConstraint s = {%ld, 0, 0}; SizeConstraint * ps = &s; return ps;}\n", lbound); fprintf (hdr, " SizeConstraint* SizeConstraints(){\n"); fprintf (hdr, " SizeConstraint s = {%ld, 0, 0}; SizeConstraint * ps = &s; return ps;}\n", lbound); /* fprintf (hdr, " AsnLen PEnc(AsnBufBits &b)const;\n"); fprintf (src, "AsnLen %s::PEnc(AsnBufBits &b)const\n", td->definedName); fprintf (src, "{\n"); fprintf (src, " FUNC(\"%s::PEnc\");\n", td->definedName); fprintf (src, " AsnLen len = 0;\n"); fprintf (src, " typename AsnList::ListElmt *currElmt;\n"); fprintf (src, " long lbound = %d;\n\n", lbound); fprintf (src, " if(Count() == lbound)\n"); fprintf (src, " {\n"); fprintf (src, " for (currElmt = first; currElmt != NULL; currElmt = currElmt->next)\n"); fprintf (src, " len += currElmt->elmt->PEnc (b);\n"); fprintf (src, " }\n"); fprintf (src, " else\n"); fprintf (src, " {\n"); fprintf (src, " throw (\"%s count does not match singlevalue constraint bound\");\n", td->definedName); fprintf (src, " }\n"); fprintf (src, " return len;\n}\n"); fprintf (hdr, " void PDec(AsnBufBits &b, AsnLen &bitsDecoded);\n"); fprintf (src, "void %s::PDec(AsnBufBits &b, AsnLen &bitsDecoded)\n", td->definedName); fprintf (src, "{\n"); fprintf (src, " T *listElmt;\n"); fprintf (src, " long lbound = %d;\n", lbound); fprintf (src, " while(lbound)\n"); fprintf (src, " {\n"); fprintf (src, " listElmt = Append();\n"); fprintf (src, " listElmt->PDec(b, bitsDecoded);\n"); fprintf (src, " lbound--;\n"); fprintf (src, " }\n"); fprintf (src, "}\n"); */ /* fprintf(hdr, " virtual int checkConstraints(ConstraintFailList* pConstraintFails)const;\n"); fprintf(src, "int %s::checkConstraints(ConstraintFailList*pConstraintFails)const\n{\n", td->cxxTypeDefInfo->className); fprintf (src, " std::string * pTmpError;\n"); fprintf (src, " char* ptr = checkSOfSingleVal(%d);\n\n", lbound); fprintf (src, " if(ptr)\n {\n"); fprintf (src, " if(pConstraintFails!=NULL)\n {\n"); fprintf (src, " pTmpError=pConstraintFails->Append();\n"); fprintf (src, " *pTmpError += ptr;\n"); fprintf (src, " *pTmpError += \"In function call: %s::checkConstraints(...)\\n\";\n", td->cxxTypeDefInfo->className); fprintf (src, " }\n"); fprintf (src, " }\n else\n {\n"); fprintf (src, " return checkListConstraints(pConstraintFails);\n"); fprintf (src, " }\n\n"); fprintf (src, " return checkListConstraints(pConstraintFails);\n"); fprintf(src, "\n}\n"); */ } else { /* fprintf(hdr, " int checkConstraints(ConstraintFailList* pConstraintFails)const;\n"); fprintf(src, "int %s::checkConstraints(ConstraintFailList* pConstraintFails)const\n{\n", td->cxxTypeDefInfo->className); fprintf(src, " return checkListConstraints(pConstraintFails);\n"); fprintf(src, "}\n\n"); */ } } esnacc-ng-1.8.1/compiler/back-ends/c++-gen/cxxconstraints.h000066400000000000000000000016621302010526100233750ustar00rootroot00000000000000/* JKG -- 7/31/03 -- */ /* ../SNACC/compiler/back-ends/c++-gen/cxxconstraints.h */ /* This file contains prototypes of functions for */ /* checking constraints and converting .asn1 */ /* primitives (with constraints) into valid C++ code */ /* Their respective implementations are in: */ /* 'cxxconstraints.c' in the pwd */ #ifndef _CXXCONSTRAINTS_H_ #define _CXXCONSTRAINTS_H_ #include "asn-incl.h" #include "asn1module.h" #include "snacc.h" #include "limits.h" #include "rules.h" #include "snacc-util.h" //void PrintCxxSetOfSizeValRangeConstraints PROTO((FILE* hdr, FILE* src, TypeDef* td)); //void PrintCxxSetOfSizeSingleValConstraints PROTO((FILE* hdr, FILE* src, TypeDef* td)); void PrintTypeDefDefault PROTO((FILE* hdr, FILE* src, TypeDef* td)); void PrintCxxSetOfSizeConstraint(FILE* hdr, SubtypeValue* sizeConstraint, Module* m, Type* type); #endif esnacc-ng-1.8.1/compiler/back-ends/c++-gen/cxxmultipleconstraints.c000066400000000000000000001103431302010526100251410ustar00rootroot00000000000000#include "cxxmultipleconstraints.h" #include #include #include extern char *bVDAGlobalDLLExport; /*finds all of the alphabets in the subtype constraints */ char* FindPermittedAlpha PARAMS((curr, cPermittedAlphabet, iAlphasize), AsnListNode* curr _AND_ unsigned char* cPermittedAlphabet _AND_ int *iAlphasize) { Subtype* currS_type=NULL; Subtype* fakeList = NULL; while(curr) { currS_type=curr->data; if(currS_type->choiceId==SUBTYPE_SINGLE && currS_type->a.single->choiceId==SUBTYPEVALUE_PERMITTEDALPHABET) { AsnListNode* currAlpha; if(currS_type->choiceId == SUBTYPE_OR) { currAlpha=currS_type->a.single->a.permittedAlphabet->a.or->first; PrintCxxPermittedAlphabetHandler(currAlpha, cPermittedAlphabet, iAlphasize); } else if(currS_type->choiceId == SUBTYPE_SINGLE) { fakeList = MT(Subtype); fakeList->choiceId = SUBTYPE_OR; APPEND(currS_type->a.single->a.permittedAlphabet, fakeList->a.or); currAlpha = fakeList->a.or->first; PrintCxxPermittedAlphabetHandler(currAlpha, cPermittedAlphabet, iAlphasize); } } curr=curr->next; } return (char*)cPermittedAlphabet; } /*Prints the declarations for constraint variables in the header file*/ int BasicTypeString_LISTS PARAMS((hdr, src, scList, iSCPresent, curr, currS_type), FILE* hdr _AND_ FILE* src _AND_ SizeConstraint *scList _AND_ int iSCPresent _AND_ AsnListNode* curr _AND_ Subtype* currS_type) { AsnListNode* pTmpnode; Subtype* fakeList = NULL; /*while there are nodes in the subtype list*/ while(curr) { /*point to the current subtype*/ currS_type=curr->data; if(currS_type->choiceId==SUBTYPE_SINGLE) { switch(currS_type->a.single->choiceId) { case SUBTYPEVALUE_VALUERANGE: { break; }/*case SUBTYPEVALUE_VALUERANGE*/ case SUBTYPEVALUE_SINGLEVALUE: { break; }/*case SUBTYPEVALUE_SINGLEVALUE*/ case SUBTYPEVALUE_SIZECONSTRAINT: { if(currS_type->choiceId == SUBTYPE_OR) { pTmpnode=currS_type->a.single->a.sizeConstraint->a.or->first; iSCPresent += SizeConstraint_LISTS(hdr, src, scList, iSCPresent, pTmpnode, currS_type); } else if(currS_type->choiceId == SUBTYPE_SINGLE) { fakeList = MT(Subtype); fakeList->choiceId = SUBTYPE_OR; APPEND(currS_type->a.single->a.sizeConstraint, fakeList->a.or); pTmpnode = fakeList->a.or->first; iSCPresent += SizeConstraint_LISTS(hdr, src, scList, iSCPresent, pTmpnode, currS_type); } break; }/*case SUBTYPEVALUE_SIZECONSTRAINT*/ default: { break; }/*default*/ }/*switch(curr......SINGLE)*/ }/*if(curr......SINGLE)*/ curr=curr->next; }/*while(curr)*/ src=src; /*avoids warning for unused parameter*/ return iSCPresent; }/*int BasicTypeString_LISTS*/ /*Finds all of the valueranges and single values in the subtype constraints*/ int ValueRange_LISTS PARAMS((hdr, src, vrList, iVRPresent, curr, currS_type), FILE* hdr _AND_ FILE* src _AND_ ValueRange* vrList _AND_ int iVRPresent _AND_ AsnListNode* curr _AND_ Subtype* currS_type) { int found = 0; vrList = vrList; //int j = 0; hdr = hdr; /*while there are still subtyes found in the list*/ while(curr) { /*point to the current subtype*/ currS_type=curr->data; if(currS_type->choiceId==SUBTYPE_SINGLE) { switch(currS_type->a.single->choiceId) { case SUBTYPEVALUE_VALUERANGE: { if(iVRPresent < 15 && currS_type->a.single->a.valueRange->lowerEndValue->endValue->basicValue->choiceId==BASICVALUE_INTEGER) { found += 1; if(currS_type->a.single->a.valueRange->lowerEndValue->valueInclusive) { vrList[iVRPresent].lowerBound = currS_type->a.single->a.valueRange->lowerEndValue->endValue->basicValue->a.integer; } else { vrList[iVRPresent].lowerBound = currS_type->a.single->a.valueRange->lowerEndValue->endValue->basicValue->a.integer + 1; } if(currS_type->a.single->a.valueRange->upperEndValue->endValue->basicValue->choiceId==BASICVALUE_INTEGER) { if(currS_type->a.single->a.valueRange->upperEndValue->valueInclusive) { vrList[iVRPresent].upperBound = currS_type->a.single->a.valueRange->upperEndValue->endValue->basicValue->a.integer; } else { vrList[iVRPresent].upperBound = currS_type->a.single->a.valueRange->upperEndValue->endValue->basicValue->a.integer + 1; } vrList[iVRPresent].upperBoundExists = 1; } else { vrList[iVRPresent].upperBound = 0; vrList[iVRPresent].upperBoundExists = 0; } iVRPresent++; } break; }/*case SUBTYPE_VALUERANGE*/ case SUBTYPEVALUE_SINGLEVALUE: { if(iVRPresent < 15 && currS_type->a.single->a.singleValue->basicValue->choiceId == BASICVALUE_INTEGER) { found += 1; vrList[iVRPresent].lowerBound = currS_type->a.single->a.singleValue->basicValue->a.integer; vrList[iVRPresent].upperBound = 0; vrList[iVRPresent].upperBoundExists = 2; iVRPresent ++; } break; }/*case SUBTYPE_SINGLEVALUE*/ case SUBTYPEVALUE_CONTAINED: default: { break; }/*default*/ }/*switch(curr......SINGLE)*/ }/*if(curr.......SINGLE)*/ curr=curr->next; }/*while(curr)*/ src=src;/*avoids warning on unused parameter*/ return found; }/*int BasicTypeInt_LISTS*/ /*assembles all permitted alphabets into one larger inclusive alphabet*/ char* PrintCxxPermittedAlphabetHandler PARAMS((currAlpha, cPermittedAlphabet, iAlphaSize), AsnListNode* currAlpha _AND_ unsigned char* cPermittedAlphabet _AND_ int *iAlphasize) { Subtype* currS_type; int found = 0; int x = 0; /************************************/ /* To avoid warning */ currAlpha=currAlpha; /* Reference all Parameters */ /************************************/ /*while there are alphabets found*/ while(currAlpha) { currS_type=currAlpha->data; if(currS_type->choiceId==SUBTYPE_SINGLE && currS_type->a.single->choiceId==SUBTYPEVALUE_SINGLEVALUE) { /*concatenate the alphabets together*/ char* temp = currS_type->a.single->a.singleValue->basicValue->a.asciiText->octs; int tempSize = strlen(temp); while(tempSize) { found = 0; for(x = 0; x < *iAlphasize; x++) { if(cPermittedAlphabet[x] == temp[tempSize - 1]) found = 1; } if(found == 0) { cPermittedAlphabet[*iAlphasize] = temp[tempSize - 1]; *iAlphasize += 1; } tempSize--; } }/*if(curr.......SINGLEVALUE)*/ if(currS_type->choiceId==SUBTYPE_SINGLE && currS_type->a.single->choiceId==SUBTYPEVALUE_VALUERANGE) { char* temp; unsigned char lower; unsigned char upper; unsigned char c_alpha; /*concatenate the alphabets together*/ temp=currS_type->a.single->a.valueRange->lowerEndValue->endValue->basicValue->a.asciiText->octs; lower=temp[0]; temp=currS_type->a.single->a.valueRange->upperEndValue->endValue->basicValue->a.asciiText->octs; upper=temp[0]; for( ; lower<=upper; lower++) { found = 0; c_alpha = lower; for(x = 0; x < *iAlphasize; x++) { if(cPermittedAlphabet[x] == c_alpha) found = 1; } if(found == 0) { cPermittedAlphabet[*iAlphasize] = c_alpha; *iAlphasize += 1; } } }/*if(curr.......VALUERANGE)*/ currAlpha=currAlpha->next; }/*while(currAlpha)*/ return (char*)cPermittedAlphabet; }/*char* PrintCxxPermittedAlphabetHandler*/ /*Handles Size Constraints*/ int SizeConstraint_LISTS PARAMS((hdr, src, scList, iSCPresent, curr, currS_type), FILE* hdr _AND_ FILE* src _AND_ SizeConstraint* scList _AND_ int iSCPresent _AND_ AsnListNode* curr _AND_ Subtype* currS_type) { int found = 0; scList = scList; //int j = 0; hdr = hdr; /*while there are still subtyes found in the list*/ while(curr) { /*point to the current subtype*/ currS_type=curr->data; if(currS_type->choiceId==SUBTYPE_SINGLE) { switch(currS_type->a.single->choiceId) { case SUBTYPEVALUE_VALUERANGE: { found += 1; if((currS_type->a.single->a.valueRange->upperEndValue->endValue->basicValue->choiceId==BASICVALUE_INTEGER && currS_type->a.single->a.valueRange->upperEndValue->endValue->basicValue->a.integer <= 65536) || currS_type->a.single->a.valueRange->upperEndValue->endValue->basicValue->choiceId==BASICVALUE_LOCALVALUEREF) { if(iSCPresent < 15 && currS_type->a.single->a.valueRange->lowerEndValue->endValue->basicValue->choiceId==BASICVALUE_INTEGER) { if(currS_type->a.single->a.valueRange->lowerEndValue->valueInclusive) { scList[iSCPresent].lowerBound = currS_type->a.single->a.valueRange->lowerEndValue->endValue->basicValue->a.integer; } else { scList[iSCPresent].lowerBound = currS_type->a.single->a.valueRange->lowerEndValue->endValue->basicValue->a.integer + 1; } } else if(currS_type->a.single->a.valueRange->lowerEndValue->endValue->basicValue->choiceId == BASICVALUE_LOCALVALUEREF) { scList[iSCPresent].lowerBound = currS_type->a.single->a.valueRange->lowerEndValue->endValue->basicValue->a.localValueRef->link->value->basicValue->a.integer; } if(currS_type->a.single->a.valueRange->upperEndValue->endValue->basicValue->choiceId==BASICVALUE_INTEGER) { if(currS_type->a.single->a.valueRange->upperEndValue->valueInclusive) { scList[iSCPresent].upperBound = currS_type->a.single->a.valueRange->upperEndValue->endValue->basicValue->a.integer; } else { scList[iSCPresent].upperBound = currS_type->a.single->a.valueRange->upperEndValue->endValue->basicValue->a.integer + 1; } } else if(currS_type->a.single->a.valueRange->upperEndValue->endValue->basicValue->choiceId == BASICVALUE_LOCALVALUEREF) { if(currS_type->a.single->a.valueRange->upperEndValue->valueInclusive) { scList[iSCPresent].upperBound = currS_type->a.single->a.valueRange->upperEndValue->endValue->basicValue->a.localValueRef->link->value->basicValue->a.integer; } else { scList[iSCPresent].upperBound = currS_type->a.single->a.valueRange->upperEndValue->endValue->basicValue->a.localValueRef->link->value->basicValue->a.integer + 1; } } scList[iSCPresent].upperBoundExists = 1; iSCPresent++; } else { scList[iSCPresent].upperBoundExists = 2; iSCPresent++; } break; }/*case SUBTYPE_VALUERANGE*/ case SUBTYPEVALUE_SINGLEVALUE: { found += 1; if(iSCPresent < 15 && currS_type->a.single->a.singleValue->basicValue->choiceId == BASICVALUE_INTEGER) { scList[iSCPresent].lowerBound = currS_type->a.single->a.singleValue->basicValue->a.integer; scList[iSCPresent].upperBound = 0; scList[iSCPresent].upperBoundExists = 0; iSCPresent++; } else if(currS_type->a.single->a.singleValue->basicValue->choiceId == BASICVALUE_LOCALVALUEREF) { scList[iSCPresent].lowerBound = currS_type->a.single->a.singleValue->basicValue->a.localValueRef->link->value->basicValue->a.integer; scList[iSCPresent].upperBound = 0; scList[iSCPresent].upperBoundExists = 0; scList[iSCPresent].upperBoundExists = 0; iSCPresent++; } break; }/*case SUBTYPE_SINGLEVALUE*/ case SUBTYPEVALUE_CONTAINED: default: { break; }/*default*/ }/*switch(curr......SINGLE)*/ }/*if(curr.......SINGLE)*/ curr=curr->next; }/*while(curr)*/ src=src;/*avoids warning on unused parameter*/ return found; }/*int BasicTypeInt_LISTS*/ /*Handles constraints found in the subtypes of primitives*/ int PrintCxxMultiConstraintOrHandler PARAMS((hdr, src, definedName, e, i), FILE* hdr _AND_ FILE* src _AND_ char* definedName _AND_ NamedType* e _AND_ int i) { int returnvalue=0; char *pszGlobalExport=""; char *className; char *tmpClassName; className = strdup(e->type->cxxTypeRefInfo->fieldName); className[0] = (char)toupper(className[0]); if(!strcmp(className, e->type->cxxTypeRefInfo->className)) { tmpClassName = strdup(className); free(className); className = malloc(strlen(tmpClassName) + 3); strcpy(className, tmpClassName); strcat(className, "_\0"); free(tmpClassName); } else if(i == 1 || i == 3) { if(!strcmp(className, definedName) ) { tmpClassName = strdup(className); free(className); className = malloc(strlen(tmpClassName) + 3); strcpy(className, tmpClassName); strcat(className, "_\0"); free(tmpClassName); } } className = Asn1TypeName2CTypeName(className); e->type->cxxTypeRefInfo->fieldName = Asn1TypeName2CTypeName(e->type->cxxTypeRefInfo->fieldName); e->type->cxxTypeRefInfo->className = Asn1TypeName2CTypeName(e->type->cxxTypeRefInfo->className); if (bVDAGlobalDLLExport) pszGlobalExport = bVDAGlobalDLLExport; switch(e->type->basicType->choiceId) { case BASICTYPE_INTEGER: { Subtype* s_type; Subtype* currS_type=NULL; Subtype* andS_type=NULL; Subtype* fakeList=NULL; AsnListNode* curr; AsnListNode* and_curr; int iVRPresent = 0; int count = 0; ValueRange vrList[15]; s_type = e->type->subtypes; if(s_type->choiceId==SUBTYPE_AND) { and_curr=s_type->a.and->first; while(and_curr) { andS_type=and_curr->data; if(andS_type->choiceId == SUBTYPE_OR) { curr=andS_type->a.or->first; iVRPresent += ValueRange_LISTS(hdr, src, vrList, iVRPresent, curr, currS_type); } else if(andS_type->choiceId == SUBTYPE_SINGLE) { fakeList = MT(Subtype); fakeList->choiceId = SUBTYPE_OR; APPEND(andS_type, fakeList->a.or); curr = fakeList->a.or->first; iVRPresent += ValueRange_LISTS(hdr, src, vrList, iVRPresent, curr, currS_type); } and_curr=and_curr->next; } } else if(s_type->choiceId == SUBTYPE_OR) { curr=s_type->a.or->first; iVRPresent += ValueRange_LISTS(hdr, src, vrList, iVRPresent, curr, currS_type); } else if(s_type->choiceId == SUBTYPE_SINGLE) { fakeList = MT(Subtype); fakeList->choiceId = SUBTYPE_OR; APPEND(s_type, fakeList->a.or); curr = fakeList->a.or->first; iVRPresent += ValueRange_LISTS(hdr, src, vrList, iVRPresent, curr, currS_type); } /*print the generic header for the generated class*/ fprintf (hdr, "class %s %s: public AsnInt {\n", pszGlobalExport, className); fprintf (hdr, " public:\n"); fprintf (hdr, " %s(AsnIntType val=0):AsnInt(val){ }\n", className); fprintf (hdr, " %s(const char *str, bool unsignedFlag = true):AsnInt(str, unsignedFlag){ }\n", className); fprintf (hdr, " %s(const AsnOcts &o, bool unsignedFlag = true):AsnInt(o, unsignedFlag){ }\n", className); fprintf (hdr, " %s(const char *str, const size_t len, bool unsignedFlag = true):AsnInt(str, len, unsignedFlag){ }\n", className); fprintf (hdr, " %s(const %s &that):AsnInt(that){ }\n\n", className, className); fprintf(hdr, " %s & operator =(const %s &o);\n", className, className); if(i == 1 || i == 3) { fprintf(src, "%s::", definedName); } fprintf(src, "%s & \n", className); if(i == 1 || i == 3) { fprintf(src, "%s::", definedName); } fprintf(src, "%s::operator =(const %s &that)\n", className, className); fprintf(src, "{\n"); fprintf(src, " m_len = that.m_len;\n"); fprintf(src, " delete[] m_bytes;\n"); fprintf(src, " m_bytes = new unsigned char[m_len];\n"); fprintf(src, " memcpy(m_bytes, that.m_bytes, m_len);\n"); fprintf(src, " return *this;\n}\n\n"); fprintf (hdr, " const ValueRange* ValueRanges(int &sizeVRList) const;\n\n"); fprintf (src, "const ValueRange* \n"); if(i == 1 || i == 3) { fprintf(src, "%s::", definedName); } fprintf(src, "%s::ValueRanges(int &sizeVRList) const\n", className); fprintf (src, "{\n"); if(iVRPresent > 0) { fprintf(src, " static const ValueRange %s_ValueRangeList[] = \n {", e->type->cxxTypeRefInfo->fieldName); for(count = 0; count < iVRPresent; count++) { fprintf(src, "{ %ld, %ld, %d }", vrList[count].lowerBound, vrList[count].upperBound, vrList[count].upperBoundExists); if(count + 1 < iVRPresent) { fprintf(src, ",\n "); } } fprintf(src, "};\n\n"); fprintf(src, " sizeVRList = %d;\n", iVRPresent); fprintf(src, " return &%s_ValueRangeList[0];\n", e->type->cxxTypeRefInfo->fieldName); } else { fprintf(src, " sizeVRList = 0;\n"); fprintf(src, " return NULL;\n"); } fprintf (src, "}\n\n"); /* fprintf(hdr, " AsnLen PEnc (AsnBufBits &_b, bool bAlign = false){return PEncConstraints(_b, bAlign);}\n"); fprintf(hdr, " void PDec (AsnBufBits &_b, AsnLen &bitsDecoded, bool bAlign = false){PDecConstraints(_b, bitsDecoded, bAlign);}\n"); */ fprintf (hdr, " };\n"); if(i != 3 && i != 0) { /* Last we declare an instance of the internal class we */ /* just created */ if(i==0) { fprintf (hdr, "typedef "); }/*if(i==0)*/ fprintf (hdr, " %s ", className); if (e->type->cxxTypeRefInfo->isPtr) { fprintf (hdr, "*"); }/*if (e->type->cxxTypeRefInfo->isPtr)*/ fprintf (hdr, "%s;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (hdr, "\n\n"); } free(e->type->cxxTypeRefInfo->className); e->type->cxxTypeRefInfo->className = strdup(className); returnvalue=1; break; }/*case BASICTYPE_INTEGER*/ case BASICTYPE_NUMERIC_STR: case BASICTYPE_PRINTABLE_STR: case BASICTYPE_IA5_STR: case BASICTYPE_VISIBLE_STR: { int bAlphafound=0; unsigned char cPermittedAlphabet[500]; char cAlpha[1000]; int iAlphasize = 0; int iSort1 = 0; int iSort2 = 0; unsigned char cSort = 0x00; int j = 0; Subtype* s_type; Subtype* currS_type=NULL; Subtype* andS_type=NULL; Subtype* fakeList = NULL; AsnListNode* curr; AsnListNode* and_curr; char* cTmp; int iSCPresent = 0; int count = 0; int iSCLowerBound = 0; int iSCUpperBound = 0; SizeConstraint scList[15]; /*print the generic header for the generated class*/ fprintf (hdr, "class %s %s: public %s {\n", pszGlobalExport, className, e->type->cxxTypeRefInfo->className); s_type = e->type->subtypes; iSort2 = iSort2; if(s_type->choiceId==SUBTYPE_AND) { and_curr=s_type->a.and->first; while(and_curr) { andS_type=and_curr->data; if(andS_type->choiceId == SUBTYPE_OR) { curr=andS_type->a.or->first; cTmp=FindPermittedAlpha(curr, cPermittedAlphabet, &iAlphasize); } else if(andS_type->choiceId == SUBTYPE_SINGLE) { fakeList = MT(Subtype); fakeList->choiceId = SUBTYPE_OR; APPEND(andS_type, fakeList->a.or); curr = fakeList->a.or->first; cTmp=FindPermittedAlpha(curr, cPermittedAlphabet, &iAlphasize); } and_curr=and_curr->next; } } else if(s_type->choiceId == SUBTYPE_OR) { curr=s_type->a.or->first; cTmp=FindPermittedAlpha(curr, cPermittedAlphabet, &iAlphasize); } else if(s_type->choiceId == SUBTYPE_SINGLE) { fakeList = MT(Subtype); fakeList->choiceId = SUBTYPE_OR; APPEND(s_type, fakeList->a.or); curr = fakeList->a.or->first; cTmp=FindPermittedAlpha(curr, cPermittedAlphabet, &iAlphasize); } if(iAlphasize > 0) { bAlphafound=1; for(iSort1 = 0; iSort1 < iAlphasize; iSort1++) { for(iSort2 = (iSort1 +1); iSort2 < iAlphasize; iSort2++) { if(cPermittedAlphabet[iSort1] > cPermittedAlphabet[iSort2]) { cSort = cPermittedAlphabet[iSort2]; cPermittedAlphabet[iSort2] = cPermittedAlphabet[iSort1]; cPermittedAlphabet[iSort1] = cSort; } } } for(iSort1 = 0; iSort1 < iAlphasize; iSort1++) { if(iSort1 == 0) j += sprintf(cAlpha+j, "0x%x", cPermittedAlphabet[iSort1]); else j += sprintf(cAlpha+j, ",0x%x", cPermittedAlphabet[iSort1]); } } s_type = e->type->subtypes; if(s_type->choiceId==SUBTYPE_AND) { and_curr=s_type->a.and->first; while(and_curr) { andS_type=and_curr->data; if(andS_type->choiceId == SUBTYPE_OR) { curr=andS_type->a.or->first; iSCPresent = BasicTypeString_LISTS(hdr, src, scList, iSCPresent, curr, currS_type); } else if(andS_type->choiceId == SUBTYPE_SINGLE) { fakeList = MT(Subtype); fakeList->choiceId = SUBTYPE_OR; APPEND(andS_type, fakeList->a.or); curr = fakeList->a.or->first; iSCPresent = BasicTypeString_LISTS(hdr, src, scList, iSCPresent, curr, currS_type); } and_curr=and_curr->next; } } else if(s_type->choiceId == SUBTYPE_OR) { curr=s_type->a.or->first; iSCPresent = BasicTypeString_LISTS(hdr, src, scList, iSCPresent, curr, currS_type); } else if(s_type->choiceId == SUBTYPE_SINGLE) { fakeList = MT(Subtype); fakeList->choiceId = SUBTYPE_OR; APPEND(s_type, fakeList->a.or); curr = fakeList->a.or->first; iSCPresent = BasicTypeString_LISTS(hdr, src, scList, iSCPresent, curr, currS_type); } fprintf (hdr, " public:\n"); fprintf (hdr, " %s():%s(){ }\n\n", className, e->type->cxxTypeRefInfo->className); fprintf (hdr, " const SizeConstraint* SizeConstraints(int &sizeList)const;\n\n"); fprintf (src, "const SizeConstraint* \n"); if(i == 1 || i == 3) { fprintf(src, "%s::", definedName); } fprintf(src, "%s::SizeConstraints(int &sizeList)const\n", className); fprintf (src, "{\n"); if(iSCPresent > 0 ) { count = 0; if(scList[count].upperBoundExists == 1 && scList[count].upperBound > iSCUpperBound) { iSCUpperBound = scList[count].upperBound; } if(scList[count].upperBoundExists == 0 && scList[count].lowerBound > iSCUpperBound) { iSCUpperBound = scList[count].lowerBound; } if(scList[count].lowerBound < iSCLowerBound) { iSCLowerBound = scList[count].lowerBound; } while(count < iSCPresent) { if(scList[count].upperBoundExists == 2) { iSCPresent = 0; } count++; } } if(iSCPresent > 0 ) { fprintf(src, " static const SizeConstraint %s_SizeConstraintList[] = \n {", e->type->cxxTypeRefInfo->fieldName); for(count = 0; count < iSCPresent; count++) { fprintf(src, "{ %ld, %ld, %d }", scList[count].lowerBound, scList[count].upperBound, scList[count].upperBoundExists); if(count + 1 < iSCPresent) { fprintf(src, ",\n "); } } fprintf(src, "};\n\n"); fprintf(src, " sizeList = %d;\n", iSCPresent); fprintf(src, " return &%s_SizeConstraintList[0];\n", e->type->cxxTypeRefInfo->fieldName); } else { fprintf(src, " sizeList = 0;\n"); fprintf(src, " return NULL;\n"); } fprintf (src, "}\n\n\n"); if(bAlphafound == 1) { fprintf (hdr, " const char* PermittedAlphabet(int &sizePermittedAlpha)const;\n\n"); fprintf (src, "const char* \n"); if(i == 1 || i == 3) { fprintf(src, "%s::", definedName); } fprintf(src, "%s::PermittedAlphabet(int &sizePermittedAlpha)const\n", className); fprintf (src, "{\n"); fprintf(src, "\n"); fprintf(src, " static const char alpha[] = {%s};\n", cAlpha); fprintf(src, " sizePermittedAlpha = %d;\n", iAlphasize); fprintf(src, " return alpha;\n"); fprintf (src, "}\n\n\n"); } fprintf (hdr, " %s& operator=(const char* str)\n", className); fprintf (hdr, " { %s::operator=(str); return *this;}\n",e->type->cxxTypeRefInfo->className); fprintf (hdr, " %s& operator=(const std::string& str)\n",className ); fprintf (hdr, " { %s::operator=(str); return *this;}\n",e->type->cxxTypeRefInfo->className); fprintf (hdr, " };\n\n"); if(i!= 3 && i != 0) { /* Last we declare an instance of the internal class we */ /* just created */ if(i==0) { fprintf (hdr, "typedef "); }/*if(i==0)*/ fprintf (hdr, " %s ", className); if (e->type->cxxTypeRefInfo->isPtr) { fprintf (hdr, "*"); }/*if (e->type->cxxTypeRefInfo->isPtr)*/ fprintf (hdr, "%s;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (hdr, "\n\n"); } free(e->type->cxxTypeRefInfo->className); e->type->cxxTypeRefInfo->className = strdup(className); returnvalue=1; break; }/* case BASICTYPE_NUMERIC_STR: *\ * case BASICTYPE_PRINTABLE_STR: * * case BASICTYPE_BMP_STR: * * case BASICTYPE_VISIBLE_STR: * * case BASICTYPE_UNIVERSAL_STR: * * case BASICTYPE_IA5_STR: * \* */ case BASICTYPE_BITSTRING: { Subtype* s_type; Subtype* currS_type=NULL; Subtype* andS_type=NULL; Subtype* fakeList = NULL; AsnListNode* curr; AsnListNode* and_curr; int iSCPresent = 0; int count = 0; int iSCLowerBound = 0; int iSCUpperBound = 0; SizeConstraint scList[15]; /*print the generic header for the generated class*/ fprintf (hdr, "class %s %s: public %s {\n", pszGlobalExport, className, e->type->cxxTypeRefInfo->className); s_type = e->type->subtypes; if(s_type->choiceId==SUBTYPE_AND) { and_curr=s_type->a.and->first; while(and_curr) { andS_type=and_curr->data; if(andS_type->choiceId == SUBTYPE_OR) { curr=andS_type->a.or->first; iSCPresent = BasicTypeString_LISTS(hdr, src, scList, iSCPresent, curr, currS_type); } else if(andS_type->choiceId == SUBTYPE_SINGLE) { fakeList = MT(Subtype); fakeList->choiceId = SUBTYPE_OR; APPEND(andS_type, fakeList->a.or); curr = fakeList->a.or->first; iSCPresent = BasicTypeString_LISTS(hdr, src, scList, iSCPresent, curr, currS_type); } and_curr=and_curr->next; } } else if(s_type->choiceId == SUBTYPE_OR) { curr=s_type->a.or->first; iSCPresent = BasicTypeString_LISTS(hdr, src, scList, iSCPresent, curr, currS_type); } else if(s_type->choiceId == SUBTYPE_SINGLE) { fakeList = MT(Subtype); fakeList->choiceId = SUBTYPE_OR; APPEND(s_type, fakeList->a.or); curr = fakeList->a.or->first; iSCPresent = BasicTypeString_LISTS(hdr, src, scList, iSCPresent, curr, currS_type); } fprintf(hdr, " public:\n"); fprintf(hdr, " %s (const char *stringForm=NULL):AsnBits(stringForm){ }\n", className); fprintf(hdr, " %s (size_t numBits):AsnBits(numBits) { }\n", className); fprintf(hdr, " %s (const unsigned char *bitOcts, size_t numBits):AsnBits(bitOcts, numBits){ }\n", className); fprintf(hdr, " %s (const %s &_b):AsnBits(_b){ }\n", className, className); fprintf (hdr, " const SizeConstraint* SizeConstraints(int &sizeList)const;\n\n"); fprintf (src, "const SizeConstraint* \n"); if(i == 1 || i == 3) { fprintf(src, "%s::", definedName); } fprintf(src, "%s::SizeConstraints(int &sizeList)const\n", className); fprintf (src, "{\n"); if(iSCPresent > 0 ) { count = 0; if(scList[count].upperBoundExists == 1 && scList[count].upperBound > iSCUpperBound) { iSCUpperBound = scList[count].upperBound; } if(scList[count].upperBoundExists == 0 && scList[count].lowerBound > iSCUpperBound) { iSCUpperBound = scList[count].lowerBound; } if(scList[count].lowerBound < iSCLowerBound) { iSCLowerBound = scList[count].lowerBound; } while(count < iSCPresent) { if(scList[count].upperBoundExists == 2) { iSCPresent = 0; } count++; } } if(iSCPresent > 0 ) { fprintf(src, " static const SizeConstraint %s_SizeConstraintList[] = \n {", e->type->cxxTypeRefInfo->fieldName); for(count = 0; count < iSCPresent; count++) { fprintf(src, "{ %ld, %ld, %d }", scList[count].lowerBound, scList[count].upperBound, scList[count].upperBoundExists); if(count + 1 < iSCPresent) { fprintf(src, ",\n "); } } fprintf(src, "};\n\n"); fprintf(src, " sizeList = %d;\n", iSCPresent); fprintf(src, " return &%s_SizeConstraintList[0];\n", e->type->cxxTypeRefInfo->fieldName); } else { fprintf(src, " sizeList = 0;\n"); fprintf(src, " return NULL;\n"); } fprintf (src, "}\n\n\n"); fprintf (hdr, " %s & operator=(const char *stringForm){ SetEqual(stringForm); return *this; }\n", className); fprintf (hdr, " };\n\n"); if (i != 3 && i != 0) { /* Last we declare an instance of the internal class we */ /* just created */ if(i==0) { fprintf (hdr, "typedef "); }/*if(i==0)*/ fprintf (hdr, " %s ", className); if (e->type->cxxTypeRefInfo->isPtr) { fprintf (hdr, "*"); }/*if (e->type->cxxTypeRefInfo->isPtr)*/ fprintf (hdr, "%s;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (hdr, "\n\n"); } free(e->type->cxxTypeRefInfo->className); e->type->cxxTypeRefInfo->className = strdup(className); returnvalue=1; break; } /* case BASICTYPE_BITSTRING: */ case BASICTYPE_OCTETSTRING: { Subtype* s_type; Subtype* currS_type=NULL; Subtype* andS_type=NULL; Subtype* fakeList = NULL; AsnListNode* curr; AsnListNode* and_curr; int iSCPresent = 0; int count = 0; int iSCLowerBound = 0; int iSCUpperBound = 0; SizeConstraint scList[15]; /*print the generic header for the generated class*/ fprintf (hdr, "class %s %s: public %s {\n", pszGlobalExport, className, e->type->cxxTypeRefInfo->className); s_type = e->type->subtypes; if(s_type->choiceId==SUBTYPE_AND) { and_curr=s_type->a.and->first; while(and_curr) { andS_type=and_curr->data; if(andS_type->choiceId == SUBTYPE_OR) { curr=andS_type->a.or->first; iSCPresent = BasicTypeString_LISTS(hdr, src, scList, iSCPresent, curr, currS_type); } else if(andS_type->choiceId == SUBTYPE_SINGLE) { fakeList = MT(Subtype); fakeList->choiceId = SUBTYPE_OR; APPEND(andS_type, fakeList->a.or); curr = fakeList->a.or->first; iSCPresent = BasicTypeString_LISTS(hdr, src, scList, iSCPresent, curr, currS_type); } and_curr=and_curr->next; } } else if(s_type->choiceId == SUBTYPE_OR) { curr=s_type->a.or->first; iSCPresent = BasicTypeString_LISTS(hdr, src, scList, iSCPresent, curr, currS_type); } else if(s_type->choiceId == SUBTYPE_SINGLE) { fakeList = MT(Subtype); fakeList->choiceId = SUBTYPE_OR; APPEND(s_type, fakeList->a.or); curr = fakeList->a.or->first; iSCPresent = BasicTypeString_LISTS(hdr, src, scList, iSCPresent, curr, currS_type); } fprintf (hdr, " public:\n"); fprintf (hdr, " %s ():AsnOcts() { }\n", className); fprintf (hdr, " %s (const char *str):AsnOcts(str) { }\n", className); fprintf (hdr, " %s (const char *str, const size_t len):AsnOcts(str, len) { }\n", className); fprintf (hdr, " %s (const %s &o):AsnOcts(o){ }\n", className, className); fprintf (hdr, " const SizeConstraint* SizeConstraints(int &sizeList)const;\n\n"); fprintf (src, "const SizeConstraint* \n"); if(i == 1 || i == 3) { fprintf(src, "%s::", definedName); } fprintf(src, "%s::SizeConstraints(int &sizeList)const\n", className); fprintf (src, "{\n"); if(iSCPresent > 0 ) { count = 0; if(scList[count].upperBoundExists == 1 && scList[count].upperBound > iSCUpperBound) { iSCUpperBound = scList[count].upperBound; } if(scList[count].upperBoundExists == 0 && scList[count].lowerBound > iSCUpperBound) { iSCUpperBound = scList[count].lowerBound; } if(scList[count].lowerBound < iSCLowerBound) { iSCLowerBound = scList[count].lowerBound; } while(count < iSCPresent) { if(scList[count].upperBoundExists == 2) { iSCPresent = 0; } count++; } } if(iSCPresent > 0 ) { fprintf(src, " static const SizeConstraint %s_SizeConstraintList[] = \n {", e->type->cxxTypeRefInfo->fieldName); for(count = 0; count < iSCPresent; count++) { fprintf(src, "{ %ld, %ld, %d }", scList[count].lowerBound, scList[count].upperBound, scList[count].upperBoundExists); if(count + 1 < iSCPresent) { fprintf(src, ",\n "); } } fprintf(src, "};\n\n"); fprintf(src, " sizeList = %d;\n", iSCPresent); fprintf(src, " return &%s_SizeConstraintList[0];\n", e->type->cxxTypeRefInfo->fieldName); } else { fprintf(src, " sizeList = 0;\n"); fprintf(src, " return NULL;\n"); } fprintf (src, "}\n\n\n"); fprintf (hdr, " %s &operator = (const AsnOcts &o)\n", className); fprintf (hdr, " { SetEqual(o); return *this;}\n"); fprintf (hdr, " %s &operator = (const char *str)\n", className); fprintf (hdr, " { SetEqual(str); return *this; }\n"); fprintf (hdr, " };\n\n"); if(i != 3 && i != 0) { /* Last we declare an instance of the internal class we */ /* just created */ if(i==0) { fprintf (hdr, "typedef "); }/*if(i==0)*/ fprintf (hdr, " %s ", className); if (e->type->cxxTypeRefInfo->isPtr) { fprintf (hdr, "*"); }/*if (e->type->cxxTypeRefInfo->isPtr)*/ fprintf (hdr, "%s;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (hdr, "\n\n"); } free(e->type->cxxTypeRefInfo->className); e->type->cxxTypeRefInfo->className = strdup(className); returnvalue=1; break; }/* case BASICTYPE_OCETSTRING: */ default: { returnvalue = 0; break; }/*default*/ }/*switch(e->type->basicType->choiceId)*/ free(className); return returnvalue; }/*int PrintCxxMultiConstraintOrHandler*/ esnacc-ng-1.8.1/compiler/back-ends/c++-gen/cxxmultipleconstraints.h000066400000000000000000000022621302010526100251460ustar00rootroot00000000000000#ifndef _cxxmultipleconstraints_h_ #define _cxxmultipleconstraints_h_ #include "asn-incl.h" #include "asn1module.h" #include "snacc.h" #include "limits.h" #include "rules.h" #include "snacc-util.h" #include "str-util.h" typedef struct SizeConstraint{ long lowerBound; long upperBound; int upperBoundExists; }SizeConstraint; typedef SizeConstraint ValueRange; typedef struct PermittedAlphabet{ unsigned char* ucApha; }PermittedAlphabet; char* PrintCxxPermittedAlphabetHandler PROTO(( AsnListNode* currAlpha, unsigned char* cPermittedAlphabet, int *iAlphasize)); int SizeConstraint_LISTS PROTO((FILE* hdr, FILE* src, SizeConstraint* scList, int iSCPresent, AsnListNode* curr, Subtype* currS_type)); int PrintCxxMultiConstraintOrHandler PROTO((FILE* hdr, FILE* src, char* definedName, NamedType* e, int i)); int ValueRange_LISTS PROTO((FILE* hdr, FILE* src, ValueRange* vrList, int iVRPresent, AsnListNode* curr, Subtype* currS_type)); int BasicTypeString_LISTS PROTO((FILE* hdr, FILE* src, SizeConstraint* scList, int iSCPresent, AsnListNode* curr, Subtype* currS_type)); char* FindPermittedAlpha PROTO((AsnListNode* curr, unsigned char* cPermittedAlphabet, int *iAlphasize)); #endif esnacc-ng-1.8.1/compiler/back-ends/c++-gen/gen-any.c000066400000000000000000000375361302010526100216450ustar00rootroot00000000000000/* * compiler/back_ends/c++_gen/gen_any.c * * prints Routine to initialize the ANY Hash table. The * ANY Hash table maps the OBJECT IDENTIFIERS or INTEGERS * to the correct decoding routines. * * Also prints an enum to identify each ANY mapping. * * MS 92 * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * INSERT_VDA_COMMENTS * * $Header: /baseline/SNACC/compiler/back-ends/c++-gen/gen-any.c,v 1.16 2003/12/19 20:55:49 leonberp Exp $ * $Log: gen-any.c,v $ * Revision 1.16 2003/12/19 20:55:49 leonberp * added parameter to PrintCxxOidValue() to allow printing of paren or quote to be specified. * * Revision 1.15 2003/07/07 14:52:35 nicholar * Eliminated headers and cleaned up include references * * Revision 1.14 2002/10/29 16:37:34 mcphersc * changed the any global int variable used for any defined by's * * Revision 1.13 2002/09/16 17:48:02 mcphersc * * iFixed warings * * Revision 1.12 2002/09/04 17:51:35 vracarl * got rid of c++ comments * * Revision 1.11 2002/05/15 14:53:10 leonberp * added support for new basicTypes to compiler * * Revision 1.10 2002/02/28 19:45:17 nicholar * Added calls to Dash2Underscore() to remove dashes in ANYs. * * Revision 1.9 2001/10/16 04:26:09 leonberp * removed destructor for any tables and moved it to the runtime library * * Revision 1.8 2001/10/12 15:05:45 leonberp * Fixed bug in InitAny destructor generator * * Revision 1.7 2001/10/12 14:53:47 leonberp * Fixed bug in InitAny destructor generator * * Revision 1.6 2001/10/11 18:34:31 leonberp * added code to generate destructor for InitAny classes so they oid and int hash tables will be cleaned up. Also fixed the hash table clean up code to be recursive. * * Revision 1.5 2001/06/11 18:30:56 rwc * Re-added actual constructor of module specific ANY DEFINED BY table update. * vda test now works again. NEED TO RE-TEST with multiple modules. * * Revision 1.4 2001/05/11 16:00:46 mcphersc * Fixed problems with Init Any's and class statement in gen-code. * Gen-code not allowing for "::" in some instances * * Revision 1.3 2001/04/18 16:28:56 rwc * Updated test for ANY DEFINED BY updates. Now supports default CSM_Buffer (AsnAnyBuffer) result if * OID is not recognized. * * Revision 1.2 2000/10/24 14:54:43 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:36:05 leonberp * First CVS Version of SNACC. * * Revision 1.4 1995/07/25 18:19:11 rj * changed `_' to `-' in file names. * * Revision 1.3 1994/10/08 03:47:53 rj * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long. * * Revision 1.2 1994/09/01 01:06:31 rj * snacc_config.h removed. * * Revision 1.1 1994/08/28 09:47:58 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include /* REN -- 5/11/2001 -- added for string functions */ #include "asn-incl.h" #include "asn1module.h" #include "str-util.h" #include "rules.h" #include "snacc-util.h" /* REN -- 5/11/2001 -- added for GetBuiltinType() */ #ifdef WIN32 #pragma warning( disable : 4100 ) /* IGNORE unreferenced formal parameter */ #endif void PrintCxxAnyEnum PROTO ((FILE *hdr, Module *m, CxxRules *r)); void PrintCxxAnyHashInitRoutine PROTO ((FILE *src, FILE *hdr, ModuleList *mods, Module *m, CxxRules *r)); void PrintCxxOidValue PROTO ((FILE *f, CxxRules *r, AsnOid *oid, int parenOrQuote)); /* REN -- 5/11/2001 -- added following prototype */ static TypeDef* GetTypeDef PROTO ((Type *t)); extern int anyEnumValG; void PrintCxxAnyCode PARAMS ((src, hdr, r, mods, m), FILE *src _AND_ FILE *hdr _AND_ CxxRules *r _AND_ ModuleList *mods _AND_ Module *m) { if (!m->hasAnys) return; PrintCxxAnyEnum (hdr, m, r); PrintCxxAnyHashInitRoutine (src, hdr, mods, m, r); } /* PrintAnyCode */ void PrintCxxAnyEnum PARAMS ((hdr, m, r), FILE *hdr _AND_ Module *m _AND_ CxxRules *r) { int firstPrinted = TRUE; char *modName; /* REN -- 5/11/2001 */ /* TypeDef *td; AnyRef *ar; AnyRefList *arl; int i; */ ValueDef *vd; Type *t; char anyId[512]; /* REN -- end */ modName = Asn1TypeName2CTypeName (m->modId->name); fprintf (hdr,"typedef enum %sAnyId\n", modName); fprintf (hdr,"{\n"); /* REN -- 5/11/2001 -- Changed method in which anyRefs get written. Original code looped through the module's basic types and local type refs and wrote the anys that referred to them. Corrected method loops through the valueRefs and writes all of the SNMP Object Types. Removed the following loops: do any lib types for (i = BASICTYPE_BOOLEAN; i < BASICTYPE_MACRODEF; i++) { arl = LIBTYPE_GET_ANY_REFS (i); if (arl != NULL) { FOR_EACH_LIST_ELMT (ar, arl) { if (!firstPrinted) fprintf (hdr,",\n"); fprintf (hdr," %s = %d", ar->anyIdName, anyEnumValG++); firstPrinted = FALSE; } } } FOR_EACH_LIST_ELMT (td, m->typeDefs) { if (td->anyRefs != NULL) { FOR_EACH_LIST_ELMT (ar, td->anyRefs) { if (!firstPrinted) fprintf (hdr,",\n"); fprintf (hdr," %s = %d", ar->anyIdName, anyEnumValG++); firstPrinted = FALSE; } } } REN -- 5/11/2001 -- added the following: */ FOR_EACH_LIST_ELMT (vd, m->valueDefs) { if (vd->value != NULL) { t = vd->value->type; if ((GetBuiltinType(t) == BASICTYPE_MACROTYPE) && (t->basicType->a.macroType->choiceId == MACROTYPE_SNMPOBJECTTYPE)) { strcpy (anyId, vd->definedName); Dash2Underscore (anyId, strlen (anyId)); strcat (anyId, "_ANY_ID"); if (!firstPrinted) fprintf (hdr,",\n"); fprintf (hdr," %s = %d", anyId, anyEnumValG); anyEnumValG++; firstPrinted = FALSE; } } } /* REN -- end */ if (firstPrinted) /* none have been printed */ fprintf (hdr,"/* NO INTEGER or OBJECT IDENTIFIER to ANY type relationships were defined (via MACROs or other mechanism) */\n ??? \n"); fprintf (hdr,"\n} %sAnyId;\n\n\n", modName); Free (modName); } /* PrintAnyEnum */ void PrintCxxAnyHashInitRoutine PARAMS ((src, hdr, mods, m, r), FILE *src _AND_ FILE *hdr _AND_ ModuleList *mods _AND_ Module *m _AND_ CxxRules *r) { TypeDef *td; int i; int installedSomeHashes=0; struct CxxTDI *cxxtdi; char *modName; /* REN -- 5/11/2001 */ /* AnyRef *ar; AnyRefList *arl; int j; */ enum BasicTypeChoiceId typeId; ValueDef *vd; Type *t; BasicValue *bv; char anyId[512]; char *typeName = NULL; /* REN -- end */ modName = Asn1TypeName2CTypeName (m->modId->name); /* print Any class src file */ fprintf (src,"// this class will automatically intialize the any hash tbl\n"); fprintf (src,"class InitAny%s\n", modName); fprintf (src,"{\n"); fprintf (src," public:\n"); fprintf (src," InitAny%s();\n", modName); fprintf (src," /* Do not add a destructor to this class! It could\n"); fprintf (src," * cause pre-mature destruction of the ANY tables.\n"); fprintf (src," * The ANY tables will be destroyed by the runtime library.\n"); fprintf (src," */\n"); #if 0 fprintf (src," ~InitAny%s() { AsnAny::AsnAnyDestroyHashTbls(); }\n",modName); #endif fprintf (src,"};\n\n"); fprintf (src,"static InitAny%s anyInitalizer;\n", modName); /* print constructor method that build hash tbl to src file*/ fprintf (src,"InitAny%s::InitAny%s()\n", modName, modName); fprintf (src,"{\n"); /* REN -- 5/11/2001 -- Changed method in which anyRefs get written. Original code looped through the module's basic types and local type refs and wrote the anys that referred to them. Corrected method loops through the valueRefs and writes all of the SNMP Object Types. Removed the following loops: first print value for OID's * do any lib types first * i = 0; for (j = BASICTYPE_BOOLEAN; j < BASICTYPE_MACRODEF; j++) { arl = LIBTYPE_GET_ANY_REFS (j); if (arl != NULL) { FOR_EACH_LIST_ELMT (ar, arl) { installedSomeHashes = TRUE; if (ar->id->choiceId == OIDORINT_OID) { fprintf (src," %s oid%d", r->typeConvTbl[BASICTYPE_OID].className, i++); PrintCxxOidValue (src, r, ar->id->a.oid); fprintf (src,";\n"); } else if (ar->id->choiceId == OIDORINT_INTID) { fprintf (src," %s int%d", r->typeConvTbl[BASICTYPE_INTEGER].className, i++); PrintCxxIntValue (src, r, ar->id->a.intId); fprintf (src,";\n"); } } } } FOR_EACH_LIST_ELMT (td, m->typeDefs) { if (td->anyRefs != NULL) { cxxtdi = td->cxxTypeDefInfo; FOR_EACH_LIST_ELMT (ar, td->anyRefs) { installedSomeHashes = TRUE; if (ar->id->choiceId == OIDORINT_OID) { fprintf (src," %s oid%d", r->typeConvTbl[BASICTYPE_OID].className, i++); PrintCxxOidValue (src, r, ar->id->a.oid); fprintf (src,";\n"); } else if (ar->id->choiceId == OIDORINT_INTID) { fprintf (src," %s int%d", r->typeConvTbl[BASICTYPE_INTEGER].className, i++); PrintCxxIntValue (src, r, ar->id->a.intId); fprintf (src,";\n"); } } } } * now print hash init calls * i = 0; for (j = BASICTYPE_BOOLEAN; j < BASICTYPE_MACRODEF; j++) { arl = LIBTYPE_GET_ANY_REFS (j); if (arl != NULL) { FOR_EACH_LIST_ELMT (ar, arl) { if (ar->id->choiceId == OIDORINT_OID) fprintf (src," AsnAny::InstallAnyByOid (oid%d, %s, new %s);\n", i++, ar->anyIdName, r->typeConvTbl[j].className); else fprintf (src," AsnAny::InstallAnyByInt (int%d, %s, new %s);\n", i++, ar->anyIdName, r->typeConvTbl[j].className); } } } FOR_EACH_LIST_ELMT (td, m->typeDefs) { if (td->anyRefs != NULL) { FOR_EACH_LIST_ELMT (ar, td->anyRefs) { cxxtdi = td->cxxTypeDefInfo; if (ar->id->choiceId == OIDORINT_OID) fprintf (src," AsnAny::InstallAnyByOid (oid%d, %s, new %s);\n", i++, ar->anyIdName, cxxtdi->className); else fprintf (src," AsnAny::InstallAnyByInt (int%d, %s, new %s);\n", i++, ar->anyIdName, cxxtdi->className); } } } REN -- 5/11/2001 -- added the following: */ /* first print value for OID's */ i = 0; FOR_EACH_LIST_ELMT (vd, m->valueDefs) { if (vd->value != NULL) { t = vd->value->type; if ((GetBuiltinType(t) == BASICTYPE_MACROTYPE) && (t->basicType->a.macroType->choiceId == MACROTYPE_SNMPOBJECTTYPE)) { bv = vd->value->basicValue; if (bv != NULL) { installedSomeHashes = TRUE; if (bv->choiceId == BASICVALUE_OID) { fprintf (src," %s oid%d", r->typeConvTbl[BASICTYPE_OID].className, i++); PrintCxxOidValue (src, r, bv->a.oid, 1); fprintf (src,";\n"); } } } } } fprintf (src,"\n\n"); /* now print hash init calls */ i = 0; FOR_EACH_LIST_ELMT (vd, m->valueDefs) { if (vd->value != NULL) { t = vd->value->type; if ((GetBuiltinType(t) == BASICTYPE_MACROTYPE) && (t->basicType->a.macroType->choiceId == MACROTYPE_SNMPOBJECTTYPE)) { bv = vd->value->basicValue; if (bv != NULL) { strcpy (anyId, vd->definedName); Dash2Underscore (anyId, strlen (anyId)); strcat (anyId, "_ANY_ID"); installedSomeHashes = TRUE; t = t->basicType->a.macroType->a.snmpObjectType->syntax; /* If the syntax of this any is a basic type, get the class name from the rules table. */ typeId = t->basicType->choiceId; if (((typeId >= BASICTYPE_BOOLEAN) && (typeId <= BASICTYPE_SETOF)) || ((typeId >= BASICTYPE_NUMERIC_STR) && (typeId <= BASICTYPE_T61_STR))) { typeName = r->typeConvTbl[typeId].className; } /* Else if the syntax of this any is either a locally defined type or an imported type, get the class name from the this type's ref info. */ else { td = GetTypeDef(t); if (td != NULL) { cxxtdi = td->cxxTypeDefInfo; typeName = cxxtdi->className; } else typeName = NULL; } if (typeName == NULL) fprintf(src, "*** ERROR *** Unknown ANY\n\n"); else { if (bv->choiceId == BASICVALUE_OID) { fprintf (src, " AsnAny::InstallAnyByOid (oid%d, %s, new %s);\n", i++, anyId, typeName); } else if (bv->choiceId == BASICVALUE_INTEGER) { fprintf (src, " AsnAny::InstallAnyByInt (%d, %s, new %s);\n", bv->a.integer, anyId, typeName); } } } } } } /* REN -- end */ if (!installedSomeHashes) { fprintf (src," /* Since no INTEGER/OID to ANY type relations were defined\n"); fprintf (src," * (usually done via MACROs) you must manually do the code\n"); fprintf (src," * to fill the hash tbl.\n"); fprintf (src," * if the ids are INTEGER use the following:\n"); fprintf (src," * AsnAny::InstallAnyByInt (3, ??_ANY_ID, new );\n"); fprintf (src," * if the ids are OBJECT IDENTIFIERs use the following:\n"); fprintf (src," * AsnAny::InstallAnyByOid (OidValue, ??_ANY_ID, new );\n"); fprintf (src," * put the ??_ANY_IDs in the AnyId enum.\n\n"); fprintf (src," * For example if you have some thing like\n"); fprintf (src," * T1 ::= SEQUENCE { id INTEGER, ANY DEFINED BY id }\n"); fprintf (src," * and the id 1 maps to the type BOOLEAN use the following:\n"); fprintf (src," * AsnAny::InstallAnyByInt (1, SOMEBOOL_ANY_ID, new AsnBool);\n"); fprintf (src," */\n ???????\n"); /* generate compile error */ } fprintf (src,"} /* InitAny::InitAny */\n\n\n"); /* RWC;4/23/01;#endif */ /* RWC;4/23/01; r;m;mods;hdr;src; */ /*AVOIDS warning.*/ } /* PrintAnyHashInitRoutine */ /* REN -- 5/11/2001 -- GetTypeDef() function added to return the type def info for the given type. */ static TypeDef* GetTypeDef PARAMS ((t), Type *t) { if (t == NULL) return NULL; switch (t->basicType->choiceId) { case BASICTYPE_LOCALTYPEREF: case BASICTYPE_IMPORTTYPEREF: return t->basicType->a.localTypeRef->link; break; default: return NULL; } /*fprintf (errFileG, "GetTypeDef: ERROR - cannot get type def for unlinked local/import type refs\n"); return NULL;*/ } /* GetTypeDef */ /* REN -- end */ esnacc-ng-1.8.1/compiler/back-ends/c++-gen/gen-code.c000066400000000000000000007165101302010526100217640ustar00rootroot00000000000000/* * compiler/back_ends/c++_gen/gen_code.c - routines for printing C++ code from type trees * * assumes that the type tree has already been run through the * c++ type generator (c++_gen/types.c). * * This was hastily written - it has some huge routines in it. * Needs a lot of cleaning up and modularization... * * Mike Sample * 92 * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/back-ends/c++-gen/gen-code.c,v 1.129 2004/04/06 15:13:41 gronej Exp $ * */ #include "snacc.h" #if TIME_WITH_SYS_TIME # include # include #else # if HAVE_SYS_TIME_H # include # else # include # endif #endif #if STDC_HEADERS || HAVE_STRING_H #include #else #include #endif #include "asn-incl.h" #include "asn1module.h" #include "rules.h" #include "snacc-util.h" #include "print.h" #include "tag-util.h" /* get GetTags/FreeTags/CountTags/TagByteLen */ #include "cxxconstraints.h" #include "cxxmultipleconstraints.h" #if META #include "meta.h" #endif enum BasicTypeChoiceId ParanoidGetBuiltinType PARAMS ((t),Type *t); void PrintConditionalIncludeOpen PROTO ((FILE *f, char *fileName)); void PrintConditionalIncludeClose PROTO ((FILE *f, char *fileName)); void PrintCxxAnyCode PROTO ((FILE *src, FILE *hdr, CxxRules *r, ModuleList *mods, Module *m)); void PrintCxxValueDef PROTO ((FILE *src, CxxRules *r, ValueDef *v)); void PrintCxxValueExtern PROTO ((FILE *hdr, CxxRules *r, ValueDef *v)); char *LookupNamespace PROTO ((Type *t, ModuleList *mods)); static void PrintCxxSeqSetPrintFunction(FILE* src, FILE* hdr, MyString className, BasicType *pBasicType); /* PER specific methods*/ static void PrintCxxDefCode_SetSeqPEREncode (FILE *src, FILE *hdr, CxxRules *r, TypeDef *td, NamedType **pSetElementNamedType, int iElementCount); /* IN, ELEMENT Count to process in arrays */ static void PrintCxxDefCode_SetSeqPERDecode (FILE *src, FILE *hdr, CxxRules *r, TypeDef *td, NamedType **pSetElementNamedType, int iElementCount); /* IN, ELEMENT Count to process in arrays */ static void PrintCxxDefCode_PERSort ( NamedType ***pppElementNamedType, /* OUT, array of sorted NameType(s) */ int **ppElementTag, /* OUT, actual tag for sorted. */ AsnList *pElementList); /* IN, actual eSNACC defs for NameType(s). */ /* flag to see if constraints were present */ int constraints_flag; long lconstraintvar=0; extern char *bVDAGlobalDLLExport; extern int gNO_NAMESPACE; extern const char *gAlternateNamespaceString; extern int genPERCode; //extern short ImportedFilesG; static const char bufTypeNameG[] = "AsnBuf"; static const char lenTypeNameG[] = "AsnLen"; static const char tagTypeNameG[] = "AsnTag"; static const char envTypeNameG[] = "ENV_TYPE"; static long longJmpValG = -100; static const char baseClassesG[] = ": public AsnType"; static int printTypesG; static int printEncodersG; static int printDecodersG; static int printPrintersG; static int printFreeG; #if META static MetaNameStyle printMetaG; static MetaPDU *meta_pdus_G; #if TCL static int printTclG; #endif #endif /* META */ /* PIERCE added 10-27-2002 */ void PrintCxxEncodeContaining(Type *t, CxxRules *r, FILE *src); void PrintCxxDecodeContaining(Type *t, CxxRules *r, FILE *src); void PrintCxxPEREncodeContaining(Type *t, CxxRules *r, FILE *src); void PrintCxxPERDecodeContaining(Type *t, CxxRules *r, FILE *src); /* PIERCE added 9-4-2002 */ void PrintCxxSetTypeByCode(NamedType *defByNamedType, CxxTRI *cxxtri, FILE *src); // normalizeValue // // strip whitespace and { } from valueNation values. // void normalizeValue(char **normalized, char *input) { int i; while(*input == ' ' || *input == '{' ) input++; *normalized = strdup(input); i = strlen(*normalized) - 1; while ( (*normalized)[i] == ' ' || (*normalized)[i] == '}' ) { (*normalized)[i] = 0; i--; } } static char *GetImportFileName (char *Impname, ModuleList *mods) { Module *currMod; char *fileName = NULL; FOR_EACH_LIST_ELMT (currMod, mods) { /* Find the import Module in the Modules and * return the header file name */ if ((strcmp(Impname, currMod->modId->name) == 0)) { /* Set the file name and break */ fileName = currMod->cxxHdrFileName; break; } } return fileName; } /* RWC; added 7/25/03 */ static Module *GetImportModuleRef (char *Impname, ModuleList *mods) { Module *currMod=NULL; FOR_EACH_LIST_ELMT (currMod, mods) { /* Find the import Module in the Modules and * return the header file name */ if ((strcmp(Impname, currMod->modId->name) == 0)) { break; } } return currMod; } /* PIERCE added 8-22-2001 */ void PrintCopyConstructor(FILE *hdr, FILE *src, char *className) { fprintf(hdr, " %s(const %s& that);\n", className, className); fprintf(src,"%s::%s(const %s &that)\n{\n",className, className,className); /*fprintf(src," Clear();\n");*/ fprintf(src," Init();\n"); fprintf(src," *this = that;\n}\n"); } void PrintSimpleMeta(FILE *hdr, char *className,int exportMember) { char *ptr=""; /* NOT DLL Exported, or ignored on Unix. */ if (bVDAGlobalDLLExport != NULL && exportMember == 1) ptr = bVDAGlobalDLLExport; fprintf(hdr, "public:\n\t%s virtual const char* typeName() const\t{ return \"%s\"; }\n", ptr, className); } void PrintSimpleCheck(FILE *hdr, FILE* src, char *className,int exportMember) { char *ptr=""; /* NOT DLL Exported, or ignored on Unix. */ if (bVDAGlobalDLLExport != NULL && exportMember == 1) ptr = bVDAGlobalDLLExport; fprintf(hdr, "\t%s virtual int checkConstraints(ConstraintFailList* pConstraintFails) const;\n", ptr); fprintf(src, "int %s::checkConstraints(ConstraintFailList* pConstraintFails) const\n{\n", className); fprintf(src, "\treturn checkListConstraints(pConstraintFails);\n"); fprintf(src, "}\n"); } static void PrintHdrComment PARAMS ((hdr, m), FILE *hdr _AND_ Module *m) { time_t now = time (NULL); fprintf (hdr, "// %s - class definitions for ASN.1 module %s\n", m->cxxHdrFileName, m->modId->name); fprintf (hdr, "//\n"); fprintf (hdr, "// This file was generated by esnacc on %s\n", ctime(&now)); fprintf (hdr, "// NOTE: this is a machine generated file-" "-editing not recommended\n"); fprintf (hdr, "\n"); } /* PrintHdrComment */ static void PrintSrcComment PARAMS ((src, m), FILE *src _AND_ Module *m) { time_t now = time (NULL); fprintf (src, "// %s - class definitions for ASN.1 module %s\n", m->cxxSrcFileName, m->modId->name); fprintf (src, "//\n"); fprintf (src, "// This file was generated by esnacc on %s\n", ctime(&now)); fprintf (src, "// NOTE: this is a machine generated file-" "-editing not recommended\n"); fprintf (src, "\n"); } /* PrintSrcComment */ static void PrintSrcIncludes PARAMS ((src, mods, m), FILE *src _AND_ ModuleList *mods _AND_ Module *m) { mods = mods; if (m->cxxHdrFileName) fprintf (src, "#include \"%s\"\n", m->cxxHdrFileName); m = m; /*AVOIDS warning.*/ } /* PrintSrcIncludes */ static void PrintTypeDecl PARAMS ((f, td), FILE *f _AND_ TypeDef *td) { switch (td->type->basicType->choiceId) { case BASICTYPE_COMPONENTSOF: case BASICTYPE_SELECTION: case BASICTYPE_UNKNOWN: case BASICTYPE_MACRODEF: case BASICTYPE_MACROTYPE: return; /* do nothing */ default: if (IsNewType (td->type)) fprintf (f, "class %s;\n", td->cxxTypeDefInfo->className); } } /* PrintTypeDecl */ static void PrintCxxType PARAMS ((hdr, mods, m, r, td, parent, t), FILE *hdr _AND_ ModuleList *mods _AND_ Module *m _AND_ CxxRules *r _AND_ TypeDef *td _AND_ Type *parent _AND_ Type *t) { char *pszNamespace=NULL; pszNamespace = LookupNamespace(t, mods); if (pszNamespace) { fprintf (hdr, "%s::%s ", pszNamespace, t->cxxTypeRefInfo->className); } else { fprintf (hdr, "%s ", t->cxxTypeRefInfo->className); } // END IF BASICTYPE_IMPORTTYPEREF if (t->cxxTypeRefInfo->isPtr) fprintf (hdr, "*"); parent = parent;td = td;r = r;m = m;mods=mods; /*AVOIDS warning.*/ } /* PrintCxxType */ /* * Uses the Constructor that takes no args. * Assumes file f is positioned inside a class definition. * All Classes get this to support the ANY type. */ static void PrintCloneMethod PARAMS ((hdr, src, td), FILE *hdr _AND_ FILE *src _AND_ TypeDef *td) { // fprintf (hdr, " AsnType *Clone() const;\n\n", td->cxxTypeDefInfo->className); fprintf (hdr, " AsnType *Clone() const;\n\n"); fprintf (src, "AsnType *%s::Clone() const\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " return new %s(*this);\n", td->cxxTypeDefInfo->className); fprintf (src, "}\n\n"); } /* PrintCloneMethod */ /* * prints inline definition of constructors if this class is * derived from a library class. * assumes FILE *f is positioned in the derived class definition (.h) * * 12/92 MS - added overloaded "=" ops for string types. */ static void PrintDerivedConstructors PARAMS ((f, r, td), FILE *f _AND_ CxxRules *r _AND_ TypeDef *td) { enum BasicTypeChoiceId typeId; char *derivedClassName; char *baseClassName; typeId = GetBuiltinType (td->type); derivedClassName = td->cxxTypeDefInfo->className; baseClassName = td->type->cxxTypeRefInfo->className; /* every class gets the no-arg constructor */ #if TCL if (printTclG && typeId == BASICTYPE_ENUMERATED) { fprintf (f, "#if TCL\n"); fprintf (f, " %s(): %s (_nmdescs[0].value) {}\n", derivedClassName, baseClassName); fprintf (f, "#else\n"); } if (printTclG && typeId == BASICTYPE_ENUMERATED) fprintf (f, "#endif\n"); #endif /* TCL */ switch (typeId) { case BASICTYPE_BOOLEAN: fprintf (f, " %s(): %s() {}\n", derivedClassName, baseClassName); fprintf (f, " %s (bool _b): %s (_b) {}\n", derivedClassName, baseClassName); break; case BASICTYPE_ENUMERATED: case BASICTYPE_INTEGER: fprintf (f, " %s(): %s() {}\n", derivedClassName, baseClassName); fprintf (f, " %s (int i): %s (i) {}\n", derivedClassName, baseClassName); break; case BASICTYPE_REAL: fprintf (f, " %s(): %s() {}\n", derivedClassName, baseClassName); fprintf (f, " %s (double d): %s (d) {}\n", derivedClassName, baseClassName); break; case BASICTYPE_OCTETSTRING: fprintf (f, " %s(): %s() {}\n", derivedClassName, baseClassName); fprintf (f, " %s (const char *str): %s (str) {}\n", derivedClassName, baseClassName); fprintf (f, " %s (const char *str, const size_t len): %s (str, len) {}\n", derivedClassName, baseClassName); fprintf (f, " %s (const %s &o): %s (o) {}\n", derivedClassName, derivedClassName, baseClassName); /* include overloading of = op. MS 12/92 */ fprintf (f, " %s &operator = (const %s &o) { if (this != &o ) AsnOcts::operator=(o); return *this; }\n", derivedClassName, derivedClassName); fprintf (f, " %s &operator = (const char *str) { AsnOcts::operator=(str); return *this; }\n", derivedClassName); break; case BASICTYPE_BITSTRING: { const char *nblStr = "nblFlag = false;"; if (HasNamedElmts (td->type)) nblStr = "nblFlag = true;"; fprintf(f, "\t%s() : %s()\t\t\t{ %s }\n", derivedClassName, baseClassName, nblStr); fprintf(f, "\t%s(size_t bits) : %s(bits)\t{ %s }\n", derivedClassName, baseClassName, nblStr); fprintf(f, "\t%s(const unsigned char* str, const size_t bitLen) :\n", derivedClassName); fprintf(f, "\t\t%s(str, bitLen)\t\t\t\t{ %s }\n", baseClassName, nblStr); // Copy constructor not needed // fprintf(f, "\t%s (const %s &o) : %s(o)\n", // derivedClassName, baseClassName, baseClassName); } break; case BASICTYPE_OID: /* TBD: Fix this code -PIERCE fprintf (f, " %s(): %s() {}\n", derivedClassName, baseClassName); fprintf (f, " %s (const char *encOid, size_t len): %s (encOid, len) {}\n", derivedClassName, baseClassName); fprintf (f, " %s (const %s &o): %s (o) {}\n", derivedClassName, baseClassName, baseClassName); fprintf (f, " %s (unsigned long a1, unsigned long a2, long a3=-1, long a4=-1, long a5=-1, long a6=-1, long a7=-1, long a8=-1, long a9=-1, long a10=-1, long a11=-1): %s (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) {}\n", baseClassName, derivedClassName, baseClassName); fprintf (f, " %s &operator = (const %s &o) { ReSet (o); return *this; }\n", derivedClassName, derivedClassName); */ printf("TBD: Attempt was made to generate code for a tagged OID outside of a SEQ or SET\n"); break; default: break; } r = r; /*AVOIDS warning.*/ } /* PrintDerivedConstructors */ #if DEPRECATED static void PrintCxxEocEncoders PARAMS ((src, td, t, bufVarName), FILE *src _AND_ TypeDef *td _AND_ Type *t _AND_ char *bufVarName) { TagList *tl; Tag *tag; int stoleChoiceTags; /* get all the tags on this type*/ tl = (TagList*) GetTags (t, &stoleChoiceTags); FreeTags (tl); bufVarName=bufVarName;td=td; /*AVOIDS warning.*/ } /* PrintCxxEocEncoders */ #endif static int HasShortLen PARAMS ((t), Type *t) { enum BasicTypeChoiceId typesType; /* * efficiency hack - use simple length (1 byte) * encoded for type (almost) guaranteed to have * encoded lengths of 0 <= len <= 127 */ typesType = GetBuiltinType (t); /*RWC;8/9/01;REMOVED when INTEGER made AsnOcts;return typesType == BASICTYPE_BOOLEAN || typesType == BASICTYPE_INTEGER || typesType == BASICTYPE_NULL || typesType == BASICTYPE_REAL || typesType == BASICTYPE_ENUMERATED; */ return typesType == BASICTYPE_BOOLEAN || typesType == BASICTYPE_NULL || typesType == BASICTYPE_REAL || typesType == BASICTYPE_ENUMERATED; } /* HasShortLen */ /* * prints length encoding code. Primitives always use * definite length and constructors get "ConsLen" * which can be configured at compile to to be indefinite * or definite. Primitives can also be "short" (isShort is true) * in which case a fast macro is used to write the length. * Types for which isShort apply are: boolean, null and * (almost always) integer and reals */ static void PrintCxxLenEncodingCode PARAMS ((f, isCons, isShort, lenVarName, bufVarName), FILE *f _AND_ int isCons _AND_ int isShort _AND_ char *lenVarName _AND_ char *bufVarName) { if (isCons) fprintf (f, " %s += BEncConsLen (%s, %s);\n", lenVarName, bufVarName, lenVarName); else { if (isShort) { fprintf (f, " BEncDefLenTo127 (%s, %s);\n", bufVarName, lenVarName); fprintf (f, " %s++;\n", lenVarName); } else fprintf (f, " %s += BEncDefLen (%s, %s);\n", lenVarName, bufVarName, lenVarName); } } /* PrintCxxLenEncodingCode */ /* prints last tag's encoding code first */ static void PrintCxxTagAndLenList PARAMS ((src, t, tagList, lenVarName, bufVarName), FILE *src _AND_ Type *t _AND_ TagList *tagList _AND_ char *lenVarName _AND_ char *bufVarName) { char *classStr; char *formStr; Tag *tg; Tag *last; int tagLen; int isShort; if ((tagList == NULL) || LIST_EMPTY (tagList)) return; /* * efficiency hack - use simple length (1 byte) * encoded for type (almost) guaranteed to have * encoded lengths of 0 <= len <= 127 */ isShort = HasShortLen (t); /* * since encoding backward encode tags backwards */ last = (Tag*)LAST_LIST_ELMT (tagList); FOR_EACH_LIST_ELMT_RVS (tg, tagList) { classStr = Class2ClassStr (tg->tclass); if (tg->form == CONS) { formStr = Form2FormStr (CONS); PrintCxxLenEncodingCode (src, TRUE, isShort, lenVarName, bufVarName); } else /* PRIM or ANY_FORM */ { formStr = Form2FormStr (PRIM); PrintCxxLenEncodingCode (src, FALSE, isShort, lenVarName, bufVarName); } fprintf (src, "\n"); //RWC;tagLen = TagByteLen (tg->code); if (tg->tclass == UNIV) { const char* ptr = DetermineCode(tg, &tagLen, 0); fprintf (src, " %s += BEncTag%d (%s, %s, %s, %s);\n", lenVarName, tagLen, bufVarName, classStr, formStr, ptr); } //RWC;Code2UnivCodeStr (tg->code)); else { const char* ptr = DetermineCode(tg, &tagLen, 1); fprintf (src, " %s += BEncTag%d (%s, %s, %s, %s);\n", lenVarName, tagLen, bufVarName, classStr, formStr, ptr); } //RWC;tg->code); } } /* PrintCxxTagAndLenList */ /* * Recursively walks through tags, printing lower lvl tags * first (since encoding is done backwards). * */ static void PrintCxxTagAndLenEncodingCode PARAMS ((src, td, t, lenVarName, bufVarName), FILE *src _AND_ TypeDef *td _AND_ Type *t _AND_ char *lenVarName _AND_ char *bufVarName) { TagList *tl; int stoleChoiceTags; /* * get all the tags on this type */ tl = (TagList*) GetTags (t, &stoleChoiceTags); /* * leave choice elmt tag enc to encoding routine */ if (!stoleChoiceTags) PrintCxxTagAndLenList (src, t, tl, lenVarName, bufVarName); FreeTags (tl); td=td; /*AVOIDS warning.*/ } /* PrintCxxTagAndLenEncodingCode */ /* * used to figure out local variables to declare * for decoding tags/len pairs on type t */ static int CxxCountVariableLevels PARAMS ((t), Type *t) { if (GetBuiltinType (t) == BASICTYPE_CHOICE) return CountTags (t) +1; /* since must decode 1 internal tag type */ else return CountTags (t); } /* CxxCountVariableLevels */ /* * returns true if elmts curr following * onward are all optional ow. false */ static int RestAreTailOptional PARAMS ((e), NamedTypeList *e) { NamedType *elmt; void *tmp; int retVal; if (e == NULL) return TRUE; tmp = (void*)CURR_LIST_NODE (e); retVal = TRUE; AsnListNext (e); FOR_REST_LIST_ELMT (elmt, e) { if ((!elmt->type->optional) && (elmt->type->defaultVal == NULL)&&(!elmt->type->extensionAddition)) { retVal = FALSE; break; } } SET_CURR_LIST_NODE (e, tmp); /* reset list to orig loc */ return retVal; } /* * prints typedef or new class given an ASN.1 type def of a primitive type * or typeref. Uses inheritance to cover re-tagging and named elmts. */ static void PrintCxxSimpleDef PARAMS ((hdr, src, m, r, td), FILE *hdr _AND_ FILE *src _AND_ Module *m _AND_ CxxRules *r _AND_ TypeDef *td) { Tag *tag; TagList *tags; char *formStr; char *classStr; int tagLen; int i; CNamedElmt *n; int stoleChoiceTags; int elmtLevel; enum BasicTypeChoiceId typeId; m = m; fprintf (hdr, "/* "); SpecialPrintType (hdr, td, td->type); fprintf (hdr, " */\n"); /* check if has been re-tagged * eg Foo ::= [APPLICATION 2] IMPLICIT REAL * or if it has named elmts in which case a new class must * be defined * eg Foo ::= INTEGER { one (1), two (2), three (3) } */ if (IsNewType (td->type)) { int hasNamedElmts; char *ptr=""; /* NOT DLL Exported, or ignored on Unix. */ if (bVDAGlobalDLLExport) ptr = bVDAGlobalDLLExport; fprintf (hdr, "class %s %s: public %s\n", ptr, td->cxxTypeDefInfo->className, td->type->cxxTypeRefInfo->className); fprintf (hdr, "{\n"); fprintf (hdr, "public:\n"); /* * must explicitly call constructors for base class */ PrintDerivedConstructors (hdr, r, td); /* do named elmts enum if any */ /* for types with named elements, inherit from the base * class and define and enum eg: * Foo ::= INTEGER { one (1), two (2), five (5) } * -> * class Foo: public AsnInt * { * public: * Foo(): AsnInt() {} * Foo (int val): AsnInt (int val) {} * enum { one = 1, two = 2, five = 5 }; * }; * or * Foo2 ::= [APPLICATION 2] INTEGER * --> * class Foo: public AsnInt * { * public: * Foo(): AsnInt() {} * Foo (int val): AsnInt (int val) {} * AsnLen BEnc { ....... } <-- holds new tag enc/dec * void BDec { ....... } <--/ * int BEncPdu { ....... } * int BDecPdu { ....... } * }; * (must 'inherit' constructors explicitly) */ if ((hasNamedElmts = HasNamedElmts (td->type)) != 0) { int count = 0; fprintf (hdr, "\n\tenum\n"); fprintf (hdr, "\t{\n"); FOR_EACH_LIST_ELMT (n, td->type->cxxTypeRefInfo->namedElmts) { fprintf (hdr, "\t\t%s = %d", n->name, n->value); if (n != (CNamedElmt *)LAST_LIST_ELMT (td->type->cxxTypeRefInfo->namedElmts)) fprintf (hdr, ",\n"); else fprintf (hdr, "\n"); count++; } fprintf (hdr, "\t};\n"); if(td->type->basicType->choiceId == BASICTYPE_ENUMERATED) { fprintf (hdr, " AsnLen PEnc(AsnBufBits &_b)const{\n"); fprintf (hdr, " long enumList[] = {"); FOR_EACH_LIST_ELMT (n, td->type->cxxTypeRefInfo->namedElmts) { fprintf (hdr, "%d", n->value); if (n != (CNamedElmt *)LAST_LIST_ELMT (td->type->cxxTypeRefInfo->namedElmts)) fprintf (hdr, ", "); } fprintf (hdr, " };\n"); fprintf (hdr, " AsnInt index = IndexedVal(enumList, %d);\n", count); fprintf (hdr, " AsnLen len = index.PEncFullyConstrained(_b, 0, %d);\n", count - 1); fprintf (hdr, " return len;}\n"); fprintf (hdr, " void PDec(AsnBufBits &_b, AsnLen &bitsDecoded){\n"); fprintf (hdr, " long enumList[] = {"); FOR_EACH_LIST_ELMT (n, td->type->cxxTypeRefInfo->namedElmts) { fprintf (hdr, "%d", n->value); if (n != (CNamedElmt *)LAST_LIST_ELMT (td->type->cxxTypeRefInfo->namedElmts)) fprintf (hdr, ", "); } fprintf (hdr, " };\n"); fprintf (hdr, " AsnInt index;\n"); fprintf (hdr, " index.PDecFullyConstrained(_b, 0, %d, bitsDecoded);\n", count - 1); fprintf (hdr, " SetIndex(enumList, %d, index);}\n", count); } } #if META if (printMetaG) { PrintCxxSimpleDefMeta_1(hdr, src, td, hasNamedElmts, n, m); } #endif /* META */ /* * Re-do BerEncode, BerDeocode, BerDecodePdu and BerDecodePdu * if this type has been re-tagged */ if ((IsDefinedByLibraryType (td->type) && !HasDefaultTag (td->type)) || (IsTypeRef (td->type) && ((td->type->tags != NULL) && !LIST_EMPTY (td->type->tags)))) { /* only BerEn/Decode BerEn/DecodePdu need to be re-done if tags are different */ /* print clone routine for ANY mgmt */ PrintCloneMethod (hdr, src, td); tags = GetTags (td->type, &stoleChoiceTags); typeId = GetBuiltinType (td->type); /* do BerEncode function */ if (printEncodersG) { fprintf (hdr, " %s B%s (%s &_b) const;\n", lenTypeNameG, r->encodeBaseName, bufTypeNameG); fprintf (src, "%s %s::B%s (%s &_b) const\n", lenTypeNameG, td->cxxTypeDefInfo->className, r->encodeBaseName, bufTypeNameG); fprintf (src, "{\n"); fprintf (src, " %s l=0;\n", lenTypeNameG); fprintf (src, " l = BEncContent (_b);\n"); /* encode each tag/len pair if any */ if (!stoleChoiceTags) { FOR_EACH_LIST_ELMT_RVS (tag, tags) { classStr = Class2ClassStr (tag->tclass); if (tag->form == ANY_FORM) { formStr = Form2FormStr (PRIM); PrintCxxLenEncodingCode (src, FALSE, HasShortLen (td->type), "l", "_b"); } else { formStr = Form2FormStr (tag->form); PrintCxxLenEncodingCode (src, TRUE, HasShortLen (td->type), "l", "_b"); } fprintf (src, "\n"); //RWC;tagLen = TagByteLen (tag->code); if (tag->tclass == UNIV) { const char* ptr = DetermineCode(tag, &tagLen, 0); fprintf (src, " l += BEncTag%d (_b, %s, %s, %s);\n", tagLen, classStr, formStr, ptr);//RWC;Code2UnivCodeStr (tag->code)); } else { const char* ptr = DetermineCode(tag, &tagLen, 1); fprintf (src, " l += BEncTag%d (_b, %s, %s, %s);\n", tagLen, classStr, formStr, ptr);//RWC;tag->code); } } } fprintf (src, " return l;\n"); fprintf (src, "}\n\n"); } /* end of BEnc function */ /* Do BDec function */ if (printDecodersG) { fprintf (hdr, " void B%s (const %s &_b, %s &bytesDecoded);\n", r->decodeBaseName, bufTypeNameG, lenTypeNameG);// envTypeNameG); fprintf (src, "void %s::B%s (const %s &_b, %s &bytesDecoded)\n", td->cxxTypeDefInfo->className, r->decodeBaseName, bufTypeNameG, lenTypeNameG);//, envTypeNameG); fprintf (src, "{\n"); fprintf (src, " FUNC(\"%s::B%s\");\n", td->cxxTypeDefInfo->className, r->decodeBaseName); fprintf (src, " %s tag;\n", tagTypeNameG); /* PL: removed to avoid unused variable warning fprintf (src, " AsnBufLoc readLoc = _b.GetReadLoc();\n"); */ /* print extra locals for redundant lengths */ for (i = 1; (tags != NULL) && (i <= LIST_COUNT (tags)); i++) fprintf (src, " %s elmtLen%d;\n", lenTypeNameG, i); if (typeId == BASICTYPE_CHOICE) fprintf (src, " %s elmtLen%d;\n", lenTypeNameG, i++); fprintf (src, "\n"); /* decode tag/length pair (s) */ elmtLevel = 0; if (!stoleChoiceTags) { FOR_EACH_LIST_ELMT (tag, tags) { classStr = Class2ClassStr (tag->tclass); if (tag->form == ANY_FORM) formStr = Form2FormStr (PRIM); else formStr = Form2FormStr (tag->form); fprintf (src, " if (((tag = BDecTag (_b, bytesDecoded)) != "); if (tag->tclass == UNIV) { fprintf (src, "MAKE_TAG_ID (%s, %s, %s))", classStr, formStr, DetermineCode(tag, NULL, 0));//RWC;Code2UnivCodeStr (tag->code)); if (tag->form == ANY_FORM) fprintf (src, "\n && (tag != MAKE_TAG_ID (%s, %s, %s)))\n", classStr, Form2FormStr (CONS), DetermineCode(tag, NULL, 0));//RWC;Code2UnivCodeStr (tag->code)); else fprintf (src, ")\n"); } else { fprintf (src, "MAKE_TAG_ID (%s, %s, %s))", classStr, formStr, DetermineCode(tag, NULL, 1));//RWC;tag->code); if (tag->form == ANY_FORM) fprintf (src, "\n && (tag != MAKE_TAG_ID (%s, %s, %s)))\n", classStr, Form2FormStr (CONS), DetermineCode(tag, NULL, 1));//RWC;tag->code); else fprintf (src, ")\n"); } fprintf (src, " {\n"); fprintf (src, " throw InvalidTagException(typeName(), tag, STACK_ENTRY);\n"); fprintf (src, " }\n"); fprintf (src, " elmtLen%d = BDecLen (_b, bytesDecoded);\n", ++elmtLevel); } } /* decode first tag from CHOICE's content */ if (typeId == BASICTYPE_CHOICE) { fprintf (src, " tag = BDecTag (_b, bytesDecoded);\n"); fprintf (src, " elmtLen%d = BDecLen (_b, bytesDecoded);\n", ++elmtLevel); } fprintf (src, " B%s (_b, tag, elmtLen%d, bytesDecoded);\n", r->decodeContentBaseName, i-1); /* grab any EOCs that match redundant, indef lengths */ for (i = elmtLevel-1; i > 0; i--) { fprintf (src, " if (elmtLen%d == INDEFINITE_LEN)\n", i); fprintf (src, " BDecEoc (_b, bytesDecoded);\n"); } fprintf (src, "}\n\n"); } /* end of BDec function */ FreeTags (tags); } /* close class def */ fprintf (hdr, "};\n\n\n"); } else /* isomorphic with referenced type, so just to a typedef */ { #if META if (printMetaG) { PrintCxxSimpleDefMeta_2(hdr, src, td, hasNamedElmts, n, m, r); } #endif /* META */ /* JKG 7/31/03 */ /* The following code enclosed in this if/else statement */ /* is constructed for constraint handling capability */ /* for primitives found outside of */ /* sequences or sets */ if (td->type->subtypes != NULL) { switch (td->type->subtypes->choiceId) { case SUBTYPE_AND: case SUBTYPE_OR: case SUBTYPE_SINGLE: { struct NamedType temp; NamedType* tmp; tmp=&temp; tmp->type=td->type; tmp->type->cxxTypeRefInfo->fieldName=td->definedName; tmp->fieldName=td->definedName; if (!PrintCxxMultiConstraintOrHandler(hdr, src, NULL, tmp, 0)) PrintTypeDefDefault(hdr, src, td); break; } default: { PrintTypeDefDefault(hdr, src, td); break; } } } else { PrintTypeDefDefault(hdr, src, td); } #if META if (printMetaG) fprintf (hdr, "#endif // META\n\n"); #endif /* META */ } } /* PrintCxxSimpleDef */ static void PrintCxxChoiceDefCode (FILE *src, FILE *hdr, ModuleList *mods, Module *m, CxxRules *r , TypeDef *td,Type *parent, Type *choice, int novolatilefuncs) { NamedType *e; char *classStr; char *formStr; char *codeStr; int tagLen=0, i; Tag *tag; TagList *tags; char *varName; CxxTRI *cxxtri; int elmtLevel=0; int varCount, tmpVarCount; int stoleChoiceTags; enum BasicTypeChoiceId tmpTypeId; NamedType *defByNamedType; NamedType **ppElementNamedType; int *pElementTag; int ii; char *ptr=""; /* NOT DLL Exported, or ignored on Unix. */ int extensionsExist = FALSE; /* put class spec in hdr file */ if (bVDAGlobalDLLExport != NULL) ptr = bVDAGlobalDLLExport; fprintf (hdr, "class %s %s%s\n", ptr, td->cxxTypeDefInfo->className, baseClassesG); fprintf (hdr, "{\n"); fprintf (hdr, "public:\n"); /* write out choiceId enum type */ FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) { if(e->type->subtypes != NULL) { switch(e->type->subtypes->choiceId) { case SUBTYPE_AND: case SUBTYPE_OR: case SUBTYPE_SINGLE: { PrintCxxMultiConstraintOrHandler(hdr, src, td->cxxTypeDefInfo->className, e, 3); break; } default: { break; } } } } fprintf (hdr, " enum %s\n", r->choiceIdEnumName); fprintf (hdr, " {\n"); FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) { fprintf (hdr, " %s = %d", e->type->cxxTypeRefInfo->choiceIdSymbol, e->type->cxxTypeRefInfo->choiceIdValue); if (e != (NamedType*)LAST_LIST_ELMT (choice->basicType->a.choice)) fprintf (hdr, ",\n"); else fprintf (hdr, "\n"); } fprintf (hdr, " };\n\n"); /* write out the choice Id field */ fprintf (hdr, " enum %s %s;\n", r->choiceIdEnumName, r->choiceIdFieldName); /* write out the choice element anonymous union */ fprintf (hdr, " union\n"); fprintf (hdr, " {\n"); FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) { fprintf (hdr, " "); PrintCxxType (hdr, mods, m, r, td, choice, e->type); fprintf (hdr, "%s;\n\n", e->type->cxxTypeRefInfo->fieldName); } fprintf (hdr, " };\n\n"); #if META if (printMetaG) { PrintCxxChoiceDefCodeMeta_1(hdr, src, td, choice, m, e); } #endif /* META */ fprintf (hdr, "\n"); /* constructors and destructor */ fprintf (hdr, " %s() {Init();}\n", td->cxxTypeDefInfo->className); /* PIERCE 8-22-2001 */ PrintCopyConstructor(hdr, src, td->cxxTypeDefInfo->className); PrintSimpleMeta(hdr,td->cxxTypeDefInfo->className,0); /* Init() member function*/ fprintf (hdr, " void Init(void);\n"); fprintf (src, "void %s::Init(void)\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " // initialize choice to no choiceId to first choice and set pointer to NULL\n"); e = FIRST_LIST_ELMT (choice->basicType->a.choice); fprintf (src, " choiceId = %sCid;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, "}\n\n"); fprintf (hdr, "\n virtual int checkConstraints(ConstraintFailList* pConstraintFails)const;\n\n"); fprintf(src, "\nint %s::checkConstraints(ConstraintFailList* pConstraintFails) const\n{\n", td->cxxTypeDefInfo->className); FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) { if (e->type->cxxTypeRefInfo->isPtr) { fprintf(src, "\tif (%s != NULL)\n", e->type->cxxTypeRefInfo->fieldName); fprintf(src, "\t\t%s->checkConstraints(pConstraintFails);\n\n", e->type->cxxTypeRefInfo->fieldName); } else { fprintf(src, "\t%s.checkConstraints(pConstraintFails);\n\n", e->type->cxxTypeRefInfo->fieldName); } } fprintf(src, "\treturn 0;\n"); fprintf(src, "}\n\n\n"); /* virtual destructor*/ fprintf (hdr, " virtual ~%s() {Clear();}\n\n", td->cxxTypeDefInfo->className); /* Clear() member*/ fprintf (hdr, " void Clear();\n\n"); fprintf (src, "void %s::Clear()\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " switch (choiceId)\n"); fprintf (src, " {\n"); FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) { tmpTypeId = GetBuiltinType (e->type); fprintf (src, " case %s:\n", e->type->cxxTypeRefInfo->choiceIdSymbol); if (e->type->cxxTypeRefInfo->isPtr) { fprintf (src, " delete %s;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName); } else if(!e->type->cxxTypeRefInfo->isPtr && ((tmpTypeId == BASICTYPE_CHOICE) || (tmpTypeId == BASICTYPE_SET) || (tmpTypeId == BASICTYPE_SEQUENCE)) ) { fprintf (src, " %s.Clear();\n", e->type->cxxTypeRefInfo->fieldName); } fprintf (src, " break;\n"); } fprintf (src, " } // end of switch\n"); fprintf (src, "} // end of Clear()\n"); fprintf (src, "\n"); /* print clone routine for ANY mgmt */ PrintCloneMethod (hdr, src, td); fprintf (hdr, " %s &operator = (const %s &that);\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, "%s &%s::operator = (const %s &that)\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " if (this != &that)\n"); fprintf (src, " {\n"); fprintf (src, " Clear();\n"); e = FIRST_LIST_ELMT (choice->basicType->a.choice); fprintf (src, " // Check first type in choice to determine if choice is empty\n"); fprintf (src, " if (that.%s != NULL)\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " {\n"); fprintf (src, " switch (choiceId = that.choiceId)\n"); fprintf (src, " {\n"); FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) { fprintf (src, " case %s:\n", e->type->cxxTypeRefInfo->choiceIdSymbol); if (e->type->cxxTypeRefInfo->isPtr) { fprintf (src, " %s = new %s(*that.%s);\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className, e->type->cxxTypeRefInfo->fieldName); } else { fprintf (src, " %s = that.%s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->fieldName); } fprintf (src, " break;\n"); } fprintf (src, " }// end of switch\n"); fprintf (src, " }// end of if\n"); fprintf (src, " }\n"); fprintf (src, "\n"); fprintf (src, " return *this;\n"); fprintf (src, "}\n\n"); /* BerEncodeContent */ if (printEncodersG) { fprintf (hdr, " %s B%s (%s &_b) const;\n", lenTypeNameG, r->encodeContentBaseName, bufTypeNameG); fprintf (src, "%s\n", lenTypeNameG); fprintf (src, "%s::B%s (%s &_b) const\n", td->cxxTypeDefInfo->className, r->encodeContentBaseName, bufTypeNameG); fprintf (src, "{\n"); fprintf (src, " FUNC(\"%s::B%s (%s &_b)\");\n", td->cxxTypeDefInfo->className, r->encodeContentBaseName, bufTypeNameG); /* print local vars */ fprintf (src, " %s l=0;\n", lenTypeNameG); fprintf (src, " switch (%s)\n", r->choiceIdFieldName); fprintf (src, " {\n"); FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) { cxxtri = e->type->cxxTypeRefInfo; fprintf (src, " case %s:\n", cxxtri->choiceIdSymbol); varName = cxxtri->fieldName; /* eSNACC 1.5 does not encode indefinite length * * PrintCxxEocEncoders (src, td, e->type, "_b"); */ /* encode content */ tmpTypeId = GetBuiltinType (e->type); if (tmpTypeId == BASICTYPE_ANYDEFINEDBY) { defByNamedType = e->type->basicType->a.anyDefinedBy->link; PrintCxxSetTypeByCode(defByNamedType, cxxtri, src); } else if (tmpTypeId == BASICTYPE_ANY) { fprintf (src, " l = %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "B%s (_b);\n", r->encodeBaseName); } else if ( (tmpTypeId == BASICTYPE_OCTETCONTAINING) || (tmpTypeId == BASICTYPE_BITCONTAINING)) { PrintCxxEncodeContaining(e->type, r, src); } else if ( tmpTypeId == BASICTYPE_EXTENSION ) { fprintf (src, " l = %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "B%s (_b);\n", r->encodeBaseName); } else { fprintf (src, " l = %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "B%s (_b);\n", r->encodeContentBaseName); } /* encode tag (s) & len (s) */ PrintCxxTagAndLenEncodingCode (src, td, e->type, "l", "_b"); fprintf (src, " break;\n\n"); } fprintf (src, " default:\n"); fprintf (src, " throw EXCEPT(\"Choice is empty\", ENCODE_ERROR);\n"); fprintf (src, " } // end switch\n"); fprintf (src, " return l;\n"); fprintf (src, "} // %s::B%s\n\n\n", td->cxxTypeDefInfo->className, r->encodeContentBaseName); } /* end of BerEncodeContent method */ /* BerDecodeContent */ if (printDecodersG) { fprintf (hdr, " void B%s (const %s &_b, %s tag, %s elmtLen, %s &bytesDecoded /*, s env*/);\n", r->decodeContentBaseName, bufTypeNameG, tagTypeNameG, lenTypeNameG, lenTypeNameG);//, envTypeNameG); fprintf (src, "void %s::B%s (const %s &_b, %s tag, %s elmtLen0, %s &bytesDecoded /*, s env*/)\n", td->cxxTypeDefInfo->className, r->decodeContentBaseName, bufTypeNameG, tagTypeNameG, lenTypeNameG, lenTypeNameG);//, envTypeNameG); fprintf (src, "{\n"); fprintf (src, " FUNC(\"%s::B%s()\");\n",td->cxxTypeDefInfo->className, r->decodeContentBaseName); fprintf (src, " Clear();\n"); //fprintf (src, " Init();\n"); /* print local vars */ /* count max number of extra length var nec * by counting tag/len pairs on components of the CHOICE */ varCount = 0; FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) { tmpVarCount = CxxCountVariableLevels (e->type); if (tmpVarCount > varCount) varCount = tmpVarCount; } /* write extra length vars - remember choice content * decoders are passed the 'key' tag so need one less * than max var count. */ for (i = 1; i < varCount; i++) fprintf (src, " %s elmtLen%d = 0;\n", lenTypeNameG, i); /* switch on given tag - choices always have the key tag decoded */ fprintf (src, " switch (tag)\n"); fprintf (src, " {\n"); FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) { if( e->type->basicType->choiceId == BASICTYPE_EXTENSION ) { extensionsExist = TRUE; } else { cxxtri = e->type->cxxTypeRefInfo; tags = GetTags (e->type, &stoleChoiceTags); if (LIST_EMPTY (tags)) { fprintf (src, " // ANY Type?\n"); fprintf (src, " case MAKE_TAG_ID (?, ?, ?):\n"); } else { tag = (Tag*)FIRST_LIST_ELMT (tags); classStr = Class2ClassStr (tag->tclass); formStr = Form2FormStr (tag->form); if (tag->tclass == UNIV) { codeStr = DetermineCode(tag, NULL, 0);//RWC;Code2UnivCodeStr (tag->code); } else { codeStr = DetermineCode(tag, NULL, 1); } if (tag->form == ANY_FORM) { fprintf (src, " case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (PRIM), codeStr); fprintf (src, " case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (CONS), codeStr); } else { fprintf (src, " case MAKE_TAG_ID (%s, %s, %s):\n", classStr, formStr, codeStr); } /* now decode extra tags/length pairs */ AsnListFirst (tags); AsnListNext (tags); elmtLevel = 0; if (stoleChoiceTags) { FOR_REST_LIST_ELMT (tag, tags) { classStr = Class2ClassStr (tag->tclass); formStr = Form2FormStr (tag->form); if (tag->tclass == UNIV) codeStr = DetermineCode(tag, NULL, 0);//RWC;Code2UnivCodeStr (tag->code); else codeStr = DetermineCode(tag, NULL, 1); if (tag->form == ANY_FORM) { fprintf (src, " case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (PRIM), codeStr); fprintf (src, " case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (CONS), codeStr); } else { fprintf (src, " case MAKE_TAG_ID (%s, %s, %s):\n", classStr, formStr, codeStr); } } } else /* didn't steal nested choice's tags */ { FOR_REST_LIST_ELMT (tag, tags) { classStr = Class2ClassStr (tag->tclass); codeStr = DetermineCode(tag, NULL, 0);//RWC;Code2UnivCodeStr (tag->code); formStr = Form2FormStr (tag->form); fprintf (src, " tag = BDecTag (_b, bytesDecoded);\n"); if (tag->form == ANY_FORM) { if (tag->tclass == UNIV) { fprintf (src, " if ((tag != MAKE_TAG_ID (%s, %s, %s))\n", classStr, Form2FormStr (PRIM), codeStr); fprintf (src, " && (tag != MAKE_TAG_ID (%s, %s, %s)))\n", classStr, Form2FormStr (CONS), codeStr); } else { fprintf (src, " if ((tag != MAKE_TAG_ID (%s, %s, %s))\n", classStr, Form2FormStr (PRIM), DetermineCode(tag, NULL, 1));//RWC;tag->code); fprintf (src, " && (tag != MAKE_TAG_ID (%s, %s, %s)))\n", classStr, Form2FormStr (CONS), DetermineCode(tag, NULL, 1));//RWC;tag->code); } } else { if (tag->tclass == UNIV) fprintf (src, " if (tag != MAKE_TAG_ID (%s, %s, %s))\n", classStr, formStr, codeStr); else fprintf (src, " if (tag != MAKE_TAG_ID (%s, %s, %s))\n", classStr, formStr, DetermineCode(tag, NULL, 1));//RWC;tag->code); } fprintf (src, " {\n"); fprintf (src, " throw InvalidTagException(typeName(), tag, STACK_ENTRY);\n"); fprintf (src, " }\n\n"); fprintf (src, " elmtLen%d = BDecLen (_b, bytesDecoded);\n", ++elmtLevel); } } } /* * if the choices element is another choice && * we didn't steal its tags then we must grab * the key tag out of the contained CHOICE */ if (!stoleChoiceTags && (GetBuiltinType (e->type) == BASICTYPE_CHOICE)) { fprintf (src, " tag = BDecTag (_b, bytesDecoded);\n"); fprintf (src, " elmtLen%d = BDecLen (_b, bytesDecoded);\n", ++elmtLevel); } varName = cxxtri->fieldName; /* set choice id for to this elment */ fprintf (src, " %s = %s;\n", r->choiceIdFieldName, cxxtri->choiceIdSymbol); /* alloc elmt if nec */ if (cxxtri->isPtr) { fprintf (src, " %s = new %s;\n", varName, cxxtri->className); } /* decode content */ tmpTypeId = GetBuiltinType (e->type); if (tmpTypeId == BASICTYPE_ANYDEFINEDBY) { /* * must check for another EOC for ANYs * since the any decode routines decode * their own first tag/len pair */ elmtLevel++; defByNamedType = e->type->basicType->a.anyDefinedBy->link; PrintCxxSetTypeByCode(defByNamedType, cxxtri, src); fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "B%s (_b, bytesDecoded);\n", r->decodeBaseName); } else if (tmpTypeId == BASICTYPE_ANY) { elmtLevel++; fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "B%s (_b, bytesDecoded);\n", r->decodeBaseName); } else if ( (tmpTypeId == BASICTYPE_OCTETCONTAINING) || (tmpTypeId == BASICTYPE_BITCONTAINING) ) { PrintCxxDecodeContaining(e->type, r, src); } else { fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "B%s (_b, tag, elmtLen%d, bytesDecoded);\n", r->decodeContentBaseName, elmtLevel); } /* decode Eoc (s) */ for (i = elmtLevel-1; i >= 0; i--) { fprintf (src, " if (elmtLen%d == INDEFINITE_LEN)\n", i); fprintf (src, " BDecEoc (_b, bytesDecoded);\n"); } fprintf (src, " break;\n\n"); FreeTags (tags); } } fprintf (src, " default:\n"); fprintf (src, " {"); if(extensionsExist) { fprintf (src, " AsnAny extAny;\n"); fprintf (src, " extension = new AsnExtension;\n"); fprintf (src, " choiceId = extensionCid;\n"); fprintf (src, " extAny.BDecContent(_b, tag, elmtLen0, bytesDecoded);\n"); fprintf (src, " extension->extList.insert( extension->extList.end(), extAny );\n"); } else { fprintf (src, " throw InvalidTagException(typeName(), tag, STACK_ENTRY);\n"); } fprintf (src, " break;\n"); fprintf (src, " }\n"); fprintf (src, " } // end switch\n"); fprintf (src, "} // %s::B%s\n\n\n", td->cxxTypeDefInfo->className, r->decodeContentBaseName); } /* end of code for printing BDecodeContent method */ /* do BEnc function */ if (printEncodersG) { fprintf (hdr, " %s B%s (%s &_b) const;\n", lenTypeNameG, r->encodeBaseName, bufTypeNameG); fprintf (src, "%s %s::B%s (%s &_b) const\n", lenTypeNameG, td->cxxTypeDefInfo->className, r->encodeBaseName, bufTypeNameG); fprintf (src, "{\n"); fprintf (src, " %s l=0;\n", lenTypeNameG); fprintf (src, " l = B%s (_b);\n", r->encodeContentBaseName); /* encode each tag/len pair if any */ FOR_EACH_LIST_ELMT_RVS (tag, choice->tags) { classStr = Class2ClassStr (tag->tclass); formStr = Form2FormStr (CONS); /* choices are constructed */ //RWC;tagLen = TagByteLen (tag->code); fprintf (src, " l += BEncConsLen (_b, l);\n"); if (tag->tclass == UNIV) { const char* ptr = DetermineCode(tag, &tagLen, 1); fprintf (src, " l += BEncTag%d (_b, %s, %s, %s);\n", tagLen, classStr, formStr, ptr);//RWC;Code2UnivCodeStr (tag->code)); } else { const char* ptr = DetermineCode(tag, &tagLen, 1); fprintf (src, " l += BEncTag%d (_b, %s, %s, %s);\n", tagLen, classStr, formStr, ptr);//RWC;tag->code); } } fprintf (src, " return l;\n"); fprintf (src, "}\n\n"); } /* end of BEnc function */ /* Do BDec function */ if (printDecodersG) { fprintf (hdr, " void B%s (const %s &_b, %s &bytesDecoded);\n", r->decodeBaseName, bufTypeNameG, lenTypeNameG); fprintf (src, "void %s::B%s (const %s &_b, %s &bytesDecoded)\n", td->cxxTypeDefInfo->className, r->decodeBaseName, bufTypeNameG, lenTypeNameG);//, envTypeNameG); fprintf (src, "{\n"); if (choice->tags->count > 0) fprintf (src, " FUNC(\"%s::B%s\")\n", td->cxxTypeDefInfo->className, r->decodeBaseName); fprintf (src, " %s elmtLen = 0;\n", lenTypeNameG); fprintf (src, " %s tag;\n", tagTypeNameG); /* print extra locals for redundant lengths */ for (i = 1; (choice->tags != NULL) && (i <= LIST_COUNT (choice->tags)); i++) { fprintf (src, " %s extraLen%d = 0;\n", lenTypeNameG, i); } fprintf (src, "\n"); /* decode tag/length pair (s) */ elmtLevel = 0; FOR_EACH_LIST_ELMT (tag, choice->tags) { classStr = Class2ClassStr (tag->tclass); formStr = Form2FormStr (CONS); /* choices are constructed */ fprintf (src, " AsnTag tagId = BDecTag (_b, bytesDecoded);\n"); fprintf (src, " if (tagId != "); if (tag->tclass == UNIV) { fprintf (src, "MAKE_TAG_ID (%s, %s, %s))", classStr, formStr, DetermineCode(tag, NULL, 0));//RWC;Code2UnivCodeStr (tag->code)); } else { fprintf (src, "MAKE_TAG_ID (%s, %s, %s))", classStr, formStr, DetermineCode(tag, NULL, 1));//RWC;tag->code); } fprintf (src, " {\n"); fprintf (src, " throw InvalidTagException(typeName(), tagId, STACK_ENTRY);\n"); fprintf (src, " }\n"); fprintf (src, " extraLen%d = BDecLen (_b, bytesDecoded);\n", ++elmtLevel); } /* decode identifying tag from choice body */ fprintf (src, " /* CHOICEs are a special case - grab identifying tag */\n"); fprintf (src, " /* this allows easier handling of nested CHOICEs */\n"); fprintf (src, " tag = BDecTag (_b, bytesDecoded);\n"); fprintf (src, " elmtLen = BDecLen (_b, bytesDecoded);\n"); fprintf (src, " B%s (_b, tag, elmtLen, bytesDecoded);\n", r->decodeContentBaseName); /* grab any EOCs that match redundant, indef lengths */ for (i = elmtLevel; i > 0; i--) { fprintf (src, " if (extraLen%d == INDEFINITE_LEN)\n", i); fprintf (src, " BDecEoc (_b, bytesDecoded);\n"); } fprintf (src, "}\n\n"); } /* end of BDec function */ if(genPERCode) { /* do PER Encode, PEnc function */ if (printEncodersG) { /****************************/ /*** FIRST, handle index encoding for PER Choice. Taking advantage of * the AsnInt class with constraints for the detailed encoding * details. Declare outside scope of source method for PEnc/PDec. */ fprintf (src, "class AsnIntChoice_%s: public AsnInt {\n", td->cxxTypeDefInfo->className); fprintf (src, " public:\n"); fprintf (src, " AsnIntChoice_%s(AsnIntType val=0):AsnInt(val){ }\n", td->cxxTypeDefInfo->className); fprintf (src, " ValueRange* ValueRanges(int &sizeVRList)\n"); fprintf (src, " {\n"); fprintf (src, " static ValueRange INT1_ValueRangeList[] = \n"); fprintf (src, " {{ 0, %d, 1 }};\n", choice->basicType->a.choice->count); /* CONSTANT value for this CHOICE. */ fprintf (src, " sizeVRList = 1;\n"); fprintf (src, " return INT1_ValueRangeList;\n"); fprintf (src, " }\n"); fprintf (src, "};\n\n"); //RWC;fprintf (hdr, " AsnLen PEnc(AsnBufBits &_b, bool bAlign = false) const {AsnLen len; len = 1;return len;};\n"); fprintf (hdr, " %s P%s (AsnBufBits &_b) const;\n", lenTypeNameG, r->encodeBaseName); fprintf (src, "%s %s::P%s (AsnBufBits &_b) const\n", lenTypeNameG, td->cxxTypeDefInfo->className, r->encodeBaseName); fprintf (src, "{\n"); fprintf (src, " %s l=0;\n", lenTypeNameG); fprintf (src, " FUNC(\"%s::P%s (AsnBufBits &_b)\");\n", td->cxxTypeDefInfo->className, r->encodeBaseName); /****************************/ /*** PERFORM sorting of Choice elements for proper index setting. */ PrintCxxDefCode_PERSort(&ppElementNamedType, &pElementTag, choice->basicType->a.choice); fprintf (src, " AsnIntChoice_%s TmpAsnIntChoice(%d);\n", td->cxxTypeDefInfo->className, choice->basicType->a.choice->count); /* CONSTANT value for this CHOICE. */ for (ii=0; ii < choice->basicType->a.choice->count; ii++) { fprintf (src, " if (%s == %s::%s)\n", r->choiceIdFieldName, td->cxxTypeDefInfo->className, ppElementNamedType[ii]->type->cxxTypeRefInfo->choiceIdSymbol); fprintf (src, " TmpAsnIntChoice.Set(%d); // SORTED index value.\n", ii); } // END FOR ii free(ppElementNamedType); free(pElementTag); /*** SETUP specific sorted index value. */ fprintf (src, " l = TmpAsnIntChoice.PEnc(_b); // LOAD PER encoded, constrained Choice index value.\n"); /****************************/ /*** NOW, setup each individual Choice element.*/ //RWC;fprintf (src, " l = P%s (_b);\n", r->encodeContentBaseName); /* print local vars */ //RWC;fprintf (src, " %s l=0;\n", lenTypeNameG); /* encode tag (s) & len (s) */ //PrintCxxTagAndLenEncodingCode (src, td, e->type, "l", "_b"); // RWC; TAGS already encoded if necessary above (non-UNIV). fprintf (src, " switch (%s)\n", r->choiceIdFieldName); fprintf (src, " {\n"); FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) { cxxtri = e->type->cxxTypeRefInfo; fprintf (src, " case %s:\n", cxxtri->choiceIdSymbol); varName = cxxtri->fieldName; /* encode content */ tmpTypeId = GetBuiltinType (e->type); if (tmpTypeId == BASICTYPE_ANYDEFINEDBY) { defByNamedType = e->type->basicType->a.anyDefinedBy->link; PrintCxxSetTypeByCode(defByNamedType, cxxtri, src); } else if (tmpTypeId == BASICTYPE_ANY) { fprintf (src, " l += %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "P%s (_b);\n", r->encodeBaseName); } else if ( (tmpTypeId == BASICTYPE_OCTETCONTAINING) || (tmpTypeId == BASICTYPE_BITCONTAINING)) { PrintCxxPEREncodeContaining(e->type, r, src); } else { fprintf (src, " l += %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "P%s (_b);\n", r->encodeBaseName); } fprintf (src, " break;\n\n"); } fprintf (src, " default:\n"); fprintf (src, " throw EXCEPT(\"Choice is empty\", ENCODE_ERROR);\n"); fprintf (src, " } // end switch\n"); /****************************/ fprintf (src, " return l;\n"); fprintf (src, "} //%s::P%s(...)\n\n", td->cxxTypeDefInfo->className, r->encodeBaseName); } /* END IF printEncodersG */ /* end of PEnc function */ /* Do PDec function */ if (printDecodersG) { fprintf (hdr, " void P%s (AsnBufBits &_b, %s &bitsDecoded);\n", r->decodeBaseName, lenTypeNameG); fprintf (src, "void %s::P%s (AsnBufBits &_b, %s &bitsDecoded)\n", td->cxxTypeDefInfo->className, r->decodeBaseName, lenTypeNameG);//, envTypeNameG); fprintf (src, "{\n"); fprintf (src, "\tClear();\n"); /* print extra locals for redundant lengths */ for (i = 1; (choice->tags != NULL) && (i <= LIST_COUNT (choice->tags)); i++) { //fprintf (src, " %s extraLen%d = 0; \n", lenTypeNameG, i); } fprintf (src, "\n"); /* decode tag/length pair (s) */ elmtLevel = 0; /****************************/ fprintf (src, " AsnIntChoice_%s TmpAsnIntChoice;\n", td->cxxTypeDefInfo->className); /*** SETUP specific sorted index value. */ fprintf (src, " TmpAsnIntChoice.PDec(_b, bitsDecoded); // LOAD PER decoded, constrained Choice index value.\n"); /* decode identifying tag from choice body */ fprintf (src, " /* CHOICEs are a special case - grab identifying tag */\n"); fprintf (src, " /* this allows easier handling of nested CHOICEs */\n"); /* print local vars */ /* count max number of extra length var nec * by counting tag/len pairs on components of the CHOICE */ varCount = 0; FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) { tmpVarCount = CxxCountVariableLevels (e->type); if (tmpVarCount > varCount) varCount = tmpVarCount; } /*** PERFORM sorting of Choice elements for proper index setting, then determine actual Choice chosen by the user. */ PrintCxxDefCode_PERSort(&ppElementNamedType, &pElementTag, choice->basicType->a.choice); for (ii=0; ii < choice->basicType->a.choice->count; ii++) { fprintf (src, " if (TmpAsnIntChoice == %d)\n", ii); fprintf (src, " {\n"); fprintf (src, " %s = %s::%s;\n", r->choiceIdFieldName, td->cxxTypeDefInfo->className, ppElementNamedType[ii]->type->cxxTypeRefInfo->choiceIdSymbol); /* Process specific tag - choices always have the key tag decoded */ e = ppElementNamedType[ii]; cxxtri = e->type->cxxTypeRefInfo; varName = cxxtri->fieldName; /* alloc elmt if nec */ if (cxxtri->isPtr) { fprintf (src, " %s = new %s;\n", varName, cxxtri->className); } /* decode content */ tmpTypeId = GetBuiltinType (e->type); if (tmpTypeId == BASICTYPE_ANYDEFINEDBY) { /* * must check for another EOC for ANYs * since the any decode routines decode * their own first tag/len pair */ elmtLevel++; defByNamedType = e->type->basicType->a.anyDefinedBy->link; PrintCxxSetTypeByCode(defByNamedType, cxxtri, src); fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "P%s (_b, bitsDecoded);\n", r->decodeBaseName); } else if (tmpTypeId == BASICTYPE_ANY) { elmtLevel++; fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "P%s (_b, bitsDecoded);\n", r->decodeBaseName); } else if ( (tmpTypeId == BASICTYPE_OCTETCONTAINING) || (tmpTypeId == BASICTYPE_BITCONTAINING) ) { PrintCxxPERDecodeContaining(e->type, r, src); } else { fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "P%s (_b, bitsDecoded);\n", r->decodeBaseName); } fprintf (src, " } // END if this Choice ID chosen\n"); } // END FOR ii free(ppElementNamedType); free(pElementTag); fprintf (src, "} // END %s::P%s(...)\n\n", td->cxxTypeDefInfo->className, r->decodeBaseName); } /* end of PDec function */ } /* if genPERCode */ /* ostream printing routine */ if (printPrintersG) { fprintf(hdr, "\tvoid Print(std::ostream& os, unsigned short indent = 0) const;\n"); fprintf(src, "void %s::Print(std::ostream& os, unsigned short indent) const\n", td->cxxTypeDefInfo->className); fprintf(src, "{\n"); fprintf(src, "\tswitch (choiceId)\n"); fprintf(src, "\t{\n"); FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) { fprintf (src, "\tcase %s:\n", e->type->cxxTypeRefInfo->choiceIdSymbol); /* value notation so print the choice elmts field name */ if (e->fieldName != NULL) fprintf(src, "\t\tos << \"%s \";\n", e->fieldName); if (e->type->cxxTypeRefInfo->isPtr) { fprintf(src, "\t\tif (%s)\n", e->type->cxxTypeRefInfo->fieldName); fprintf(src, "\t\t\t%s->Print(os, indent);\n", e->type->cxxTypeRefInfo->fieldName); fprintf(src, "\t\telse\n"); fprintf(src, "\t\t\tos << \"\\n\";\n"); } else { fprintf(src, "\t\t%s.Print(os, indent);\n", e->type->cxxTypeRefInfo->fieldName); } fprintf (src, "\t\tbreak;\n\n"); } fprintf (src, "\t} // end of switch\n"); fprintf (src, "} // end of %s::Print()\n\n", td->cxxTypeDefInfo->className); /* ################################################################## */ /* RWC;1/12/00; ADDED XML output capability. */ fprintf (hdr, " void PrintXML (std::ostream &os, const char *lpszTitle=NULL) const;\n"); fprintf (src, "void %s::PrintXML (std::ostream &os, const char *lpszTitle) const\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " if (lpszTitle)\n"); fprintf (src, " {\n"); fprintf (src, " os << \"<\" << lpszTitle;\n"); fprintf (src, " os << \" typeName=\\\"%s\\\" type=\\\"CHOICE\\\">\";\n", td->cxxTypeDefInfo->className); fprintf (src, " }\n"); fprintf (src, " else\n"); fprintf (src, " os << \"<%s type=\\\"CHOICE\\\">\";\n", td->cxxTypeDefInfo->className); fprintf (src, " switch (choiceId)\n"); fprintf (src, " {\n"); FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) { fprintf (src, " case %s:\n", e->type->cxxTypeRefInfo->choiceIdSymbol); /* value notation so print the choice elmts field name */ if (e->type->cxxTypeRefInfo->isPtr) { fprintf (src, " if (%s)\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " %s->PrintXML(os", e->type->cxxTypeRefInfo->fieldName); if (e->fieldName != NULL) fprintf (src, ",\"%s\");\n", e->fieldName); else fprintf (src, ");\n"); fprintf (src, " else\n"); fprintf (src, " {\n"); if (e->fieldName != NULL) { fprintf (src, " os << \"<%s -- void3 -- /%s>\" << std::endl;\n", e->fieldName, e->fieldName); } else { fprintf (src, " os << \"<%s -- void3 -- /%s>\" << std::endl;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->fieldName); } fprintf (src, " }\n"); } else fprintf (src, " %s.PrintXML(os, \"%s\");\n", e->type->cxxTypeRefInfo->fieldName, e->fieldName); fprintf (src, " break;\n\n"); } fprintf (src, " } // end of switch\n"); fprintf (src, " if (lpszTitle)\n"); fprintf (src, " os << \"\";\n"); fprintf (src, " else\n"); fprintf (src, " os << \"\";\n", td->cxxTypeDefInfo->className); fprintf (src, "} // %s::PrintXML\n\n", td->cxxTypeDefInfo->className); /* END XML Print capability. */ /* ################################################################## */ } /* end of Print Method code */ /* close class definition */ fprintf (hdr, "};\n\n\n"); novolatilefuncs = novolatilefuncs; parent=parent; /*AVOIDS warning.*/ } /* PrintCxxChoiceDefCode */ static void PrintCxxSeqDefCode (FILE *src, FILE *hdr, ModuleList *mods, Module *m, CxxRules *r ,TypeDef *td, Type *parent, Type *seq, int novolatilefuncs) { NamedType *e; char *classStr; char *formStr; char *codeStr; int tagLen, i=0; Tag *tag; TagList *tags; char *varName; CxxTRI *cxxtri=NULL; int elmtLevel=0; int varCount, tmpVarCount; int stoleChoiceTags; int inTailOptElmts; enum BasicTypeChoiceId tmpTypeId; NamedType *defByNamedType; NamedType *tmpElmt; int allOpt; // DEFINE PER encode/decode tmp vars. NamedType **pSeqElementNamedType=NULL; int ii; int extensionAdditionFound = FALSE; /* put class spec in hdr file */ char *ptr=""; /* NOT DLL Exported, or ignored on Unix. */ if (bVDAGlobalDLLExport != NULL) ptr = bVDAGlobalDLLExport; fprintf (hdr, "class %s %s%s\n", ptr, td->cxxTypeDefInfo->className, baseClassesG); fprintf (hdr, "{\n"); fprintf (hdr, "public:\n"); /* write out the sequence elmts */ FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence) { fprintf (hdr, " "); /* JKG 7/31/03 */ /*The following code enclosed in this if/else statement */ /*is constructed for constraint handling capability */ /*for primitives found in sequences or sets */ if(e->type->subtypes!=NULL) { switch(e->type->subtypes->choiceId) { case SUBTYPE_AND: case SUBTYPE_OR: case SUBTYPE_SINGLE: { if(!PrintCxxMultiConstraintOrHandler(hdr, src, td->cxxTypeDefInfo->className, e, 1)) { PrintCxxType (hdr, mods, m, r, td, seq, e->type); fprintf (hdr, "%s;\n\n", e->type->cxxTypeRefInfo->fieldName); } break; } default: { PrintCxxType (hdr, mods, m, r, td, seq, e->type); fprintf (hdr, "%s;\n\n", e->type->cxxTypeRefInfo->fieldName); break; } } } else { PrintCxxType (hdr, mods, m, r, td, seq, e->type); fprintf (hdr, "%s;\n\n", e->type->cxxTypeRefInfo->fieldName); } fprintf (hdr, "\n"); } #if META if (printMetaG) { PrintCxxSeqDefCodeMeta_1(hdr, src, td, seq, m, e) } #endif /* META */ /* constructors and destructor: */ /* Default constructor */ fprintf (hdr, " %s() {Init();}\n", td->cxxTypeDefInfo->className); /* Init() member function */ fprintf (hdr, " void Init(void);\n"); fprintf (src, "void %s::Init(void)\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence) { if ((e->type->cxxTypeRefInfo->isPtr)) { #if TCL fprintf (src, "#if TCL\n"); fprintf (src, " %s = new %s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className); fprintf (src, "#else\n"); fprintf (src, " %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, "#endif // TCL\n"); #else /* Default member initialization is a work in progress for eSNACC 1.6 */ /* initialize default members to their default values */ if (e->type->defaultVal != NULL) { Value *defVal = GetValue(e->type->defaultVal->value); /* HANDLE DEFAULT VALUE DECODING FOR DER by initializing the respective members to their default * values. */ switch(ParanoidGetBuiltinType(e->type)) { case BASICTYPE_INTEGER: case BASICTYPE_ENUMERATED: fprintf(src," %s = new %s(%d);\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className, defVal->basicValue->a.integer); break; case BASICTYPE_BOOLEAN: fprintf(src," %s = new %s(%s);\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className, defVal->basicValue->a.boolean == 0 ? "false": "true"); break; case BASICTYPE_BITSTRING: { NamedNumberList *pNNL = GetNamedElmts(e->type); BasicValue *pBV; pBV = GetLastNamedNumberValue(pNNL); if (defVal->basicValue->choiceId == BASICVALUE_VALUENOTATION && pBV != NULL) { char *defBitStr; normalizeValue(&defBitStr, defVal->basicValue->a.valueNotation->octs); fprintf(src," %s = new %s(%d);\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className, pBV->a.integer); fprintf(src, " %s->SetBit(%s::%s);\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className, defBitStr); free(defBitStr); } else printf("\nWARNING: unsupported use of default BIT STRING\n"); } break; default: { fprintf (src, " %s = new %s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className); } } /* end switch */ } else { if(e->type->optional) { fprintf (src, " %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName); } else { fprintf (src, " %s = new %s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className); } } /* end of default member initialization */ #endif /* TCL */ } } fprintf (src, "}\n\n"); /* virtual destructor */ fprintf (hdr, " virtual ~%s() {Clear();}\n", td->cxxTypeDefInfo->className); /* Clear() member */ fprintf (hdr, " void Clear();\n"); /*JKG: 7/30/03 -- virtual check Constraints method*/ fprintf(hdr, "\n\tint checkConstraints(ConstraintFailList* pConstraintFails) const;\n\n"); fprintf(src, "\nint %s::checkConstraints(ConstraintFailList* pConstraintFails) const{\n", td->cxxTypeDefInfo->className); FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence) { if (e->type->cxxTypeRefInfo->isPtr) { fprintf(src, "\tif (%s != NULL)\n", e->type->cxxTypeRefInfo->fieldName); fprintf(src, "\t\t%s->checkConstraints(pConstraintFails);\n\n", e->type->cxxTypeRefInfo->fieldName); } else { fprintf(src, "\t%s.checkConstraints(pConstraintFails);\n\n", e->type->cxxTypeRefInfo->fieldName); } } fprintf(src, "\treturn 0;\n"); fprintf(src, "}\n\n\n"); fprintf (src, "void %s::Clear()\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence) { tmpTypeId = GetBuiltinType (e->type); if (e->type->cxxTypeRefInfo->isPtr) { fprintf (src, " if(%s)\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " delete %s;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName); } else if(!e->type->cxxTypeRefInfo->isPtr && ((tmpTypeId == BASICTYPE_CHOICE) || (tmpTypeId == BASICTYPE_SET) || (tmpTypeId == BASICTYPE_SEQUENCE)) ) { fprintf (src, " %s.Clear();\n", e->type->cxxTypeRefInfo->fieldName); } } fprintf (src, "}\n\n"); /* PIERCE 8-22-2001 */ PrintCopyConstructor(hdr, src, td->cxxTypeDefInfo->className); PrintSimpleMeta(hdr, td->cxxTypeDefInfo->className,0); /* print clone routine for ANY mgmt */ PrintCloneMethod (hdr, src, td); /* print operator = overload */ fprintf (hdr, " %s &operator = (const %s &that);\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, "%s &%s::operator = (const %s &that)\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " if (this != &that)\n"); fprintf (src, " {\n"); fprintf (src, " Clear();\n"); FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence) { if (e->type->cxxTypeRefInfo->isPtr) { fprintf (src, " if (that.%s)\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " {\n"); fprintf (src, " if (!%s)\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " %s = new %s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className); fprintf (src, " *%s = *that.%s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->fieldName); fprintf (src, " }\n"); fprintf (src, " else\n"); fprintf (src, " {\n"); fprintf (src, " delete %s;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " }\n"); } else { fprintf (src, " %s = that.%s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->fieldName); } } fprintf (src, " }\n"); fprintf (src, "\n"); fprintf (src, " return *this;\n"); fprintf (src, "}\n\n"); /* BerEncodeContent method */ if (printEncodersG) { fprintf(hdr, " %s B%s (%s &_b) const;\n", lenTypeNameG, r->encodeContentBaseName, bufTypeNameG); fprintf(src, "%s\n", lenTypeNameG); fprintf(src, "%s::B%s (%s &_b) const\n", td->cxxTypeDefInfo->className, r->encodeContentBaseName, bufTypeNameG); fprintf(src, "{\n"); /* print local vars */ fprintf(src, " %s totalLen = 0;\n", lenTypeNameG); fprintf(src, " %s l=0;\n\n", lenTypeNameG); FOR_EACH_LIST_ELMT_RVS (e, seq->basicType->a.sequence) { cxxtri = e->type->cxxTypeRefInfo; varName = cxxtri->fieldName; /* print optional test if nec */ if (e->type->defaultVal != NULL) { Value *defVal = GetValue(e->type->defaultVal->value); /* HANDLE DEFAULT VALUE ENCODING FOR DER */ switch(ParanoidGetBuiltinType(e->type)) { case BASICTYPE_INTEGER: case BASICTYPE_ENUMERATED: fprintf(src," if ( %s(%s) && *%s != %d )\n {\n", cxxtri->optTestRoutineName, varName, varName, defVal->basicValue->a.integer); break; case BASICTYPE_BITSTRING: { if (defVal->basicValue->choiceId == BASICVALUE_VALUENOTATION) { char *defBitStr; normalizeValue(&defBitStr, defVal->basicValue->a.valueNotation->octs); fprintf(src, " if (%s(%s) && (!%s->soloBitCheck(%s::%s))) {\n", cxxtri->optTestRoutineName, varName, varName, cxxtri->className, defBitStr); free(defBitStr); } else { fprintf(errFileG, "WARNING: unsupported use of default BIT STRING\n"); } } break; case BASICTYPE_BOOLEAN: fprintf(src, " if (%s(%s) && *%s != %s ) {\n", cxxtri->optTestRoutineName, varName, varName, defVal->basicValue->a.boolean ? "true" : "false"); break; default: fprintf(src, " if (%s) {\n", varName); break; } } else if (e->type->optional) { fprintf(src, " if (%s(%s)) {\n", cxxtri->optTestRoutineName, varName); } /* eSNACC does not encode indefinite length * * PrintCxxEocEncoders (src, td, e->type, "_b"); */ /* encode content */ tmpTypeId = GetBuiltinType (e->type); if (tmpTypeId == BASICTYPE_ANYDEFINEDBY) { defByNamedType = e->type->basicType->a.anyDefinedBy->link; PrintCxxSetTypeByCode(defByNamedType, cxxtri, src); fprintf (src, " l = %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "B%s (_b);\n", r->encodeBaseName); } else if (tmpTypeId == BASICTYPE_ANY) { fprintf (src, " l = %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "B%s (_b);\n", r->encodeBaseName); } else if ( (tmpTypeId == BASICTYPE_OCTETCONTAINING) || (tmpTypeId == BASICTYPE_BITCONTAINING)) { PrintCxxEncodeContaining(e->type, r, src); } else if ( tmpTypeId == BASICTYPE_EXTENSION ) { fprintf (src, " l = %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "BEnc (_b);\n"); } else { fprintf (src, " l = %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "B%s (_b);\n", r->encodeContentBaseName); } /* encode tag (s) & len (s) */ PrintCxxTagAndLenEncodingCode (src, td, e->type, "l", "_b"); fprintf (src, " totalLen += l;\n"); /* close optional test if nec */ if (e->type->optional || (e->type->defaultVal != NULL)) fprintf (src, " }\n\n"); else fprintf (src, "\n"); } fprintf (src, " return totalLen;\n"); fprintf (src, "} // %s::B%s\n\n\n", td->cxxTypeDefInfo->className, r->encodeContentBaseName); } /* end of BerEncodeContent method printing code */ /* write BerDecodeContent to src */ if (printDecodersG) { fprintf (hdr, " void B%s (const %s &_b, %s tag, %s elmtLen, %s &bytesDecoded);\n\n", r->decodeContentBaseName, bufTypeNameG, tagTypeNameG, lenTypeNameG, lenTypeNameG);//, envTypeNameG); fprintf (src, "void %s::B%s (const %s &_b, %s /*tag0*/, %s elmtLen0, %s &bytesDecoded)\n", td->cxxTypeDefInfo->className, r->decodeContentBaseName, bufTypeNameG, tagTypeNameG, lenTypeNameG, lenTypeNameG);//, envTypeNameG); fprintf (src, "{\n"); fprintf (src, " FUNC(\" %s::B%s\");\n", td->cxxTypeDefInfo->className, r->decodeContentBaseName); fprintf (src, " Clear();\n"); /* PL: removed to avoid used variable warning fprintf (src, " AsnBufLoc readLoc = _b.GetReadLoc();\n"); */ /* print local vars */ fprintf (src, " %s tag1 = %s();\n", tagTypeNameG, tagTypeNameG); fprintf (src, " %s seqBytesDecoded = 0;\n", lenTypeNameG); /* count max number of extra length var nec */ varCount = 0; FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence) { tmpVarCount = CxxCountVariableLevels (e->type); if (tmpVarCount > varCount) varCount = tmpVarCount; } /* write extra length vars */ for (i = 1; i <= varCount; i++) fprintf (src, " %s elmtLen%d = 0;\n", lenTypeNameG, i); /* handle empty seq */ if ((seq->basicType->a.sequence == NULL) || LIST_EMPTY (seq->basicType->a.sequence)) { fprintf (src, " if (elmtLen0 == INDEFINITE_LEN)\n"); fprintf (src, " BDecEoc (_b, bytesDecoded);\n"); fprintf (src, " else if (elmtLen0 != 0)\n"); fprintf (src, " {\n"); fprintf (src, " throw EXCEPT(\"Expected an empty sequence\", DECODE_ERROR);\n"); fprintf (src, " }\n"); } else { /* check if all elmts are optional */ AsnListFirst (seq->basicType->a.sequence); inTailOptElmts = IsTailOptional (seq->basicType->a.sequence); e = (NamedType*)FIRST_LIST_ELMT (seq->basicType->a.sequence); tmpTypeId = GetBuiltinType (e->type); if (!inTailOptElmts) { if (((tmpTypeId == BASICTYPE_ANY) || (tmpTypeId == BASICTYPE_ANYDEFINEDBY)) && (CountTags (e->type) == 0)) { if ((e->type->optional) && (e != (NamedType*)LAST_LIST_ELMT (seq->basicType->a.sequence))) fprintf (src, "\n"); } else fprintf (src, " tag1 = BDecTag (_b, seqBytesDecoded);\n\n"); } else { fprintf (src, " if (elmtLen0 == 0)\n"); fprintf (src, " return;\n"); fprintf (src, " else\n"); fprintf (src, " {\n"); if (((tmpTypeId == BASICTYPE_ANY) || (tmpTypeId == BASICTYPE_ANYDEFINEDBY)) && (CountTags (e->type) == 0)) { if ((e->type->optional) && (e != (NamedType*)LAST_LIST_ELMT (seq->basicType->a.sequence))) fprintf (src, "\n"); } else fprintf (src, " tag1 = BDecTag (_b, seqBytesDecoded);\n\n"); fprintf (src, " if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))\n"); fprintf (src, " {\n"); fprintf (src, " BDEC_2ND_EOC_OCTET (_b, seqBytesDecoded);\n"); fprintf (src, " bytesDecoded += seqBytesDecoded;\n"); fprintf (src, " return;\n"); fprintf (src, " }\n"); fprintf (src, " }\n\n"); } /***********************************************************************/ /***********************************************************************/ /***********************************************************************/ FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence) { if( e->type->basicType->choiceId != BASICTYPE_EXTENSION ) { cxxtri = e->type->cxxTypeRefInfo; elmtLevel = 0; tags = GetTags (e->type, &stoleChoiceTags); if (LIST_EMPTY (tags)) fprintf (src, " // ANY type\n"); else { tag = (Tag*)FIRST_LIST_ELMT (tags); classStr = Class2ClassStr (tag->tclass); codeStr = DetermineCode(tag, NULL, 0);//RWC;Code2UnivCodeStr (tag->code); formStr = Form2FormStr (tag->form); fprintf (src, " if ("); if (tag->tclass == UNIV) { if (tag->form == ANY_FORM) { fprintf (src, "(tag1 == MAKE_TAG_ID (%s, %s, %s))\n", classStr, Form2FormStr (PRIM), codeStr); fprintf (src, " || (tag1 == MAKE_TAG_ID (%s, %s, %s))", classStr, Form2FormStr (CONS), codeStr); } else fprintf (src, "(tag1 == MAKE_TAG_ID (%s, %s, %s))", classStr, formStr, codeStr); } else { if (tag->form == ANY_FORM) { fprintf (src, "(tag1 == MAKE_TAG_ID (%s, %s, %s))\n", classStr, Form2FormStr (PRIM), DetermineCode(tag, NULL, 1));//RWC;tag->code); fprintf (src, " || (tag1 == MAKE_TAG_ID (%s, %s, %s))", classStr, Form2FormStr (CONS), DetermineCode(tag, NULL, 1));//RWC;tag->code); } else fprintf (src, "(tag1 == MAKE_TAG_ID (%s, %s, %s))", classStr, formStr, DetermineCode(tag, NULL, 1));//RWC;tag->code); } /* now decode extra tags/length pairs */ AsnListFirst (tags); AsnListNext (tags); if (stoleChoiceTags) { FOR_REST_LIST_ELMT (tag, tags) { fprintf (src, "\n || "); classStr = Class2ClassStr (tag->tclass); formStr = Form2FormStr (tag->form); if (tag->tclass == UNIV) codeStr = DetermineCode(tag, NULL, 0);//RWC;Code2UnivCodeStr (tag->code); else codeStr = DetermineCode(tag, NULL, 1); if (tag->form == ANY_FORM) { fprintf (src, "(tag1 == MAKE_TAG_ID (%s, %s, %s))\n", classStr, Form2FormStr (PRIM), codeStr); fprintf (src, " || (tag1 == MAKE_TAG_ID (%s, %s, %s))", classStr, Form2FormStr (CONS), codeStr); } else { fprintf (src, "(tag1 == MAKE_TAG_ID (%s, %s, %s))", classStr, formStr, codeStr); } } fprintf (src, ")\n"); fprintf (src, " {\n"); fprintf (src, " elmtLen%d = BDecLen (_b, seqBytesDecoded);\n", ++elmtLevel); } else /* didn't steal nested choice's tags */ { fprintf (src, ")\n"); fprintf (src, " {\n"); fprintf (src, " elmtLen%d = BDecLen (_b, seqBytesDecoded);\n", ++elmtLevel); FOR_REST_LIST_ELMT (tag, tags) { classStr = Class2ClassStr (tag->tclass); formStr = Form2FormStr (tag->form); fprintf (src, " tag1 = BDecTag (_b, seqBytesDecoded);\n\n"); if (tag->tclass == UNIV) codeStr = DetermineCode(tag, NULL, 0);//RWC;Code2UnivCodeStr (tag->code); else codeStr = DetermineCode(tag, NULL, 1); if (tag->form == ANY_FORM) { fprintf (src, " if ((tag1 != MAKE_TAG_ID (%s, %s, %s))\n", classStr, Form2FormStr (PRIM), codeStr); fprintf (src, " && (tag1 != MAKE_TAG_ID (%s, %s, %s)))\n", classStr, Form2FormStr (CONS), codeStr); } else fprintf (src, " if (tag1 != MAKE_TAG_ID (%s, %s, %s))\n", classStr, formStr, codeStr); fprintf (src, " {\n"); fprintf (src, " throw InvalidTagException(typeName(), tag1, STACK_ENTRY);\n"); fprintf (src, " }\n\n"); fprintf (src, " elmtLen%d = BDecLen (_b, seqBytesDecoded);\n", ++elmtLevel); } } } /* * if this seq element is CHOICE && * we didn't steal its tags then we must grab * the key tag out of the contained CHOICE */ if (!stoleChoiceTags && (GetBuiltinType (e->type) == BASICTYPE_CHOICE)) { fprintf (src, " tag1 = BDecTag (_b, seqBytesDecoded);\n"); fprintf (src, " elmtLen%d = BDecLen (_b, seqBytesDecoded);\n", ++elmtLevel); } varName = cxxtri->fieldName; /* decode content */ if (cxxtri->isPtr) { if (e->type->defaultVal) { fprintf(src, " // delete default value\n"); fprintf(src, " delete %s;\n", varName); } fprintf (src, " %s = new %s;\n", varName, cxxtri->className); } /* decode content */ tmpTypeId = GetBuiltinType (e->type); if (tmpTypeId == BASICTYPE_ANYDEFINEDBY) { /* * must check for another EOC for ANYs * since the any decode routines decode * their own first tag/len pair */ elmtLevel++; defByNamedType = e->type->basicType->a.anyDefinedBy->link; PrintCxxSetTypeByCode(defByNamedType, cxxtri, src); fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "B%s (_b, seqBytesDecoded);\n", r->decodeBaseName); } else if (tmpTypeId == BASICTYPE_ANY) { elmtLevel++; fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "B%s (_b, seqBytesDecoded);\n", r->decodeBaseName); } else if ( (tmpTypeId == BASICTYPE_OCTETCONTAINING) || (tmpTypeId == BASICTYPE_BITCONTAINING) ) { PrintCxxDecodeContaining(e->type, r, src); } else { fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "B%s (_b, tag1, elmtLen%d, seqBytesDecoded);\n", r->decodeContentBaseName, elmtLevel); } /* decode Eoc (s) */ for (i = elmtLevel-1; i > 0; i--) { fprintf (src, " if (elmtLen%d == INDEFINITE_LEN)\n", i); fprintf (src, " BDecEoc (_b, seqBytesDecoded);\n\n"); } /* * print code for getting the next tag */ inTailOptElmts = RestAreTailOptional (seq->basicType->a.sequence); if (e != (NamedType*)LAST_LIST_ELMT (seq->basicType->a.sequence)) { tmpElmt = (NamedType*)NEXT_LIST_ELMT (seq->basicType->a.sequence); tmpTypeId = GetBuiltinType (tmpElmt->type); if (!inTailOptElmts) { if ((tmpTypeId == BASICTYPE_ANY || tmpTypeId == BASICTYPE_ANYDEFINEDBY) && CountTags (tmpElmt->type) == 0) { /* don't get a tag since ANY's decode their own */ if (e->type->optional || (tmpElmt->type->optional && tmpElmt != (NamedType*)LAST_LIST_ELMT (seq->basicType->a.sequence))) /* let this cause a compile error in the generated code */ fprintf (src, " \n"); } else { if(!tmpElmt->type->extensionAddition) { fprintf (src, " tag1 = BDecTag (_b, seqBytesDecoded);\n"); } } } else { fprintf (src, " if (seqBytesDecoded == elmtLen0)\n"); fprintf (src, " {\n"); fprintf (src, " bytesDecoded += seqBytesDecoded;\n"); fprintf (src, " return;\n"); fprintf (src, " }\n"); fprintf (src, " else\n"); fprintf (src, " {\n"); if ((tmpTypeId == BASICTYPE_ANY || tmpTypeId == BASICTYPE_ANYDEFINEDBY) && !CountTags (tmpElmt->type)) { /* don't get a tag since ANY's decode their own */ if (e->type->optional || (tmpElmt->type->optional && tmpElmt != (NamedType *)LAST_LIST_ELMT (seq->basicType->a.sequence))) { /* * let this cause a compile error in the generated code */ fprintf (src, " \n"); } fprintf (src, " tag1 = _b.PeekByte();\n\n"); fprintf (src, " if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))\n"); fprintf (src, " {\n"); fprintf (src, " BDecEoc (_b, seqBytesDecoded);\n\n"); fprintf (src, " bytesDecoded += seqBytesDecoded;\n"); fprintf (src, " return;\n"); fprintf (src, " }\n"); } else if (tmpTypeId == BASICTYPE_EXTENSION) { fprintf (src, " tag1 = _b.PeekByte();\n\n"); fprintf (src, " if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))\n"); fprintf (src, " {\n"); fprintf (src, " BDecEoc (_b, seqBytesDecoded);\n\n"); fprintf (src, " bytesDecoded += seqBytesDecoded;\n"); fprintf (src, " return;\n"); fprintf (src, " }\n"); } else { fprintf (src, " tag1 = BDecTag (_b, seqBytesDecoded);\n\n"); fprintf (src, " if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))\n"); fprintf (src, " {\n"); fprintf (src, " BDEC_2ND_EOC_OCTET (_b, seqBytesDecoded);\n"); fprintf (src, " bytesDecoded += seqBytesDecoded;\n"); fprintf (src, " return;\n"); fprintf (src, " }\n"); } fprintf (src, " }\n"); } } /* * close tag check if (if there is one) and * print else clause to handle missing non-optional elmt * errors */ tmpTypeId = GetBuiltinType (e->type); if ((tmpTypeId == BASICTYPE_ANYDEFINEDBY || tmpTypeId == BASICTYPE_ANY) && !CountTags (e->type)) { /* do nothing - no tag check if stmt to close */ fprintf (src, "\n\n"); } else if (!e->type->optional && !e->type->defaultVal) { fprintf (src, " }\n"); /* end of tag check if */ fprintf (src, " else\n"); fprintf (src, " {\n"); if(e->type->extensionAddition) { fprintf (src, " throw EXCEPT(\"SEQUENCE is missing non-optional expected extension addition elmt\", DECODE_ERROR);\n"); } else { fprintf (src, " throw EXCEPT(\"SEQUENCE is missing non-optional root elmt (%s)\", DECODE_ERROR);\n", e->fieldName); } fprintf (src, " }\n\n"); } else fprintf (src, " }\n\n"); /* end of tag check if */ FreeTags (tags); } else { extensionAdditionFound = TRUE; } } /***********************************************************************/ /***********************************************************************/ /***********************************************************************/ /* for last elmt only */ fprintf (src, " bytesDecoded += seqBytesDecoded;\n"); fprintf (src, " if (elmtLen0 == INDEFINITE_LEN)\n"); fprintf (src, " {\n"); if(extensionAdditionFound) { fprintf (src, " // keep grabbing any's into the extension list\n"); fprintf (src, " // until EOC is found\n"); fprintf (src, " bool b_not_EOC = true;\n"); fprintf (src, " while(b_not_EOC)\n"); fprintf (src, " {\n"); fprintf (src, " tag1 = _b.PeekByte();\n\n"); fprintf (src, " if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))\n"); fprintf (src, " {\n"); fprintf (src, " BDecEoc (_b, seqBytesDecoded);\n\n"); fprintf (src, " bytesDecoded += seqBytesDecoded;\n"); fprintf (src, " b_not_EOC = false;\n"); fprintf (src, " }\n"); fprintf (src, " else\n"); fprintf (src, " {\n"); fprintf (src, " AsnAny extAny;\n"); fprintf (src, " extAny.BDec(_b, seqBytesDecoded);\n"); fprintf (src, " extension.extList.insert(extension.extList.end(), extAny);\n"); fprintf (src, " }\n"); fprintf (src, " }\n"); } else { fprintf (src, " BDecEoc (_b, bytesDecoded);\n"); fprintf (src, " return;\n"); } fprintf (src, " }\n"); fprintf (src, " else if (seqBytesDecoded != elmtLen0)\n"); fprintf (src, " {\n"); if(extensionAdditionFound) { fprintf (src, " while(seqBytesDecoded < elmtLen0)\n"); fprintf (src, " {\n"); fprintf (src, " AsnAny extAny;\n"); fprintf (src, " extAny.BDec(_b, seqBytesDecoded);\n"); fprintf (src, " extension.extList.insert(extension.extList.end(), extAny);\n"); fprintf (src, " }\n"); fprintf (src, " return;\n"); } else { fprintf (src, " throw EXCEPT(\"Length discrepancy on sequence\", DECODE_ERROR);\n"); } fprintf (src, " }\n"); fprintf (src, " else\n"); fprintf (src, " return;\n"); } /* end of non-empty set else clause */ fprintf (src, "} // %s::B%s\n\n", td->cxxTypeDefInfo->className, r->decodeContentBaseName); } /* end of code for printing ber decode content method */ /* do BEnc function */ if (printEncodersG) { fprintf (hdr, " %s B%s (%s &_b) const;\n", lenTypeNameG, r->encodeBaseName, bufTypeNameG); fprintf (src, "%s %s::B%s (%s &_b) const\n", lenTypeNameG, td->cxxTypeDefInfo->className, r->encodeBaseName, bufTypeNameG); fprintf (src, "{\n"); fprintf (src, " %s l=0;\n", lenTypeNameG); fprintf (src, " l = B%s (_b);\n", r->encodeContentBaseName); /* encode each tag/len pair if any */ FOR_EACH_LIST_ELMT_RVS (tag, seq->tags) { classStr = Class2ClassStr (tag->tclass); formStr = Form2FormStr (CONS); /* seq's are constructed */ fprintf (src, " l += BEncConsLen (_b, l);\n"); if (tag->tclass == UNIV) { const char* ptr = DetermineCode(tag, &tagLen, 0); fprintf (src, " l += BEncTag%d (_b, %s, %s, %s);\n", tagLen, classStr, formStr, ptr);//RWC;Code2UnivCodeStr (tag->code)); } else { const char* ptr = DetermineCode(tag, &tagLen, 1); fprintf (src, " l += BEncTag%d (_b, %s, %s, %s);\n", tagLen, classStr, formStr, ptr);//RWC;tag->code); } } fprintf (src, " return l;\n"); fprintf (src, "}\n\n"); } /* end of BEnc function */ /* Do BDec function */ if (printDecodersG) { fprintf (hdr, " void B%s (const %s &_b, %s &bytesDecoded);\n", r->decodeBaseName, bufTypeNameG, lenTypeNameG);//, envTypeNameG); fprintf (src, "void %s::B%s (const %s &_b, %s &bytesDecoded)\n", td->cxxTypeDefInfo->className, r->decodeBaseName, bufTypeNameG, lenTypeNameG);//, envTypeNameG); fprintf (src, "{\n"); fprintf (src, " FUNC(\" %s::B%s\");\n", td->cxxTypeDefInfo->className, r->decodeBaseName); fprintf (src, " %s tag;\n", tagTypeNameG); /* print extra locals for redundant lengths */ for (i = 1; (seq->tags != NULL) && (i <= LIST_COUNT (seq->tags)); i++) fprintf (src, " %s elmtLen%d;\n", lenTypeNameG, i); fprintf (src, "\n"); /* decode tag/length pair (s) */ elmtLevel = 0; FOR_EACH_LIST_ELMT (tag, seq->tags) { classStr = Class2ClassStr (tag->tclass); formStr = Form2FormStr (CONS); /* seqs are constructed */ fprintf (src, " if ((tag = BDecTag (_b, bytesDecoded)) != "); if (tag->tclass == UNIV) fprintf (src, "MAKE_TAG_ID (%s, %s, %s))\n", classStr, formStr, DetermineCode(tag, NULL, 0));//RWC;Code2UnivCodeStr (tag->code)); else fprintf (src, "MAKE_TAG_ID (%s, %s, %s))\n", classStr, formStr, DetermineCode(tag, NULL, 1));//RWC;tag->code); fprintf (src, " {\n"); fprintf (src, " throw InvalidTagException(typeName(), tag, STACK_ENTRY);\n"); fprintf (src, " }\n"); fprintf (src, " elmtLen%d = BDecLen (_b, bytesDecoded);\n", ++elmtLevel); } fprintf (src, " B%s (_b, tag, elmtLen%d, bytesDecoded);\n", r->decodeContentBaseName, elmtLevel); /* grab any EOCs that match redundant, indef lengths */ for (i = elmtLevel-1; i > 0; i--) { fprintf (src, " if (elmtLen%d == INDEFINITE_LEN)\n", i); fprintf (src, " BDecEoc (_b, bytesDecoded);\n"); } fprintf (src, "}\n\n"); } /* end of BDec function */ if(genPERCode) { /* PER Encode, PerEnc */ if (printEncodersG) //RWC;TBD; SHOULD set printEncodersP with FLAG!!!! { /*** RWC;PRESENT. ***/ /* FIRST, create array containing all SEQUENCE elements. */ pSeqElementNamedType = (NamedType **)calloc( seq->basicType->a.sequence->count, sizeof(NamedType *)); ii = 0; FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence) { pSeqElementNamedType[ii++] = e; } /* END FOR each SEQUENCE element. */ /*RWC;ONLY FOR SET.PrintCxxDefCode_PERSort(&pSetElementNamedType, &pSetElementTag, set->basicType->a.set);*/ /* THIRD, perform actual encoding using SEQUENCE element pointers. * FOR_EACH_LIST_ELMT (e, set->basicType->a.set) */ PrintCxxDefCode_SetSeqPEREncode (src, hdr, r, td, pSeqElementNamedType, seq->basicType->a.sequence->count); } // END IF printEncodersG /* end of PerEncode */ /* PER Decode, PerDecode */ if (printDecodersG) { PrintCxxDefCode_SetSeqPERDecode (src, hdr, r, td, pSeqElementNamedType, seq->basicType->a.sequence->count); } } /* end of PerDecode */ if (pSeqElementNamedType) free(pSeqElementNamedType); /* write code for printing */ if (printPrintersG) { PrintCxxSeqSetPrintFunction(src, hdr, td->cxxTypeDefInfo->className, seq->basicType); /* ################################################################## RWC;1/12/00; ADDED XML output capability. */ fprintf (hdr, " void PrintXML (std::ostream &os, const char *lpszTitle=NULL) const;\n"); fprintf (src,"void %s::PrintXML (std::ostream &os, \n", td->cxxTypeDefInfo->className); fprintf (src," const char *lpszTitle) const\n"); fprintf (src, "{\n"); allOpt = AllElmtsOptional (seq->basicType->a.sequence); fprintf (src, " if (lpszTitle)\n"); fprintf (src, " {\n"); fprintf (src, " os << \"<\" << lpszTitle;\n"); fprintf (src, " if (typeName() && strlen(typeName()))\n"); fprintf (src, " {\n"); fprintf (src, " os << \" typeName=\\\"\" << typeName() << \"\\\"\";\n"); fprintf (src, " }\n"); fprintf (src, " }\n"); fprintf (src, " else\n"); fprintf (src, " {\n"); fprintf (src, " os << \"\" << std::endl;\n"); FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence) { inTailOptElmts = IsTailOptional (seq->basicType->a.sequence); if (e->type->cxxTypeRefInfo->isPtr) { fprintf (src, " if (%s (%s))\n", cxxtri->optTestRoutineName, e->type->cxxTypeRefInfo->fieldName); fprintf (src, " {\n"); fprintf (src, " %s->PrintXML(os", e->type->cxxTypeRefInfo->fieldName); if (e->fieldName != NULL) fprintf (src, ", \"%s\"", e->fieldName); fprintf (src, ");\n"); fprintf (src, " }\n"); } else { fprintf (src, " %s.PrintXML(os", e->type->cxxTypeRefInfo->fieldName); if (e->fieldName != NULL) fprintf (src, ", \"%s\"", e->fieldName); fprintf (src, ");\n"); } fprintf (src, "\n"); } fprintf (src, " if (lpszTitle)\n"); fprintf (src, " {\n"); fprintf (src, " os << \"\" << std::endl;\n"); fprintf (src, " }\n"); fprintf (src, " else\n"); fprintf (src, " if (typeName() && strlen(typeName()))\n"); fprintf (src, " {\n"); fprintf (src, " os << \"\" << std::endl;\n"); fprintf (src, " }\n"); fprintf (src, "} // %s::PrintXML\n\n\n", td->cxxTypeDefInfo->className); /* END XML Print capability. ################################################################## */ } /* end of print method code printer */ /* close class definition */ fprintf (hdr, "};\n\n\n"); novolatilefuncs = novolatilefuncs; parent=parent; /*AVOIDS warning.*/ } /* PrintCxxSeqDefCode */ static void PrintCxxSetDefCode (FILE *src, FILE *hdr, ModuleList *mods, Module *m, CxxRules *r, TypeDef *td, Type *parent, Type *set, int novolatilefuncs) { NamedType *e; char *classStr; char *formStr; char *codeStr; int tagLen; int i=0; Tag *tag; TagList *tags; char *varName; CxxTRI *cxxtri=NULL; int elmtLevel=0; int varCount, tmpVarCount; int stoleChoiceTags; int inTailOptElmts; int mandatoryElmtCount; enum BasicTypeChoiceId tmpTypeId; NamedType *defByNamedType; int allOpt; // DEFINE PER encode/decode tmp vars. int *pSetElementTag=NULL; NamedType **pSetElementNamedType=NULL; int extensionAdditions = FALSE; /* put class spec in hdr file */ char *ptr=""; /* NOT DLL Exported, or ignored on Unix. */ if (bVDAGlobalDLLExport != NULL) ptr = bVDAGlobalDLLExport; fprintf (hdr, "class %s %s%s\n", ptr, td->cxxTypeDefInfo->className, baseClassesG); fprintf (hdr, "{\n"); fprintf (hdr, "public:\n"); /* write out the set elmts */ FOR_EACH_LIST_ELMT (e, set->basicType->a.set) { fprintf (hdr, " "); /* JKG 7/31/03 */ /*The following code enclosed in this if/else statement */ /*is constructed for constraint handling capability */ /*for primitives found in sequences or sets */ if(e->type->subtypes!=NULL) { switch(e->type->subtypes->choiceId) { case SUBTYPE_AND: case SUBTYPE_OR: case SUBTYPE_SINGLE: { if(!PrintCxxMultiConstraintOrHandler(hdr, src, td->definedName, e, 1)) { PrintCxxType (hdr, mods, m, r, td, set, e->type); fprintf (hdr, "%s;\n\n", e->type->cxxTypeRefInfo->fieldName); } break; } default: { PrintCxxType (hdr, mods, m, r, td, set, e->type); fprintf (hdr, "%s;\n\n", e->type->cxxTypeRefInfo->fieldName); break; } } } else { PrintCxxType (hdr, mods, m, r, td, set, e->type); fprintf (hdr, "%s;\n\n", e->type->cxxTypeRefInfo->fieldName); } } fprintf (hdr, "\n"); #if META if (printMetaG) { PrintCxxSetDefCodeMeta_1(hdr, src, td, set, m, e); } #endif /* META */ /* Default constructor */ fprintf (hdr, " %s(){Init();}\n", td->cxxTypeDefInfo->className); /* Init() member function */ fprintf (hdr, " void Init(void);\n"); fprintf (src, "void %s::Init(void)\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); FOR_EACH_LIST_ELMT (e, set->basicType->a.set) { if (e->type->cxxTypeRefInfo->isPtr) { #if TCL fprintf (src, "#if TCL\n"); fprintf (src, " %s = new %s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className); fprintf (src, "#else // TCL\n"); fprintf (src, " %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName); #else if (e->type->defaultVal != NULL) { Value *defVal = GetValue(e->type->defaultVal->value); /* HANDLE DEFAULT VALUE DECODING FOR DER by initializing the respective members to their default * values. */ switch(ParanoidGetBuiltinType(e->type)) { case BASICTYPE_INTEGER: case BASICTYPE_ENUMERATED: fprintf(src," %s = new %s(%d);\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className, defVal->basicValue->a.integer); break; case BASICTYPE_BOOLEAN: fprintf(src," %s = new %s(%s);\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className, defVal->basicValue->a.boolean == 0 ? "false": "true"); break; case BASICTYPE_BITSTRING: { NamedNumberList *pNNL = GetNamedElmts(e->type); BasicValue *pBV; pBV = GetLastNamedNumberValue(pNNL); if (defVal->basicValue->choiceId == BASICVALUE_VALUENOTATION && pBV != NULL) { char *defBitStr; normalizeValue(&defBitStr, defVal->basicValue->a.valueNotation->octs); fprintf(src," %s = new %s(%d);\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className, pBV->a.integer); fprintf(src, " %s->SetBit(%s::%s);\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className, defBitStr); free(defBitStr); } else printf("\nWARNING: unsupported use of default BIT STRING\n"); } break; default: { fprintf (src, " %s = new %s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className); } } /* end switch */ } else { if(e->type->optional) { fprintf (src, " %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName); } else { fprintf (src, " %s = new %s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className); } } #endif } } fprintf (src, "}\n\n"); /* PIERCE added 8-22-2001 Simple META support */ PrintCopyConstructor(hdr, src, td->cxxTypeDefInfo->className); PrintSimpleMeta(hdr, td->cxxTypeDefInfo->className,0); /* virtual destructor */ fprintf (hdr, " virtual ~%s() {Clear();}\n", td->cxxTypeDefInfo->className); /* Clear() member*/ fprintf (hdr, " void Clear();\n"); fprintf (src, "void %s::Clear()\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); FOR_EACH_LIST_ELMT (e, set->basicType->a.set) { tmpTypeId = GetBuiltinType (e->type); if(e->type->cxxTypeRefInfo->isPtr){ /** * C++ > 1998 allows deletion of null pointer. * This means i hate old c++ */ fprintf (src, " delete %s;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName); } else if(!e->type->cxxTypeRefInfo->isPtr && ((tmpTypeId == BASICTYPE_CHOICE) || (tmpTypeId == BASICTYPE_SET) || (tmpTypeId == BASICTYPE_SEQUENCE)) ) { fprintf (src, " %s.Clear();\n", e->type->cxxTypeRefInfo->fieldName); } } fprintf (src, "}\n\n"); fprintf(hdr, "\n virtual int checkConstraints(ConstraintFailList* pConstraintFails) const;\n\n"); fprintf(src, "\nint %s::checkConstraints(ConstraintFailList* pConstraintFails) const\n{\n", td->cxxTypeDefInfo->className); FOR_EACH_LIST_ELMT (e, set->basicType->a.set) { if (e->type->cxxTypeRefInfo->isPtr) { fprintf(src, "\tif (%s != NULL)\n", e->type->cxxTypeRefInfo->fieldName); fprintf(src, "\t\t%s->checkConstraints(pConstraintFails);\n\n", e->type->cxxTypeRefInfo->fieldName); } else { fprintf(src, "\t\t%s.checkConstraints(pConstraintFails);\n\n", e->type->cxxTypeRefInfo->fieldName); } } fprintf(src, "\treturn 0;\n"); fprintf(src, "}\n\n\n"); /* print clone routine for ANY mgmt */ PrintCloneMethod (hdr, src, td); fprintf (hdr, " %s &operator = (const %s &that);\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, "%s &%s::operator = (const %s &that)\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " if (this != &that)\n"); fprintf (src, " {\n"); fprintf (src, " Clear();\n"); FOR_EACH_LIST_ELMT (e, set->basicType->a.set) { if (e->type->cxxTypeRefInfo->isPtr) { fprintf (src, " if (that.%s)\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " {\n"); fprintf (src, " if (!%s)\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " %s = new %s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className); fprintf (src, " *%s = *that.%s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->fieldName); fprintf (src, " }\n"); fprintf (src, " else\n"); fprintf (src, " {\n"); fprintf (src, " delete %s;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " }\n"); } else { fprintf (src, " %s = that.%s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->fieldName); } } fprintf (src, " }\n"); fprintf (src, "\n"); fprintf (src, " return *this;\n"); fprintf (src, "}\n\n"); /* BerEncode content*/ if (printEncodersG) { fprintf (hdr, " %s B%s (%s &_b) const;\n", lenTypeNameG, r->encodeContentBaseName, bufTypeNameG); fprintf (src, "%s %s::B%s (%s &_b) const\n", lenTypeNameG, td->cxxTypeDefInfo->className, r->encodeContentBaseName, bufTypeNameG); fprintf (src, "{\n"); /* print local vars */ fprintf (src, " %s totalLen = 0;\n", lenTypeNameG); fprintf (src, " %s l=0;\n\n", lenTypeNameG); /* PIERCE changed 11-05-2002 * use an std::list of AsnBuf instead of an array of CSM_Buffers to * sort the elements of the set. */ fprintf (src, " std::list bufList;\n"); fprintf (src, " std::list::iterator iBuf;\n"); FOR_EACH_LIST_ELMT_RVS (e, set->basicType->a.set) { cxxtri = e->type->cxxTypeRefInfo; varName = cxxtri->fieldName; /* print optional test if nec*/ if (e->type->optional || (e->type->defaultVal != NULL)) { fprintf (src, " if (%s (%s))\n", cxxtri->optTestRoutineName, varName); fprintf (src, " {\n"); } /* encode content */ tmpTypeId = GetBuiltinType (e->type); if (tmpTypeId == BASICTYPE_ANYDEFINEDBY) { fprintf(src, " iBuf = bufList.insert(bufList.begin(), AsnBuf());\n"); defByNamedType = e->type->basicType->a.anyDefinedBy->link; PrintCxxSetTypeByCode(defByNamedType, cxxtri, src); fprintf (src, " l = %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "B%s (*iBuf);\n", r->encodeBaseName); } else if (tmpTypeId == BASICTYPE_ANY) { fprintf(src, " iBuf = bufList.insert(bufList.begin(), AsnBuf());\n"); fprintf (src, " l = %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "B%s (*iBuf);\n", r->encodeBaseName); } else if ( (tmpTypeId == BASICTYPE_OCTETCONTAINING) || (tmpTypeId == BASICTYPE_BITCONTAINING)) { fprintf(src, " iBuf = bufList.insert(bufList.begin(), AsnBuf());\n"); PrintCxxEncodeContaining(e->type, r, src); } else if ( tmpTypeId == BASICTYPE_EXTENSION ) { fprintf (src, " l = %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "B%s (_b);\n", r->encodeBaseName); } else { fprintf(src, " iBuf = bufList.insert(bufList.begin(), AsnBuf());\n"); fprintf (src, " l = %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "B%s (*iBuf);\n", r->encodeContentBaseName); } /* encode tag (s) & len (s) */ PrintCxxTagAndLenEncodingCode (src, td, e->type, "l", "(*iBuf)"); fprintf (src, " totalLen += l;\n"); /** NOW, encode for SET DER rule ordering.*/ /** RWC; Buffers handle files or memory. **/ /* close optional test if nec */ if (e->type->optional || (e->type->defaultVal != NULL)) fprintf (src, " }\n\n"); else fprintf (src, "\n"); } #if 0 /** LAST, Order for SET DER rule ordering.*/ /** re-order all elements, add to "_b".*/ fprintf (src, " vdasnacc_sortSet(tmpEnc, iii);\n"); /** These "SET" components are now ordered in ascending order, ** ready to be loaded into the output buffer. (RWC; TBD; make output ** buffers accept these allocated buffers directly, no copy). **/ fprintf (src, " tmpCount = iii; /** REMEMBER how many we have**/\n"); fprintf (src, " for (iii=0; iii < tmpCount; iii++)\n"); fprintf (src, " SM_WriteToAsnBuf(tmpEnc[iii], _b);\n"); fprintf (src, " for (iii=0; iii < tmpCount; iii++) delete tmpEnc[iii];\n"); fprintf (src, " free(outputBuf.DataPtr());\n"); #endif fprintf (src, " sortSet(bufList);\n"); fprintf (src, " iBuf = bufList.begin();\n"); fprintf (src, " while(iBuf != bufList.end())\n"); fprintf (src, " {\n"); fprintf (src, " iBuf->ResetMode();\n"); fprintf (src, " _b.splice(*iBuf);\n"); fprintf (src, " iBuf++;\n"); fprintf (src, " }\n"); /** internal definition bracket for "tmpCount".**/ fprintf (src, " return totalLen;\n"); fprintf (src, "} // %s::B%s\n\n\n", td->cxxTypeDefInfo->className, r->encodeContentBaseName); } /* end of BerEncodeContent */ /* write BerDecodeContent */ if (printDecodersG) { fprintf (hdr, " void B%s (const %s &_b, %s tag, %s elmtLen, %s &bytesDecoded);\n\n", r->decodeContentBaseName, bufTypeNameG, tagTypeNameG, lenTypeNameG, lenTypeNameG);//, envTypeNameG); fprintf (src, "void %s::B%s (const %s &_b, %s /*tag0*/, %s elmtLen0, %s &bytesDecoded)\n", td->cxxTypeDefInfo->className, r->decodeContentBaseName, bufTypeNameG, tagTypeNameG, lenTypeNameG, lenTypeNameG);//, envTypeNameG); fprintf (src, "{\n"); fprintf (src, " FUNC(\"%s::B%s\");\n",td->cxxTypeDefInfo->className, r->decodeContentBaseName); fprintf (src, " Clear();\n"); fprintf (src, " AsnBufLoc readLoc;\n readLoc = _b.GetReadLoc();\n"); /* print local vars */ fprintf (src, " %s tag1 = %s();\n", tagTypeNameG, tagTypeNameG); fprintf (src, " %s setBytesDecoded = 0;\n", lenTypeNameG); fprintf (src, " unsigned int mandatoryElmtsDecoded = 0;\n"); /* count max number of extra length var nec */ varCount = 0; FOR_EACH_LIST_ELMT (e, set->basicType->a.set) { tmpVarCount = CxxCountVariableLevels (e->type); if (tmpVarCount > varCount) varCount = tmpVarCount; } /* write extra length vars */ for (i = 1; i <= varCount; i++) fprintf (src, " %s elmtLen%d;\n", lenTypeNameG, i); fprintf (src, "\n"); /* handle empty set */ if ((set->basicType->a.set == NULL) || LIST_EMPTY (set->basicType->a.set)) { fprintf (src, " if (elmtLen0 == INDEFINITE_LEN)\n"); fprintf (src, " BDecEoc (_b, bytesDecoded);\n"); fprintf (src, " else if (elmtLen0 != 0)\n"); fprintf (src, " {\n"); fprintf (src, " throw EXCEPT(\"Expected an empty sequence\", DECODE_ERROR);\n"); fprintf (src, " }\n"); } else { fprintf (src, " for (; (setBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN); )\n"); fprintf (src, " {\n"); fprintf (src, " readLoc = _b.GetReadLoc();\n"); fprintf (src, " tag1 = BDecTag (_b, setBytesDecoded);\n\n"); fprintf (src, " if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))\n"); fprintf (src, " {\n"); fprintf (src, " BDEC_2ND_EOC_OCTET (_b, setBytesDecoded);\n"); fprintf (src, " break; /* exit for loop */\n"); fprintf (src, " }\n"); fprintf (src, " elmtLen1 = BDecLen (_b, setBytesDecoded);\n"); fprintf (src, " switch (tag1)\n"); fprintf (src, " {\n"); mandatoryElmtCount = 0; FOR_EACH_LIST_ELMT (e, set->basicType->a.set) { if( e->type->basicType->choiceId != BASICTYPE_EXTENSION ) { cxxtri = e->type->cxxTypeRefInfo; tags = GetTags (e->type, &stoleChoiceTags); if (LIST_EMPTY (tags)) { fprintf (src, " // ANY Type ?\n"); fprintf (src, " case MAKE_TAG_ID (?, ?, ?):\n"); } else { tag = (Tag*)FIRST_LIST_ELMT (tags); classStr = Class2ClassStr (tag->tclass); formStr = Form2FormStr (tag->form); if (tag->tclass == UNIV) codeStr = DetermineCode(tag, NULL, 0);//RWC;Code2UnivCodeStr (tag->code); else codeStr = DetermineCode(tag, NULL, 1); if (tag->form == ANY_FORM) { fprintf (src, " case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (PRIM), codeStr); fprintf (src, " case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (CONS), codeStr); } else fprintf (src, " case MAKE_TAG_ID (%s, %s, %s):\n", classStr, formStr, codeStr); /* now decode extra tags/length pairs */ AsnListFirst (tags); AsnListNext (tags); elmtLevel = 1; if (stoleChoiceTags) { FOR_REST_LIST_ELMT (tag, tags) { classStr = Class2ClassStr (tag->tclass); formStr = Form2FormStr (tag->form); if (tag->tclass == UNIV) codeStr = DetermineCode(tag, NULL, 0);//RWC;Code2UnivCodeStr (tag->code); else codeStr = DetermineCode(tag, NULL, 1); if (tag->form == ANY_FORM) { fprintf (src, " case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (PRIM), codeStr); fprintf (src, " case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (CONS), codeStr); } else fprintf (src, " case MAKE_TAG_ID (%s, %s, %s):\n", classStr, formStr, codeStr); } } else /* didn't steal nested choice's tags */ { FOR_REST_LIST_ELMT (tag, tags) { classStr = Class2ClassStr (tag->tclass); codeStr = DetermineCode(tag, NULL, 0);//RWC;Code2UnivCodeStr (tag->code); formStr = Form2FormStr (tag->form); fprintf (src, " tag1 = BDecTag (_b, setBytesDecoded);\n"); if (tag->form == ANY_FORM) { if (tag->tclass == UNIV) { fprintf (src, " if ((tag1 != MAKE_TAG_ID (%s, %s, %s))\n", classStr, Form2FormStr (PRIM), codeStr); fprintf (src, " && (tag1 != MAKE_TAG_ID (%s, %s, %s)))\n", classStr, Form2FormStr (CONS), codeStr); } else { fprintf (src, " if ((tag1 != MAKE_TAG_ID (%s, %s, %s))\n", classStr, Form2FormStr (PRIM), DetermineCode(tag, NULL, 1));//RWC;tag->code); fprintf (src, " && (tag1 != MAKE_TAG_ID (%s, %s, %s)))\n", classStr, Form2FormStr (CONS), DetermineCode(tag, NULL, 1));//RWC;tag->code); } } else { if (tag->tclass == UNIV) fprintf (src, " if (tag1 != MAKE_TAG_ID (%s, %s, %s))\n", classStr, formStr, codeStr); else fprintf (src, " if (tag1 != MAKE_TAG_ID (%s, %s, %s))\n", classStr, formStr, DetermineCode(tag, NULL, 1));//RWC;tag->code); } fprintf (src, " {\n"); fprintf (src, " throw InvalidTagException(typeName(), tag1, STACK_ENTRY);\n"); fprintf (src, " }\n\n"); fprintf (src, " elmtLen%d = BDecLen (_b, setBytesDecoded);\n", ++elmtLevel); } } } /* * if the choices element is another choice && * we didn't steal its tags then we must grab * the key tag out of the contained CHOICE */ if (!stoleChoiceTags && (GetBuiltinType (e->type) == BASICTYPE_CHOICE)) { fprintf (src, " tag1 = BDecTag (_b, setBytesDecoded);\n"); fprintf (src, " elmtLen%d = BDecLen (_b, setBytesDecoded);\n", ++elmtLevel); } varName = cxxtri->fieldName; /* decode content */ if (cxxtri->isPtr) { if (e->type->defaultVal) { fprintf(src, " // delete default value\n"); fprintf(src, " delete %s;\n", varName); } fprintf (src, "\t\t%s = new %s;\n", varName, cxxtri->className); } /* decode content */ tmpTypeId = GetBuiltinType (e->type); /*fprintf (src, " tag1 = BDecTag (_b, setBytesDecoded);\n\n");*/ /*fprintf (src, " elmtLen1 = BDecLen (_b, setBytesDecoded);\n");*/ if (tmpTypeId == BASICTYPE_ANYDEFINEDBY) { /* * must check for another EOC for ANYs * since the any decode routines decode * their own first tag/len pair */ elmtLevel++; fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); defByNamedType = e->type->basicType->a.anyDefinedBy->link; PrintCxxSetTypeByCode(defByNamedType, cxxtri, src); fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "B%s (_b, setBytesDecoded);\n", r->decodeBaseName); } else if (tmpTypeId == BASICTYPE_ANY) { elmtLevel++; fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "B%s (_b, setBytesDecoded);\n", r->decodeBaseName); } else if ( (tmpTypeId == BASICTYPE_OCTETCONTAINING) || (tmpTypeId == BASICTYPE_BITCONTAINING) ) { PrintCxxDecodeContaining(e->type, r, src); } else { fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "B%s (_b, tag1, elmtLen%d, setBytesDecoded);\n", r->decodeContentBaseName, elmtLevel); } /* decode Eoc (s) */ for (i = elmtLevel-1; i >= 1; i--) { fprintf (src, " if (elmtLen%d == INDEFINITE_LEN)\n", i); fprintf (src, " BDecEoc (_b, setBytesDecoded);\n\n"); } /* keep track of decoded non-optional elmts */ if ( (!e->type->optional) && (e->type->defaultVal == NULL) && (!e->type->extensionAddition) ) { mandatoryElmtCount++; fprintf (src, " mandatoryElmtsDecoded++;\n"); } fprintf (src, " break;\n\n"); FreeTags (tags); } else { extensionAdditions = TRUE; } } /* for each elmt */ fprintf (src, " default:\n"); if(extensionAdditions) { fprintf (src, " {\n"); fprintf (src, " _b.SetReadLoc(readLoc);\n"); fprintf (src, " AsnAny extAny;\n"); fprintf (src, " extAny.BDec(_b, setBytesDecoded);\n"); fprintf (src, " extension.extList.insert(extension.extList.end(), extAny);\n"); fprintf (src, " }\n"); } else { fprintf (src, " throw InvalidTagException(typeName(), tag1, STACK_ENTRY);\n"); } fprintf (src, " } // end switch\n"); fprintf (src, " } // end for loop\n"); fprintf (src, " bytesDecoded += setBytesDecoded;\n"); fprintf (src, " if (mandatoryElmtsDecoded < %d)\n", mandatoryElmtCount); fprintf (src, " {\n"); fprintf (src, " throw EXCEPT(\"non-optional SET element missing\", DECODE_ERROR);\n"); fprintf (src, " }\n"); } /* if not empty set clause */ fprintf (src, "} // %s::B%s\n\n", td->cxxTypeDefInfo->className, r->decodeContentBaseName); } /* end of decode content method code */ if(genPERCode) { /* PerEncode */ if (printEncodersG) //RWC;TBD; SHOULD set printEncodersP with FLAG!!!! { PrintCxxDefCode_PERSort(&pSetElementNamedType, &pSetElementTag, set->basicType->a.set); // // THIRD, perform actual encoding using re-arranged Set element // pointers. //FOR_EACH_LIST_ELMT (e, set->basicType->a.set) PrintCxxDefCode_SetSeqPEREncode (src, hdr, r, td, pSetElementNamedType, set->basicType->a.set->count); } // END IF printEncodersG /* end of PerEncode */ /* PerDecode */ if (printDecodersG) { PrintCxxDefCode_SetSeqPERDecode (src, hdr, r, td, pSetElementNamedType, set->basicType->a.set->count); } } /* end of PerDecode */ if (pSetElementTag) free(pSetElementTag); if (pSetElementNamedType) free(pSetElementNamedType); /* BerEncode */ if (printEncodersG) { fprintf (hdr, " %s B%s (%s &_b) const;\n", lenTypeNameG, r->encodeBaseName, bufTypeNameG); fprintf (src, "%s\n", lenTypeNameG); fprintf (src, "%s::B%s (%s &_b) const\n", td->cxxTypeDefInfo->className, r->encodeBaseName, bufTypeNameG); fprintf (src, "{\n"); fprintf (src, " %s l=0;\n", lenTypeNameG); fprintf (src, " l = B%s (_b);\n", r->encodeContentBaseName); /* encode each tag/len pair if any */ FOR_EACH_LIST_ELMT_RVS (tag, set->tags) { classStr = Class2ClassStr (tag->tclass); formStr = Form2FormStr (CONS); /* set's are constructed */ //RWC;tagLen = TagByteLen (tag->code); fprintf (src, " l += BEncConsLen (_b, l);\n"); if (tag->tclass == UNIV) fprintf (src, " l += BEncTag%d (_b, %s, %s, %s);\n", tagLen, classStr, formStr, DetermineCode(tag, &tagLen, 0));//RWC;Code2UnivCodeStr (tag->code)); else fprintf (src, " l += BEncTag%d (_b, %s, %s, %s);\n", tagLen, classStr, formStr, DetermineCode(tag, &tagLen, 1));//RWC;tag->code); } fprintf (src, " return l;\n"); fprintf (src, "}\n\n"); } /* end of BerEncode */ /* BerDecode */ if (printDecodersG) { fprintf (hdr, " void B%s (const %s &_b, %s &bytesDecoded);\n", r->decodeBaseName, bufTypeNameG, lenTypeNameG);//, envTypeNameG); fprintf (src, "void %s::B%s (const %s &_b, %s &bytesDecoded)\n", td->cxxTypeDefInfo->className, r->decodeBaseName, bufTypeNameG, lenTypeNameG);//, envTypeNameG); fprintf (src, "{\n"); fprintf (src, " FUNC(\"%s::B%s\");\n", td->cxxTypeDefInfo->className, r->decodeBaseName); fprintf (src, " %s tag;\n", tagTypeNameG); /* print extra locals for redundant lengths */ for (i = 1; (set->tags != NULL) && (i <= LIST_COUNT (set->tags)); i++) fprintf (src, " %s elmtLen%d;\n", lenTypeNameG, i); fprintf (src, "\n"); /* decode tag/length pair (s) */ elmtLevel = 0; FOR_EACH_LIST_ELMT (tag, set->tags) { classStr = Class2ClassStr (tag->tclass); formStr = Form2FormStr (CONS); /* sets are constructed */ fprintf (src, " if ((tag = BDecTag (_b, bytesDecoded)) != "); if (tag->tclass == UNIV) fprintf (src, "MAKE_TAG_ID (%s, %s, %s))\n", classStr, formStr, DetermineCode(tag, NULL, 0));//RWC;Code2UnivCodeStr (tag->code)); else fprintf (src, "MAKE_TAG_ID (%s, %s, %s))\n", classStr, formStr, DetermineCode(tag, NULL, 1));//RWC;tag->code); fprintf (src, " {\n"); fprintf (src, " throw InvalidTagException(typeName(), tag, STACK_ENTRY);\n"); fprintf (src, " }\n"); fprintf (src, " elmtLen%d = BDecLen (_b, bytesDecoded);\n", ++elmtLevel); } fprintf (src, " B%s (_b, tag, elmtLen%d, bytesDecoded);\n", r->decodeContentBaseName, i-1); /* grab any EOCs that match redundant, indef lengths */ for (i = elmtLevel-1; i > 0; i--) { fprintf (src, " if (elmtLen%d == INDEFINITE_LEN)\n", i); fprintf (src, " BDecEoc (_b, bytesDecoded);\n"); } fprintf (src, "}\n\n"); } /* end of BerDecode */ /* write code for printing */ if (printPrintersG) { PrintCxxSeqSetPrintFunction(src, hdr, td->cxxTypeDefInfo->className, set->basicType); /* ################################################################## RWC;1/12/00; ADDED XML output capability. */ fprintf (hdr, " void PrintXML (std::ostream &os, const char *lpszTitle=NULL) const;\n"); fprintf (src, "void %s::PrintXML (std::ostream &os, const char *lpszTitle) const\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); allOpt = AllElmtsOptional (set->basicType->a.set); fprintf (src, " if (lpszTitle)\n"); fprintf (src, " {\n"); fprintf (src, " os << \"<\" << lpszTitle;\n"); fprintf (src, " os << \" typeName=\\\"%s\\\" type=\\\"SET\\\">\" << std::endl;\n", td->cxxTypeDefInfo->className); fprintf (src, " }\n"); fprintf (src, " else\n"); fprintf (src, " os << \"<%s type=\\\"SET\\\">\" << std::endl;\n", td->cxxTypeDefInfo->className); FOR_EACH_LIST_ELMT (e, set->basicType->a.set) { inTailOptElmts = IsTailOptional (set->basicType->a.set); if (e->type->cxxTypeRefInfo->isPtr) fprintf (src, " if (%s (%s))\n", cxxtri->optTestRoutineName, e->type->cxxTypeRefInfo->fieldName); fprintf (src, " {\n"); if (e->type->cxxTypeRefInfo->isPtr) { fprintf (src, " (*%s).PrintXML(os", e->type->cxxTypeRefInfo->fieldName); if (e->fieldName != NULL) fprintf (src, ", \"%s\"", e->fieldName); fprintf (src, ");\n"); } else { fprintf (src, " %s.PrintXML(os", e->type->cxxTypeRefInfo->fieldName); if (e->fieldName != NULL) fprintf (src, ", \"%s\"", e->fieldName); fprintf (src, ");\n"); } fprintf (src, " }\n"); if (e->type->cxxTypeRefInfo->isPtr) { fprintf (src, " else\n"); if (e->fieldName) fprintf (src, " os << \"<%s -- void2 -- />\" << std::endl;\n", e->fieldName); else fprintf (src, " os << \"<%s -- void2 -- />\" << std::endl;\n", e->type->cxxTypeRefInfo->fieldName); } fprintf (src, "\n"); } /* END For each set element */ fprintf (src, " if (lpszTitle)\n"); fprintf (src, " os << \"\" << std::endl;\n"); fprintf (src, " else\n"); fprintf (src, " os << \"\" << std::endl;\n", td->cxxTypeDefInfo->className); fprintf (src, "} // %s::PrintXML\n\n\n", td->cxxTypeDefInfo->className); /* END XML Print capability. ################################################################## */ } /* end of print method code */ /* close class definition */ fprintf (hdr, "};\n\n\n"); novolatilefuncs = novolatilefuncs; parent=parent; /*AVOIDS warning.*/ } /* PrintCxxSetDefCode */ /* * PIERCE added 8-21-2001 template code to handle SET/SEQ OF * */ static void PrintCxxListClass (FILE *hdr, FILE * src, TypeDef *td, Type *lst, Module* m, ModuleList *mods) { int idecl; struct NamedType p_etemp; NamedType* p_e; char typeNameStr[256]; char *lcn; /* list class name */ char *ecn; /* (list) elmt class name */ const char* exportStr; char *pszNamespace; char pcvarname[100]; idecl=0; p_e=&p_etemp; p_e->type=lst->basicType->a.setOf; m = m; // Set DLL export string if (bVDAGlobalDLLExport == NULL) exportStr = ""; else exportStr = bVDAGlobalDLLExport; ecn = lst->basicType->a.setOf->cxxTypeRefInfo->className; if(p_e->type->subtypes!=NULL) { sprintf(pcvarname, "PERGen_%s%ld", ecn, lconstraintvar); lconstraintvar+=1; p_e->type->cxxTypeRefInfo->fieldName=&pcvarname[0]; switch (p_e->type->subtypes->choiceId) { case SUBTYPE_AND: case SUBTYPE_OR: case SUBTYPE_SINGLE: { if(PrintCxxMultiConstraintOrHandler(hdr, src, td->definedName, p_e, 0)) { constraints_flag=1; } break; } default: { break; } } } ecn=lst->basicType->a.setOf->cxxTypeRefInfo->className; pszNamespace = LookupNamespace(lst, mods); lcn = td->cxxTypeDefInfo->className; fprintf (hdr, "class %s : public ", lcn); switch (lst->basicType->choiceId) { case BASICTYPE_SEQUENCEOF: sprintf (typeNameStr,"\"%s\"", lcn); if (pszNamespace) fprintf (hdr, "AsnSeqOf<%s::%s>\n", pszNamespace, ecn); else fprintf (hdr, "AsnSeqOf<%s>\n", ecn); break; case BASICTYPE_SETOF: sprintf (typeNameStr,"\"%s\"", lcn); if (pszNamespace) fprintf (hdr, "AsnSetOf<%s::%s>\n", pszNamespace, ecn); else fprintf (hdr, "AsnSetOf<%s>\n", ecn); break; default: /* TBD print error? */ break; } fprintf (hdr, "{\n"); // Print typeName() and Clone() functions fprintf(hdr, "public:\n"); fprintf(hdr, "\t%s virtual const char* typeName() const\t{ return \"%s\"; }\n", exportStr, lcn); fprintf(hdr, "\t%s virtual AsnType* Clone() const\t\t\t{ return new %s(*this); }\n", exportStr, lcn); // JKG--added functionality for sequence of and set of constraints if (td->type->subtypes != NULL) { /*Subtype* s_type;*/ /*s_type = (Subtype*)td->type->subtypes->a.single->a.sizeConstraint->a.or->last->data;*/ /* Only single size constraints that are themselves single are supported */ if ((td->type->subtypes->choiceId == SUBTYPE_SINGLE) && (td->type->subtypes->a.single->choiceId == SUBTYPEVALUE_SIZECONSTRAINT) && (td->type->subtypes->a.single->a.sizeConstraint->choiceId == SUBTYPE_SINGLE)) { PrintCxxSetOfSizeConstraint(hdr, td->type->subtypes->a.single->a.sizeConstraint->a.single, m, td->type); } else { PrintErrLoc(m->asn1SrcFileName, (long)td->type->lineNo); fprintf(errFileG, "ERROR - unsupported constraint\n"); } } fprintf(hdr, "};\n\n"); } static void PrintCxxSetOfDefCode PARAMS ((src, hdr, mods, m, r, td, parent, setOf, novolatilefuncs), FILE *src _AND_ FILE *hdr _AND_ ModuleList *mods _AND_ Module *m _AND_ CxxRules *r _AND_ TypeDef *td _AND_ Type *parent _AND_ Type *setOf _AND_ int novolatilefuncs) { // Get rid of warnings novolatilefuncs = novolatilefuncs; parent = parent; m = m; r = r; mods = mods; src = src; /* do class */ PrintCxxListClass (hdr, src, td, setOf, m, mods); } /* PrintCxxSetOfDefCode */ static void PrintCxxAnyDefCode PARAMS ((src, hdr, mods, m, r, td, parent, any), FILE *src _AND_ FILE *hdr _AND_ ModuleList *mods _AND_ Module *m _AND_ CxxRules *r _AND_ TypeDef *td _AND_ Type *parent _AND_ Type *any) { fprintf (hdr, "/* "); SpecialPrintType (hdr, td, td->type); fprintf (hdr, " */\n"); fprintf (hdr, "typedef %s %s;\n\n", td->type->cxxTypeRefInfo->className, td->cxxTypeDefInfo->className); any=any;parent=parent;r=r;m=m;mods=mods;src=src; /*AVOIDS warning.*/ } /* PrintCxxAnyDefCode */ static void PrintCxxTypeDefCode PARAMS ((src, hdr, mods, m, r, td, novolatilefuncs), FILE *src _AND_ FILE *hdr _AND_ ModuleList *mods _AND_ Module *m _AND_ CxxRules *r _AND_ TypeDef *td _AND_ int novolatilefuncs) { switch (td->type->basicType->choiceId) { case BASICTYPE_BOOLEAN: /* library type */ case BASICTYPE_REAL: /* library type */ case BASICTYPE_OCTETSTRING: /* library type */ case BASICTYPE_NULL: /* library type */ case BASICTYPE_EXTERNAL: /* library type */ case BASICTYPE_OID: /* library type */ case BASICTYPE_RELATIVE_OID: case BASICTYPE_INTEGER: /* library type */ case BASICTYPE_BITSTRING: /* library type */ case BASICTYPE_ENUMERATED: /* library type */ case BASICTYPE_NUMERIC_STR: /* 22 */ case BASICTYPE_PRINTABLE_STR: /* 23 */ case BASICTYPE_UNIVERSAL_STR: /* 24 */ case BASICTYPE_IA5_STR: /* 25 */ case BASICTYPE_BMP_STR: /* 26 */ case BASICTYPE_UTF8_STR: /* 27 */ case BASICTYPE_UTCTIME: /* 28 tag 23 */ case BASICTYPE_GENERALIZEDTIME: /* 29 tag 24 */ case BASICTYPE_GRAPHIC_STR: /* 30 tag 25 */ case BASICTYPE_VISIBLE_STR: /* 31 tag 26 aka ISO646String */ case BASICTYPE_GENERAL_STR: /* 32 tag 27 */ case BASICTYPE_OBJECTDESCRIPTOR: /* 33 tag 7 */ case BASICTYPE_VIDEOTEX_STR: /* 34 tag 21 */ case BASICTYPE_T61_STR: /* 35 tag 20 */ PrintCxxSimpleDef (hdr, src, m, r, td); break; case BASICTYPE_SEQUENCEOF: /* list types */ case BASICTYPE_SETOF: PrintCxxSetOfDefCode (src, hdr, mods, m, r, td, NULL, td->type, novolatilefuncs); break; case BASICTYPE_IMPORTTYPEREF: /* type references */ case BASICTYPE_LOCALTYPEREF: /* * if this type has been re-tagged then * must create new class instead of using a typedef */ PrintCxxSimpleDef (hdr, src, m, r, td); break; case BASICTYPE_ANYDEFINEDBY: /* ANY types */ case BASICTYPE_ANY: PrintCxxAnyDefCode (src, hdr, mods, m, r, td, NULL, td->type); break; case BASICTYPE_CHOICE: PrintCxxChoiceDefCode (src, hdr, mods, m, r, td, NULL, td->type, novolatilefuncs); break; case BASICTYPE_SET: PrintCxxSetDefCode (src, hdr, mods, m, r, td, NULL, td->type, novolatilefuncs); break; case BASICTYPE_SEQUENCE: PrintCxxSeqDefCode (src, hdr, mods, m, r, td, NULL, td->type, novolatilefuncs); break; case BASICTYPE_COMPONENTSOF: case BASICTYPE_SELECTION: case BASICTYPE_UNKNOWN: case BASICTYPE_MACRODEF: case BASICTYPE_MACROTYPE: /* do nothing */ break; default: /* TBD: print error? */ break; } } /* PrintCxxTypeDefCode */ void PrintCxxCode PARAMS ((src, hdr, if_META (printMeta COMMA meta COMMA meta_pdus COMMA) mods, m, r, longJmpVal, printTypes, printValues, printEncoders, printDecoders, printPrinters, printFree if_TCL (COMMA printTcl), novolatilefuncs), FILE *src _AND_ FILE *hdr _AND_ if_META (MetaNameStyle printMeta _AND_) if_META (const Meta *meta _AND_) if_META (MetaPDU *meta_pdus _AND_) ModuleList *mods _AND_ Module *m _AND_ CxxRules *r _AND_ long longJmpVal _AND_ int printTypes _AND_ int printValues _AND_ int printEncoders _AND_ int printDecoders _AND_ int printPrinters _AND_ int printFree if_TCL (_AND_ int printTcl) _AND_ int novolatilefuncs) { Module *currMod; AsnListNode *currModTmp; TypeDef *td; ValueDef *vd; longJmpValG = longJmpVal; printTypesG = printTypes; printEncodersG = printEncoders; printDecodersG = printDecoders; printPrintersG = printPrinters; printFreeG = printFree; #if META printMetaG = printMeta; meta_pdus_G = meta_pdus; #if TCL printTclG = printTcl; #endif /* TCL */ #endif /* META */ PrintSrcComment (src, m); PrintHdrComment (hdr, m); PrintConditionalIncludeOpen (hdr, m->cxxHdrFileName); #if META if (printMetaG) { fprintf (src, "\n"); fprintf (src, "#ifndef META\n"); fprintf (src, "#define META 1\n"); fprintf (src, "#endif\n"); #if TCL if (printTclG) { fprintf (src, "#ifndef TCL\n"); fprintf (src, "#define TCL META\n"); fprintf (src, "#endif\n"); } #endif /* TCL */ } #endif /* META */ fprintf (hdr, "#include \"asn-incl.h\"\n"); fprintf (hdr, "#include \"asn-listset.h\"\n"); fprintf (src, "\n"); //RWC; PRINT before possible "namespace" designations. PrintSrcIncludes (src, mods, m); FOR_EACH_LIST_ELMT (currMod, mods) { if ((strcmp(m->cxxHdrFileName, currMod->cxxHdrFileName) == 0)) { // Code to see the import module list AND load possible "namespace" refs. ImportModuleList *ModLists; ImportModule *impMod; char *ImpFile = NULL; ModLists = currMod->imports; currModTmp = mods->curr; //RWC; FOR_EACH_LIST_ELMT(impMod, ModLists) { ImpFile = GetImportFileName (impMod->modId->name, mods); if (ImpFile != NULL) fprintf (hdr, "#include \"%s\"\n", ImpFile); if (impMod->moduleRef == NULL) // RWC; attempt to update... impMod->moduleRef = GetImportModuleRef(impMod->modId->name, mods); if (impMod->moduleRef && impMod->moduleRef->namespaceToUse) { fprintf(src,"using namespace %s;\n", impMod->moduleRef->namespaceToUse); } } mods->curr = currModTmp; // RWC;RESET loop control } // Don't duplicate header file referenced in source // if ((strcmp(m->cxxHdrFileName, currMod->cxxHdrFileName) != 0)) // { // if ((ImportedFilesG == FALSE) || (currMod->ImportedFlag == TRUE)) // fprintf (hdr, "#include \"%s\"\n", currMod->cxxHdrFileName); // } } fprintf (hdr, "\n"); fprintf (src, "\n"); /* 7-09-2001 Pierce Leonberger * Added code to include all SNACC generated code in the SNACC namespace. * If the namespace name was overridden with the '-ns' switch then * use the name specified. If the '-nons' switch was used then don't * use namespaces for SNACC generated code. */ if (gNO_NAMESPACE == 0) { fprintf(hdr, "#ifndef NO_NAMESPACE\n"); fprintf(src, "#ifndef NO_NAMESPACE\n"); if (gAlternateNamespaceString) { fprintf(hdr, "using namespace SNACC;\n"); fprintf(src, "using namespace SNACC;\n"); fprintf(hdr, "namespace %s {\n", gAlternateNamespaceString); fprintf(src, "namespace %s {\n", gAlternateNamespaceString); } else if (m->namespaceToUse) { fprintf(hdr, "using namespace SNACC;\n"); fprintf(src, "using namespace SNACC;\n"); fprintf(hdr, "namespace %s {\n", m->namespaceToUse); fprintf(src, "namespace %s {\n", m->namespaceToUse); } else { fprintf(hdr, "namespace SNACC {\n"); fprintf(src, "namespace SNACC {\n"); } fprintf(hdr, "#endif\n"); fprintf(src, "#endif\n"); } if (bVDAGlobalDLLExport) { fprintf(hdr, "#ifndef %s\n", bVDAGlobalDLLExport); fprintf(hdr, "#if defined(WIN32)\n"); fprintf(hdr, "#pragma warning( disable : 4251)\n"); if (strcmp(bVDAGlobalDLLExport, "SNACCDLL_API") == 0) { /* Special case for compatibility */ fprintf(hdr, "#ifdef SNACCDLL_EXPORTS\n"); } else { fprintf(hdr, "#ifdef %s_EXPORTS\n", bVDAGlobalDLLExport); } fprintf(hdr, "#define %s __declspec(dllexport)\n", bVDAGlobalDLLExport); fprintf(hdr, "#else\n"); fprintf(hdr, "#define %s __declspec(dllimport)\n", bVDAGlobalDLLExport); fprintf(hdr, "#endif // %s\n", bVDAGlobalDLLExport); fprintf(hdr, "#else // Handle Unix...\n"); fprintf(hdr, "#define %s \n", bVDAGlobalDLLExport); fprintf(hdr, "#endif // WIN32\n"); fprintf(hdr, "#endif // %s\n", bVDAGlobalDLLExport); } fprintf (hdr, "//------------------------------------------------------------------------------\n"); fprintf (hdr, "// class declarations:\n\n"); FOR_EACH_LIST_ELMT (td, m->typeDefs) { PrintTypeDecl (hdr, td); } fprintf (hdr, "\n"); #if META if (printMeta) { fprintf (hdr, "#if META\n"); fprintf (src, "#if META\n\n"); fprintf (hdr, "//------------------------------------------------------------------------------\n"); char *ptr=""; /* NOT DLL Exported, or ignored on Unix. */ if (bVDAGlobalDLLExport != NULL) { ptr = bVDAGlobalDLLExport; } fprintf(hdr, "extern const %s AsnModuleDesc %sModuleDesc;\n", ptr, m->cxxname); fprintf(src, "//------------------------------------------------------------------------------\n"); fprintf(src, "static const AsnTypeDesc *%sModuleTypes[] = {\n", m->cxxname); FOR_EACH_LIST_ELMT(td, m->typeDefs) { fprintf(src, " &%s::_desc,\n", td->cxxTypeDefInfo->className); } fprintf(src, " NULL\n"); fprintf(src, "};\n"); fprintf(src, "const AsnModuleDesc %sModuleDesc = { \"%s\", %sModuleTypes };\n\n", m->cxxname, m->modId->name, m->cxxname); fprintf(hdr, "#endif // META\n\n"); fprintf(src, "#endif // META\n\n"); } #endif /* META */ /* REMOVE PIERCE changed to print the Value definitions to the header file * 10-25-2001 */ if (printValues) { fprintf(src, "//------------------------------------------------------------------------------\n"); fprintf(src, "// value defs\n\n"); FOR_EACH_LIST_ELMT (vd, m->valueDefs) { PrintCxxValueDef(src, r, vd); } fprintf(src, "\n"); } /* REMOVE PIERCE changed const values to print to the header file only. This negates the * need to extern or export the const values. * 10-25-2001 */ if (printValues) { fprintf(hdr, "//------------------------------------------------------------------------------\n"); fprintf(hdr, "// externs for value defs\n\n"); FOR_EACH_LIST_ELMT (vd, m->valueDefs) PrintCxxValueExtern (hdr, r, vd); fprintf(hdr, "//------------------------------------------------------------------------------\n"); } fprintf(hdr, "//------------------------------------------------------------------------------\n"); fprintf(hdr, "// class definitions:\n\n"); fprintf(src, "//------------------------------------------------------------------------------\n"); fprintf(src, "// class member definitions:\n\n"); PrintCxxAnyCode (src, hdr, r, mods, m); FOR_EACH_LIST_ELMT (td, m->typeDefs) { PrintCxxTypeDefCode (src, hdr, mods, m, r, td, novolatilefuncs); } /* 7-09-2001 Pierce Leonberger */ if (gNO_NAMESPACE == 0) { fprintf(hdr, "#ifndef NO_NAMESPACE\n"); fprintf(hdr, "} // namespace close\n"); fprintf(hdr, "#endif\n"); fprintf(src, "#ifndef NO_NAMESPACE\n"); fprintf(src, "} // namespace close\n"); fprintf(src, "#endif\n"); } PrintConditionalIncludeClose (hdr, m->cxxHdrFileName); } /* PrintCxxCode */ void PrintCxxEncodeContaining(Type *t, CxxRules *r, FILE *src) { fprintf(src, " l += %s", t->cxxTypeRefInfo->fieldName); if (t->cxxTypeRefInfo->isPtr) fprintf(src, "->"); else fprintf(src, "."); fprintf(src, "B%s(_b);\n", r->encodeBaseName); /* If this is a BITSTRING CONTAINING encode a NULL octet for the unused * bits */ if (t->basicType->choiceId == BASICTYPE_BITCONTAINING) { fprintf(src," _b.PutByteRvs((char) 0 ); //encode 0 for unused bits\n"); fprintf(src," l++;\n"); } } void PrintCxxDecodeContaining(Type *t, CxxRules *r, FILE *src) { NamedType *defByNamedType; /* Encode Content of contained type */ if (t->basicType->a.stringContaining->basicType->choiceId == BASICTYPE_ANYDEFINEDBY) { defByNamedType = t->basicType->a.stringContaining->basicType->a.anyDefinedBy->link; PrintCxxSetTypeByCode(defByNamedType, t->cxxTypeRefInfo, src); } if (t->basicType->choiceId == BASICTYPE_BITCONTAINING) { fprintf(src,"\n"); fprintf(src," // Decode unused bits and make sure it's 0\n"); fprintf(src," char unusedBits;\n"); fprintf(src," unusedBits = _b.GetByte();\n"); fprintf(src," seqBytesDecoded++;\n"); fprintf(src," if (unusedBits != '0x0')\n"); fprintf(src," throw DecodeException(STACK_ENTRY);\n"); fprintf(src,"\n"); } fprintf (src, " %s", t->cxxTypeRefInfo->fieldName); if (t->cxxTypeRefInfo->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "B%s (_b, seqBytesDecoded);\n", r->decodeBaseName); } void PrintCxxPEREncodeContaining(Type *t, CxxRules *r, FILE *src) { fprintf(src, " l += %s", t->cxxTypeRefInfo->fieldName); if (t->cxxTypeRefInfo->isPtr) fprintf(src, "->"); else fprintf(src, "."); fprintf(src, "P%s(_b);\n", r->encodeBaseName); /* If this is a BITSTRING CONTAINING encode a NULL octet for the unused * bits */ if (t->basicType->choiceId == BASICTYPE_BITCONTAINING) { fprintf(src," unsigned char _tmp[] = {0x00};\n"); fprintf(src," _b.PutBits(tmp , 8); //encode 0 for unused bits\n"); fprintf(src," l++;\n"); } } void PrintCxxPERDecodeContaining(Type *t, CxxRules *r, FILE *src) { NamedType *defByNamedType; /* Encode Content of contained type */ if (t->basicType->a.stringContaining->basicType->choiceId == BASICTYPE_ANYDEFINEDBY) { defByNamedType = t->basicType->a.stringContaining->basicType->a.anyDefinedBy->link; PrintCxxSetTypeByCode(defByNamedType, t->cxxTypeRefInfo, src); } if (t->basicType->choiceId == BASICTYPE_BITCONTAINING) { fprintf(src,"\n"); fprintf(src," // Decode unused bits and make sure it's 0\n"); fprintf(src," unsigned char* unusedBits;\n"); fprintf(src," unusedBits = _b.GetBits(8);\n"); fprintf(src," bitsDecoded++;\n"); fprintf(src," if (unusedBits[0] != '0x0')\n"); fprintf(src," throw DecodeException(STACK_ENTRY);\n"); fprintf(src,"\n"); } fprintf (src, " %s", t->cxxTypeRefInfo->fieldName); if (t->cxxTypeRefInfo->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "P%s (_b, bitsDecoded);\n", r->decodeBaseName); } void PrintCxxSetTypeByCode(NamedType *defByNamedType, CxxTRI *cxxtri, FILE *src) { char *varName = cxxtri->fieldName; if (GetBuiltinType (defByNamedType->type) == BASICTYPE_OID) { fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "SetTypeByOid ("); if (defByNamedType->type->cxxTypeRefInfo->isPtr) fprintf (src, " *"); fprintf (src, "%s);\n", defByNamedType->type->cxxTypeRefInfo->fieldName); } else if (GetBuiltinType (defByNamedType->type) == BASICTYPE_INTEGER) { fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "SetTypeByInt ("); if (defByNamedType->type->cxxTypeRefInfo->isPtr) fprintf (src, " *"); fprintf (src, "%s);\n", defByNamedType->type->cxxTypeRefInfo->fieldName); } else if (GetBuiltinType (defByNamedType->type) == BASICTYPE_CHOICE) { NamedType *nt; Type *t = GetType(defByNamedType->type); if (defByNamedType->type->cxxTypeRefInfo->isPtr) fprintf(src, " switch (%s->choiceId)\n", defByNamedType->type->cxxTypeRefInfo->fieldName); else fprintf(src, " switch (%s.choiceId)\n", defByNamedType->type->cxxTypeRefInfo->fieldName); fprintf(src, " {\n"); FOR_EACH_LIST_ELMT(nt, t->basicType->a.choice) { fprintf(src, " case %s::%sCid:\n", defByNamedType->type->cxxTypeRefInfo->className, nt->fieldName); if (nt->type->basicType->choiceId == BASICTYPE_INTEGER || nt->type->basicType->choiceId == BASICTYPE_ENUMERATED) { fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); if (defByNamedType->type->cxxTypeRefInfo->isPtr) fprintf(src, "SetTypeByInt(*%s->%s);\n", defByNamedType->type->cxxTypeRefInfo->fieldName, nt->fieldName); else fprintf(src, "SetTypeByInt(*%s.%s);\n", defByNamedType->type->cxxTypeRefInfo->fieldName, nt->fieldName); } else { fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); if (defByNamedType->type->cxxTypeRefInfo->isPtr) fprintf(src, "SetTypeByOid(*%s->%s);\n", defByNamedType->type->cxxTypeRefInfo->fieldName, nt->fieldName); else fprintf(src, "SetTypeByOid(*%s.%s);\n", defByNamedType->type->cxxTypeRefInfo->fieldName, nt->fieldName); } fprintf(src, " break;\n"); } fprintf(src, " }\n"); } } char * LookupNamespace PARAMS ((t, mods), Type *t _AND_ ModuleList *mods) { char *pszNamespace=NULL; Module *mTmp=NULL; TypeDef *ptTmp=NULL; BasicType *pbtTmp2=NULL; //RWC; HANDLE namespace designations of specific modules on declarations, // if necessary. (May have to lookup module name to get namespace). pbtTmp2 = t->basicType; if (pbtTmp2->choiceId == BASICTYPE_SEQUENCEOF || pbtTmp2->choiceId == BASICTYPE_SETOF) pbtTmp2 = pbtTmp2->a.sequenceOf->basicType; // Burrow 1 more layer down for SequenceOf/SetOf if (pbtTmp2->choiceId == BASICTYPE_IMPORTTYPEREF) { // RWC; IF IMPORTED, then we need to check for // optional namespace designation (only in .h) FOR_EACH_LIST_ELMT (mTmp, mods) { ptTmp = LookupType(mTmp->typeDefs, pbtTmp2->a.importTypeRef->typeName); //WHAT we are looking for... if (ptTmp != NULL) break; //FOUND the MODULE that contains our defninition... } // END FOR each module. if (ptTmp != NULL && mTmp != NULL && mTmp->namespaceToUse) // FOUND our MODULE... { pszNamespace = mTmp->namespaceToUse; // DO NOT DELETE... } //LookupType PARAMS ((typeDefList, typeName), } // IF BASICTYPE_IMPORTTYPEREF return(pszNamespace); } /* END LookupNamespace(...)*/ void PrintCxxSeqSetPrintFunction(FILE* src, FILE* hdr, MyString className, BasicType *pBasicType) { int allOpt; int inTailOptElmts; NamedTypeList* pElmtList; NamedType *e; fprintf(hdr, "\tvoid Print(std::ostream& os, unsigned short indent = 0) const;\n"); fprintf(src, "void %s::Print(std::ostream& os, unsigned short indent) const\n", className); fprintf(src, "{\n"); if (pBasicType->choiceId == BASICTYPE_SEQUENCE) { fprintf(src, "\tos << \"{ -- SEQUENCE --\" << std::endl;\n"); pElmtList = pBasicType->a.sequence; } else if (pBasicType->choiceId == BASICTYPE_SET) { fprintf(src, "\tos << \"{ -- SET --\" << std::endl;\n"); pElmtList = pBasicType->a.set; } else abort(); allOpt = AllElmtsOptional(pElmtList); if (allOpt) fprintf(src, "\tint nonePrinted = true;\n"); fprintf(src, "++indent;\n\n"); FOR_EACH_LIST_ELMT (e, pElmtList) { inTailOptElmts = IsTailOptional(pElmtList); if (e->type->cxxTypeRefInfo->isPtr) { fprintf(src, "\tif (%s (%s))\n", e->type->cxxTypeRefInfo->optTestRoutineName, e->type->cxxTypeRefInfo->fieldName); fprintf (src, "\t{\n"); if (allOpt) { if (e != FIRST_LIST_ELMT (pElmtList)) { fprintf(src, "\t\tif (!nonePrinted)\n"); fprintf(src, "\t\t\tos << \",\" << std::endl;\n"); } fprintf(src, "\t\tnonePrinted = false;\n"); } /* cannot be first elmt ow allOpt is true */ else if (inTailOptElmts) fprintf (src, "\t\tos << \",\"<< std::endl;\n"); fprintf(src, "\t\tIndent(os, indent);\n"); if (e->fieldName != NULL) fprintf(src, "\t\tos << \"%s \";\n", e->fieldName); fprintf(src, "\t\t%s->Print(os, indent);\n", e->type->cxxTypeRefInfo->fieldName); fprintf(src, "\t}\n"); } else { fprintf(src, "\tIndent(os, indent);\n"); if (e->fieldName != NULL) fprintf(src, "\tos << \"%s \";\n", e->fieldName); fprintf(src, "\t%s.Print(os, indent);\n", e->type->cxxTypeRefInfo->fieldName); if (e != LAST_LIST_ELMT (pElmtList)) fprintf(src, "\tos << ',' << std::endl;\n"); } fprintf (src, "\n"); if (e == LAST_LIST_ELMT (pElmtList)) fprintf(src, "\tos << std::endl;\n"); } fprintf(src, "\t--indent;\n"); fprintf(src, "\tIndent(os, indent);\n"); fprintf(src, "\tos << \"}\\n\";\n"); fprintf (src, "} // end of %s::Print()\n\n", className); } /* end of PrintCxxSeqSetPrintFunction() */ /* * RWC; */ static void PrintCxxDefCode_SetSeqPEREncode (FILE *src, FILE *hdr, CxxRules *r, TypeDef *td, NamedType **pSetElementNamedType, int iElementCount) /* IN, ELEMENT Count to process in array*/ { NamedType *e; char *varName; CxxTRI *cxxtri=NULL; enum BasicTypeChoiceId tmpTypeId; NamedType *defByNamedType; int extensionsExist = FALSE; // DEFINE PER encode/decode tmp vars. int ii=0; long lOptional_Default_ElmtCount=0; const char* tabAndlenVar = "\tl"; fprintf(hdr, "\t%s\t\tP%s(AsnBufBits &_b) const;\n", lenTypeNameG, r->encodeBaseName); /*RWC; {AsnLen len; len = 1;return len;};\n"); RWC; MUST sort the results by tag; usually explicit except for RWC; untagged Choices which can be nested. We must determine which RWC; tag can go 1st from any Choice, potentially nested. RWC; (FORWARD ENCODING FOR PER!)*/ fprintf(src, "%s %s::P%s(AsnBufBits &_b) const\n", lenTypeNameG, td->cxxTypeDefInfo->className, r->encodeBaseName); fprintf(src, "{\n\t%s l = 0;\n", lenTypeNameG); /* SECOND, determine ahead of time the bit count for OPTIONAL/DEFAULT values. */ for (ii=0; ii < iElementCount; ii++) { e = pSetElementNamedType[ii]; //RWC; ALSO, count any OPTIONAL/DEFAULT ASN.1 elements. if ( (e->type->optional || e->type->defaultVal != NULL) && (!e->type->extensionAddition)) lOptional_Default_ElmtCount++; } /* NEXT, decode this number of bits, if any, to determine the presence/absence of OPTIONAL/DEFAULT elements.*/ if (lOptional_Default_ElmtCount) { /* NOW, load PER encoding flag to indicate what OPTIONAL/DEFAULT fields are actually present.*/ /* FOR PER ENCODING OF Set, we must load a bitfield of length "lOptional_Default_ElmtCount", indicating presence of optional or default field data. */ int iOptional_Default_ElementIndex=0; fprintf(src, "\n\t// Build and encode preamble"); fprintf(src, "\n\tAsnBits SnaccOptionalDefaultBits(%ld);\n", lOptional_Default_ElmtCount); for (ii=0; ii < iElementCount; ii++) { e = pSetElementNamedType[ii]; if ( (e->type->optional || e->type->defaultVal != NULL) && (!e->type->extensionAddition)) { fprintf (src, "\tif (%s != NULL)\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, "\t\tSnaccOptionalDefaultBits.SetBit(%d);\n", iOptional_Default_ElementIndex++); } /* END IF OPTIONAL/DEFAULT */ } /* END FOR each element. */ fprintf (src, "\t_b.PutBits(SnaccOptionalDefaultBits.data(), %ld);\n", lOptional_Default_ElmtCount); fprintf (src, "\tl += %ld;\n", lOptional_Default_ElmtCount); } /* END IF lOptional_Default_ElmtCount */ /* NEXT, process each element of the Set/Sequence for decoding. */ fprintf(src, "\n\t// Encode the elements of the SEQUENCE\n"); for (ii=0; ii < iElementCount; ii++) { e = pSetElementNamedType[ii]; if(!e->type->extensionAddition) { if ( (e->type->optional || e->type->defaultVal != NULL) && (!e->type->extensionAddition)) { fprintf(src, "\tif (%s != NULL)\t// Optional OR Default\n", e->type->cxxTypeRefInfo->fieldName); tabAndlenVar = "\t\tl"; } cxxtri = e->type->cxxTypeRefInfo; varName = cxxtri->fieldName; /* encode tag(s), not UNIV but APL, CNTX or PRIV tags ONLY for PER */ /*RWC;TBD; UPDATE to reflect PER encoding rules for encoding length, no tags RWC;TBD; unless explicit (probably need to write a PER version, checking type).*/ //RWC;NOT FOR PER;PrintCxxTagAndLenEncodingCode (src, td, e->type, "l", "(*iBuf)"); /* encode content */ tmpTypeId = GetBuiltinType (e->type); if (tmpTypeId == BASICTYPE_ANYDEFINEDBY) { //RWC;TBD; we may have to investigate individual types here to //RWC;TBD; restrict which codes are printed for PER... defByNamedType = e->type->basicType->a.anyDefinedBy->link; PrintCxxSetTypeByCode(defByNamedType, cxxtri, src); fprintf(src, "%s += %s", tabAndlenVar, varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "P%s(_b);\n", r->encodeBaseName); } else if (tmpTypeId == BASICTYPE_ANY) { //RWC;NOTE: we will assume here that the ANY buffer is already //RWC;NOTE: properly PER encoder; we have no way of checking. fprintf(src, "%s += %s", tabAndlenVar, varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "P%s(_b);\n", r->encodeBaseName); } else if ( (tmpTypeId == BASICTYPE_OCTETCONTAINING) || (tmpTypeId == BASICTYPE_BITCONTAINING)) { PrintCxxPEREncodeContaining(e->type, r, src); //RWC;TBD; THIS CALL WILL NOT UPDATE THE COUNT VALUE PROPERLY; must reflect //RWC;TBD; PER encoding forward, l+=, instead of l= } else { fprintf(src, "%s += %s", tabAndlenVar, varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "P%s(_b);\n", r->encodeBaseName);/*RWC;r->encodeContentBaseName);*/ } } else { extensionsExist = TRUE; } } /* END FOR iElementCount */ if(extensionsExist) { fprintf (src, " \t/* WARNING: PER does not yet support extensibility */\n"); } fprintf(src, "\n\treturn l;\n"); fprintf(src, "}\t// %s::P%s\n\n\n", td->cxxTypeDefInfo->className, r->encodeBaseName); } /* END PrintCxxDefCode_SetSeqPEREncode(...) */ /* * RWC; This method only handles the entire routine decode operations for both Set and Sequence PER Decode. * element decodes, not the wrapping logic. */ static void PrintCxxDefCode_SetSeqPERDecode (FILE *src, FILE *hdr, CxxRules *r, TypeDef *td, NamedType **pSetElementNamedType, int iElementCount) /* IN, ELEMENT Count to process in arrays */ { NamedType *e; char *varName; CxxTRI *cxxtri=NULL; int elmtLevel=0; int varCount, tmpVarCount; enum BasicTypeChoiceId tmpTypeId; NamedType *defByNamedType; // DEFINE PER encode/decode tmp vars. int ii=0; int iOptional_Default_ElementIndex=0; long lOptional_Default_ElmtCount=0; if (pSetElementNamedType == NULL) { printf("****** PrintCxxDefCode_SetSeqPERDecode: MUST HAVE PER Encoders as well as PER Decoders! *****\n"); return; } /***RWC; PERFORM PDec operations first... */ fprintf(hdr, "\tvoid\t\tP%s(AsnBufBits& _b, %s& bitsDecoded);\n\n", r->decodeBaseName, lenTypeNameG); fprintf(src, "void %s::P%s(AsnBufBits& _b, %s& bitsDecoded)\n", td->cxxTypeDefInfo->className, r->decodeBaseName, lenTypeNameG); fprintf(src, "{\n"); fprintf(src, "\tClear();\n"); /* count max number of extra length var nec */ varCount = 0; /* decode tag/length pair (s) */ elmtLevel = 0; for (ii=0; ii < iElementCount; ii++) //FOR_EACH_LIST_ELMT (e, set->basicType->a.set) { e = pSetElementNamedType[ii]; tmpVarCount = CxxCountVariableLevels (e->type); if (tmpVarCount > varCount) varCount = tmpVarCount; if ( (e->type->optional || e->type->defaultVal != NULL) && (!e->type->extensionAddition)) { lOptional_Default_ElmtCount++; } } /* NEXT, decode this number of bits, if any, to determine the presence/absence of OPTIONAL/DEFAULT elements. MUST BE DONE BEFORE TAGs.*/ if (lOptional_Default_ElmtCount) { fprintf(src, "\n\t// Decode the preamble\n"); fprintf(src, "\tAsnBits SnaccOptionalDefaultBits;\n"); fprintf(src, "\tbitsDecoded += _b.GetBits(SnaccOptionalDefaultBits, %ld);\n", lOptional_Default_ElmtCount); } //****************** /****RWC; PERFORM PDecContent operations here... ***/ /* print content local vars */ // fprintf (src, " unsigned int mandatoryElmtsDecoded = 0;\n"); //****************** /* write extra length vars */ // fprintf (src, "{\n"); // RWC; Temporary until I figure out the local var names from combining PDec with PDecContent // for (i = 1; i <= varCount; i++) // fprintf (src, " %s elmtLen%d = 0; //RWC;default to infinite for now.\n", lenTypeNameG, i); // fprintf (src, "\n"); /* handle empty set */ //RWC;if ((set->basicType->a.set == NULL) || LIST_EMPTY (set->basicType->a.set)) if (iElementCount == 0) { // RWC; Allow for "{" editing... /*fprintf (src, " throw EXCEPT(\"Expected an empty sequence\", DECODE_ERROR);\n"); fprintf (src, " }\n");*/ } else { fprintf(src, "\n\t// Decode each of the elements\n"); for (ii=0; ii < iElementCount; ii++) { const char* tabStr = "\t"; e = pSetElementNamedType[ii]; if(!e->type->extensionAddition) { cxxtri = e->type->cxxTypeRefInfo; if (e->type->optional || (e->type->defaultVal != NULL)) { tabStr = "\t\t"; fprintf(src, "\tif (SnaccOptionalDefaultBits.GetBit(%d))\n", iOptional_Default_ElementIndex++); fprintf(src, "\t{\n"); } varName = cxxtri->fieldName; /* decode content */ if (cxxtri->isPtr) { //fprintf(src, "%sif(%s)\n", tabStr, varName); //fprintf(src, "%s%sdelete %s;\n", tabStr, tabStr, varName); fprintf(src, "%s%s = new %s;\n", tabStr, varName, cxxtri->className); /* END IF subtypes, PER-Visible */ } /* decode content */ tmpTypeId = GetBuiltinType (e->type); if ((tmpTypeId == BASICTYPE_OCTETCONTAINING) || (tmpTypeId == BASICTYPE_BITCONTAINING)) { PrintCxxPERDecodeContaining(e->type, r, src); } else { if (tmpTypeId == BASICTYPE_ANYDEFINEDBY) { elmtLevel++; defByNamedType = e->type->basicType->a.anyDefinedBy->link; PrintCxxSetTypeByCode(defByNamedType, cxxtri, src); } else if (tmpTypeId == BASICTYPE_ANY) { elmtLevel++; } if (cxxtri->isPtr) fprintf(src, "%s%s->", tabStr, varName); else fprintf(src, "%s%s.", tabStr, varName); fprintf(src, "P%s(_b, bitsDecoded);\n", r->decodeBaseName); } if (e->type->optional || (e->type->defaultVal != NULL)) fprintf (src, "\t}\n\n"); } } /* for each elmt */ } /* if not empty set clause */ fprintf (src, "} // %s::P%s()\n\n", td->cxxTypeDefInfo->className, r->decodeBaseName); } /* END PrintCxxDefCode_SetSeqPERDecode(...) */ /*** This routine handles sorting of groups of NameType element(s) based on the * Set and Choice sorting rules. */ static void PrintCxxDefCode_PERSort ( NamedType ***pppElementNamedType, /* OUT, array of sorted NameType(s) */ int **ppElementTag, /* OUT, actual tag for sorted. */ AsnList *pElementList) /* IN, actual eSNACC defs for NameType(s). */ { NamedType **pElementNamedType; int *pElementTag; NamedType *e; NamedType *pnamedTypeTmp; Tag *tag; TagList *tags; int tagTmp; int stoleChoiceTags; int ii=0, iii; /* * FIRST, determine encode order by looking at each element tag/type. * (careful with untagged Choice elements, may be nested). * If not tagged in the ASN.1 syntax, then we sort based on the IMPLICIT * tag, even though it may not be encoded for PER. * pElementList->count total elements for PER encode sorting.*/ pElementTag = *ppElementTag = (int *)calloc(pElementList->count, sizeof(int)); pElementNamedType = *pppElementNamedType = (NamedType **)calloc(pElementList->count, sizeof(NamedType *)); FOR_EACH_LIST_ELMT (e, pElementList) { /*RWC;SEE tag-utils.c, line 175 for example of looking at nested *RWC; untagged Choice(s). For PER, NEED to return lowest tag *RWC; value in nested untagged Choice for sorting. *RWC; The call to GetTags will only return tags with non-tagged *RWC; "Choice" elements if present (flagged by "stoleChoiceTags").*/ tags = GetTags (e->type, &stoleChoiceTags); if (LIST_EMPTY (tags)) { pElementTag[ii] = 0; /* RWC; IGNORE; for now */ } /* END IF (LIST_EMPTY (tags))*/ else if (stoleChoiceTags) { /* FOR untagged Choice, determine lowest possible tag for * PER sorting order.*/ pElementTag[ii] = 9999; FOR_EACH_LIST_ELMT (tag, tags) { if (tag->code < pElementTag[ii]) pElementTag[ii] = tag->code; /* ONLY 1st element for sorting.*/ } } else { tag = (Tag*)FIRST_LIST_ELMT (tags); pElementTag[ii] = tag->code; // ONLY 1st element for sorting. } pElementNamedType[ii] = e; ii++; } // END FOR each element. // SECOND, sort this group of elements based on these tags. for (ii=0; ii < pElementList->count-1; ii++) { for (iii=ii+1; iii < pElementList->count; iii++) { // LOCATE smallest tag value if (pElementTag[iii] < pElementTag[ii]) { // THEN switch them. tagTmp = pElementTag[ii]; pnamedTypeTmp = pElementNamedType[ii]; pElementTag[ii] = pElementTag[iii]; pElementNamedType[ii] = pElementNamedType[iii]; pElementTag[iii] = tagTmp; pElementNamedType[iii] = pnamedTypeTmp; } } // END for remaining elements (for sorting) } // END FOR each element } /* END PrintCxxDefCode_PERSort(...) */ void PrintCxxSimpleDefMeta_1(FILE * hdr, FILE* src, TypeDef* td, int hasNamedElmts, CNamedElmt *n, Module* m) { hdr = hdr; src = src; td = td; hasNamedElmts = hasNamedElmts; n = n; m = m; #if META const char *T, *t; int a3; fprintf (hdr, "\n"); fprintf (hdr, "#if META\n"); fprintf (src, "#if META\n\n"); fprintf (src, "static AsnType *create%s()\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " return new %s;\n", td->cxxTypeDefInfo->className); fprintf (src, "}\n\n"); if ((hasNamedElmts = HasNamedElmts (td->type))) { fprintf (hdr, " static const AsnNameDesc _nmdescs[];\n"); fprintf (src, "const AsnNameDesc %s::_nmdescs[] =\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); FOR_EACH_LIST_ELMT (n, td->type->cxxTypeRefInfo->namedElmts) #if 0 /* (no asn1 names available!) */ if (printMetaG == META_backend_names) else /* META_asn1_names */ #endif fprintf (src, " \"%s\", %s, // %d\n", n->name, n->name, n->value); fprintf (src, " NULL, -1\n"); fprintf (src, "};\n\n"); } switch (GetBuiltinType (td->type)) { case BASICTYPE_BOOLEAN: T = "BOOLEAN"; t = "Bool"; a3 = FALSE; break; case BASICTYPE_ENUMERATED: T = "ENUMERATED"; t = "Enum"; a3 = TRUE; break; case BASICTYPE_INTEGER: T = "INTEGER"; t = "Int"; a3 = TRUE; break; case BASICTYPE_REAL: T = "REAL"; t = "Real"; a3 = FALSE; break; case BASICTYPE_OCTETSTRING: T = "OCTET_STRING"; t = "Octs"; a3 = FALSE; break; case BASICTYPE_BITSTRING: T = "BIT_STRING"; t = "Bits"; a3 = TRUE; break; case BASICTYPE_OID: T = "OID"; t = "Oid"; a3 = FALSE; case BASICTYPE_RELATIVE_OID: T = "RELATIVE_OID"; t = "RelativeOid"; a3 = FALSE; default: T = t = "?"; a3 = FALSE; } fprintf (hdr, " static const Asn%sTypeDesc _desc;\n", t); fprintf (hdr, " const AsnTypeDesc *_getdesc() const;\n"); fprintf (src, "const Asn%sTypeDesc %s::_desc\n", t, td->cxxTypeDefInfo->className); fprintf (src, "(\n"); fprintf (src, " &%sModuleDesc,\n", m->cxxname); if (printMetaG == META_backend_names) fprintf (src, " \"%s\", // `%s'\n", td->cxxTypeDefInfo->className, td->definedName); else /* META_asn1_names */ fprintf (src, " \"%s\", // `%s'\n", td->definedName, td->cxxTypeDefInfo->className); fprintf (src, " %s,\n", isMetaPDU (m->modId->name, td->definedName, meta_pdus_G) ? "true" : "false"); fprintf (src, " AsnTypeDesc::%s,\n", T); fprintf (src, " create%s", td->cxxTypeDefInfo->className); if (a3) fprintf (src, ",\n %s", hasNamedElmts ? "_nmdescs" : "NULL"); fprintf (src, "\n);\n\n"); fprintf (src, "const AsnTypeDesc *%s::_getdesc() const\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " return &_desc;\n"); fprintf (src, "}\n\n"); fprintf (hdr, "#endif // META\n"); fprintf (src, "#endif // META\n\n"); #if TCL #endif #endif //META } void PrintCxxSimpleDefMeta_2(FILE * hdr, FILE* src, TypeDef* td, int hasNamedElmts, CNamedElmt *n, Module* m, CxxRules *r) { hdr = hdr; src = src; td = td; hasNamedElmts = hasNamedElmts; n = n; m = m; r = r; #if META fprintf (hdr, "#if META\n"); fprintf (src, "#if META\n\n"); fprintf (src, "static AsnType *create%s()\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " return new %s;\n", td->cxxTypeDefInfo->className); fprintf (src, "}\n\n"); fprintf (hdr, "struct %s: public %s\n", td->cxxTypeDefInfo->className, td->type->cxxTypeRefInfo->className); fprintf (hdr, "{\n"); PrintDerivedConstructors (hdr, r, td); PrintCloneMethod (hdr, src, td); fprintf (hdr, " static const AsnAliasTypeDesc _desc;\n"); fprintf (hdr, " const AsnTypeDesc *_getdesc() const;\n"); fprintf (src, "const AsnAliasTypeDesc %s::_desc\n", td->cxxTypeDefInfo->className); fprintf (src, "(\n"); fprintf (src, " &%sModuleDesc,\n", m->cxxname); if (printMetaG == META_backend_names) fprintf (src, " \"%s\", // `%s'\n", td->cxxTypeDefInfo->className, td->definedName); else /* META_asn1_names */ fprintf (src, " \"%s\", // `%s'\n", td->definedName, td->cxxTypeDefInfo->className); fprintf (src, " %s,\n", isMetaPDU (m->modId->name, td->definedName, meta_pdus_G) ? "true" : "false"); fprintf (src, " AsnTypeDesc::ALIAS,\n"); fprintf (src, " create%s,\n", td->cxxTypeDefInfo->className); fprintf (src, " &%s::_desc\n);\n\n", td->type->cxxTypeRefInfo->className); fprintf (src, "const AsnTypeDesc *%s::_getdesc() const\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " return &_desc;\n"); fprintf (src, "}\n\n"); fprintf (hdr, "};\n\n"); fprintf (hdr, "#else // META\n\n"); fprintf (src, "#endif // META\n\n"); #endif //META } void PrintCxxChoiceDefCodeMeta_1(FILE* hdr, FILE* src, TypeDef* td, Type* choice, Module* m, NamedType* e) { hdr = hdr; src = src; td = td; choice = choice; m = m; e = e; #if META fprintf (hdr, "#if META\n"); fprintf (src, "#if META\n\n"); fprintf (hdr, " static const AsnChoiceTypeDesc _desc;\n"); fprintf (hdr, " static const AsnChoiceMemberDesc _mdescs[];\n\n"); fprintf (hdr, " const AsnTypeDesc *_getdesc() const;\n"); fprintf (hdr, " AsnType *_getref (const char *membername, bool create = false);\n\n"); fprintf (src, "static AsnType *create%s()\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " return new %s;\n", td->cxxTypeDefInfo->className); fprintf (src, "}\n\n"); fprintf (src, "const AsnChoiceMemberDesc %s::_mdescs[] =\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) if (printMetaG == META_backend_names) fprintf (src, " AsnChoiceMemberDesc (\"%s\", &%s::_desc), // `%s'\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className, e->fieldName ? e->fieldName : ""); else /* META_asn1_names */ fprintf (src, " AsnChoiceMemberDesc (\"%s\", &%s::_desc), // `%s'\n", e->fieldName ? e->fieldName : e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className, e->type->cxxTypeRefInfo->fieldName); fprintf (src, " AsnChoiceMemberDesc()\n"); fprintf (src, "};\n\n"); fprintf (src, "const AsnChoiceTypeDesc %s::_desc\n", td->cxxTypeDefInfo->className); fprintf (src, "(\n"); fprintf (src, " &%sModuleDesc,\n", m->cxxname); if (printMetaG == META_backend_names) fprintf (src, " \"%s\", // `%s'\n", td->cxxTypeDefInfo->className, td->definedName); else /* META_asn1_names */ fprintf (src, " \"%s\", // `%s'\n", td->definedName, td->cxxTypeDefInfo->className); fprintf (src, " %s,\n", isMetaPDU (m->modId->name, td->definedName, meta_pdus_G) ? "true" : "false"); fprintf (src, " AsnTypeDesc::CHOICE,\n"); fprintf (src, " create%s,\n", td->cxxTypeDefInfo->className); fprintf (src, " _mdescs\n"); fprintf (src, ");\n\n"); fprintf (src, "const AsnTypeDesc *%s::_getdesc() const\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " return &_desc;\n"); fprintf (src, "}\n\n"); fprintf (src, "AsnType *%s::_getref (const char *membername, bool create)\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " ChoiceIdEnum newCid = (ChoiceIdEnum)_desc.choicebyname (membername);\n"); fprintf (src, " if (newCid == -1)\n"); fprintf (src, " return NULL;\n"); fprintf (src, " if (newCid == choiceId)\n"); fprintf (src, " {\n"); fprintf (src, " switch (choiceId)\n"); fprintf (src, " {\n"); FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) { fprintf (src, " case %sCid:\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " return %s;\n", e->type->cxxTypeRefInfo->fieldName); } fprintf (src, " default:\n"); fprintf (src, " return NULL;\n"); fprintf (src, " }\n"); fprintf (src, " }\n"); fprintf (src, " else\n"); fprintf (src, " {\n"); fprintf (src, " if (create)\n"); fprintf (src, " {\n"); fprintf (src, "// switch (choiceId)\n"); fprintf (src, "// {\n"); FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) { fprintf (src, "// case %sCid:\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, "// delete %s;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, "// %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, "// break;\n"); } fprintf (src, "// default:\n"); fprintf (src, "// return NULL;\n"); fprintf (src, "// }\n"); e = FIRST_LIST_ELMT (choice->basicType->a.choice); fprintf (src, " // simply delete any member, the virtual function table takes care of the rest:\n"); fprintf (src, " delete %s;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " switch (choiceId = newCid)\n"); fprintf (src, " {\n"); FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) { fprintf (src, " case %sCid:\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " return %s = new %s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className); } fprintf (src, " default: // internal error!\n"); fprintf (src, " return NULL;\n"); fprintf (src, " }\n"); fprintf (src, " }\n"); fprintf (src, " else\n"); fprintf (src, " return NULL;\n"); fprintf (src, " }\n"); fprintf (src, "}\n\n"); #if TCL if (printTclG) { fprintf (hdr, "#if TCL\n"); fprintf (src, "#if TCL\n\n"); fprintf (hdr, " int TclGetDesc (Tcl_DString *) const;\n"); fprintf (hdr, " int TclGetVal (Tcl_Interp *) const;\n"); fprintf (hdr, " int TclSetVal (Tcl_Interp *, const char *valstr);\n\n"); fprintf (src, "int %s::TclGetDesc (Tcl_DString *valstr) const\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " Tcl_DStringAppendElement (valstr, (char*)_desc.choicebyvalue (choiceId));\n"); fprintf (src, " // hack: since all members are pointers, we don't have to check for its type via choiceId, because all we want to know is whether it's NULL or not:\n"); e = FIRST_LIST_ELMT (choice->basicType->a.choice); fprintf (src, " Tcl_DStringAppendElement (valstr, %s ? \"valid\" : \"void\");\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " return TCL_OK;\n"); fprintf (src, "}\n\n"); fprintf (src, "int %s::TclGetVal (Tcl_Interp *interp) const\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " switch (choiceId)\n"); fprintf (src, " {\n"); FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) { fprintf (src, " case %sCid:\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " if (%s)\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " if (%s->TclGetVal (interp) != TCL_OK)\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, " break;\n"); } fprintf (src, " default:\n"); fprintf (src, " Tcl_SetResult (interp, \"illegal choiceId in %s\", TCL_STATIC);\n", td->cxxTypeDefInfo->className); fprintf (src, " Tcl_SetErrorCode (interp, \"SNACC\", \"ILLCHOICE\", NULL);\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, " }\n"); fprintf (src, " Tcl_DString valstr;\n"); fprintf (src, " Tcl_DStringInit (&valstr);\n"); fprintf (src, " Tcl_DStringAppendElement (&valstr, (char*)_desc.choicebyvalue (choiceId));\n"); fprintf (src, " Tcl_DStringAppendElement (&valstr, interp->result);\n"); fprintf (src, " Tcl_ResetResult (interp);\n"); fprintf (src, " Tcl_DStringResult (interp, &valstr);\n"); fprintf (src, " return TCL_OK;\n"); fprintf (src, "}\n\n"); fprintf (src, "int %s::TclSetVal (Tcl_Interp *interp, const char *valstr)\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " Args elem;\n"); fprintf (src, " if (Tcl_SplitList (interp, (char*)valstr, &elem.c, &elem.v) != TCL_OK)\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, " if (elem.c != 2)\n"); fprintf (src, " {\n"); fprintf (src, " sprintf (interp->result, \"syntax error: expected a pair, but it's got %%d element(s)\", elem.c);\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, " }\n"); fprintf (src, " AsnType *member = _getref (elem.v[0], true);\n"); fprintf (src, " if (!member)\n"); fprintf (src, " {\n"); fprintf (src, " Tcl_AppendResult (interp, \"illegal choice \", elem.v[0], \" for %s\", NULL);\n", td->cxxTypeDefInfo->className); fprintf (src, " Tcl_SetErrorCode (interp, \"SNACC\", \"ILLCHOICE\", NULL);\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, " }\n"); fprintf (src, " return member->TclSetVal (interp, elem.v[1]);\n"); fprintf (src, "}\n\n"); fprintf (hdr, "#endif // TCL\n"); fprintf (src, "#endif // TCL\n\n"); } #endif /* TCL */ fprintf (hdr, "#endif // META\n"); fprintf (src, "#endif // META\n\n"); #endif /* META */ } void PrintCxxSeqDefCodeMeta_1(FILE* hdr, FILE* src, TypeDef* td, Type* seq, Module* m, NamedType* e) { hdr = hdr; src = src; td = td; seq = seq; m = m; e = e; #if META fprintf (hdr, "#if META\n"); fprintf (src, "#if META\n\n"); fprintf (hdr, " static const AsnSequenceTypeDesc _desc;\n"); fprintf (hdr, " static const AsnSequenceMemberDesc _mdescs[];\n"); fprintf (hdr, " const AsnTypeDesc *_getdesc() const;\n"); fprintf (hdr, " AsnType *_getref (const char *membername, bool create = false);\n\n"); fprintf (src, "static AsnType *create%s()\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " return new %s;\n", td->cxxTypeDefInfo->className); fprintf (src, "}\n\n"); fprintf (src, "const AsnSequenceMemberDesc %s::_mdescs[] =\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence) if (printMetaG == META_backend_names) fprintf (src, " AsnSequenceMemberDesc (\"%s\", &%s::_desc, %s), // `%s'\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className, e->type->optional || e->type->defaultVal ? "true" : "false", e->fieldName ? e->fieldName : ""); else /* META_asn1_names */ fprintf (src, " AsnSequenceMemberDesc (\"%s\", &%s::_desc, %s), // `%s'\n", e->fieldName ? e->fieldName : e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className, e->type->optional || e->type->defaultVal ? "true" : "false", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " AsnSequenceMemberDesc()\n"); fprintf (src, "};\n\n"); fprintf (src, "const AsnSequenceTypeDesc %s::_desc\n", td->cxxTypeDefInfo->className); fprintf (src, "(\n"); fprintf (src, " &%sModuleDesc,\n", m->cxxname); if (printMetaG == META_backend_names) fprintf (src, " \"%s\", // `%s'\n", td->cxxTypeDefInfo->className, td->definedName); else /* META_asn1_names */ fprintf (src, " \"%s\", // `%s'\n", td->definedName, td->cxxTypeDefInfo->className); fprintf (src, " %s,\n", isMetaPDU (m->modId->name, td->definedName, meta_pdus_G) ? "true" : "false"); fprintf (src, " AsnTypeDesc::SEQUENCE,\n"); fprintf (src, " create%s,\n", td->cxxTypeDefInfo->className); fprintf (src, " _mdescs\n"); fprintf (src, ");\n\n"); fprintf (src, "const AsnTypeDesc *%s::_getdesc() const\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " return &_desc;\n"); fprintf (src, "}\n\n"); fprintf (src, "AsnType *%s::_getref (const char *membername, bool create)\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence) { fprintf (src, " if (!strcmp (membername, \"%s\"))\n", e->type->cxxTypeRefInfo->fieldName); if (e->type->cxxTypeRefInfo->isPtr) { fprintf (src, " {\n"); fprintf (src, " if (!%s && create)\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " %s = new %s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className); fprintf (src, " return %s;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " }\n"); } else fprintf (src, " return &%s;\n", e->type->cxxTypeRefInfo->fieldName); } fprintf (src, " return NULL;\n"); fprintf (src, "}\n\n"); #if TCL if (printTclG) { fprintf (hdr, "#if TCL\n"); fprintf (src, "#if TCL\n\n"); fprintf (hdr, " int TclGetDesc (Tcl_DString *) const;\n"); fprintf (hdr, " int TclGetVal (Tcl_Interp *) const;\n"); fprintf (hdr, " int TclSetVal (Tcl_Interp *, const char *valstr);\n"); fprintf (hdr, " int TclUnsetVal (Tcl_Interp *, const char *membname);\n\n"); fprintf (src, "int %s::TclGetDesc (Tcl_DString *valstr) const\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " Tcl_DStringStartSublist (valstr);\n\n"); FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence) { fprintf (src, " Tcl_DStringStartSublist (valstr);\n"); fprintf (src, " Tcl_DStringAppendElement (valstr, \"%s\");\n", e->type->cxxTypeRefInfo->fieldName); if (e->type->cxxTypeRefInfo->isPtr) fprintf (src, " Tcl_DStringAppendElement (valstr, %s ? \"valid\" : \"void\");\n", e->type->cxxTypeRefInfo->fieldName); else fprintf (src, " Tcl_DStringAppendElement (valstr, %s \"valid\");\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " Tcl_DStringEndSublist (valstr);\n\n"); } fprintf (src, " Tcl_DStringEndSublist (valstr);\n\n"); fprintf (src, " return TCL_OK;\n"); fprintf (src, "}\n\n"); fprintf (src, "int %s::TclGetVal (Tcl_Interp *interp) const\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " Tcl_DString valstr;\n\n"); fprintf (src, " Tcl_DStringInit (&valstr);\n\n"); FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence) { if (e->type->cxxTypeRefInfo->isPtr) { fprintf (src, " if (%s)\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " {\n"); fprintf (src, " Tcl_DStringStartSublist (&valstr);\n"); fprintf (src, " Tcl_DStringAppendElement (&valstr, \"%s\");\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " if (%s->TclGetVal (interp) != TCL_OK)\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " goto Error;\n"); fprintf (src, " Tcl_DStringAppendElement (&valstr, interp->result);\n"); fprintf (src, " Tcl_ResetResult (interp);\n"); fprintf (src, " Tcl_DStringEndSublist (&valstr);\n"); fprintf (src, " }\n\n"); } else { fprintf (src, " Tcl_DStringStartSublist (&valstr);\n"); fprintf (src, " Tcl_DStringAppendElement (&valstr, \"%s\");\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " if (%s.TclGetVal (interp) != TCL_OK)\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " goto Error;\n"); fprintf (src, " Tcl_DStringAppendElement (&valstr, interp->result);\n"); fprintf (src, " Tcl_ResetResult (interp);\n"); fprintf (src, " Tcl_DStringEndSublist (&valstr);\n\n"); } } fprintf (src, " Tcl_DStringResult (interp, &valstr);\n"); fprintf (src, " return TCL_OK;\n\n"); fprintf (src, "Error:\n"); fprintf (src, " Tcl_DStringFree (&valstr);\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, "}\n\n"); fprintf (src, "int %s::TclSetVal (Tcl_Interp *interp, const char *valstr)\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " int i;\n"); fprintf (src, " Args elems;\n"); fprintf (src, " if (Tcl_SplitList (interp, (char*)valstr, &elems.c, &elems.v) != TCL_OK)\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, " Args* elempairs = new Args[elems.c];\n"); fprintf (src, " for (i=0; iresult, \"syntax error in element #%%d: expected a pair, but it's got %%d element(s)\", i, elempairs[i].c);\n"); fprintf (src, " delete elempairs;\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, " }\n"); fprintf (src, " }\n"); fprintf (src, "\n"); fprintf (src, " for (const AsnSequenceMemberDesc *m=_mdescs; m->name; m++)\n"); fprintf (src, " {\n"); fprintf (src, " int count = 0;\n"); fprintf (src, " for (i=0; iname))\n"); fprintf (src, " count++;\n"); fprintf (src, " if (count > 1)\n"); fprintf (src, " {\n"); fprintf (src, " sprintf (interp->result, \"duplicate value for member \\\"%%s\\\" in list\", m->name);\n"); fprintf (src, " Tcl_SetErrorCode (interp, \"SNACC\", \"DUPMEMB\", NULL);\n"); fprintf (src, " delete elempairs;\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, " }\n"); fprintf (src, " if (!m->optional && count < 1)\n"); fprintf (src, " {\n"); fprintf (src, " sprintf (interp->result, \"mandatory member \\\"%%s\\\" is missing in list\", m->name);\n"); fprintf (src, " Tcl_SetErrorCode (interp, \"SNACC\", \"MISSMAND\", NULL);\n"); fprintf (src, " delete elempairs;\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, " }\n"); fprintf (src, " \n"); fprintf (src, " }\n"); fprintf (src, "\n"); fprintf (src, " for (i=0; ibasicType->a.sequence) { fprintf (src, " if (!strcmp (elempairs[i].v[0], \"%s\"))\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " {\n"); if (e->type->cxxTypeRefInfo->isPtr) { fprintf (src, " if (!%s)\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " %s = new %s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className); fprintf (src, " if (%s->TclSetVal (interp, elempairs[i].v[1]))\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " {\n"); fprintf (src, " delete elempairs;\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, " }\n"); } else { fprintf (src, " if (%s.TclSetVal (interp, elempairs[i].v[1]))\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " {\n"); fprintf (src, " delete elempairs;\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, " }\n"); } fprintf (src, " }\n"); } fprintf (src, " }\n"); fprintf (src, "\n"); fprintf (src, " // look for unmentioned optional members and delete them:\n"); FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence) { if (e->type->optional || e->type->defaultVal) { fprintf (src, " {\n"); fprintf (src, " bool present = false;\n"); fprintf (src, " for (i=0; itype->cxxTypeRefInfo->fieldName); fprintf (src, " present = true;\n"); fprintf (src, " if (!present)\n"); fprintf (src, " {\n"); fprintf (src, " delete %s;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " }\n"); fprintf (src, " }\n"); } } fprintf (src, "\n"); fprintf (src, " delete elempairs;\n"); fprintf (src, " return TCL_OK;\n"); fprintf (src, "}\n\n"); fprintf (src, "int %s::TclUnsetVal (Tcl_Interp *interp, const char *membernames)\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " Args elems;\n"); fprintf (src, " if (Tcl_SplitList (interp, (char*)membernames, &elems.c, &elems.v) != TCL_OK)\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, "\n"); fprintf (src, " for (int i=0; ibasicType->a.sequence) { fprintf (src, " if (!strcmp (elems.v[i], \"%s\"))\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " {\n"); if (e->type->optional || e->type->defaultVal) { fprintf (src, " delete %s;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName); } else { fprintf (src, " return _desc.mandatmemberr (interp, elems.v[i]);\n"); } fprintf (src, " }\n"); } fprintf (src, " }\n"); fprintf (src, " return TCL_OK;\n"); fprintf (src, "}\n\n"); fprintf (hdr, "#endif // TCL\n"); fprintf (src, "#endif // TCL\n\n"); } #endif /* TCL */ fprintf (hdr, "#endif // META\n\n"); fprintf (src, "#endif // META\n\n"); #endif /* META*/ } void PrintCxxSetDefCodeMeta_1(FILE* hdr, FILE* src, TypeDef* td, Type* set, Module* m, NamedType* e) { hdr = hdr; src = src; td = td; set = set; m = m; e = e; #if META fprintf (hdr, "#if META\n"); fprintf (src, "#if META\n\n"); fprintf (hdr, " static const AsnSetTypeDesc _desc;\n"); fprintf (hdr, " static const AsnSetMemberDesc _mdescs[];\n"); fprintf (hdr, " const AsnTypeDesc *_getdesc() const;\n"); fprintf (hdr, " AsnType *_getref (const char *membername, bool create = false);\n\n"); fprintf (src, "static AsnType *create%s()\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " return new %s;\n", td->cxxTypeDefInfo->className); fprintf (src, "}\n\n"); fprintf (src, "const AsnSetMemberDesc %s::_mdescs[] =\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); FOR_EACH_LIST_ELMT (e, set->basicType->a.set) if (printMetaG == META_backend_names) fprintf (src, " AsnSetMemberDesc (\"%s\", &%s::_desc, %s), // `%s'\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className, e->type->optional || e->type->defaultVal ? "true" : "false", e->fieldName ? e->fieldName : ""); else /* META_asn1_names */ fprintf (src, " AsnSetMemberDesc (\"%s\", &%s::_desc, %s), // `%s'\n", e->fieldName ? e->fieldName : e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className, e->type->optional || e->type->defaultVal ? "true" : "false", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " AsnSetMemberDesc()\n"); fprintf (src, "};\n\n"); fprintf (src, "const AsnSetTypeDesc %s::_desc\n", td->cxxTypeDefInfo->className); fprintf (src, "(\n"); fprintf (src, " &%sModuleDesc,\n", m->cxxname); if (printMetaG == META_backend_names) fprintf (src, " \"%s\", // `%s'\n", td->cxxTypeDefInfo->className, td->definedName); else /* META_asn1_names */ fprintf (src, " \"%s\", // `%s'\n", td->definedName, td->cxxTypeDefInfo->className); fprintf (src, " %s,\n", isMetaPDU (m->modId->name, td->definedName, meta_pdus_G) ? "true" : "false"); fprintf (src, " AsnTypeDesc::SET,\n"); fprintf (src, " create%s,\n", td->cxxTypeDefInfo->className); fprintf (src, " _mdescs\n"); fprintf (src, ");\n\n"); fprintf (src, "const AsnTypeDesc *%s::_getdesc() const\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " return &_desc;\n"); fprintf (src, "}\n\n"); fprintf (src, "AsnType *%s::_getref (const char *membername, bool create)\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); FOR_EACH_LIST_ELMT (e, set->basicType->a.set) { fprintf (src, " if (!strcmp (membername, \"%s\"))\n", e->type->cxxTypeRefInfo->fieldName); if (e->type->cxxTypeRefInfo->isPtr) { fprintf (src, " {\n"); fprintf (src, " if (!%s && create)\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " %s = new %s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className); fprintf (src, " return %s;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " }\n"); } else fprintf (src, " return &%s;\n", e->type->cxxTypeRefInfo->fieldName); } fprintf (src, " return NULL;\n"); fprintf (src, "}\n\n"); #if TCL if (printTclG) { fprintf (hdr, "#if TCL\n"); fprintf (src, "#if TCL\n\n"); fprintf (hdr, " int TclGetDesc (Tcl_DString *) const;\n"); fprintf (hdr, " int TclGetVal (Tcl_Interp *) const;\n"); fprintf (hdr, " int TclSetVal (Tcl_Interp *, const char *valstr);\n"); fprintf (hdr, " int TclUnsetVal (Tcl_Interp *, const char *membernames);\n\n"); fprintf (src, "int %s::TclGetDesc (Tcl_DString *valstr) const\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " Tcl_DStringStartSublist (valstr);\n\n"); FOR_EACH_LIST_ELMT (e, set->basicType->a.set) { fprintf (src, " Tcl_DStringStartSublist (valstr);\n"); fprintf (src, " Tcl_DStringAppendElement (valstr, \"%s\");\n", e->type->cxxTypeRefInfo->fieldName); if (e->type->cxxTypeRefInfo->isPtr) fprintf (src, " Tcl_DStringAppendElement (valstr, %s ? \"valid\" : \"void\");\n", e->type->cxxTypeRefInfo->fieldName); else fprintf (src, " Tcl_DStringAppendElement (valstr, \"valid\");\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " Tcl_DStringEndSublist (valstr);\n\n"); } fprintf (src, " Tcl_DStringEndSublist (valstr);\n\n"); fprintf (src, " return TCL_OK;\n"); fprintf (src, "}\n\n"); fprintf (src, "int %s::TclGetVal (Tcl_Interp *interp) const\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " Tcl_DString valstr;\n\n"); fprintf (src, " Tcl_DStringInit (&valstr);\n\n"); FOR_EACH_LIST_ELMT (e, set->basicType->a.set) { if (e->type->cxxTypeRefInfo->isPtr) { fprintf (src, " if (%s)\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " {\n"); fprintf (src, " Tcl_DStringStartSublist (&valstr);\n"); fprintf (src, " Tcl_DStringAppendElement (&valstr, \"%s\");\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " if (%s->TclGetVal (interp) != TCL_OK)\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " goto Error;\n"); fprintf (src, " Tcl_DStringAppendElement (&valstr, interp->result);\n"); fprintf (src, " Tcl_ResetResult (interp);\n"); fprintf (src, " Tcl_DStringEndSublist (&valstr);\n"); fprintf (src, " }\n\n"); } else { fprintf (src, " Tcl_DStringStartSublist (&valstr);\n"); fprintf (src, " Tcl_DStringAppendElement (&valstr, \"%s\");\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " if (%s.TclGetVal (interp) != TCL_OK)\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " goto Error;\n"); fprintf (src, " Tcl_DStringAppendElement (&valstr, interp->result);\n"); fprintf (src, " Tcl_ResetResult (interp);\n"); fprintf (src, " Tcl_DStringEndSublist (&valstr);\n\n"); } } fprintf (src, " Tcl_DStringResult (interp, &valstr);\n"); fprintf (src, " return TCL_OK;\n\n"); fprintf (src, "Error:\n"); fprintf (src, " Tcl_DStringFree (&valstr);\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, "}\n\n"); fprintf (src, "int %s::TclSetVal (Tcl_Interp *interp, const char *valstr)\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " int i;\n"); fprintf (src, " Args elems;\n"); fprintf (src, " if (Tcl_SplitList (interp, (char*)valstr, &elems.c, &elems.v) != TCL_OK)\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, " Args* elempairs = new Args[elems.c];\n"); fprintf (src, " for (i=0; iresult, \"syntax error in element #%%d: expected a pair, but it's got %%d element(s)\", i, elempairs[i].c);\n"); fprintf (src, " delete elempairs;\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, " }\n"); fprintf (src, " }\n"); fprintf (src, "\n"); fprintf (src, " for (const AsnSetMemberDesc *m=_mdescs; m->name; m++)\n"); fprintf (src, " {\n"); fprintf (src, " int count = 0;\n"); fprintf (src, " for (i=0; iname))\n"); fprintf (src, " count++;\n"); fprintf (src, " if (count > 1)\n"); fprintf (src, " {\n"); fprintf (src, " sprintf (interp->result, \"duplicate value for member \\\"%%s\\\" in list\", m->name);\n"); fprintf (src, " Tcl_SetErrorCode (interp, \"SNACC\", \"DUPMEMB\", NULL);\n"); fprintf (src, " delete elempairs;\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, " }\n"); fprintf (src, " if (!m->optional && count < 1)\n"); fprintf (src, " {\n"); fprintf (src, " sprintf (interp->result, \"mandatory member \\\"%%s\\\" is missing in list\", m->name);\n"); fprintf (src, " Tcl_SetErrorCode (interp, \"SNACC\", \"MISSMAND\", NULL);\n"); fprintf (src, " delete elempairs;\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, " }\n"); fprintf (src, " \n"); fprintf (src, " }\n"); fprintf (src, "\n"); fprintf (src, " for (i=0; ibasicType->a.set) { fprintf (src, " if (!strcmp (elempairs[i].v[0], \"%s\"))\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " {\n"); if (e->type->cxxTypeRefInfo->isPtr) { fprintf (src, " if (!%s)\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " %s = new %s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className); fprintf (src, " if (%s->TclSetVal (interp, elempairs[i].v[1]))\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " {\n"); fprintf (src, " delete elempairs;\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, " }\n"); } else { fprintf (src, " if (%s.TclSetVal (interp, elempairs[i].v[1]))\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " {\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, " delete elempairs;\n"); fprintf (src, " }\n"); } fprintf (src, " }\n"); } fprintf (src, " }\n"); fprintf (src, "\n"); fprintf (src, " // look for unmentioned optional members and delete them:\n"); FOR_EACH_LIST_ELMT (e, set->basicType->a.set) { if (e->type->optional || e->type->defaultVal) { fprintf (src, " {\n"); fprintf (src, " bool present = false;\n"); fprintf (src, " for (i=0; itype->cxxTypeRefInfo->fieldName); fprintf (src, " present = true;\n"); fprintf (src, " if (!present)\n"); fprintf (src, " {\n"); fprintf (src, " delete %s;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " }\n"); fprintf (src, " }\n"); } } fprintf (src, "\n"); fprintf (src, " delete elempairs;\n"); fprintf (src, " return TCL_OK;\n"); fprintf (src, "}\n\n"); fprintf (src, "int %s::TclUnsetVal (Tcl_Interp *interp, const char *membernames)\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " Args elems;\n"); fprintf (src, " if (Tcl_SplitList (interp, (char*)membernames, &elems.c, &elems.v) != TCL_OK)\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, "\n"); fprintf (src, " for (int i=0; ibasicType->a.set) { fprintf (src, " if (!strcmp (elems.v[i], \"%s\"))\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " {\n"); if (e->type->optional || e->type->defaultVal) { fprintf (src, " delete %s;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName); } else { fprintf (src, " return _desc.mandatmemberr (interp, elems.v[i]);\n"); } fprintf (src, " }\n"); } fprintf (src, " }\n"); fprintf (src, " return TCL_OK;\n"); fprintf (src, "}\n\n"); fprintf (hdr, "#endif // TCL\n"); fprintf (src, "#endif // TCL\n\n"); } #endif /* TCL */ fprintf (hdr, "#endif // META\n\n"); fprintf (src, "#endif // META\n\n"); #endif /* META */ } /* EOF gen-code.c (for back-ends/c++-gen) */ esnacc-ng-1.8.1/compiler/back-ends/c++-gen/gen-vals.c000066400000000000000000000173631302010526100220170ustar00rootroot00000000000000/* * compiler/back_ends/c++_gen/gen_vals.c - prints ASN.1 values in c++ format * * MS 92 * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/back-ends/c++-gen/gen-vals.c,v 1.8 2004/04/06 15:13:41 gronej Exp $ * $Log: gen-vals.c,v $ * Revision 1.8 2004/04/06 15:13:41 gronej * *** empty log message *** * * Revision 1.7 2003/12/19 20:55:49 leonberp * added parameter to PrintCxxOidValue() to allow printing of paren or quote to be specified. * * Revision 1.6 2003/07/07 14:52:35 nicholar * Eliminated headers and cleaned up include references * * Revision 1.5 2002/10/21 17:18:52 mcphersc * fixed long int * * Revision 1.4 2002/05/15 14:53:11 leonberp * added support for new basicTypes to compiler * * Revision 1.3 2001/08/30 17:25:38 rwc * Updated AsnOid constructor, automatic build of constants to now load strings, not * the 10 parameter constructor choice (which was removed by Pierce eariler). * * Revision 1.2 2000/10/24 14:54:46 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:36:06 leonberp * First CVS Version of SNACC. * * Revision 1.4 1995/07/25 18:20:05 rj * use true/false instead of AsnBool::true/false. * * changed `_' to `-' in file names. * * Revision 1.3 1994/10/08 03:47:57 rj * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long. * * Revision 1.2 1994/09/01 00:17:22 rj * snacc_config.h removed. * * Revision 1.1 1994/08/28 09:48:05 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include "asn-incl.h" #include "asn1module.h" #include "str-util.h" #include "rules.h" extern char *bVDAGlobalDLLExport; void PrintCxxValuesClass PROTO ((FILE *f, CxxRules *r, Value *v)); void PrintCxxValueInstantiation PROTO ((FILE *f, CxxRules *r, Value *v)); void PrintCxxOidValue PROTO ((FILE *f, CxxRules *r, AsnOid *oid, int parenOrQuote)); void PrintCxxIntValue PROTO ((FILE *f, CxxRules *r, AsnInt oid)); static void PrintCxxValueDefsName PROTO ((FILE *f, CxxRules *r, ValueDef *v)); void PrintCxxValueDef PARAMS ((src, r, v), FILE *src _AND_ CxxRules *r _AND_ ValueDef *v) { /* just do oid's, ints and bools for now */ if ((v->value->basicValue->choiceId != BASICVALUE_OID) && (v->value->basicValue->choiceId != BASICVALUE_INTEGER) && (v->value->basicValue->choiceId != BASICVALUE_BOOLEAN)) return; if (v->value->basicValue->choiceId == BASICVALUE_OID) { fprintf(src, "const char *"); PrintCxxValueDefsName (src, r, v); fprintf(src, " ="""); PrintCxxOidValue (src, r, v->value->basicValue->a.oid, 2); fprintf(src, """;\n\n"); } else { /* * put instantiation in src file */ fprintf (src, "const "); PrintCxxValuesClass (src, r, v->value); fprintf (src, " "); PrintCxxValueDefsName (src, r, v); fprintf (src, " "); PrintCxxValueInstantiation (src, r, v->value); fprintf (src, ";\n\n"); } } /* PrintCxxValueDef */ void PrintCxxValueExtern PARAMS ((hdr, r, v), FILE *hdr _AND_ CxxRules *r _AND_ ValueDef *v) { /* just do oid's, ints and bools for now */ if ((v->value->basicValue->choiceId != BASICVALUE_OID) && (v->value->basicValue->choiceId != BASICVALUE_INTEGER) && (v->value->basicValue->choiceId != BASICVALUE_BOOLEAN)) return; /* * put extern declaration in hdr file */ if (bVDAGlobalDLLExport != NULL) fprintf (hdr, "extern const %s ", bVDAGlobalDLLExport); else fprintf (hdr, "extern const "); if (v->value->basicValue->choiceId == BASICVALUE_OID) { fprintf(hdr, "char *"); PrintCxxValueDefsName (hdr, r, v); fprintf(hdr, ";\n"); } else { PrintCxxValuesClass (hdr, r, v->value); fprintf (hdr, " "); PrintCxxValueDefsName (hdr, r, v); fprintf (hdr, ";\n"); } } /* PrintCxxValueExtern */ static void PrintCxxValueDefsName PARAMS ((f, r, v), FILE *f _AND_ CxxRules *r _AND_ ValueDef *v) { char *cName; cName = Asn1ValueName2CValueName (v->definedName); fprintf (f, "%s", cName); Free (cName); r=r; /*AVOIDS warning.*/ } void PrintCxxValuesClass PARAMS ((f, r, v), FILE *f _AND_ CxxRules *r _AND_ Value *v) { /* needs work - just do ints bools and oid's for now */ switch (v->basicValue->choiceId) { case BASICVALUE_OID: fprintf (f, "%s", r->typeConvTbl[BASICTYPE_OID].className); break; case BASICVALUE_INTEGER: fprintf (f, "%s", r->typeConvTbl[BASICTYPE_INTEGER].className); break; case BASICVALUE_BOOLEAN: fprintf (f, "%s", r->typeConvTbl[BASICTYPE_BOOLEAN].className); break; default: break; } } void PrintCxxValueInstantiation PARAMS ((f, r, v), FILE *f _AND_ CxxRules *r _AND_ Value *v) { /* needs work - just do oids, ints and bools for now */ switch (v->basicValue->choiceId) { case BASICVALUE_OID: PrintCxxOidValue (f, r, v->basicValue->a.oid, 1); break; case BASICVALUE_INTEGER: PrintCxxIntValue (f, r, v->basicValue->a.integer); break; case BASICVALUE_BOOLEAN: fprintf (f, "(%s)", v->basicValue->a.boolean ? "true" : "false"); break; default: break; } } /* * given an AOID, c++ AOID constructors params are produced. * This is used for turning ASN.1 OBJECT ID values * into usable c++ values. * * eg for the oid { 0 1 2 } (in AOID format) * (0,1,2) * is produced. * * To wrap the dotted notation in parens pass in a parenOrQuote value of 1 * * To wrap the dotted notation in quotes pass in a parenOrQuote value of 2 */ void PrintCxxOidValue (FILE *f, CxxRules *r, AsnOid *v, int parenOrQuote) { unsigned short int firstArcNum; unsigned long arcNum; int i; if (parenOrQuote == 1) fprintf (f, "(\""); else fprintf (f, "\""); /* un-munge first two arc numbers */ for (arcNum = 0, i=0; (i < (int)v->octetLen) && (v->octs[i] & 0x80);i++) arcNum = (arcNum << 7) + (v->octs[i] & 0x7f); arcNum = (arcNum << 7) + (v->octs[i] & 0x7f); i++; firstArcNum = (unsigned short)(arcNum/40); if (firstArcNum > 2) firstArcNum = 2; #ifdef NOW_CONST_OIDS_ARE_STRINGS fprintf (f, "%u, %u", firstArcNum, arcNum - (firstArcNum * 40)); #else fprintf (f, "%u.%lu", firstArcNum, arcNum - (firstArcNum * 40)); #endif for (; i < (int)v->octetLen; ) { for (arcNum = 0; (i < (int)v->octetLen) && (v->octs[i] & 0x80);i++) arcNum = (arcNum << 7) + (v->octs[i] & 0x7f); arcNum = (arcNum << 7) + (v->octs[i] & 0x7f); i++; #ifdef NOW_CONST_OIDS_ARE_STRINGS fprintf (f, ", %u", arcNum); #else fprintf (f, ".%lu", arcNum); #endif } if (parenOrQuote == 1) fprintf (f, "\")"); else fprintf (f, "\""); r=r; /*AVOIDS warning.*/ } /* PrintCxxOidValue */ void PrintCxxIntValue PARAMS ((f, r, v), FILE *f _AND_ CxxRules *r _AND_ AsnInt v) { fprintf (f, "(%d)", v); r=r; /*AVOIDS warning.*/ } /* PrintCxxIntValue */ esnacc-ng-1.8.1/compiler/back-ends/c++-gen/kwd.c000066400000000000000000000061431302010526100210620ustar00rootroot00000000000000/* * compiler/back_ends/c++_gen/kwd.c - routines for determining whether a given str is a C++ * keyword * * NOTE: this was hacked up really quickly. It uses a slow linear * search. A much better approach is to use a hash tbl. * * MS 92 * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/back-ends/c++-gen/kwd.c,v 1.3 2004/02/12 18:55:09 gronej Exp $ * $Log: kwd.c,v $ * Revision 1.3 2004/02/12 18:55:09 gronej * Stable SNACC * non optional choices, sets and sequences are now not pointers * merged with list code * all memory leaks within SNACC fixed * * Revision 1.2 2003/07/07 14:52:35 nicholar * Eliminated headers and cleaned up include references * * Revision 1.1.1.1 2000/08/21 20:36:06 leonberp * First CVS Version of SNACC. * * Revision 1.7 1995/09/07 19:05:01 rj * where the C++ compiler has got the bool type built-in, let the C++ backend avoid conflicts with the new keywords. * * Revision 1.6 1995/08/17 14:56:12 rj * bool added to the list of reserved words * * Revision 1.5 1995/07/25 18:22:40 rj * file name has been shortened for redundant part: c++-gen/c++-kwd -> c++-gen/kwd. * * Revision 1.4 1995/02/17 20:10:40 rj * inclusion order fixed. * * Revision 1.3 1994/10/08 03:48:04 rj * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long. * * Revision 1.2 1994/09/01 00:19:44 rj * snacc_config.h removed; more portable .h file inclusion. * * Revision 1.1 1994/08/28 09:48:11 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include "config.h" #include "snacc.h" #if STDC_HEADERS || HAVE_STRING_H #include #else #include #endif /* * last elmt will be NULL. * key words grabbed from C++/Stroustrup 2.0 */ static char *cxxKWdG[] = { "asm", "auto", "break", "case", "catch", "char", "class", "const", "continue", "default", "delete", "do", "double", "else", "enum", "extern", "float", "for", "friend", "goto", "if", "inline", "int", "long", "new", "operator", "private", "protected", "public", "register", "return", "short", "signed", "sizeof", "static", "struct", "switch", "template", "this", "throw", "try", "typedef", "union", "unsigned", "virtual", "void", "volatile", "while", #if BOOL_BUILTIN "bool", "true", "false", #endif NULL }; /* * returns non-zero if the given str is a C++ key word */ int IsCxxKeyWord PARAMS ((str), char *str) { int i; for (i=0; (cxxKWdG[i] != NULL) && (strcmp (cxxKWdG[i],str) != 0); i++) ; return cxxKWdG[i] != NULL; } esnacc-ng-1.8.1/compiler/back-ends/c++-gen/rules.c000066400000000000000000000303341302010526100214260ustar00rootroot00000000000000/* * compiler/back_ends/c++_gen/rules.c - initialized c rule structure * inits a table that contains info about * converting each ASN.1 type to a C++ class * * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/back-ends/c++-gen/rules.c,v 1.12 2004/02/20 19:36:05 gronej Exp $ * $Log: rules.c,v $ * Revision 1.12 2004/02/20 19:36:05 gronej * Updated compiler to support extensibility in set's sequences * Eliminated unreferenced warnings for extraLen and elmtLen in produced code * * Revision 1.11 2004/02/12 18:55:09 gronej * Stable SNACC * non optional choices, sets and sequences are now not pointers * merged with list code * all memory leaks within SNACC fixed * * Revision 1.10 2004/01/29 21:21:44 gronej * Took all Init() calls out of Clear() functions in generated code * * Revision 1.9 2004/01/14 19:07:53 gronej * Updated Compiler to accept and process relative-oid's * * Revision 1.8 2003/07/07 14:52:35 nicholar * Eliminated headers and cleaned up include references * * Revision 1.7 2002/10/28 19:57:02 leonberp * Added BITSTRING CONTAINING support and fixed CONTAINED ANY DEFINED BY * * Revision 1.6 2002/10/24 21:07:21 leonberp * latest fixing for OCTET CONTAINING * * Revision 1.5 2002/09/04 17:51:34 vracarl * got rid of c++ comments * * Revision 1.4 2002/05/15 17:00:57 leonberp * added support for new basicTypes to compiler * * Revision 1.3 2002/05/15 14:53:12 leonberp * added support for new basicTypes to compiler * * Revision 1.2 2002/05/10 16:39:39 leonberp * latest changes for release 2.2 * includes integrating asn-useful into C & C++ runtime library, the compiler changes that go along with that, SnaccException changes for C++ runtime and compiler * * Revision 1.1.1.1 2000/08/21 20:36:06 leonberp * First CVS Version of SNACC. * * Revision 1.4 1995/07/25 18:24:13 rj * file name has been shortened for redundant part: c++-gen/c++-rules -> c++-gen/rules. * * changed `_' to `-' in file names. * * Revision 1.3 1994/10/08 03:47:49 rj * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long. * * Revision 1.2 1994/09/01 01:53:33 rj * snacc_config.h removed. * * Revision 1.1 1994/08/28 09:47:54 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include "asn-incl.h" #include "asn1module.h" #include "rules.h" CxxRules cxxRulesG = { 4, "choiceId", "ChoiceIdEnum", "a", "ChoiceUnion", FALSE, "Enc", "Dec", "EncContent", "DecContent", "EncPdu", "DecPdu", { { /* 0 */ BASICTYPE_UNKNOWN, "???", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, "NOT_NULL", "unknown" }, { /* 1 */ BASICTYPE_BOOLEAN, /* 1 */ "AsnBool", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "bool" }, { /* 2 */ BASICTYPE_INTEGER, /* 2 */ "AsnInt", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "integer" }, { /* 3 */ BASICTYPE_BITSTRING, "AsnBits", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "bits" }, {/* 4 */ BASICTYPE_OCTETSTRING, "AsnOcts", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "octs" }, {/* 5 */ BASICTYPE_NULL, "AsnNull", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "null" }, { /* 6 */ BASICTYPE_OID, "AsnOid", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "oid" }, { /* 7 */ BASICTYPE_REAL, "AsnReal", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "real" }, {/* 8 */ BASICTYPE_ENUMERATED, "AsnEnum", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "enumeration" }, {/* 9 */ BASICTYPE_SEQUENCE, NULL, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "seq" }, {/* 10 */ BASICTYPE_SEQUENCEOF, "AsnList", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "seqOf" }, {/* 11 */ BASICTYPE_SET, NULL, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, "NOT_NULL", "set" }, {/* 12 */ BASICTYPE_SETOF, "AsnList", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "setOf" }, {/* 13 */ BASICTYPE_CHOICE, NULL, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, "NOT_NULL", "choice" }, {/* 14 */ BASICTYPE_SELECTION, NULL, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "foo" }, {/* 15 */ BASICTYPE_COMPONENTSOF, NULL, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "bar" }, {/* 16 */ BASICTYPE_ANY, "AsnAny", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "any" }, {/* 17 */ BASICTYPE_ANYDEFINEDBY, "AsnAnyDefinedBy", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "anyDefBy" }, {/* 18 */ BASICTYPE_LOCALTYPEREF, NULL, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "foo" }, {/* 19 */ BASICTYPE_IMPORTTYPEREF, NULL, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "bar" }, {/* 20 */ BASICTYPE_MACROTYPE, NULL, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "foo" }, {/* 21 */ BASICTYPE_MACRODEF, NULL, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "foo" }, {/* 22 */ BASICTYPE_NUMERIC_STR, "NumericString", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "numericString" }, {/* 23 */ BASICTYPE_PRINTABLE_STR, "PrintableString", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "printableString" }, {/* 24 */ BASICTYPE_UNIVERSAL_STR, "UniversalString", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "universalString" }, {/* 25 */ BASICTYPE_IA5_STR, "IA5String", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "ia5String" }, {/* 26 */ BASICTYPE_BMP_STR, "BMPString", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "bmpString" }, {/* 27 */ BASICTYPE_UTF8_STR, "UTF8String", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "utf8String" }, {/* 28 */ BASICTYPE_UTCTIME, /* 23 */ "UTCTime", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "utcTime" }, {/* 29 */ BASICTYPE_GENERALIZEDTIME, /* 24 */ "GeneralizedTime", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "generalizedTime" }, {/* 30 */ BASICTYPE_GRAPHIC_STR, /* 25 */ "GraphicString", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "graphicString" }, {/* 31 */ BASICTYPE_VISIBLE_STR, /* 26 */ "VisibleString", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "visibleString" }, {/* 32 */ BASICTYPE_GENERAL_STR, /* 27 */ "GeneralString", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "generalString" }, {/* 33 */ BASICTYPE_OBJECTDESCRIPTOR, "ObjectDescriptor", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "objectDescriptor" } , {/* 34 */ BASICTYPE_VIDEOTEX_STR, "VideotexString", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "videotexString" } , {/* 35 */ BASICTYPE_T61_STR, "T61String", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "t61String" }, {/* 36 */ BASICTYPE_EXTERNAL, "EXTERNAL", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, "NOT_NULL", "external" }, {/* 37 */ BASICTYPE_OCTETCONTAINING, NULL, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "octetContainer" }, {/* 38 */ BASICTYPE_BITCONTAINING, NULL, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "bitContainer" }, { /* 39 */ BASICTYPE_RELATIVE_OID, "AsnRelativeOid", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "relativeOid" }, { /* 40 */ BASICTYPE_EXTENSION, "AsnExtension", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NULL", "extension" } } }; esnacc-ng-1.8.1/compiler/back-ends/c++-gen/rules.h000066400000000000000000000057521302010526100214410ustar00rootroot00000000000000/* * compiler/back_ends/c++_gen/rules.h * * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/back-ends/c++-gen/rules.h,v 1.8 2004/01/29 21:21:44 gronej Exp $ * $Log: rules.h,v $ * Revision 1.8 2004/01/29 21:21:44 gronej * Took all Init() calls out of Clear() functions in generated code * * Revision 1.7 2004/01/14 19:07:53 gronej * Updated Compiler to accept and process relative-oid's * * Revision 1.6 2002/10/28 20:50:58 leonberp * Ok.. I think this is the final fix for OCTET/BIT STRING CONTAINING * * Revision 1.5 2002/10/24 21:07:21 leonberp * latest fixing for OCTET CONTAINING * * Revision 1.4 2002/05/10 16:39:39 leonberp * latest changes for release 2.2 * includes integrating asn-useful into C & C++ runtime library, the compiler changes that go along with that, SnaccException changes for C++ runtime and compiler * * Revision 1.3 2001/07/12 19:34:22 leonberp * Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. * * Revision 1.2 2000/10/24 14:54:46 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:36:06 leonberp * First CVS Version of SNACC. * * Revision 1.3 1995/07/25 18:24:21 rj * file name has been shortened for redundant part: c++-gen/c++-rules -> c++-gen/rules. * * Revision 1.2 1994/10/08 03:47:50 rj * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long. * * Revision 1.1 1994/08/28 09:47:55 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #ifndef _RulesInclude #define _RulesInclude /* see asn1module.h for CxxTDI (C++ type def info) */ typedef struct CxxRules { int maxDigitsToAppend; char *choiceIdFieldName; /* name of choiceId field */ char *choiceIdEnumName; /* name (tag) for choiceId enum def name */ char *choiceUnionFieldName; /* what the name of the choice's union is */ char *choiceUnionName; /* name (tag) for choice union def name */ int capitalizeNamedElmts; char *encodeBaseName; char *decodeBaseName; char *encodeContentBaseName; char *decodeContentBaseName; char *encodePduBaseName; char *decodePduBaseName; CxxTDI typeConvTbl[BASICTYPE_EXTENSION + 1]; } CxxRules; extern CxxRules cxxRulesG; #endif esnacc-ng-1.8.1/compiler/back-ends/c++-gen/types.c000066400000000000000000000500201302010526100214320ustar00rootroot00000000000000/* * compiler/back-ends/c++-gen/types.c - fills in c++ type information * * MS 91/92 * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * INSERT_VDA_COMMENTS * * $Header: /baseline/SNACC/compiler/back-ends/c++-gen/types.c,v 1.12 2004/03/25 19:20:16 gronej Exp $ * $Log: types.c,v $ * Revision 1.12 2004/03/25 19:20:16 gronej * fixed some linux warnings * * Revision 1.11 2004/01/14 19:07:53 gronej * Updated Compiler to accept and process relative-oid's * * Revision 1.10 2003/12/17 19:05:04 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.9.2.1 2003/12/04 16:11:32 gronej * Fixed bitsDecoded to return correct value * * Revision 1.9 2003/07/07 14:52:35 nicholar * Eliminated headers and cleaned up include references * * Revision 1.8 2002/10/28 19:57:03 leonberp * Added BITSTRING CONTAINING support and fixed CONTAINED ANY DEFINED BY * * Revision 1.7 2002/10/24 21:07:21 leonberp * latest fixing for OCTET CONTAINING * * Revision 1.6 2002/09/16 17:48:19 mcphersc * Fixed warnings * Z * * Revision 1.5 2002/09/04 17:53:24 vracarl * got rid of c++ comments * * Revision 1.4 2002/05/15 14:53:12 leonberp * added support for new basicTypes to compiler * * Revision 1.3 2001/01/02 14:33:24 rwc * Updated to remove last print on VDA DER Rules when compiling. Cleaner builds by application running compiler. * * Revision 1.2 2000/10/24 14:54:46 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:36:06 leonberp * First CVS Version of SNACC. * * Revision 1.4 1995/07/25 18:25:11 rj * file name has been shortened for redundant part: c++-gen/c++-types -> c++-gen/types. * * changed `_' to `-' in file names. * * Revision 1.3 1994/10/08 03:47:51 rj * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long. * * Revision 1.2 1994/09/01 01:06:02 rj * snacc_config.h removed. * * Revision 1.1 1994/08/28 09:47:56 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include #include #include "asn-incl.h" #include "asn1module.h" #include "snacc-util.h" #include "str-util.h" #include "rules.h" static DefinedObj *definedNamesG; /* unexported prototypes */ void FillCxxTypeDefInfo PROTO ((CxxRules *r, Module *m, TypeDef *td)); static void FillCxxFieldNames PROTO ((CxxRules *r, NamedTypeList *firstSibling)); static void FillCxxTypeRefInfo PROTO ((CxxRules *r, Module *m, TypeDef *head, Type *parent, Type *t)); static void FillCxxStructElmts PROTO ((CxxRules *r, Module *m, TypeDef *head, Type *parent, NamedTypeList *t)); static void FillCxxChoiceElmts PROTO ((CxxRules *r, Module *m, TypeDef *head, Type *parent, NamedTypeList *first)); static int IsCxxPtr PROTO ((CxxRules *r, TypeDef *td, Type *parent, Type *t)); void FillCxxTDIDefaults PROTO ((CxxRules *r, CxxTDI *ctdi, TypeDef *td)); /* * allocates and fills all the cxxTypeInfos * in the type trees for every module in the list */ void FillCxxTypeInfo PARAMS ((r, modList), CxxRules *r _AND_ ModuleList *modList) { TypeDef *td; Module *m; /* * go through each module's type defs and fill * in the C type and enc/dec routines etc */ definedNamesG = NULL; FOR_EACH_LIST_ELMT (m, modList) { FOR_EACH_LIST_ELMT (td, m->typeDefs) FillCxxTypeDefInfo (r, m, td); } /* * now that type def info is filled in * set up set/seq/list/choice elements that ref * those definitions */ FOR_EACH_LIST_ELMT (m, modList) { FOR_EACH_LIST_ELMT (td, m->typeDefs) FillCxxTypeRefInfo (r, m, td, NULL, td->type); } /* * modules compiled together (ie one call to snacc with * multiple args) likely to be C compiled together so * need a unique routines/types/defines/enum values * since assuming they share same name space. * All Typedefs, union, struct & enum Tags, and defined values * (enum consts), #define names * are assumed to share the same name space */ /* done with checking for name conflicts */ FreeDefinedObjs (&definedNamesG); } /* FillCxxTypeInfo */ /* * allocates and fills structure holding C type definition information * fo the given ASN.1 type definition. Does not fill CTRI for contained * types etc. */ void FillCxxTypeDefInfo PARAMS ((r, m, td), CxxRules *r _AND_ Module *m _AND_ TypeDef *td) { char *tmpName; CxxTDI *cxxtdi; /* * if CxxTDI is present this type def has already been 'filled' */ if (td->cxxTypeDefInfo != NULL) return; cxxtdi = MT (CxxTDI); td->cxxTypeDefInfo = cxxtdi; /* get default type def attributes from table for type on rhs of ::= */ FillCxxTDIDefaults (r, cxxtdi, td); /* * if defined by a ref to another type definition fill in that type * def's CxxTDI so can inherit (actully completly replace default * attributes) from it */ if ((td->type->basicType->choiceId == BASICTYPE_LOCALTYPEREF) || (td->type->basicType->choiceId == BASICTYPE_IMPORTTYPEREF)) { /* * Fill in CxxTDI for defining type if nec. * this works for importTypeRef as well since both a.localTypeRef * and a.importTypeRef are of type TypeRef */ FillCxxTypeDefInfo (r, td->type->basicType->a.localTypeRef->module, td->type->basicType->a.localTypeRef->link); tmpName = cxxtdi->className; /* save className */ /* copy all type def info and restore name related stuff - hack*/ *cxxtdi = *td->type->basicType->a.localTypeRef->link->cxxTypeDefInfo; cxxtdi->className = tmpName; /* restore className */ } /* * check for any "--snacc" attributes that overide the current * cxxtdi fields * UNDEFINED FOR C++ ParseTypeDefAttribs (cxxtdi, td->attrList); */ m=m; /*AVOIDS warning.*/ } /* FillCxxTypeDefInfo */ static void FillCxxTypeRefInfo PARAMS ((r, m, head, parent, t), CxxRules *r _AND_ Module *m _AND_ TypeDef *head _AND_ Type *parent _AND_ Type *t) { CxxTRI *cxxtri; CxxTDI *tmpCxxtdi; ValueDef *namedElmt; CNamedElmt *cne; CNamedElmt **cneHndl; char *elmtName; int len; enum BasicTypeChoiceId basicTypeId; /* * you must check for cycles yourself before calling this */ if (t->cxxTypeRefInfo == NULL) { cxxtri = MT (CxxTRI); t->cxxTypeRefInfo = cxxtri; } else cxxtri = t->cxxTypeRefInfo; basicTypeId = t->basicType->choiceId; tmpCxxtdi = &r->typeConvTbl[basicTypeId]; /* get base type def info from the conversion table in the rules */ cxxtri->isEnc = tmpCxxtdi->isEnc; if ( (basicTypeId == BASICTYPE_OCTETCONTAINING) || (basicTypeId == BASICTYPE_BITCONTAINING) ) { cxxtri->className = r->typeConvTbl[t->basicType->a.stringContaining->basicType->choiceId].className; } else cxxtri->className = tmpCxxtdi->className; cxxtri->optTestRoutineName = tmpCxxtdi->optTestRoutineName; /* * convert named elmts to C++ names. * check for name conflict with other defined Types/Names/Values */ if (((basicTypeId == BASICTYPE_INTEGER) || (basicTypeId == BASICTYPE_ENUMERATED) || (basicTypeId == BASICTYPE_BITSTRING)) && !(LIST_EMPTY (t->basicType->a.integer))) { cxxtri->namedElmts = AsnListNew (sizeof (void*)); FOR_EACH_LIST_ELMT (namedElmt, t->basicType->a.integer) { cneHndl = (CNamedElmt**)AsnListAppend (cxxtri->namedElmts); cne = *cneHndl = MT (CNamedElmt); elmtName = Asn1ValueName2CValueName (namedElmt->definedName); len = strlen (elmtName); cne->name = Malloc (len + 1 + r->maxDigitsToAppend); strcpy (cne->name, elmtName); Free (elmtName); /* not very efficient */ if (namedElmt->value->basicValue->choiceId == BASICVALUE_INTEGER) cne->value = namedElmt->value->basicValue->a.integer; else { fprintf (errFileG, "Warning: unlinked defined value. Using -9999999\n"); cne->value = -9999999; } if (r->capitalizeNamedElmts) Str2UCase (cne->name, len); /* * append digits if enum value name is a keyword */ MakeCxxStrUnique (definedNamesG, cne->name, r->maxDigitsToAppend, 1); /* not nec since each class hides the enum scope DefineObj (&definedNamesG, cne->name); */ } } /* fill in rest of type info depending on the type */ switch (basicTypeId) { case BASICTYPE_BOOLEAN: /* library types */ case BASICTYPE_INTEGER: case BASICTYPE_BITSTRING: case BASICTYPE_OCTETSTRING: case BASICTYPE_NULL: case BASICTYPE_OID: case BASICTYPE_RELATIVE_OID: case BASICTYPE_REAL: case BASICTYPE_ENUMERATED: /* don't need to do anything else */ break; case BASICTYPE_SEQUENCEOF: /* list types */ case BASICTYPE_SETOF: /* fill in component type */ FillCxxTypeRefInfo (r, m, head, t, t->basicType->a.setOf); break; case BASICTYPE_IMPORTTYPEREF: /* type references */ case BASICTYPE_LOCALTYPEREF: /* * grab class name from link (link is the def of the * the ref'd type) */ if (t->basicType->a.localTypeRef->link != NULL) { /* inherit attributes from referenced type */ tmpCxxtdi= t->basicType->a.localTypeRef->link->cxxTypeDefInfo; cxxtri->className = tmpCxxtdi->className; cxxtri->isEnc = tmpCxxtdi->isEnc; cxxtri->optTestRoutineName = tmpCxxtdi->optTestRoutineName; } break; case BASICTYPE_ANYDEFINEDBY: /* ANY types */ break; /* these are handled now */ case BASICTYPE_ANY: /* Enhanced ANY processing always on */ break; case BASICTYPE_CHOICE: /* * must fill field names BEFORE filling choice elmts * (allows better naming for choice ids) */ FillCxxFieldNames (r, t->basicType->a.choice); FillCxxChoiceElmts (r, m, head, t, t->basicType->a.choice); break; case BASICTYPE_SET: case BASICTYPE_SEQUENCE: FillCxxStructElmts (r, m, head, t, t->basicType->a.set); FillCxxFieldNames (r, t->basicType->a.set); break; case BASICTYPE_COMPONENTSOF: case BASICTYPE_SELECTION: fprintf (errFileG, "Compiler error - COMPONENTS OF or SELECTION type slipped through normalizing phase.\n"); break; case BASICTYPE_UNKNOWN: case BASICTYPE_MACRODEF: case BASICTYPE_MACROTYPE: /* do nothing */ break; default: break; } /* * figure out whether this is a ptr based on the enclosing * type (if any) and optionality/default */ cxxtri->isPtr = (unsigned char)IsCxxPtr (r, head, parent, t); /* let user overide any defaults with the --snacc attributes */ /* undefined for C++ ParseTypeRefAttribs (ctri, t->attrList); */ } /* FillCxxTypeRefInfo */ static void FillCxxStructElmts PARAMS ((r, m, head, parent, elmts), CxxRules *r _AND_ Module *m _AND_ TypeDef *head _AND_ Type *parent _AND_ NamedTypeList *elmts) { NamedType *et; FOR_EACH_LIST_ELMT (et, elmts) { FillCxxTypeRefInfo (r, m, head, parent, et->type); } } /* FillCxxStructElmts */ /* * Figures out non-conflicting enum names for the * choice id's */ static void FillCxxChoiceElmts PARAMS ((r, m, head, parent, elmts), CxxRules *r _AND_ Module *m _AND_ TypeDef *head _AND_ Type *parent _AND_ NamedTypeList *elmts) { NamedType *et; int idCount = 0; CxxTRI *cxxtri; int len; /* * fill in type info for elmt types first */ FOR_EACH_LIST_ELMT (et, elmts) FillCxxTypeRefInfo (r, m, head, parent, et->type); /* * set choiceId Symbol & value * eg * Car ::= CHOICE { class Car { * chev ChevCar, -> enum ChoiceIdEnum { * ford FordCar chevCid, * toyota ToyotaCar fordCid, * } toyotaCid } choiceId; * union CarChoiceUnion { * ChevCar *chev; * FordCar *ford; * ToyotaCar *toyota; }; * ... * } * NOTE that the union is anonymous */ FOR_EACH_LIST_ELMT (et, elmts) { cxxtri = et->type->cxxTypeRefInfo; if (cxxtri == NULL) continue; /* wierd type */ cxxtri->choiceIdValue = idCount++; len = strlen (cxxtri->fieldName); cxxtri->choiceIdSymbol = Malloc (len + 4); strcpy (cxxtri->choiceIdSymbol, cxxtri->fieldName); strcat (cxxtri->choiceIdSymbol, "Cid"); if (r->capitalizeNamedElmts) Str2UCase (cxxtri->choiceIdSymbol, len); } } /* FillCxxChoiceElmts */ /* * takes a list of "sibling" (eg same level in a structure) * ElmtTypes and fills sets up the c field names in * the CxxTRI struct */ static void FillCxxFieldNames PARAMS ((r, elmts), CxxRules *r _AND_ NamedTypeList *elmts) { NamedType *et; CxxTRI *cxxtri; DefinedObj *fieldNames; int len; char *tmpName; char *asn1FieldName; char *cFieldName; /* * Initialize fieldname data * allocate (if nec) and fill in CTRI fieldname if poss * from asn1 field name. leave blank otherwise */ fieldNames = NewObjList(); FOR_EACH_LIST_ELMT (et, elmts) { cxxtri = et->type->cxxTypeRefInfo; if (cxxtri == NULL) { cxxtri = MT (CxxTRI); et->type->cxxTypeRefInfo = cxxtri; } if (et->fieldName != NULL) { /* * can assume that the field names are * distinct because they have passed the * error checking step. * However, still call MakeCxxStrUnique * to change any field names that * conflict with C++ keywords */ asn1FieldName = et->fieldName; tmpName = Asn1FieldName2CFieldName (asn1FieldName); cxxtri->fieldName = Malloc (strlen (tmpName) + 1 + r->maxDigitsToAppend); strcpy (cxxtri->fieldName, tmpName); Free (tmpName); /* old cxxtri->fieldName = Asn1FieldName2CFieldName (asn1FieldName); */ MakeCxxStrUnique (fieldNames, cxxtri->fieldName, r->maxDigitsToAppend, 1); DefineObj (&fieldNames, cxxtri->fieldName); } } FOR_EACH_LIST_ELMT (et, elmts) { cxxtri = et->type->cxxTypeRefInfo; /* * generate field names for those without them */ if (cxxtri->fieldName == NULL) { if ((et->type->basicType->choiceId == BASICTYPE_LOCALTYPEREF) || (et->type->basicType->choiceId == BASICTYPE_IMPORTTYPEREF)) { /* * take ref'd type name as field name * convert first let to lower case */ tmpName = et->type->basicType->a.localTypeRef->link->cxxTypeDefInfo->className; tmpName = Asn1TypeName2CTypeName (tmpName); cFieldName = Malloc (strlen (tmpName) + r->maxDigitsToAppend +1); strcpy (cFieldName, tmpName); Free (tmpName); if (isupper (cFieldName[0])) cFieldName[0] = (char)tolower (cFieldName[0]); } else { /* * get default field name for this type */ tmpName = r->typeConvTbl[et->type->basicType->choiceId].defaultFieldName; cFieldName = Malloc (strlen (tmpName) + r->maxDigitsToAppend +1); strcpy (cFieldName, tmpName); if (isupper (cFieldName[0])) cFieldName[0] = (char)tolower (cFieldName[0]); } len = strlen (cFieldName); /* * try to use just the type name (with lower case first char). * if that is already used in this type or a C++ keyword, * append ascii digits to field name until unique * in this type */ MakeCxxStrUnique (fieldNames, cFieldName, r->maxDigitsToAppend, 1); DefineObj (&fieldNames, cFieldName); cxxtri->fieldName = cFieldName; } } FreeDefinedObjs (&fieldNames); } /* FillCxxFieldNames */ /* * returns true if this c type for this type should be * be ref'd as a ptr */ static int IsCxxPtr PARAMS ((r, td, parent, t), CxxRules *r _AND_ TypeDef *td _AND_ Type *parent _AND_ Type *t) { CxxTDI *cxxtdi; int retVal = FALSE; /* * inherit ptr attriubutes from ref'd type if any * otherwise grab lib c type def from the CxxRules */ if ((t->basicType->choiceId == BASICTYPE_LOCALTYPEREF) || (t->basicType->choiceId == BASICTYPE_IMPORTTYPEREF)) { cxxtdi = t->basicType->a.localTypeRef->link->cxxTypeDefInfo; } else cxxtdi = &r->typeConvTbl[GetBuiltinType (t)]; /* no parent means t is the root of a typedef */ if ((parent == NULL) && (cxxtdi->isPtrForTypeDef)) retVal = TRUE; else if ((parent != NULL) && ((parent->basicType->choiceId == BASICTYPE_SET) || (parent->basicType->choiceId == BASICTYPE_SEQUENCE)) && (cxxtdi->isPtrInSetAndSeq)) retVal = TRUE; else if ((parent != NULL) && ((parent->basicType->choiceId == BASICTYPE_SETOF) || (parent->basicType->choiceId == BASICTYPE_SEQUENCEOF)) && (cxxtdi->isPtrInList)) retVal = TRUE; else if ((parent != NULL) && (parent->basicType->choiceId == BASICTYPE_CHOICE) && (cxxtdi->isPtrInChoice)) retVal = TRUE; else if (((t->optional) || (t->defaultVal != NULL)) && (cxxtdi->isPtrForOpt)) retVal = TRUE; return retVal; td=td; /*AVOIDS warning.*/ } /* IsCxxPtr */ /* fill given cxxtdi with defaults from table for given typedef */ void FillCxxTDIDefaults PARAMS ((r, cxxtdi, td), CxxRules *r _AND_ CxxTDI *cxxtdi _AND_ TypeDef *td) { CxxTDI *tblCxxtdi; int typeIndex; char *tmpName; typeIndex = GetBuiltinType (td->type); if (typeIndex < 0) return; tblCxxtdi = &r->typeConvTbl[typeIndex]; memcpy (cxxtdi, tblCxxtdi, sizeof (CxxTDI)); /* make sure class name is unique wrt to previously defined classes */ tmpName = Asn1TypeName2CTypeName (td->definedName); cxxtdi->className = Malloc (strlen (tmpName) + r->maxDigitsToAppend +1); strcpy (cxxtdi->className, tmpName); Free (tmpName); MakeCxxStrUnique (definedNamesG, cxxtdi->className, r->maxDigitsToAppend, 1); DefineObj (&definedNamesG, cxxtdi->className); } /* FillCxxTDIDefaults */ esnacc-ng-1.8.1/compiler/back-ends/c-gen/000077500000000000000000000000001302010526100177775ustar00rootroot00000000000000esnacc-ng-1.8.1/compiler/back-ends/c-gen/gen-any.c000066400000000000000000000443131302010526100215060ustar00rootroot00000000000000/* * compiler/back-ends/c-gen/gen-any.c * * prints Routine to initialize the ANY Hash table. The * ANY Hash table maps the OBJECT IDENTIFIERS or INTEGERS * to the correct encoding/decoding etc routines. * * Also prints an enum to identify each ANY mapping. * * if the given module has no ANY or ANY DEFINED BY types * nothing is printed. * * MS 92 * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/back-ends/c-gen/gen-any.c,v 1.8 2003/07/07 14:53:38 nicholar Exp $ * $Log: gen-any.c,v $ * Revision 1.8 2003/07/07 14:53:38 nicholar * Eliminated headers and cleaned up include references * * Revision 1.7 2003/04/29 21:05:37 leonberp * integerated Deepak's changes for IOB support * * Revision 1.6 2002/10/30 13:12:16 mcphersc * anyEnumValG is now set via the -a argument in snacc.c * * Revision 1.5 2002/09/16 17:34:47 mcphersc * iFixed warnings * * Revision 1.4 2002/09/04 17:54:19 vracarl * got rid of c++ comments * * Revision 1.3 2002/02/28 19:45:20 nicholar * Added calls to Dash2Underscore() to remove dashes in ANYs. * * Revision 1.2 2000/10/24 14:54:46 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:36:05 leonberp * First CVS Version of SNACC. * * Revision 1.3 1995/07/25 18:33:43 rj * file name has been shortened for redundant part: c-gen/gen-c-any -> c-gen/gen-any. * * changed `_' to `-' in file names. * * Revision 1.2 1994/09/01 00:21:15 rj * snacc_config.h removed. * * Revision 1.1 1994/08/28 09:48:15 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include #include "asn-incl.h" #include "asn1module.h" #include "rules.h" #include "str-util.h" #include "enc-rules.h" /* REN -- 1/13/98 -- added next line for proto of GetBuiltinType() */ #include "snacc-util.h" int anyEnumValG = 0; void PrintCAnyEnum PROTO ((FILE *hdr, Module *m, CRules *r)); void PrintCAnyHashInitRoutine(FILE *src, FILE *hdr, ModuleList *mods, Module *m, CRules *r, int printEncoders, int printDecoders, int printPrinters, int printFree); void PrintCOidValue PROTO ((FILE *f, CRules *r, AsnOid *oid)); /* REN -- 1/13/98 -- added following prototype */ TypeDef* GetTypeDef PROTO ((Type *t)); void PrintCAnyCode(FILE *src, FILE *hdr, CRules *r, ModuleList *mods, Module *m, int printEncoders, int printDecoders, int printPrinters, int printFree) { EncRulesType *encoding; if (!m->hasAnys) return; /* XXX - Currently any types will only be able to be used with one of * the encoding rules. To fix, we need seperate hashes for each encoding * rule */ encoding = GetEncRules(); if(!SetEncRules(*encoding)) { fprintf(stderr, "Failed to set encoding rules.\n"); return; } PrintCAnyEnum (hdr, m, r); PrintCAnyHashInitRoutine (src, hdr, mods, m, r, printEncoders, printDecoders, printPrinters, printFree); } /* PrintAnyCode */ void PrintCAnyEnum PARAMS ((hdr, m, r), FILE *hdr _AND_ Module *m _AND_ CRules *r) { /* TypeDef *td; AnyRef *ar; AnyRefList *arl; int i;*/ int firstPrinted = TRUE; char *modName; /* REN -- 1/13/98 */ ValueDef *vd; Type *t; char anyId[256]; /* REN -- end */ modName = Asn1TypeName2CTypeName (m->modId->name); fprintf (hdr,"typedef enum %sAnyId\n", modName); fprintf (hdr,"{\n"); /* REN -- 1/13/98 -- Changed method in which anyRefs get written. Original code looped through the module's basic types and local type refs and wrote the anys that referred to them. My method loops throught the valueRefs and writes the all the SNMP Object Types. Removed the following loops: * do any lib types * for (i = BASICTYPE_BOOLEAN; i < BASICTYPE_MACRODEF; i++) { arl = LIBTYPE_GET_ANY_REFS (i); if (arl != NULL) { FOR_EACH_LIST_ELMT (ar, arl) { if (!firstPrinted) fprintf (hdr,",\n"); fprintf (hdr," %s = %d", ar->anyIdName, anyEnumValG++); firstPrinted = FALSE; } } } FOR_EACH_LIST_ELMT (td, m->typeDefs) { if (td->anyRefs != NULL) { FOR_EACH_LIST_ELMT (ar, td->anyRefs) { if (!firstPrinted) fprintf (hdr,",\n"); fprintf (hdr," %s = %d", ar->anyIdName, anyEnumValG++); firstPrinted = FALSE; } } } Handle Imported type refs This code is needed to ensure that OBJECT-TYPE macros with SYNTAX using an imported type are correctly generated if (m->imports) { FOR_EACH_LIST_ELMT (im, m->imports) { if (im->importElmts) { ImportElmt *ie; FOR_EACH_LIST_ELMT(ie, im->importElmts) { if (ie->resolvedRef && ie->resolvedRef->choiceId == IMPORTELMTCHOICE_TYPE) { FOR_EACH_LIST_ELMT(ar, ie->resolvedRef->a.type->anyRefs) { if (!firstPrinted) fprintf (hdr,",\n"); fprintf (hdr," %s = %d", ar->anyIdName, anyEnumValG++); firstPrinted = FALSE; } } } } } } REN -- 1/13/98 -- added the following: */ FOR_EACH_LIST_ELMT (vd, m->valueDefs) { if (vd->value != NULL) { t = vd->value->type; if ((GetBuiltinType(t) == BASICTYPE_MACROTYPE) && (t->basicType->a.macroType->choiceId == MACROTYPE_SNMPOBJECTTYPE)) { strcpy (anyId, vd->definedName); Dash2Underscore (anyId, strlen (anyId)); strcat (anyId, "_ANY_ID"); if (!firstPrinted) fprintf (hdr,",\n"); fprintf (hdr," %s = %d", anyId, anyEnumValG); anyEnumValG++; firstPrinted = FALSE; } } } /* REN -- end */ if (firstPrinted) /* none have been printed */ fprintf (hdr,"/* NO INTEGER or OBJECT IDENTIFIER to ANY type relationships were defined (via MACROs or other mechanism) */\n???\n"); fprintf (hdr,"} %sAnyId;\n\n\n", modName); Free (modName); r = r; /* AVOIDS warning. */ } /* PrintAnyEnum */ void PrintCAnyHashInitRoutine(FILE *src, FILE *hdr, ModuleList *mods, Module *m, CRules *r, int printEncoders, int printDecoders, int printPrinters, int printFree) { TypeDef *td; /* AnyRef *ar; AnyRefList *arl;*/ char *modName; CTDI *ctdi; int i; /* int j;*/ enum BasicTypeChoiceId typeId; char *encRoutineName=NULL; char *decRoutineName=NULL; char *freeRoutineName=NULL; char *printRoutineName=NULL; int installedSomeHashes = FALSE; /* REN -- 1/13/98 */ ValueDef *vd; Type *t; BasicValue *bv; char anyId[256]; char *typeName=NULL; /* REN -- end */ /* print proto in hdr file */ modName = Asn1TypeName2CTypeName (m->modId->name); fprintf (hdr,"void InitAny%s();\n\n", modName); /* print routine to src file */ fprintf (src,"void InitAny%s()\n", modName); fprintf (src,"{\n"); /* REN -- 1/13/98 -- Changed method in which anyRefs get written. Original code looped through the module's basic types and local type refs and wrote the anys that referred to them. My method loops throught the valueRefs and writes the all the SNMP Object Types. Removed the following loops: * first print value for OID's * * do any lib types first * i = 0; for (j = BASICTYPE_BOOLEAN; j < BASICTYPE_MACRODEF; j++) { arl = LIBTYPE_GET_ANY_REFS (j); if (arl != NULL) { FOR_EACH_LIST_ELMT (ar, arl) { installedSomeHashes = TRUE; if (ar->id->choiceId == OIDORINT_OID) { fprintf (src," %s oid%d =", r->typeConvTbl[BASICTYPE_OID].cTypeName, i++); PrintCOidValue (src, r, ar->id->a.oid); fprintf (src,";\n"); } } } } FOR_EACH_LIST_ELMT (td, m->typeDefs) { if (td->anyRefs != NULL) { ctdi = td->cTypeDefInfo; FOR_EACH_LIST_ELMT (ar, td->anyRefs) { installedSomeHashes = TRUE; if (ar->id->choiceId == OIDORINT_OID) { fprintf (src," %s oid%d =", r->typeConvTbl[BASICTYPE_OID].cTypeName, i++); PrintCOidValue (src, r, ar->id->a.oid); fprintf (src,";\n"); } } } } fprintf (src,"\n\n"); * now print hash init calls * i = 0; * do lib types first * for (j = BASICTYPE_BOOLEAN; j < BASICTYPE_MACRODEF; j++) { arl = LIBTYPE_GET_ANY_REFS (j); if (arl != NULL) { FOR_EACH_LIST_ELMT (ar, arl) { encRoutineName = r->typeConvTbl[j].encodeRoutineName; decRoutineName = r->typeConvTbl[j].decodeRoutineName; printRoutineName = r->typeConvTbl[j].printRoutineName; * * use NULL free routine for types that * have empyt macros for their free routines * (since the any hash tbl needs the addr of the routine) * switch (j) { case BASICTYPE_BOOLEAN: case BASICTYPE_INTEGER: case BASICTYPE_NULL: case BASICTYPE_REAL: case BASICTYPE_ENUMERATED: freeRoutineName = "NULL"; break; default: freeRoutineName = r->typeConvTbl[j].freeRoutineName; } if (ar->id->choiceId == OIDORINT_OID) fprintf (src," InstallAnyByOid (%s, &oid%d, sizeof (%s), (EncodeFcn) B%s, (DecodeFcn)B%s, (FreeFcn)%s, (PrintFcn)%s);\n\n", ar->anyIdName, i++, r->typeConvTbl[j].cTypeName, encRoutineName, decRoutineName, freeRoutineName, printRoutineName); else fprintf (src," InstallAnyByInt (%s, %d, sizeof (%s), (EncodeFcn) B%s, (DecodeFcn)B%s, (FreeFcn)%s, (PrintFcn)%s);\n\n", ar->anyIdName, ar->id->a.intId, r->typeConvTbl[j].cTypeName, encRoutineName, decRoutineName, freeRoutineName, printRoutineName); } } } FOR_EACH_LIST_ELMT (td, m->typeDefs) { if (td->anyRefs != NULL) { ctdi = td->cTypeDefInfo; FOR_EACH_LIST_ELMT (ar, td->anyRefs) { typeId = GetBuiltinType (td->type); encRoutineName = ctdi->encodeRoutineName; decRoutineName = ctdi->decodeRoutineName; printRoutineName = ctdi->printRoutineName; * * use NULL free routine for types that * have empyt macros for their free routines * (since the any hash tbl needs the addr of the routine) * switch (typeId) { case BASICTYPE_BOOLEAN: case BASICTYPE_INTEGER: case BASICTYPE_NULL: case BASICTYPE_REAL: case BASICTYPE_ENUMERATED: freeRoutineName = "NULL"; break; default: freeRoutineName = ctdi->freeRoutineName; } if (ar->id->choiceId == OIDORINT_OID) fprintf (src," InstallAnyByOid (%s, &oid%d, sizeof (%s), (EncodeFcn) B%s, (DecodeFcn)B%s, (FreeFcn)%s, (PrintFcn)%s);\n\n", ar->anyIdName, i++, ctdi->cTypeName, encRoutineName, decRoutineName, freeRoutineName, printRoutineName); else fprintf (src," InstallAnyByInt (%s, %d, sizeof (%s), (EncodeFcn) B%s, (DecodeFcn)B%s, (FreeFcn)%s, (PrintFcn)%s);\n\n", ar->anyIdName, ar->id->a.intId, ctdi->cTypeName, encRoutineName, decRoutineName, freeRoutineName, printRoutineName); } } } REN -- 1/13/98 -- added the following: */ /* first print value for OID's */ i = 0; FOR_EACH_LIST_ELMT (vd, m->valueDefs) { if (vd->value != NULL) { t = vd->value->type; if ((GetBuiltinType(t) == BASICTYPE_MACROTYPE) && (t->basicType->a.macroType->choiceId == MACROTYPE_SNMPOBJECTTYPE)) { bv = vd->value->basicValue; if (bv != NULL) { installedSomeHashes = TRUE; if (bv->choiceId == BASICVALUE_OID) { fprintf (src," %s oid%d =", r->typeConvTbl[BASICTYPE_OID].cTypeName, i++); PrintCOidValue (src, r, bv->a.oid); fprintf (src,";\n"); } } } } } fprintf (src,"\n\n"); /* now print hash init calls */ i = 0; FOR_EACH_LIST_ELMT (vd, m->valueDefs) { if (vd->value != NULL) { t = vd->value->type; if ((GetBuiltinType(t) == BASICTYPE_MACROTYPE) && (t->basicType->a.macroType->choiceId == MACROTYPE_SNMPOBJECTTYPE)) { bv = vd->value->basicValue; if (bv != NULL) { strcpy (anyId, vd->definedName); Dash2Underscore (anyId, strlen (anyId)); strcat (anyId, "_ANY_ID"); installedSomeHashes = TRUE; t = t->basicType->a.macroType->a.snmpObjectType->syntax; /* If the syntax of this any is a basic type, get the function pointers from the rules table. */ if (((t->basicType->choiceId >= BASICTYPE_BOOLEAN) && (t->basicType->choiceId <= BASICTYPE_SETOF)) || ((t->basicType->choiceId >= BASICTYPE_NUMERIC_STR) && (t->basicType->choiceId <= BASICTYPE_T61_STR))) { typeId = t->basicType->choiceId; encRoutineName = r->typeConvTbl[typeId].encodeRoutineName; decRoutineName = r->typeConvTbl[typeId].decodeRoutineName; printRoutineName = r->typeConvTbl[typeId].printRoutineName; switch (typeId) { case BASICTYPE_BOOLEAN: case BASICTYPE_INTEGER: case BASICTYPE_NULL: case BASICTYPE_REAL: case BASICTYPE_ENUMERATED: freeRoutineName = "NULL"; break; default: freeRoutineName = r->typeConvTbl[typeId].freeRoutineName; } typeName = r->typeConvTbl[typeId].cTypeName; } /* Else if the syntax of this any is either a locally defined type or an imported type, get the function names from the this type's ref info. */ else { td = GetTypeDef(t); if (td != NULL) { ctdi = td->cTypeDefInfo; encRoutineName = ctdi->encodeRoutineName; decRoutineName = ctdi->decodeRoutineName; printRoutineName = ctdi->printRoutineName; freeRoutineName = ctdi->freeRoutineName; typeName = ctdi->cTypeName; } else encRoutineName = NULL; } if (bv->choiceId == BASICVALUE_OID) fprintf(src, " InstallAnyByOid (%s, &oid%d, ", anyId, i++); else if (bv->choiceId == BASICVALUE_INTEGER) fprintf(src, " InstallAnyByInt (%s, %d, ", anyId, bv->a.integer); if (encRoutineName != NULL) { fprintf(src, "sizeof (%s), (EncodeFcn)B%s, ", typeName, encRoutineName); fprintf(src, "(DecodeFcn)B%s, ", decRoutineName); if (printFree) fprintf(src, "(FreeFcn)%s, ", freeRoutineName); else fprintf(src, "(FreeFcn)NULL, "); if (printPrinters) fprintf(src, "(PrintFcn)%s);\n\n", printRoutineName); else fprintf(src, "(PrintFcn)NULL);\n\n"); } else fprintf(src, "*** ERROR *** Unknown ANY\n\n"); } } } } /* REN -- end */ if (!installedSomeHashes) { fprintf (src," /* Since no INTEGER/OID to ANY type relations were defined\n"); fprintf (src," * (usually done via MACROs) you must manually do the code\n"); fprintf (src," * to fill the hash tbl.\n"); fprintf (src," * if the ids are INTEGER use the following:\n"); fprintf (src," * InstallAnyByInt (??_ANY_ID, intVal, sizeof (Foo), (EncodeFcn) %sEncFoo, (DecodeFcn)%sDecFoo, (FreeFcn)FreeFoo, (PrintFcn)PrintFoo);\n", GetEncRulePrefix(), GetEncRulePrefix()); fprintf (src," * if the ids are OBJECT IDENTIFIERs use the following:\n"); fprintf (src," * InstallAnyByOid (??_ANY_ID, oidVal, sizeof (Foo), (EncodeFcn) %sEncFoo, (DecodeFcn)%sDecFoo, (FreeFcn)FreeFoo, (PrintFcn)PrintFoo);\n", GetEncRulePrefix(), GetEncRulePrefix()); fprintf (src," * put the ??_ANY_IDs in the AnyId enum.\n\n"); fprintf (src," * For example if you have some thing like\n"); fprintf (src," * T1 ::= SEQUENCE { id INTEGER, ANY DEFINED BY id }\n"); fprintf (src," * and the id 1 maps to the type BOOLEAN use the following:\n"); fprintf (src," * InstallAnyByInt (SOMEBOOL_ANY_ID, 1, sizeof (AsnBool), (EncodeFcn) %sEncAsnBool, (DecodeFcn)%sDecAsnBool, (FreeFcn)NULL, (PrintFcn)PrintAsnBool);;\n", GetEncRulePrefix(), GetEncRulePrefix()); fprintf (src," */\n ???????\n"); /* generate compile error */ } fprintf (src,"} /* InitAny%s */\n\n\n", modName); Free (modName); printDecoders = printDecoders; printEncoders = printEncoders; mods = mods; /* AVOIDS warnings. */ } /* PrintAnyHashInitRoutine */ /* REN -- 1/13/98 -- GetTypeDef() function added to return the type def info for the given type. */ TypeDef* GetTypeDef PARAMS ((t), Type *t) { if (t == NULL) return NULL; switch (t->basicType->choiceId) { case BASICTYPE_LOCALTYPEREF: case BASICTYPE_IMPORTTYPEREF: return t->basicType->a.localTypeRef->link; break; default: return NULL; } /*fprintf (fHandle, "GetTypeDef: ERROR - cannot get type def for unlinked local/import type refs\n"); return NULL;*/ } /* GetTypeDef */ /* REN -- end */ esnacc-ng-1.8.1/compiler/back-ends/c-gen/gen-code.c000066400000000000000000000511561302010526100216340ustar00rootroot00000000000000/* * compiler/back-ends/c-gen/gen-code.c - generate C hdr and src files * * Assumes you have called FillCTypeInfo * * MS 92 * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/back-ends/c-gen/gen-code.c,v 1.17 2004/03/25 19:20:16 gronej Exp $ * $Log: gen-code.c,v $ * Revision 1.17 2004/03/25 19:20:16 gronej * fixed some linux warnings * * Revision 1.16 2004/03/12 18:51:20 gronej * updated c-library to error on extension additions as it does with untagged elements * * Revision 1.15 2004/01/14 19:07:53 gronej * Updated Compiler to accept and process relative-oid's * * Revision 1.14 2003/12/17 19:05:04 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.13.2.1 2003/11/05 14:58:57 gronej * working PER code merged with esnacc_1_6 * * Revision 1.13 2003/07/30 15:20:22 colestor * Added "#pragma" to disable MS Windows compiler warning on produced .c * source file for unused local variables. * * Revision 1.12 2003/07/30 00:48:15 colestor * Removed final init_* method declarations. Also, for "C" code generation, to move * all IMPORT include references to the module .h file (as in C++). This allows the resulting * .c source to properly build with appropriately ordered IMPORT references. * * Revision 1.11 2003/07/28 11:13:51 colestor * Changes to complete handing of the "--snacc namespace" compiler directive. * Also, updates to handle ASN.1 constant integer tag designations for C++/C. * * Revision 1.10 2003/07/07 14:53:38 nicholar * Eliminated headers and cleaned up include references * * Revision 1.9 2003/04/29 21:05:15 leonberp * integerated Deepak's changes for IOB support * * Revision 1.8 2003/02/07 17:03:12 leonberp * added #ifdef __cplusplus extern "C" * * Revision 1.7 2002/11/01 16:19:54 mcphersc * Fixed compiler warnings and errors not caught by microsoft * * Revision 1.6 2002/10/30 13:39:56 mcphersc * added include references to sources include file, and only produce src and include files for non imported files - files not referenced by the -I option * * Revision 1.5 2002/10/07 13:45:25 mcphersc * When a "-u filename" is on the argument line, the executable will go into an infinite * loop. This fixes that problem * * Revision 1.4 2002/10/01 13:51:34 mcphersc * Modified snacc to accept either the -I import option or the original way to list the * asn modules on the command line * * Revision 1.3 2002/09/04 17:59:34 vracarl * got rid of c++ comments * * Revision 1.2 2000/10/24 14:54:46 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:36:05 leonberp * First CVS Version of SNACC. * * Revision 1.4 1995/07/25 18:39:46 rj * file name has been shortened for redundant part: c-gen/gen-c-code -> c-gen/gen-code. * * PrintConditionalIncludeOpen() and PrintConditionalIncludeClose() moved to back-ends/cond.c * * changed `_' to `-' in file names. * * Revision 1.3 1995/02/18 12:50:53 rj * typo fixed. * * Revision 1.2 1994/09/01 00:21:54 rj * snacc_config.h and other superfluous .h files removed. * * Revision 1.1 1994/08/28 09:48:17 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include #include #include "asn-incl.h" #include "asn1module.h" #include "rules.h" #include "str-util.h" #include "enc-rules.h" #include "lib-types.h" #include "tag-util.h" /* Function Prototypes */ char *Code2UnivCodeStr PROTO ((BER_UNIV_CODE code)); void PrintCAnyCode(FILE *src, FILE *hdr, CRules *r, ModuleList *mods, Module *m, int printEncoders, int printDecoders, int printPrinters, int printFree); void PrintCContentDecoder PROTO ((FILE *src, FILE *hdr, CRules *r, Module *m, TypeDef *td, long int *longJmpVal)); void PrintCContentEncoder PROTO ((FILE *src, FILE *hdr, CRules *r, Module *m, TypeDef *td)); void PrintCDecoder PROTO ((FILE *src, FILE *hdr, CRules *r, Module *m, TypeDef *td, long int *longJmpVal)); void PrintCEncoder PROTO ((FILE *src, FILE *hdr, CRules *r, Module *m, TypeDef *td)); void PrintCFree PROTO ((FILE *src, FILE *hdr, CRules *r, ModuleList *mods, Module *m, TypeDef *td)); void PrintCPrinter PROTO ((FILE *src, FILE *hdr, CRules *r, ModuleList *mods, Module *m, TypeDef *td)); void PrintCTypeDef PROTO ((FILE *f, CRules *r, Module *m, TypeDef *td)); void PrintCValueDef PROTO ((FILE *src, CRules *r, ValueDef *v)); void PrintCValueExtern PROTO ((FILE *hdr, CRules *r, ValueDef *v)); void PrintCValueInstantiation PROTO ((FILE *hdr, CRules *r, Value *v)); void PrintConditionalIncludeOpen PROTO ((FILE *f, char *fileName)); void PrintConditionalIncludeClose PROTO ((FILE *f, char *fileName)); /* Global Variables */ extern int isTableConstraintAllowed; /* defined in snacc.c */ /* unexported prototypes */ static void PrintCSrcComment PROTO ((FILE *src, Module *m)); static void PrintCSrcIncludes PROTO ((FILE *src, Module *m, ModuleList *mods)); static void PrintCHdrComment PROTO ((FILE *hdr, Module *m)); static void PrintCHdrObjectDeclaration_and_Init PROTO ((FILE *hdr, Module *m, CRules *r)); //RWC;static void PrintCHdrObjectField PROTO ((FILE *hdr, Module *m, CRules *r, char *objName, ObjectAssignmentField *oaf)); //extern short ImportedFilesG; /* * Fills the hdr file with the C type and encode/decode prototypes * Fills the src file with the encoded/decode routine definitions */ void PrintCCode PARAMS ((src, hdr, mods, m, r, longJmpVal, printTypes, printValues, printEncoders, printDecoders, printPrinters, printFree), FILE *src _AND_ FILE *hdr _AND_ ModuleList *mods _AND_ Module *m _AND_ CRules *r _AND_ long int longJmpVal _AND_ int printTypes _AND_ int printValues _AND_ int printEncoders _AND_ int printDecoders _AND_ int printPrinters _AND_ int printFree) { TypeDef *td; ValueDef *vd; /* Deepak: suppose the asn source file is test.asn * then the C source file name is test.c and C header file is test.h */ PrintCSrcComment (src, m); // Deepak: Write the comments in the source file. PrintCSrcIncludes (hdr/*RWC;src*/, m, mods); // Deepak: #include "asn-incl.h" and #include "test.h". PrintCHdrComment (hdr, m); // Deepak: Write the comments in the header file. PrintConditionalIncludeOpen (hdr, m->cHdrFileName); /* Deepak: the above fn writes * #ifndef _test_h_ * #define _test_h_ */ /* PIERCE TBD: Is this necessary still after Deepak's mods? * * Add include reference to source file * */ fprintf (src, "#include \"%s\"\n", m->cHdrFileName); fprintf (hdr,"\n\n"); fprintf (hdr,"#ifdef __cplusplus\n"); fprintf (hdr,"extern \"C\" {\n"); fprintf (hdr,"#endif\n"); // RWC; ADDED to remove warning about "unreferenced local variable" for // variables that are hardcoded by the eSNACC compiler; depending on // the recursed data types (e.g. in a CHOICE), the variables may not be // used. We just ignore the warning. fprintf (hdr,"#ifdef _WIN32\n"); fprintf (hdr,"#pragma warning( disable : 4101 )\n"); fprintf (hdr,"#endif\n"); fprintf (src,"\n\n"); if (printValues) { /* put value defs at beginning of .c file */ FOR_EACH_LIST_ELMT (vd, m->valueDefs) { PrintCValueDef (src, r, vd); } } PrintCAnyCode (src, hdr, r, mods, m, printEncoders, printDecoders, printPrinters, printFree); FOR_EACH_LIST_ELMT (td, m->typeDefs) { if (printTypes) PrintCTypeDef (hdr, r, m, td); /* for PDU type or types ref'd with ANY/ANY DEF BY */ if (printEncoders && ((td->anyRefs != NULL) || td->cTypeDefInfo->isPdu)) PrintCEncoder (src, hdr, r, m, td); /* for PDU type or types ref'd with ANY/ANY DEF BY */ if (printDecoders && ((td->anyRefs != NULL) || td->cTypeDefInfo->isPdu)) PrintCDecoder (src, hdr, r, m, td, &longJmpVal); if (printEncoders) { PrintCContentEncoder (src, hdr, r, m, td); //if (td->bHasTableConstraint) // PrintCTableConstraintEncoder (src, hdr, m, td); // Deepak: 25/Mar/2003 } if (printDecoders) { PrintCContentDecoder (src, hdr, r, m, td, &longJmpVal); //if (td->bHasTableConstraint) // PrintCTableConstraintDecoder (src, hdr, m, td); // Deepak: 25/Mar/2003 } if (printPrinters) PrintCPrinter (src, hdr, r, mods, m, td); if (printFree) PrintCFree (src, hdr, r, mods, m, td); /* only print new lines for normal types */ switch (td->type->basicType->choiceId) { case BASICTYPE_SEQUENCEOF: /* list types */ case BASICTYPE_SETOF: case BASICTYPE_CHOICE: case BASICTYPE_SET: case BASICTYPE_SEQUENCE: case BASICTYPE_SEQUENCET: // Deepak: 30/Nov/2002 case BASICTYPE_OBJECTCLASS: // Deepak: 14/Mar/2003 fprintf (src, "\n"); /* fall through */ case BASICTYPE_IMPORTTYPEREF: /* type references */ case BASICTYPE_LOCALTYPEREF: case BASICTYPE_BOOLEAN: /* library type */ case BASICTYPE_REAL: /* library type */ case BASICTYPE_OCTETSTRING: /* library type */ case BASICTYPE_NULL: /* library type */ case BASICTYPE_OID: /* library type */ case BASICTYPE_RELATIVE_OID: /* library type */ case BASICTYPE_INTEGER: /* library type */ case BASICTYPE_BITSTRING: /* library type */ case BASICTYPE_ENUMERATED: /* library type */ case BASICTYPE_ANYDEFINEDBY: /* ANY types */ case BASICTYPE_ANY: case BASICTYPE_NUMERIC_STR: /* library type */ case BASICTYPE_PRINTABLE_STR: /* library type */ case BASICTYPE_IA5_STR: /* library type */ case BASICTYPE_BMP_STR: /* library type */ case BASICTYPE_UNIVERSAL_STR: /* library type */ case BASICTYPE_UTF8_STR: /* library type */ case BASICTYPE_T61_STR: /* library type */ fprintf (hdr, "\n"); break; default: break; } } // Declare ObjectAssignment, ObjestSetAssignment, & initialize them. if(isTableConstraintAllowed) { PrintCHdrObjectDeclaration_and_Init (hdr, m, r); // Deepak: 24/Mar/2003 } if (printValues) { /* put value externs at end of .h file */ FOR_EACH_LIST_ELMT (vd, m->valueDefs) { PrintCValueExtern (hdr, r, vd); } } fprintf (hdr,"#ifdef __cplusplus\n"); fprintf (hdr,"extern \"C\" {\n"); fprintf (hdr,"#endif\n"); PrintConditionalIncludeClose (hdr, m->cHdrFileName); } /* PrintCCode */ void PrintConstraintValueCheckingCode PARAMS ((src, td, t, nt), FILE *src _AND_ TypeDef *td _AND_ Type *t _AND_ NamedType *nt) { if(t == NULL || nt == NULL) return; fprintf (src, "\tfor(index=0; index < %s_Size; index++)\n", t->tableConstraint->objSetAssignment->objectSetName); fprintf (src, "\t{\n"); fprintf (src, "\t\tif(&v->%s == &%s[index].%s)\n", nt->fieldName, t->tableConstraint->objSetAssignment->objectSetName, nt->fieldName); fprintf (src, "\t\t\tbreak;\n"); fprintf (src, "\t}\n"); fprintf (src, "\n"); fprintf (src, "\tif(&v->%s == %s_Size)\n", nt->fieldName, t->tableConstraint->objSetAssignment->objectSetName); fprintf (src, "\t\treturn 0;\n"); fprintf (src, "\n"); td=td; } /* PrintConstraintValueCheckingCode */ static void // Deepak: 24/Mar/2003 PrintCHdrObjectDeclaration_and_Init PARAMS ((hdr, m, r), FILE *hdr _AND_ Module *m _AND_ CRules *r) { ObjectAssignment *oa; ObjectSetAssignment *osa; int osaCount=0; char *osaName=""; //RWC;char *objName=""; //////////////////////////////////////////////////////////////////////////////////// /* Declare Object Assignments */ // Deepak: 13/Mar/2003 fprintf (hdr, "/* ========== Object Declarations ========== */\n"); FOR_EACH_LIST_ELMT (oa, m->objAssignments) { fprintf (hdr, "%s %s;\n", Asn1ValueName2CValueName(oa->objectClassName), Asn1ValueName2CValueName(oa->objectName)); } fprintf (hdr, "\n"); //////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////// /* Declare Object Set Assignments */ // Deepak: 13/Mar/2003 fprintf (hdr, "\n/* ========== Object Set Declarations ========== */\n"); FOR_EACH_LIST_ELMT (osa, m->objSetAssignments) { osaCount = osa->objectNameList->count; osaName = Asn1ValueName2CValueName(osa->objectSetName); fprintf (hdr, "%s %s[%d];\n", Asn1ValueName2CValueName(osa->objectClassName), osaName, osaCount); fprintf (hdr, "int %s_Size = %d;\n", osaName, osaCount); fprintf (hdr, "\n"); } //////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////// // Init Module Objects //RWC;REMOVED;fprintf (hdr, "/* ========== init_%sObjects() ========== */\n", moduleName); /*RWC;REMOVED; fprintf (hdr, "void init_%sObjects()\n", moduleName); fprintf (hdr, "{\n"); FOR_EACH_LIST_ELMT (oa, m->objAssignments) { objName = Asn1ValueName2CValueName(oa->objectName); FOR_EACH_LIST_ELMT (oaf, oa->objectAssignmentField) { PrintCHdrObjectField (hdr, m, r, objName, oaf); } fprintf (hdr, "\n"); } fprintf (hdr, "}\n"); fprintf (hdr, "\n"); //////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////// // Init Module Object Sets FOR_EACH_LIST_ELMT (osa, m->objSetAssignments) { currOsa = 0; osaCount = osa->objectNameList->count; osaName = Asn1ValueName2CValueName(osa->objectSetName); fprintf (hdr, "void init_%s()\n", osaName); fprintf (hdr, "{\n"); FOR_EACH_LIST_ELMT (tOrV, osa->objectNameList) // Deepak: 24/Mar/2003 { if(tOrV->choiceId) oa = tOrV->a.value->basicValue->a.objAssignment; else // this tOrV can never be type as per my knowledge. continue; sprintf(osaName, "%s[%d]", Asn1ValueName2CValueName(osa->objectSetName), currOsa); FOR_EACH_LIST_ELMT (oaf, oa->objectAssignmentField) { PrintCHdrObjectField (hdr, m, r, osaName, oaf); } fprintf (hdr, "\n"); currOsa++; } fprintf (hdr, "}\n"); fprintf (hdr, "\n"); } //////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////// // Module Init fprintf (hdr, "void %s_init()\n", moduleName); fprintf (hdr, "{\n"); fprintf (hdr, "\tinit_%sValue();\n", moduleName); fprintf (hdr, "\tinit_%sObjects();\n", moduleName); FOR_EACH_LIST_ELMT (osa, m->objSetAssignments) { fprintf (hdr, "\tinit_%s()\n", Asn1ValueName2CValueName(osa->objectSetName)); } fprintf (hdr, "}\n"); fprintf (hdr, "\n"); //////////////////////////////////////////////////////////////////////////////////// *RWC;REMOVED;*/ r=r; } /* PrintCHdrObjectDeclaration_and_Init */ /*RWC;REMOVED; static void // Deepak: 24/Mar/2003 PrintCHdrObjectField PARAMS ((hdr, m, r, objName, oaf), FILE *hdr _AND_ Module *m _AND_ CRules *r _AND_ char *objName _AND_ ObjectAssignmentField *oaf) { char *objFieldName=""; objFieldName = Asn1ValueName2CValueName(oaf->objectFieldName); if(oaf->bPresent && oaf->typeOrValue->choiceId) { // value fprintf (hdr, "\t%s.%s = ", objName, objFieldName); PrintCValueInstantiation (hdr, r, oaf->typeOrValue->a.value); fprintf (hdr, ";\n"); } // Print here if optional arguments are present or not if(oaf->bOptional) // Deepak: 22/Mar/2003 { fprintf (hdr, "\t%s.m.%sPresent = %d;\n", objName, objFieldName, oaf->bPresent?1:0); } // Now write the BasicType_Unknown initialisation here... if(oaf->bPresent && oaf->bUnknownType) // Unknown Type Deepak: 22/Mar/2003 { // value char *typeName = Asn1ValueName2CValueName(oaf->typeOrValue->a.type->basicType->a.localTypeRef->typeName); //fprintf (hdr, "\t%s.%sName = \"%s\";\n", objName, objFieldName, typeName); fprintf (hdr, "\t%s.%s = %s;\n", objName, objFieldName, typeName); fprintf (hdr, "\t%s.%sSize = sizeof(%s);\n", objName, objFieldName, typeName); fprintf (hdr, "\t%s.encode%s = &%s%s%sContent;\n", objName, objFieldName, GetEncRulePrefix(), r->encodeRoutineBaseName, typeName); fprintf (hdr, "\t%s.decode%s = &%s%s%sContent;\n", objName, objFieldName, GetEncRulePrefix(), r->decodeRoutineBaseName, typeName); // fprintf (hdr, "\t%s.tag = %d;\n", objName, LIBTYPE_GET_UNIV_TAG_CODE(oaf->typeOrValue->a.type->basicType->a.localTypeRef->link->type->basicType->choiceId)); typeName = Code2UnivCodeStr(LIBTYPE_GET_UNIV_TAG_CODE(oaf->typeOrValue->a.type->basicType->a.localTypeRef->link->type->basicType->choiceId)); fprintf (hdr, "\t%s.tagId = %s;\n", objName, typeName); } m; } / * PrintCHdrObjectField * / ***RWC;REMOVED **/ static void PrintCSrcComment PARAMS ((src, m), FILE *src _AND_ Module *m) { long int t; t = time (0); fprintf (src, "/*\n"); fprintf (src, " * %s\n", m->cSrcFileName); fprintf (src, " * \"%s\" ASN.1 module encode/decode/print/free C src.\n", m->modId->name); fprintf (src, " * This file was generated by esnacc on %s", ctime (&t)); fprintf (src, " * NOTE: This is a machine generated file - editing not recommended\n"); fprintf (src, " */\n\n"); } /* PrintSrcComment */ static char *GetImportFileName (char *Impname, ModuleList *mods) { Module *currMod; char *fileName = NULL; FOR_EACH_LIST_ELMT (currMod, mods) { /* Find the import Module in the Modules and * return the header file name */ if ((strcmp(Impname, currMod->modId->name) == 0)) { /* Set the file name and break */ fileName = currMod->cHdrFileName; break; } } return fileName; } /* RWC; CHANGED to print to hdr file instead of src file to avoid * interaction of multiple include references; this way all files * will appropriately pull in their respective references. */ static void PrintCSrcIncludes PARAMS ((inFile, m, mods ), FILE *inFile _AND_ Module *m _AND_ ModuleList *mods /* _AND_ char *srcref*/) { void *tmp; Module *currMod; AsnListNode *currModTmp; /* * include snacc runtime library related hdrs */ fprintf (inFile, "\n#include \"asn-incl.h\"\n"); /* * print out include files in same order of the module * list. every module in the list includes the others and it's * own .h */ tmp = (void*)CURR_LIST_NODE (mods); FOR_EACH_LIST_ELMT (currMod, mods) { if ((strcmp(m->cHdrFileName, currMod->cHdrFileName) == 0)) { ImportModuleList *ModLists; ImportModule *impMod; char *ImpFile = NULL; ModLists = currMod->imports; currModTmp = mods->curr; //RWC;FIXES infinite loop problem. // IN case changed inside loop. FOR_EACH_LIST_ELMT(impMod, ModLists) { ImpFile = GetImportFileName (impMod->modId->name, mods); if (ImpFile != NULL) fprintf (inFile, "#include \"%s\"\n", ImpFile); } mods->curr = currModTmp; // RWC;RESET loop control } // if ((ImportedFilesG == FALSE) || (impMod->ImportedFlag == TRUE)) // { // // Only include if Module was exported // if (impMod->exportStatus != 0) // { // // Check that the source header is not part of // // These references. // if ((strcmp(impMod->cHdrFileName, srcref) != 0)) // fprintf (src, "#include \"%s\"\n", impMod->cHdrFileName); // } // } // endif // fprintf (src, "#include \"%s\"\n", impMod->cHdrFileName); } //RWC;if (m->cHdrFileName != NULL) //RWC; fprintf (inFile, "#include \"%s\"\n", m->cHdrFileName); SET_CURR_LIST_NODE (mods, tmp); m=m; /* AVOIDS warning. */ } /* PrintCSrcIncludes */ static void PrintCHdrComment PARAMS ((f, m), FILE *f _AND_ Module *m) { long int t; t = time (0); fprintf (f, "/*\n"); fprintf (f, " * %s\n", m->cHdrFileName); fprintf (f, " * \"%s\" ASN.1 module C type definitions and" " prototypes\n", m->modId->name); fprintf (f, " * This file was generated by esnacc on %s", ctime (&t)); fprintf (f, " * NOTE: This is a machine generated file-" "-editing not recommended\n"); fprintf (f, " */\n\n"); } /* PrintCHdrComment */ esnacc-ng-1.8.1/compiler/back-ends/c-gen/gen-dec.c000066400000000000000000002216011302010526100214470ustar00rootroot00000000000000/* * compiler/back-ends/c-gen/gen-dec.c - routines for printing C decoders from type trees * * The type tree has already been run through the c type generator * (type-info.c). Types that the type generator didn't know how * to handle (or didn't want/need to handle eg macros) get the * C_NO_TYPE label and are ignored for code generation. * * NOTE: this is a real rats nest - it sort of evolved. It was * written assuming SETs/SEQ/CHOICE etc could be nested * hence all the crap about 'levels'. * * Mike Sample * 91/10/23 * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/back-ends/c-gen/gen-dec.c,v 1.15 2004/03/12 18:51:20 gronej Exp $ * */ #include #include "asn-incl.h" #include "asn1module.h" #include "rules.h" #include "snacc-util.h" #include "util.h" #include "tag-util.h" #include "enc-rules.h" static CRules *genDecCRulesG; char *valueArgNameG = "v"; static long *longJmpValG; static char *decodedLenVarNameG = "totalElmtsLen"; static char *itemLenVarNameG = "elmtLen"; /*static char *mecVarNameG = "mandatoryElmtCount";*/ static char *tagIdVarNameG = "tagId"; char *bufTypeNameG = "GenBuf *"; char *lenTypeNameG = "AsnLen"; char *tagTypeNameG = "AsnTag"; char *envTypeNameG = "ENV_TYPE"; /* non-exported prototypes */ static void PrintCDecoderPrototype PROTO ((FILE *hdr, TypeDef *td)); static void PrintCDecoderDeclaration PROTO ((FILE *src, TypeDef *td)); static void PrintCDecoderDefine PROTO ((FILE *src, TypeDef *td)); static int RecCountVariableLevels PROTO ((Type *t)); static int CountVariableLevels PROTO ((Type *t)); static void PrintCDecoderLocals PROTO ((FILE *src, TypeDef *td)); /*static void PrintCListDecoderLocals PROTO ((FILE *src));*/ static void PrintCSetDecodeCode PROTO ((FILE *src, TypeDef *td, Type *parent, NamedTypeList *e, int elmtLevel, int totalLevel, int tagLevel, char *varName)); static void PrintCSeqDecodeCode PROTO ((FILE *src, TypeDef *td, Type *parent, NamedTypeList *e, int elmtLevel, int totalLevel, int tagLevel, char *varName)); static void PrintCListDecoderCode PROTO ((FILE *src, TypeDef *td, Type *t, int elmtLevel, int totalLevel, int tagLevel, char *varName)); static void PrintCChoiceDecodeCode PROTO ((FILE *src, TypeDef *td, Type *t, int elmtLevel, int totalLevel, int tagLevel, char *varName)); /*static void PrintCLenDecodingCode PROTO ((FILE *f)); static void PrintCDecoderIncludes PROTO ((FILE *src, Module *m, ModuleList *mods)); */ static void PrintCElmtDecodeCode PROTO ((FILE *src, TypeDef *td, Type *parent, Type *t, int elmtLevel, int totalLevel, int tagLevel, char *parnetVarName, char *elmtVarName, int stoleChoiceTags)); void PrintCDecoder PARAMS ((src, hdr, r, m, td, longJmpVal), FILE *src _AND_ FILE *hdr _AND_ CRules *r _AND_ Module *m _AND_ TypeDef *td _AND_ long *longJmpVal) { int i; enum BasicTypeChoiceId typeId; int elmtLevel; CTDI *ctdi; Tag *tag; char *classStr; char *formStr; int stoleChoiceTags; TagList *tags; EncRulesType *encoding; ctdi = td->cTypeDefInfo; if (!ctdi->genDecodeRoutine) return; encoding = GetEncRules(); while (SetEncRules(*encoding)) { encoding++; /* * if is type that refs another pdu type or lib type * without generating a new type via tagging or named elmts * print define to the hdr file * (a type is a pdu by default if it is ref'd by an ANY) */ if (!IsNewType (td->type) && (!IsTypeRef (td->type) || (IsTypeRef (td->type) && (td->type->basicType->a.localTypeRef->link->cTypeDefInfo->isPdu || ((td->type->basicType->a.localTypeRef->link->anyRefs != NULL) && !LIST_EMPTY (td->type->basicType->a.localTypeRef->link->anyRefs)))))) { fprintf(hdr,"#define %s%s %s%s\n", GetEncRulePrefix(), td->cTypeDefInfo->decodeRoutineName, GetEncRulePrefix(), td->type->cTypeRefInfo->decodeRoutineName); return; } typeId = GetBuiltinType (td->type); /* print proto type to hdr file */ fprintf (hdr, "void %s%s PROTO ((%s b, %s *result, %s *bytesDecoded," " %s env));\n", GetEncRulePrefix(), ctdi->decodeRoutineName, bufTypeNameG, ctdi->cTypeName, lenTypeNameG, envTypeNameG); /* print routine in src */ fprintf (src, "void %s%s PARAMS ((b, result, bytesDecoded, env),\n", GetEncRulePrefix(), ctdi->decodeRoutineName); fprintf (src, "%s b _AND_\n", bufTypeNameG); fprintf (src, "%s *result _AND_\n", ctdi->cTypeName); fprintf (src, "%s *bytesDecoded _AND_\n", lenTypeNameG); fprintf (src, "%s env)\n", envTypeNameG); fprintf (src, "{\n"); fprintf (src, " %s tag;\n", tagTypeNameG); /* print extra locals for redundant lengths */ tags = GetTags (td->type, &stoleChoiceTags); for (i = 1; !stoleChoiceTags && (i <= LIST_COUNT (tags)); ++i) fprintf (src, " %s elmtLen%d;\n", lenTypeNameG, i); /* add extra len for choice */ if (typeId == BASICTYPE_CHOICE) fprintf (src," %s elmtLen%d;\n", lenTypeNameG, i); fprintf (src,"\n"); /* decode tag/length pairs */ elmtLevel = 0; if (!stoleChoiceTags) { FOR_EACH_LIST_ELMT (tag, tags) { classStr = Class2ClassStr (tag->tclass); if (tag->form == ANY_FORM) formStr = Form2FormStr (PRIM); else formStr = Form2FormStr (tag->form); fprintf (src, " if (((tag = %sDecTag (b, bytesDecoded, env)) != \n", GetEncRulePrefix()); if (tag->tclass == UNIV) { fprintf(src, " MAKE_TAG_ID (%s, %s, %s))", classStr, formStr, DetermineCode(tag, NULL, 0)); if (tag->form == ANY_FORM) fprintf(src, "&&\n (tag != MAKE_TAG_ID (%s, %s, %s)))\n", classStr, Form2FormStr (CONS), DetermineCode(tag, NULL, 0)); else fprintf(src, ")\n"); } else { fprintf(src, " MAKE_TAG_ID (%s, %s, %s))", classStr, formStr, DetermineCode(tag, NULL, 1)); if (tag->form == ANY_FORM) { fprintf(src, "&&\n (tag != MAKE_TAG_ID" " (%s, %s, %s)))\n", classStr, Form2FormStr (CONS), DetermineCode(tag, NULL, 1)); } else { fprintf (src,")\n"); } } fprintf(src, " {\n"); fprintf(src, " Asn1Error (\"%s%s: ERROR - wrong tag\\n\");\n", GetEncRulePrefix(), ctdi->decodeRoutineName); fprintf(src, " longjmp (env, %d);\n", (int)(*longJmpVal)--); fprintf(src, " }\n"); fprintf(src, " elmtLen%d = %sDecLen (b, bytesDecoded, env);\n", ++elmtLevel, GetEncRulePrefix()); } } /* for choices always decode first tag of the choice's content */ if (typeId == BASICTYPE_CHOICE) { fprintf(src, " tag = %sDecTag (b, bytesDecoded, env);\n", GetEncRulePrefix()); fprintf(src, " elmtLen%d = %sDecLen (b, bytesDecoded, env);\n", ++elmtLevel, GetEncRulePrefix()); } if ((typeId != BASICTYPE_ANY) && (typeId != BASICTYPE_ANYDEFINEDBY)) fprintf(src, " %s%sContent (b, tag, elmtLen%d, result, bytesDecoded, env);\n", GetEncRulePrefix(), ctdi->decodeRoutineName, elmtLevel); else fprintf(src, " %s%s (b, result, bytesDecoded, env);\n", GetEncRulePrefix(), ctdi->decodeRoutineName); /* grab any EOCs that match redundant, indef lengths */ for (i = elmtLevel-1; i > 0; i--) { fprintf(src, " if (elmtLen%d == INDEFINITE_LEN)\n", i); fprintf(src, " %sDecEoc (b, bytesDecoded, env);\n", GetEncRulePrefix()); } fprintf(src, "} /* %s%s */\n\n", GetEncRulePrefix(), ctdi->decodeRoutineName); FreeTags (tags); } m = m; r = r; /* AVOIDS warning. */ } /* PrintCDecoder */ void PrintCContentDecoder PARAMS ((src, hdr, r, m, td, longJmpVal), FILE *src _AND_ FILE *hdr _AND_ CRules *r _AND_ Module *m _AND_ TypeDef *td _AND_ long *longJmpVal) { CTDI *ctdi; CTypeId rhsTypeId; /* cTypeId of the type that defined this typedef */ EncRulesType* encoding; longJmpValG = longJmpVal; genDecCRulesG = r; ctdi = td->cTypeDefInfo; if ((ctdi == NULL) || (td->type->cTypeRefInfo == NULL)) { fprintf (stderr,"PrintCDecoder: ERROR - no type info\n"); return; } if (!ctdi->genDecodeRoutine) return; rhsTypeId = td->type->cTypeRefInfo->cTypeId; encoding = GetEncRules(); while(SetEncRules(*encoding)) { encoding++; switch (rhsTypeId) { /* * type refs or primitive types are * defined as calls to the referenced type */ case C_ANY: //RWC;fprintf (hdr, "/* ANY - Fix Me! */\n"); case C_ANYDEFINEDBY: fprintf(hdr, "#define %s%s %s%s\n", GetEncRulePrefix(), td->cTypeDefInfo->decodeRoutineName, GetEncRulePrefix(), td->type->cTypeRefInfo->decodeRoutineName); /* fprintf(hdr, "#define %s%s( b, tagId, elmtLen, v, bytesDecoded, env) ", GetEncRulePrefix(), td->cTypeDefInfo->decodeRoutineName); fprintf (hdr, "%s%s (b, tagId, elmtLen, v, bytesDecoded, env)", GetEncRulePrefix(), td->type->cTypeRefInfo->decodeRoutineName); */ fprintf (hdr,"\n\n"); break; case C_LIB: case C_TYPEREF: PrintCDecoderDefine (hdr, td); fprintf (hdr,"\n\n"); break; case C_CHOICE: PrintCDecoderPrototype (hdr, td); fprintf (hdr,"\n\n"); PrintCDecoderDeclaration (src, td); fprintf (src,"{\n"); PrintCDecoderLocals (src, td); fprintf (src,"\n\n"); PrintCChoiceDecodeCode (src, td, td->type, FIRST_LEVEL-1, FIRST_LEVEL,FIRST_LEVEL-1, valueArgNameG); fprintf (src, " (*bytesDecoded) += totalElmtsLen1;\n"); fprintf (src,"} /* %s%sContent */", GetEncRulePrefix(), td->cTypeDefInfo->decodeRoutineName); fprintf (src,"\n\n"); break; case C_STRUCT: PrintCDecoderPrototype (hdr, td); fprintf (hdr,"\n\n"); PrintCDecoderDeclaration (src, td); fprintf (src,"{\n"); PrintCDecoderLocals (src, td); fprintf (src,"\n\n"); if (td->type->basicType->choiceId == BASICTYPE_SET) PrintCSetDecodeCode (src, td, td->type, td->type->basicType->a.set, FIRST_LEVEL-1, FIRST_LEVEL, FIRST_LEVEL-1, valueArgNameG); else PrintCSeqDecodeCode (src, td, td->type, td->type->basicType->a.sequence, FIRST_LEVEL-1, FIRST_LEVEL, FIRST_LEVEL-1, valueArgNameG); fprintf (src, " (*bytesDecoded) += totalElmtsLen1;\n"); fprintf (src,"} /* %s%sContent */", GetEncRulePrefix(), td->cTypeDefInfo->decodeRoutineName); fprintf (src,"\n\n"); break; case C_LIST: PrintCDecoderPrototype (hdr, td); fprintf (hdr,"\n\n"); PrintCDecoderDeclaration (src, td); fprintf (src,"{\n"); PrintCDecoderLocals (src, td); fprintf (src,"\n\n"); PrintCListDecoderCode (src, td, td->type, FIRST_LEVEL-1, FIRST_LEVEL, FIRST_LEVEL-1, valueArgNameG); fprintf (src, " (*bytesDecoded) += totalElmtsLen1;\n"); fprintf (src,"} /* %s%sContent */", GetEncRulePrefix(), td->cTypeDefInfo->decodeRoutineName); fprintf (src,"\n\n"); break; case C_NO_TYPE: /* fprintf (src,"< sorry, unsupported type >\n\n"); */ return; /* dont' print newlines */ break; default: fprintf (stderr,"PrintCContentDecoder: ERROR - unknown c type id\n"); return; break; } } m = m; /* AVOIDS warning. */ } /* PrintCContentDecoder */ /* * Prints prototype for decode routine in hdr file */ static void PrintCDecoderPrototype PARAMS ((hdr, td), FILE *hdr _AND_ TypeDef *td) { CTDI *ctdi; ctdi = td->cTypeDefInfo; fprintf (hdr,"void %s%sContent PROTO ((%s b, %s tagId%d, %s elmtLen%d, %s *v, %s *bytesDecoded, %s env));\n", GetEncRulePrefix(), ctdi->decodeRoutineName, bufTypeNameG, tagTypeNameG, FIRST_LEVEL-1, lenTypeNameG, FIRST_LEVEL-1, ctdi->cTypeName, lenTypeNameG, envTypeNameG); } /* PrintCDecoderPrototype */ /* * Prints declarations of decode routine for the given type def */ static void PrintCDecoderDeclaration PARAMS ((src,td), FILE *src _AND_ TypeDef *td) { CTDI *ctdi; ctdi = td->cTypeDefInfo; fprintf (src,"void\n"); fprintf (src,"%s%sContent PARAMS ((b, tagId%d, elmtLen%d, v, bytesDecoded, env),\n", GetEncRulePrefix(), ctdi->decodeRoutineName, FIRST_LEVEL -1, FIRST_LEVEL -1); fprintf (src,"%s b _AND_\n", bufTypeNameG); fprintf (src,"%s tagId%d _AND_\n", tagTypeNameG, FIRST_LEVEL -1); fprintf (src,"%s elmtLen%d _AND_\n", lenTypeNameG, FIRST_LEVEL -1); fprintf (src,"%s *v _AND_\n", ctdi->cTypeName); fprintf (src,"%s *bytesDecoded _AND_\n", lenTypeNameG); fprintf (src,"%s env)\n", envTypeNameG); } /* PrintCDecoderDeclaration */ /* * makes a define for type refs or primitive type renaming * EG: * TypeX ::= INTEGER --> #define BerDecodeTypeX(b,v) BerDecodeInteger(b,v) * TypeX ::= TypeY --> #define BerDecodeTypeX(b,v) BerDecodeTypeY(b,v) */ static void PrintCDecoderDefine PARAMS ((hdr, td), FILE *hdr _AND_ TypeDef *td) { fprintf(hdr, "#define %s%sContent %s%sContent", GetEncRulePrefix(), td->cTypeDefInfo->decodeRoutineName, GetEncRulePrefix(), td->type->cTypeRefInfo->decodeRoutineName); /* fprintf(hdr, "#define %sContent( b, tagId, elmtLen, v, bytesDecoded, env) ", td->cTypeDefInfo->decodeRoutineName); fprintf (hdr, "%s%sContent (b, tagId, elmtLen, v, bytesDecoded, env)", td->type->cTypeRefInfo->decodeRoutineName); */ } /* PrintCDecoderDefine */ /* * used to figure out local variables to declare */ static int RecCountVariableLevels PARAMS ((t), Type *t) { CTRI *ctri; int maxLevels = 0; NamedType *e; int tagCount; int typeCount; void *tmp; enum BasicTypeChoiceId typeId; ctri = t->cTypeRefInfo; typeId = GetBuiltinType (t); /* embedded struct/choices aren't really an issue any more */ if ((ctri->cTypeId == C_STRUCT) || (ctri->cTypeId == C_CHOICE)) { maxLevels = 1; tagCount = CountTags (t); tmp = (void*)CURR_LIST_NODE (t->basicType->a.set); FOR_EACH_LIST_ELMT (e, t->basicType->a.set) { if ((e->type == NULL) || (e->type->cTypeRefInfo == NULL)) continue; typeCount = RecCountVariableLevels (e->type); if (typeCount > maxLevels) maxLevels = typeCount; } SET_CURR_LIST_NODE (t->basicType->a.set, tmp); return maxLevels + tagCount; } else if (ctri->cTypeId == C_LIST) { return CountTags (t) +RecCountVariableLevels (t->basicType->a.setOf); } else if (typeId == BASICTYPE_CHOICE) return CountTags (t) +1; else if ((typeId == BASICTYPE_ANY) || (typeId == BASICTYPE_ANYDEFINEDBY)) return CountTags (t) +1; else return CountTags (t); } /* RecCountVariableLevels */ /* * returns the number of variable contexts needed for * decoding the contents of this type. Does not consider tags on this type. */ static int CountVariableLevels PARAMS ((t), Type *t) { CTRI *ctri; int maxLevels = 0; NamedType *e; int typeCount; void *tmp; ctri = t->cTypeRefInfo; if ((ctri->cTypeId == C_STRUCT) || (ctri->cTypeId == C_CHOICE)) { maxLevels = 1; tmp = (void*)CURR_LIST_NODE (t->basicType->a.set); FOR_EACH_LIST_ELMT (e, t->basicType->a.set) { if ((e->type == NULL) || (e->type->cTypeRefInfo == NULL)) continue; typeCount = RecCountVariableLevels (e->type); /* add extra level since must decode key tag in choice */ if (GetBuiltinType (e->type) == BASICTYPE_CHOICE) typeCount++; if (typeCount > maxLevels) maxLevels = typeCount; } SET_CURR_LIST_NODE (t->basicType->a.set, tmp); return maxLevels; } else if (ctri->cTypeId == C_LIST) return RecCountVariableLevels (t->basicType->a.setOf); else if ((ctri->cTypeId == C_ANY) || (ctri->cTypeId == C_ANYDEFINEDBY)) return 1; else return 0; } /* CountVariableLevels */ /* * prints local vars for constructed types (set/seq/choice) */ static void PrintCDecoderLocals PARAMS ((src,td), FILE *src _AND_ TypeDef *td) { int levels; int i; levels = CountVariableLevels (td->type); fprintf (src, " int seqDone = FALSE;\n"); for (i = 0; i < levels; i++) { fprintf (src, " %s totalElmtsLen%d = 0;\n", lenTypeNameG, i + FIRST_LEVEL); fprintf (src, " %s elmtLen%d;\n", lenTypeNameG, i + FIRST_LEVEL); fprintf (src, " %s tagId%d;\n", tagTypeNameG, i + FIRST_LEVEL); if (i == 0) fprintf (src, " int mandatoryElmtCount%d = 0;\n", i + FIRST_LEVEL); } } /* PrintCDecoderLocals */ /* * given the Type *(t) of an elmt in a set/seq/choice/list, * prints decoding code. * elmtVarName is string ptr ref to field being decoded * eg "(&personnelRecord.name)" * stoleChoiceTags is as returned by GetTags * * elmtLevel - last elmtLen# var that is valid/used (has a len) * totalLevel - totalElmtsLen# to be used for running total of dec bytes * tagIdLevel - last tagId# var that is valid/used (contains a tag) */ static void PrintCElmtDecodeCode PARAMS ((src, td, parent, t, elmtLevel, totalLevel, tagLevel, parentVarName, elmtVarName, stoleChoiceTags), FILE *src _AND_ TypeDef *td _AND_ Type *parent _AND_ Type *t _AND_ int elmtLevel _AND_ int totalLevel _AND_ int tagLevel _AND_ char *parentVarName _AND_ char *elmtVarName _AND_ int stoleChoiceTags) { CTRI *ctri; Type *tmpType; char idVarRef[MAX_VAR_REF]; NamedType *idNamedType; enum BasicTypeChoiceId tmpTypeId; ctri = t->cTypeRefInfo; /* check if meant to be encoded */ if (!ctri->isEncDec) return; tmpType = GetType (t); if(!tmpType->extensionAddition) { if (tmpType->basicType->choiceId == BASICTYPE_ANY) { fprintf (src,"/* ANY - Fix Me ! */\n"); fprintf (src,"\tSetAnyTypeUnknown(%s);\n", elmtVarName); //RWC;fprintf (src," SetAnyTypeBy\?\?\?(%s, \?\?\?);\n", elmtVarName); fprintf (src," %s%s (b, %s, &%s%d, env);\n", GetEncRulePrefix(), "DecAsnAny"/*RWC;NOT VALID FOR C_TYPEREF;ctri->decodeRoutineName*/, elmtVarName, decodedLenVarNameG, totalLevel); } else if (tmpType->basicType->choiceId == BASICTYPE_ANYDEFINEDBY) { /* get type of 'defining' field (int/enum/oid)*/ idNamedType = t->basicType->a.anyDefinedBy->link; tmpTypeId = GetBuiltinType (idNamedType->type); if (tmpTypeId == BASICTYPE_OID || tmpTypeId == BASICTYPE_RELATIVE_OID) { MakeVarPtrRef (genDecCRulesG, td, parent, idNamedType->type, parentVarName, idVarRef); fprintf (src, " SetAnyTypeByOid (%s, %s);\n", elmtVarName, idVarRef); } else { /* want to ref int by value not ptr */ MakeVarValueRef (genDecCRulesG, td, parent, idNamedType->type, parentVarName, idVarRef); fprintf (src, " SetAnyTypeByInt (%s, %s);\n", elmtVarName, idVarRef); } fprintf (src," %s%s (b, %s, &%s%d, env);\n", GetEncRulePrefix(), ctri->decodeRoutineName, elmtVarName, decodedLenVarNameG, totalLevel); } else switch (ctri->cTypeId) { case C_LIB: case C_TYPEREF: /* * choices and octet/bit str types need tagId argument */ if ((tmpType->basicType->choiceId == BASICTYPE_CHOICE) && !stoleChoiceTags) { /* * strip off top tag of choice in not already done * since choice decoders assume you are passing in * their top tag */ fprintf (src, " %s%d = %sDecTag (b, &%s%d, env);\n", tagIdVarNameG, ++tagLevel, GetEncRulePrefix(), decodedLenVarNameG, totalLevel); fprintf (src, " %s%d = %sDecLen (b, &%s%d, env);\n", itemLenVarNameG, ++elmtLevel, GetEncRulePrefix(), decodedLenVarNameG, totalLevel); } fprintf (src," %s%sContent (b, %s%d, %s%d, %s, &%s%d, env);\n", GetEncRulePrefix(), ctri->decodeRoutineName, tagIdVarNameG, tagLevel, itemLenVarNameG, elmtLevel, elmtVarName, decodedLenVarNameG, totalLevel); break; /* * NOTE: the CHOICE, STRUCT and LIST switch clauses won't * fire due to the current 'normalization' * (see normalize.c) */ case C_CHOICE: /* * strip off top tag of choice in not already done * since choice decoders assume you are passing in * their top tag */ if (!stoleChoiceTags) { fprintf (src, " %s%d = %sDecTag (b, &%s%d, env);\n\n", tagIdVarNameG, ++tagLevel, GetEncRulePrefix(), decodedLenVarNameG, totalLevel); fprintf (src, " %s%d = %sDecLen (b, &%s%d, env);\n", itemLenVarNameG, ++elmtLevel, GetEncRulePrefix(), decodedLenVarNameG, totalLevel); } PrintCChoiceDecodeCode (src, td, t, elmtLevel, totalLevel+1, tagLevel, elmtVarName); break; case C_STRUCT: if (t->basicType->choiceId == BASICTYPE_SET) PrintCSetDecodeCode (src, td, t, t->basicType->a.set, elmtLevel, totalLevel+1, tagLevel, elmtVarName); else { PrintCSeqDecodeCode (src, td, t, t->basicType->a.sequence, elmtLevel,totalLevel+1, tagLevel, elmtVarName); fprintf (src," seqDone = FALSE;\n"); } fprintf (src," %s%d += %s%d;\n", decodedLenVarNameG, totalLevel, decodedLenVarNameG, totalLevel+1); break; case C_LIST: PrintCListDecoderCode (src, td, t, elmtLevel, totalLevel+1, tagLevel, elmtVarName); fprintf (src,"\n\n"); fprintf (src," %s%d += %s%d;\n", decodedLenVarNameG, totalLevel, decodedLenVarNameG, totalLevel+1); break; case C_NO_TYPE: break; default: fprintf (stderr,"PrintCElmtDecodeCode: ERROR - unknown c type id\n"); break; } } } /* PrintCElmtDecodeCode */ /* * Prints code for decoding the elmts of SET */ static void PrintCSetDecodeCode PARAMS ((src, td, parent, elmts, elmtLevel, totalLevel, tagLevel, varName), FILE *src _AND_ TypeDef *td _AND_ Type *parent _AND_ NamedTypeList *elmts _AND_ int elmtLevel _AND_ int totalLevel _AND_ int tagLevel _AND_ char *varName) { NamedType *e; CTRI *ctri; TagList *tags; Tag *tag; enum BasicTypeChoiceId builtinType; char *classStr; char *formStr; char *codeStr; int mandatoryCount = 0; char tmpVarName[MAX_VAR_REF]; int stoleChoiceTags; char *routineName; int initialTagLevel; int initialElmtLevel; initialTagLevel = tagLevel; initialElmtLevel = elmtLevel; routineName = td->cTypeDefInfo->decodeRoutineName; if ((elmts == NULL) || LIST_EMPTY (elmts)) /* empty set */ { fprintf (src," if (elmtLen%d == INDEFINITE_LEN)\n", elmtLevel); fprintf (src," {\n"); fprintf (src," %sDecEoc (b, &totalElmtsLen%d, env);\n", GetEncRulePrefix(), totalLevel); fprintf (src," }\n"); fprintf (src," else if (elmtLen%d != 0)\n", elmtLevel); fprintf (src," {\n"); fprintf (src," Asn1Error (\"Expected an empty SET\\n\");\n"); fprintf (src," longjmp (env, %d);\n", (int)(*longJmpValG)--); fprintf (src," }\n"); /* forget about possible extension types for now fprintf (src," if (elmtLen%d == INDEFINITE_LEN)\n", elmtLevel); fprintf (src," {\n"); fprintf (src," tagId%d = %sDecTag (b, &totalElmtsLen%d, env);\n\n", ++tagLevel, GetEncRulePrefix(), totalLevel); fprintf (src," if (tagId%d == EOC_TAG_ID)\n", tagLevel); fprintf (src," %sDEC_2ND_EOC_OCTET (b, &totalElmtsLen%d, env)\n", GetEncRulePrefix(), totalLevel); fprintf (src," else\n"); fprintf (src," BerDiscardElmt (b, &totalElmtsLen%d, env);\n\n",totalLevel); fprintf (src," }\n"); fprintf (src," else\n"); fprintf (src," {\n"); fprintf (src," BufSkip (b, elmtLen%d);\n", elmtLevel); fprintf (src," totalElmtsLen%d += elmtLen%d;\n", totalLevel, elmtLevel); fprintf (src," }\n"); */ return; } fprintf (src, "for ( ; (totalElmtsLen%d < elmtLen%d) || (elmtLen%d == INDEFINITE_LEN);)\n", totalLevel, elmtLevel, elmtLevel); fprintf (src, "{\n"); fprintf (src, " tagId%d = %sDecTag (b, &totalElmtsLen%d, env);\n\n", ++tagLevel, GetEncRulePrefix(), totalLevel); fprintf (src, " if ((tagId%d == EOC_TAG_ID) && (elmtLen%d == INDEFINITE_LEN))\n", tagLevel, elmtLevel); fprintf (src, " {\n"); fprintf (src, " %sDEC_2ND_EOC_OCTET (b, &totalElmtsLen%d, env)\n", GetEncRulePrefix(), totalLevel); fprintf (src, " break; /* got EOC so can exit this SET's for loop*/\n"); fprintf (src, " }\n"); fprintf (src, " elmtLen%d = %sDecLen (b, &totalElmtsLen%d, env);\n", ++elmtLevel, GetEncRulePrefix(), totalLevel); fprintf (src, " switch (tagId%d)\n", tagLevel); fprintf (src, " {\n"); FOR_EACH_LIST_ELMT (e, elmts) { if(!e->type->extensionAddition) { elmtLevel = initialElmtLevel+1; tagLevel = initialTagLevel+1; if ((e->type == NULL) || (e->type->cTypeRefInfo == NULL)) { fprintf (src, "< ERROR - no c type information - prob unsuported type>\n"); continue; } ctri = e->type->cTypeRefInfo; /* check if meant to be encoded */ if (!ctri->isEncDec) continue; tags = GetTags (e->type, &stoleChoiceTags); builtinType = GetBuiltinType (e->type); if ((tags == NULL) || LIST_EMPTY (tags)) { if ((builtinType != BASICTYPE_ANY) && (builtinType != BASICTYPE_ANYDEFINEDBY)) { if(e->type->extensionAddition) { fprintf (src, "\n"); fprintf (src, "<--Suggest removing extension marker and making all respective extension additions optional>\n"); } else { fprintf (src, "\n"); } } else { fprintf (src," /* ANY - Fix Me ! */\n"); fprintf (src," case MAKE_TAG_ID (?,?,?):\n"); } } else { tag = (Tag*)FIRST_LIST_ELMT (tags); classStr = Class2ClassStr (tag->tclass); codeStr = DetermineCode(tag, NULL, 0);//RWC;Code2UnivCodeStr (tag->code); formStr = Form2FormStr (tag->form); if (tag->tclass == UNIV) { if (tag->form == ANY_FORM) { fprintf (src," case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (CONS), codeStr); fprintf (src," case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (PRIM), codeStr); } else fprintf (src," case MAKE_TAG_ID (%s, %s, %s):\n", classStr, formStr, codeStr); } else { if (tag->form == ANY_FORM) { fprintf (src," case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (CONS), DetermineCode(tag, NULL, 1));//RWC;tag->code); fprintf (src," case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (PRIM), DetermineCode(tag, NULL, 1));//RWC;tag->code); } else fprintf (src," case MAKE_TAG_ID (%s, %s, %s):\n", classStr, formStr, DetermineCode(tag, NULL, 1));//RWC;tag->code); } AsnListFirst (tags); AsnListNext (tags); /* set curr to 2nd tag */ FOR_REST_LIST_ELMT (tag, tags) { codeStr = DetermineCode(tag, NULL, 0);//RWC;Code2UnivCodeStr (tag->code); classStr = Class2ClassStr (tag->tclass); formStr = Form2FormStr (tag->form); if (stoleChoiceTags) { classStr = Class2ClassStr(tag->tclass); formStr = Form2FormStr(tag->form); if (tag->tclass == UNIV) { codeStr = DetermineCode(tag, NULL, 0); } else { codeStr = DetermineCode(tag, NULL, 1); } if (tag->form == ANY_FORM) { fprintf(src, " case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr(CONS), codeStr); fprintf(src, " case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr(PRIM), codeStr); } else { fprintf(src, " case MAKE_TAG_ID (%s, %s, %s):\n", classStr, formStr, codeStr); } } else { tagLevel = initialTagLevel+2; if (tag->form == ANY_FORM) { fprintf (src," tagId%d = %sDecTag (b, &totalElmtsLen%d, env);\n", tagLevel, GetEncRulePrefix(), totalLevel); if (tag->tclass == UNIV) { fprintf (src,"if ((tagId%d != MAKE_TAG_ID (%s, %s, %s)) &&\n", tagLevel, classStr, Form2FormStr (PRIM), codeStr); fprintf (src," (tagId%d != MAKE_TAG_ID (%s, %s, %s)))\n", tagLevel, classStr, Form2FormStr (CONS), codeStr); } else { fprintf (src,"if ((tagId%d != MAKE_TAG_ID (%s, %s, %s)) &&\n", tagLevel, classStr, Form2FormStr (PRIM), DetermineCode(tag, NULL, 1));//RWC;tag->code); fprintf (src," (tagId%d != MAKE_TAG_ID (%s, %s, %s)))\n", tagLevel, classStr, Form2FormStr (CONS), DetermineCode(tag, NULL, 1));//RWC;tag->code); } } else { if (tag->tclass == UNIV) fprintf (src,"if ((tagId%d = %sDecTag (b, &totalElmtsLen%d, env)) != MAKE_TAG_ID (%s, %s, %s))\n", tagLevel, GetEncRulePrefix(), totalLevel, classStr, formStr, codeStr); else fprintf (src,"if ((tagId%d = %sDecTag (b, &totalElmtsLen%d, env)) != MAKE_TAG_ID (%s, %s, %s))\n", tagLevel, GetEncRulePrefix(), totalLevel, classStr, formStr, DetermineCode(tag, NULL, 1));//RWC;tag->code); } fprintf (src," {\n"); fprintf (src," Asn1Error (\"Unexpected Tag\\n\");\n"); fprintf (src," longjmp (env, %d);\n", (int)(*longJmpValG)--); fprintf (src," }\n\n"); fprintf (src,"elmtLen%d = %sDecLen (b, &totalElmtsLen%d, env);\n", ++elmtLevel, GetEncRulePrefix(), totalLevel); } } } MakeVarPtrRef (genDecCRulesG, td, parent, e->type, varName, tmpVarName); /* * allocate mem for decoding result */ PrintElmtAllocCode (src, e->type, tmpVarName); PrintCElmtDecodeCode (src, td, parent, e->type, elmtLevel, totalLevel, tagLevel, varName, tmpVarName, stoleChoiceTags); /* * must check for another EOC for ANYs * Since the any decode routines * decode their own first tag/len pair */ if ((builtinType == BASICTYPE_ANY) || (builtinType == BASICTYPE_ANYDEFINEDBY)) PrintEocDecoders (src, elmtLevel, initialElmtLevel, itemLenVarNameG, totalLevel, decodedLenVarNameG); /* * must check for another EOC for tagged CHOICEs * since the choice decoder routines do not check * for an EOC on the choice's overall length - * they are only passed the tag/len of the choice's * component. */ else if ((builtinType == BASICTYPE_CHOICE) && !(stoleChoiceTags) && ((tags != NULL) && !LIST_EMPTY (tags))) PrintEocDecoders (src, elmtLevel, initialElmtLevel, itemLenVarNameG, totalLevel, decodedLenVarNameG); else PrintEocDecoders (src, elmtLevel-1, initialElmtLevel, itemLenVarNameG, totalLevel, decodedLenVarNameG); if ((!e->type->optional) && (e->type->defaultVal == NULL)) { mandatoryCount++; fprintf (src, " mandatoryElmtCount%d++;\n", totalLevel); } FreeTags (tags); } fprintf (src," break;\n\n"); } /* end for */ fprintf (src, " default:\n"); fprintf (src, " Asn1Error (\"%s%sContent: ERROR - Unexpected tag in SET\\n\");\n", GetEncRulePrefix(), routineName); fprintf (src, " longjmp (env, %d);\n", (int)(*longJmpValG)--); fprintf (src, " break;\n"); /* fprintf (src, " Asn1Warning (\"%s%sContent: Warning - unexpected tag in SET, discarding elmt\\n\");\n", GetEncRulePrefix(), routineName); fprintf (src, " BerDiscardElmt (b, &totalElmtsLen%d, env);\n\n", totalLevel); */ fprintf (src, " } /* end switch */\n"); fprintf (src, " } /* end for */\n"); fprintf (src, " if (mandatoryElmtCount%d != %d)\n", totalLevel, mandatoryCount); fprintf (src, " {\n"); fprintf (src, " Asn1Error (\"%s%sContent: ERROR - non-optional elmt missing from SET\\n\");\n", GetEncRulePrefix(), routineName); fprintf (src, " longjmp (env, %d);\n", (int)(*longJmpValG)--); fprintf (src, " }\n"); } /* PrintCSetDecodeCode */ /* * Prints code for decoding the elmts of a SEQUENCE */ static void PrintCSeqDecodeCode PARAMS ((src, td, parent, elmts, elmtLevel, totalLevel, tagLevel, varName), FILE *src _AND_ TypeDef *td _AND_ Type *parent _AND_ NamedTypeList *elmts _AND_ int elmtLevel _AND_ int totalLevel _AND_ int tagLevel _AND_ char *varName) { CTRI *ctri; NamedType *e; NamedType *tmpElmt; NamedType *last; TagList *tags; Tag *tag; enum BasicTypeChoiceId builtinType; enum BasicTypeChoiceId tmpTypeId; char *classStr; char *formStr; char *codeStr; char tmpVarName[MAX_VAR_REF]; int stoleChoiceTags; int inTailOptElmts = FALSE; int initialElmtLevel; int initialTagLevel; initialTagLevel = tagLevel; initialElmtLevel = elmtLevel; if ((elmts == NULL) || LIST_EMPTY (elmts)) /* empty seq */ { fprintf (src," if (elmtLen%d == INDEFINITE_LEN)\n", elmtLevel); fprintf (src," {\n"); fprintf (src," %sDecEoc (b, &totalElmtsLen%d, env);\n", GetEncRulePrefix(), totalLevel); fprintf (src," }\n"); fprintf (src," else if (elmtLen%d != 0)\n", elmtLevel); fprintf (src," {\n"); fprintf (src," Asn1Error (\"Expected an empty SEQUENCE\\n\");\n"); fprintf (src," longjmp (env, %d);\n", (int)(*longJmpValG)--); fprintf (src," }\n"); /* forget about extended types for now fprintf (src," tagId%d = %sDecTag (b, &totalElmtsLen%d, env);\n\n", tagLevel+1, GetEncRulePrefix(), totalLevel); fprintf (src," {\n"); fprintf (src," if (tagId%d == EOC_TAG_ID)\n", tagLevel+1); fprintf (src," %sDEC_2ND_EOC_OCTET (b, &totalElmtsLen%d, env)\n", GetEncRulePrefix(), totalLevel); fprintf (src," else\n"); fprintf (src," BerDiscardElmt (b, &totalElmtsLen%d, env);\n\n",totalLevel); fprintf (src," }\n"); fprintf (src," else \n"); fprintf (src," {\n"); fprintf (src," BufSkip (b, elmtLen%d);\n", elmtLevel); fprintf (src," totalElmtsLen%d += elmtLen%d\n", totalLevel, elmtLevel); fprintf (src," }\n"); */ return; } /* * must set list curr since IsTailOptional checks from curr pt * onward */ AsnListFirst (elmts); inTailOptElmts = IsTailOptional (elmts); e = (NamedType*)FIRST_LIST_ELMT (elmts); tmpTypeId = GetBuiltinType (e->type); /* * print code to decode the first tag */ tagLevel++; if (!inTailOptElmts) { if (((tmpTypeId == BASICTYPE_ANY) || (tmpTypeId == BASICTYPE_ANYDEFINEDBY)) && (CountTags (e->type) == 0)) { if ((e->type->optional) && (e != (NamedType*)LAST_LIST_ELMT (elmts))) { /* let this cause a compile error in the generated code */ fprintf (src,"\n"); } } else fprintf (src, " tagId%d = %sDecTag (b, &totalElmtsLen%d, env);\n\n", tagLevel, GetEncRulePrefix(), totalLevel); } else { fprintf (src, " if ((elmtLen%d != INDEFINITE_LEN) && (totalElmtsLen%d == elmtLen%d))\n", elmtLevel, totalLevel, elmtLevel); fprintf (src, " seqDone = TRUE;\n"); fprintf (src, " else\n"); fprintf (src, " {\n"); if (((tmpTypeId == BASICTYPE_ANY) || (tmpTypeId == BASICTYPE_ANYDEFINEDBY)) && (CountTags (e->type) == 0)) { if ((e->type->optional) && (e != (NamedType*)LAST_LIST_ELMT (elmts))) { /* let this cause a compile error in the generated code */ fprintf (src,"\n"); } } else fprintf (src, " tagId%d = %sDecTag (b, &totalElmtsLen%d, env);\n\n", tagLevel, GetEncRulePrefix(), totalLevel); fprintf (src," if ((elmtLen%d == INDEFINITE_LEN) && (tagId%d == EOC_TAG_ID))\n", elmtLevel, tagLevel); fprintf (src, " {\n"); fprintf (src, " %sDEC_2ND_EOC_OCTET (b, &totalElmtsLen%d, env)\n", GetEncRulePrefix(), totalLevel); fprintf (src, " seqDone = TRUE;\n"); fprintf (src, " }\n"); fprintf (src, " }\n\n"); } last = (NamedType*)LAST_LIST_ELMT (elmts); FOR_EACH_LIST_ELMT (e, elmts) { elmtLevel = initialElmtLevel; tagLevel = initialTagLevel+1; if ((e->type == NULL) || (e->type->cTypeRefInfo == NULL)) { fprintf (src, "< ERROR - no c type information - prob unsuported type>\n"); continue; } ctri = e->type->cTypeRefInfo; /* check if meant to be encoded */ if (!ctri->isEncDec) continue; tags = GetTags (e->type, &stoleChoiceTags); builtinType = GetBuiltinType (e->type); if ((tags == NULL) || LIST_EMPTY (tags)) { if ((builtinType != BASICTYPE_ANY) && (builtinType != BASICTYPE_ANYDEFINEDBY)) { if(e->type->extensionAddition) { fprintf (src, "\n"); fprintf (src, "<--Suggest removing extension marker and making all respective extension additions optional>\n"); } else { fprintf (src, "\n"); } } if (inTailOptElmts) { fprintf (src," if (!seqDone)"); } /* always enclose elmt decoder in block */ fprintf (src," {\n"); /* else { fprintf (src," if (tagId%d == MAKE_TAG_ID (?, ?, ?))\n", tagLevel); fprintf (src," {\n"); } */ } else /* has tags */ { tag = (Tag*)FIRST_LIST_ELMT (tags); classStr = Class2ClassStr (tag->tclass); codeStr = DetermineCode(tag, NULL, 0);//RWC;Code2UnivCodeStr (tag->code); formStr = Form2FormStr (tag->form); if (inTailOptElmts) fprintf (src," if ((!seqDone) && ("); else fprintf (src," if (("); if (tag->tclass == UNIV) { if (tag->form == ANY_FORM) { fprintf(src, "(tagId%d == MAKE_TAG_ID (%s, %s, %s)) ||\n", tagLevel, classStr, Form2FormStr(PRIM), codeStr); fprintf(src, "(tagId%d == MAKE_TAG_ID (%s, %s, %s))", tagLevel, classStr, Form2FormStr (CONS), codeStr); } else fprintf(src, "(tagId%d == MAKE_TAG_ID (%s, %s, %s))", tagLevel, classStr, formStr, codeStr); } else { if (tag->form == ANY_FORM) { fprintf (src,"(tagId%d == MAKE_TAG_ID (%s, %s, %s)) ||\n", tagLevel, classStr, Form2FormStr (PRIM), DetermineCode(tag, NULL, 1));//RWC;tag->code); fprintf (src,"(tagId%d == MAKE_TAG_ID (%s, %s, %s))", tagLevel, classStr, Form2FormStr (CONS), DetermineCode(tag, NULL, 1));//RWC;tag->code); } else fprintf (src,"(tagId%d == MAKE_TAG_ID (%s, %s, %s))", tagLevel, classStr, formStr, DetermineCode(tag, NULL, 1));//RWC;tag->code); } if (!stoleChoiceTags) { fprintf (src,"))\n"); fprintf (src, " {\n"); fprintf (src," elmtLen%d = %sDecLen (b, &totalElmtsLen%d, env);\n", ++elmtLevel, GetEncRulePrefix(), totalLevel); } AsnListFirst (tags); AsnListNext (tags); FOR_REST_LIST_ELMT (tag, tags) { classStr = Class2ClassStr (tag->tclass); codeStr = DetermineCode(tag, NULL, 0);//RWC;Code2UnivCodeStr (tag->code); formStr = Form2FormStr (tag->form); if (stoleChoiceTags) { fprintf (src," ||\n"); if (tag->tclass == UNIV) { if (tag->form == ANY_FORM) { fprintf (src," (tagId%d ==MAKE_TAG_ID (%s, %s, %s))", tagLevel, classStr, Form2FormStr (PRIM), codeStr); fprintf (src,"||\n (tagId%d == MAKE_TAG_ID (%s, %s, %s))", tagLevel, classStr, Form2FormStr (CONS), codeStr); } else fprintf (src," (tagId%d ==MAKE_TAG_ID (%s, %s, %s))", tagLevel, classStr, formStr, codeStr); } else { if (tag->form == ANY_FORM) { fprintf (src," (tagId%d == MAKE_TAG_ID (%s, %s, %s))", tagLevel, classStr, Form2FormStr (PRIM), DetermineCode(tag, NULL, 1));//RWC;tag->code); fprintf (src,"||\n (tagId%d == MAKE_TAG_ID (%s, %s, %s))", tagLevel, classStr, Form2FormStr (CONS), DetermineCode(tag, NULL, 1));//RWC;tag->code); } else fprintf (src," (tagId%d == MAKE_TAG_ID (%s, %s, %s))", tagLevel, classStr, formStr, DetermineCode(tag, NULL, 1));//RWC;tag->code); } } else { tagLevel = initialTagLevel + 2; fprintf (src, " tagId%d = %sDecTag (b, &totalElmtsLen%d, env);\n\n", tagLevel, GetEncRulePrefix(), totalLevel); if (tag->tclass == UNIV) { if (tag->form == ANY_FORM) { fprintf (src," if ((tagId%d != MAKE_TAG_ID (%s, %s, %s)) &&\n", tagLevel, classStr, Form2FormStr (PRIM), codeStr); fprintf (src," (tagId%d != MAKE_TAG_ID (%s, %s, %s)))\n", tagLevel, classStr, Form2FormStr (CONS), codeStr); } else fprintf (src," if (tagId%d != MAKE_TAG_ID (%s, %s, %s))\n", tagLevel, classStr, formStr, codeStr); } else { if (tag->form == ANY_FORM) { fprintf (src," if ((tagId%d != MAKE_TAG_ID (%s, %s, %s)) &&\n", tagLevel, classStr, Form2FormStr (PRIM), DetermineCode(tag, NULL, 1));//RWC;tag->code); fprintf (src," (tagId%d != MAKE_TAG_ID (%s, %s, %s)))\n", tagLevel, classStr, Form2FormStr (CONS), DetermineCode(tag, NULL, 1));//RWC;tag->code); } else fprintf (src," if (tagId%d != MAKE_TAG_ID (%s, %s, %s))\n", tagLevel, classStr, formStr, DetermineCode(tag, NULL, 1));//RWC;tag->code); } fprintf (src," {\n"); fprintf (src," Asn1Error (\"Unexpected Tag\\n\");\n"); fprintf (src," longjmp (env, %d);\n",(int)(*longJmpValG)--); fprintf (src," }\n\n"); fprintf (src," elmtLen%d = %sDecLen (b, &totalElmtsLen%d, env);\n", ++elmtLevel, GetEncRulePrefix(), totalLevel); } } /* end tag list for */ if (stoleChoiceTags) { fprintf (src,"))\n"); fprintf (src, " {\n"); fprintf (src, " elmtLen%d = %sDecLen (b, &totalElmtsLen%d, env);\n", ++elmtLevel, GetEncRulePrefix(), totalLevel); } } MakeVarPtrRef (genDecCRulesG, td, parent, e->type, varName, tmpVarName); /* * allocate mem for decoding result */ PrintElmtAllocCode (src, e->type, tmpVarName); PrintCElmtDecodeCode (src, td, parent, e->type, elmtLevel, totalLevel, tagLevel, varName, tmpVarName, stoleChoiceTags); /* * must check for another EOC for ANYs * Since the any decode routines * decode their own first tag/len pair */ if ((builtinType == BASICTYPE_ANY) || (builtinType == BASICTYPE_ANYDEFINEDBY)) PrintEocDecoders (src, elmtLevel, initialElmtLevel, itemLenVarNameG, totalLevel, decodedLenVarNameG); /* * must check for another EOC for tagged CHOICEs * since the choice decoder routines do not check * for an EOC on the choice's overall length - * they are only passed the tag/len of the choice's * component. */ else if ((builtinType == BASICTYPE_CHOICE) && (!stoleChoiceTags) && ((tags != NULL) && !LIST_EMPTY (tags))) PrintEocDecoders (src, elmtLevel, initialElmtLevel, itemLenVarNameG, totalLevel, decodedLenVarNameG); else PrintEocDecoders (src, elmtLevel-1, initialElmtLevel, itemLenVarNameG, totalLevel, decodedLenVarNameG); /* could check cons len vs decode len here */ if (!inTailOptElmts) { /* * determine whether next elmt in Seq is start * of tailing optionals */ AsnListNext (elmts); inTailOptElmts = IsTailOptional (elmts); AsnListPrev (elmts); } /* * print code for getting the next tag */ tmpTypeId = GetBuiltinType (e->type); if (e != last) { tmpElmt = (NamedType*)NEXT_LIST_ELMT (elmts); tmpTypeId = GetBuiltinType (tmpElmt->type); if (!inTailOptElmts) { if (((tmpTypeId == BASICTYPE_ANY) || (tmpTypeId == BASICTYPE_ANYDEFINEDBY)) && (CountTags (tmpElmt->type) == 0)) { if ((e->type->optional) || ((tmpElmt->type->optional) && (tmpElmt != last))) { /* let this cause a compile error in the gen'd code */ fprintf (src," \n"); } /* don't get a tag since ANY's decode their own */ } else fprintf (src, " tagId%d = %sDecTag (b, &totalElmtsLen%d, env);\n", initialTagLevel+1, GetEncRulePrefix(), totalLevel); } else { fprintf (src, " if ((elmtLen%d != INDEFINITE_LEN) && (totalElmtsLen%d == elmtLen%d))\n", initialElmtLevel, totalLevel, initialElmtLevel); fprintf (src, " seqDone = TRUE;\n"); fprintf (src, " else\n"); fprintf (src, " {\n"); if (((tmpTypeId == BASICTYPE_ANY) || (tmpTypeId == BASICTYPE_ANYDEFINEDBY)) && (CountTags (tmpElmt->type) == 0)) { if ((e->type->optional) || ((tmpElmt->type->optional) && (tmpElmt != last))) { /* let this cause a compile error in the gen'd code */ fprintf (src," \n"); } /* peek ahead for first octet of eoc */ fprintf (src," tagId%d = BufPeekByte (b);\n", initialTagLevel+1); fprintf (src," if ((elmtLen%d == INDEFINITE_LEN) && (tagId%d == EOC_TAG_ID))\n", initialElmtLevel, initialTagLevel+1); fprintf (src, " {\n"); fprintf (src, " %sDecEoc (b, &totalElmtsLen%d, env);\n", GetEncRulePrefix(), totalLevel); fprintf (src, " seqDone = TRUE;\n"); fprintf (src, " }\n"); } else { fprintf (src, " tagId%d = %sDecTag (b, &totalElmtsLen%d, env);\n\n", initialTagLevel+1, GetEncRulePrefix(), totalLevel); fprintf (src," if ((elmtLen%d == INDEFINITE_LEN) && (tagId%d == EOC_TAG_ID))\n", initialElmtLevel, initialTagLevel+1); fprintf (src, " {\n"); fprintf (src, " %sDEC_2ND_EOC_OCTET (b, &totalElmtsLen%d, env)\n", GetEncRulePrefix(), totalLevel); fprintf (src, " seqDone = TRUE;\n"); fprintf (src, " }\n"); } fprintf (src, " }\n"); } } else /* for last elmt only */ { fprintf (src," seqDone = TRUE;\n"); fprintf (src," if (elmtLen%d == INDEFINITE_LEN)\n", initialElmtLevel); fprintf (src," %sDecEoc (b, &totalElmtsLen%d, env);\n", GetEncRulePrefix(), totalLevel); fprintf (src," else if (totalElmtsLen%d != elmtLen%d)\n", totalLevel, initialElmtLevel); fprintf (src," longjmp (env, %d);\n",(int)(*longJmpValG)--); } /* * close (tag check/seqDone test) if block and * print else clause to handle missing non-optional elmt * errors */ tmpTypeId = GetBuiltinType (e->type); if (((tmpTypeId == BASICTYPE_ANYDEFINEDBY) || (tmpTypeId == BASICTYPE_ANY)) && (CountTags (e->type) == 0)) { /* close if stmt block */ fprintf (src," }\n"); } else if (!e->type->optional && (e->type->defaultVal == NULL)) { fprintf (src, " }\n"); /* end of tag check if */ fprintf (src, " else\n"); fprintf (src, " longjmp (env, %d);\n", (int)(*longJmpValG)--); } else { fprintf (src, " }\n"); /* end of tag check if */ } fprintf (src,"\n\n"); FreeTags (tags); } /* * print code to make sure that truly finished with sequence */ fprintf (src," if (!seqDone)\n"); fprintf (src, " longjmp (env, %d);\n\n", (int)(*longJmpValG)--); } /* PrintCSeqDecodeCode */ /* * Generates code for internally defined lists * eg: * TypeX = SET { foo INTEGER, bar SEQUENCE OF INTEGER } --> * BerDecodeTypeX (b, len, v, bytesDecoded, env) * { * ... * listLen1 = BerDecodeLen (b, &totalElmtsLen, env); * retVal->bar = NewList(); * for ( ; totalElmtsLen1 < listLen1 || listLen1== INDEFINITE_LEN;) * { * tagId1 = BerDecodeTag (b, &totalElmtsLen1, env); * check for EOC * elmtLen1 = BerDecodeLen (b, &totalElmtsLen1, env) * tmpInt = Asn1Alloc (sizeof (int)); * BerDecodeInteger (b, elmtLen1, tmpInt, &totalElmtsLen1, env); * AppendList (retVal->bar, tmpInt); * } * totalElmtsLen += totalElmtsLen1; * ... * } */ static void PrintCListDecoderCode PARAMS ((src, td, list, elmtLevel, totalLevel, tagLevel, varName), FILE *src _AND_ TypeDef *td _AND_ Type *list _AND_ int elmtLevel _AND_ int totalLevel _AND_ int tagLevel _AND_ char *varName) { CTRI *ctri; TagList *tags; Tag *tag; enum BasicTypeChoiceId builtinType; char *classStr; char *formStr; char *codeStr; char tmpVarName[MAX_VAR_REF]; int stoleChoiceTags; int initialTagLevel; int initialElmtLevel; int taglessAny; initialTagLevel = tagLevel; initialElmtLevel = elmtLevel; ctri = list->basicType->a.setOf->cTypeRefInfo; tags = GetTags (list->basicType->a.setOf, &stoleChoiceTags); builtinType = GetBuiltinType (list->basicType->a.setOf); taglessAny = (((tags == NULL) || LIST_EMPTY (tags)) && ((builtinType == BASICTYPE_ANY) || (builtinType == BASICTYPE_ANYDEFINEDBY))); fprintf (src, " for (totalElmtsLen%d = 0; (totalElmtsLen%d < elmtLen%d) || (elmtLen%d == INDEFINITE_LEN);)\n", totalLevel, totalLevel, elmtLevel, elmtLevel); fprintf (src, " {\n"); fprintf (src," %s **tmpVar;\n", ctri->cTypeName); if (taglessAny) { fprintf (src, " tagId%d = BufPeekByte (b);\n\n", ++tagLevel); fprintf (src, " if ((tagId%d == EOC_TAG_ID) && (elmtLen%d == INDEFINITE_LEN))\n", tagLevel, elmtLevel); fprintf (src, " {\n"); fprintf (src, " %sDecEoc (b, &totalElmtsLen%d, env);\n", GetEncRulePrefix(), totalLevel); fprintf (src, " break; /* got EOC so can exit this SET OF/SEQ OF's for loop*/\n"); fprintf (src, " }\n"); } else { fprintf (src, " tagId%d = %sDecTag (b, &totalElmtsLen%d, env);\n\n", ++tagLevel, GetEncRulePrefix(), totalLevel); fprintf (src, " if ((tagId%d == EOC_TAG_ID) && (elmtLen%d == INDEFINITE_LEN))\n", tagLevel, elmtLevel); fprintf (src, " {\n"); fprintf (src, " %sDEC_2ND_EOC_OCTET (b, &totalElmtsLen%d, env)\n", GetEncRulePrefix(), totalLevel); fprintf (src, " break; /* got EOC so can exit this SET OF/SEQ OF's for loop*/\n"); fprintf (src, " }\n"); } if ((tags == NULL) || LIST_EMPTY (tags)) { if (!taglessAny) fprintf (src, "\n"); /* else { fprintf (src," if (tagId%d == MAKE_TAG_ID (?, ?, ?))",tagLevel); fprintf (src," {\n"); } */ } else if (!stoleChoiceTags) /* choice decoder will check tag */ { tag = (Tag*)FIRST_LIST_ELMT (tags); classStr = Class2ClassStr (tag->tclass); codeStr = DetermineCode(tag, NULL, 0);//RWC;Code2UnivCodeStr (tag->code); formStr = Form2FormStr (tag->form); if (tag->tclass == UNIV) { if (tag->form == ANY_FORM) { fprintf (src," if ((tagId%d == MAKE_TAG_ID (%s, %s, %s)) ||", tagLevel, classStr, Form2FormStr (PRIM), codeStr); fprintf (src," (tagId%d == MAKE_TAG_ID (%s, %s, %s))", tagLevel, classStr, Form2FormStr (CONS), codeStr); } else fprintf (src," if ((tagId%d == MAKE_TAG_ID (%s, %s, %s))", tagLevel, classStr, formStr, codeStr); } else { if (tag->form == ANY_FORM) { fprintf (src," if ((tagId%d == MAKE_TAG_ID (%s, %s, %s)) ||\n", tagLevel, classStr, Form2FormStr (PRIM), DetermineCode(tag, NULL, 1));//RWC;tag->code); fprintf (src," (tagId%d == MAKE_TAG_ID (%s, %s, %s))", tagLevel, classStr, Form2FormStr (CONS), DetermineCode(tag, NULL, 1));//RWC;tag->code); } else fprintf (src," if ((tagId%d == MAKE_TAG_ID (%s, %s, %s))", tagLevel, classStr, formStr, DetermineCode(tag, NULL, 1));//RWC;tag->code); } fprintf (src,")\n"); fprintf (src, " {\n"); fprintf (src, " elmtLen%d = %sDecLen (b, &totalElmtsLen%d, env);\n", ++elmtLevel, GetEncRulePrefix(), totalLevel); AsnListFirst (tags); AsnListNext (tags); FOR_REST_LIST_ELMT (tag, tags) { tagLevel = initialTagLevel+2; fprintf (src, " tagId%d = %sDecTag (b, &totalElmtsLen%d, env);\n\n", tagLevel, GetEncRulePrefix(), totalLevel); classStr = Class2ClassStr (tag->tclass); codeStr = DetermineCode(tag, NULL, 0);//RWC;Code2UnivCodeStr (tag->code); formStr = Form2FormStr (tag->form); if (tag->tclass == UNIV) { if (tag->form == ANY_FORM) { fprintf (src," if ((tagId%d != MAKE_TAG_ID (%s, %s, %s)) ||\n", tagLevel, classStr, Form2FormStr (PRIM), codeStr); fprintf (src," (tagId%d != MAKE_TAG_ID (%s, %s, %s)))\n", tagLevel, classStr, Form2FormStr (CONS), codeStr); } else fprintf (src," if (tagId%d != MAKE_TAG_ID (%s, %s, %s))\n", tagLevel, classStr, formStr, codeStr); } else { if (tag->form == ANY_FORM) { fprintf (src," if ((tagId%d != MAKE_TAG_ID (%s, %s, %s)) ||\n", tagLevel, classStr, Form2FormStr (PRIM), DetermineCode(tag, NULL, 1));//RWC;tag->code); fprintf (src," (tagId%d != MAKE_TAG_ID (%s, %s, %s)))\n", tagLevel, classStr, Form2FormStr (CONS), DetermineCode(tag, NULL, 1));//RWC;tag->code); } else fprintf (src," if (tagId%d != MAKE_TAG_ID (%s, %s, %s))\n", tagLevel, classStr, formStr, DetermineCode(tag, NULL, 1));//RWC;tag->code); } fprintf (src," {\n"); fprintf (src," Asn1Error (\"Unexpected Tag\\n\");\n"); fprintf (src," longjmp (env, %d);\n", (int)(*longJmpValG)--); fprintf (src," }\n\n"); fprintf (src," elmtLen%d = %sDecLen (b, &totalElmtsLen%d, env);\n", ++elmtLevel, GetEncRulePrefix(), totalLevel); } } if (stoleChoiceTags) { fprintf (src, " elmtLen%d = %sDecLen (b, &totalElmtsLen%d, env);\n", ++elmtLevel, GetEncRulePrefix(), totalLevel); } strcpy (tmpVarName, "(*tmpVar)"); fprintf (src," tmpVar = (%s**) AsnListAppend (%s);\n", ctri->cTypeName, varName); fprintf (src, " %s = (%s*) Asn1Alloc (sizeof (%s));\n", tmpVarName, ctri->cTypeName, ctri->cTypeName); fprintf (src," CheckAsn1Alloc (%s, env);\n", tmpVarName); PrintCElmtDecodeCode (src, td, list, list->basicType->a.setOf, elmtLevel, totalLevel, tagLevel, varName, tmpVarName, stoleChoiceTags); /* * must check for another EOC for ANYs * Since the any decode routines * decode their own first tag/len pair */ if ((builtinType == BASICTYPE_ANY) || (builtinType == BASICTYPE_ANYDEFINEDBY)) PrintEocDecoders (src, elmtLevel, initialElmtLevel, itemLenVarNameG, totalLevel, decodedLenVarNameG); /* * must check for another EOC for tagged CHOICEs * since the choice decoder routines do not check * for an EOC on the choice's overall length - * they are only passed the tag/len of the choice's * component. */ else if ((builtinType == BASICTYPE_CHOICE) && (!stoleChoiceTags) && ((tags != NULL) && !LIST_EMPTY (tags))) PrintEocDecoders (src, elmtLevel, initialElmtLevel, itemLenVarNameG, totalLevel, decodedLenVarNameG); else PrintEocDecoders (src, elmtLevel-1, initialElmtLevel, itemLenVarNameG, totalLevel, decodedLenVarNameG); if ((!stoleChoiceTags) && (!taglessAny)) { fprintf (src, " } /* end of tag check if */\n"); fprintf (src, " else /* wrong tag */\n"); fprintf (src," {\n"); fprintf (src," Asn1Error (\"Unexpected Tag\\n\");\n"); fprintf (src," longjmp (env, %d);\n", (int)(*longJmpValG)--); fprintf (src," }\n"); } fprintf (src, " } /* end of for */\n\n"); FreeTags (tags); } /* PrintCListDecodeCode */ /* * t is the choice type pointer */ static void PrintCChoiceDecodeCode PARAMS ((src, td, t, elmtLevel, totalLevel, tagLevel, varName), FILE *src _AND_ TypeDef *td _AND_ Type *t _AND_ int elmtLevel _AND_ int totalLevel _AND_ int tagLevel _AND_ char *varName) { NamedType *e; CTRI *ctri; TagList *tags; Tag *tag; enum BasicTypeChoiceId builtinType; char *classStr; char *formStr; char *codeStr; char tmpVarName[MAX_VAR_REF]; char choiceIdVarName[MAX_VAR_REF]; int stoleChoiceTags; void *tmp; int initialTagLevel; int initialElmtLevel; initialTagLevel = tagLevel; initialElmtLevel = elmtLevel; fprintf (src, " switch (tagId%d)\n", tagLevel); fprintf (src, " {\n"); FOR_EACH_LIST_ELMT (e, t->basicType->a.choice) { /* hack ! remember curr loc cause called routine hacks it */ tmp = (void*)CURR_LIST_NODE (t->basicType->a.choice); tagLevel = initialTagLevel; elmtLevel = initialElmtLevel; if ((e->type == NULL) || (e->type->cTypeRefInfo == NULL)) { fprintf (src, "< ERROR - no c type information - prob unsuported type>\n"); continue; } if(e->type->extensionAddition) { fprintf(src, "< ERROR - extensibility unsupported in c-library>\n"); continue; } ctri = e->type->cTypeRefInfo; tags = GetTags (e->type, &stoleChoiceTags); builtinType = GetBuiltinType (e->type); if ((tags == NULL) || LIST_EMPTY (tags)) { if ((builtinType != BASICTYPE_ANY) && (builtinType != BASICTYPE_ANYDEFINEDBY)) { if(e->type->extensionAddition) { fprintf (src, "\n"); fprintf (src, "<--Suggest removing extension marker and making all respective extension additions optional>\n"); } else { fprintf (src, "\n"); } } else { fprintf (src, " /* You must hand code ANY type refs */\n"); fprintf (src," case MAKE_TAG_ID (?, ?, ?):\n"); } } else { tag = (Tag*)FIRST_LIST_ELMT (tags); classStr = Class2ClassStr (tag->tclass); codeStr = DetermineCode(tag, NULL, 0);//RWC;Code2UnivCodeStr (tag->code); formStr = Form2FormStr (tag->form); if (tag->tclass == UNIV) { if (tag->form == ANY_FORM) { fprintf (src," case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (PRIM), codeStr); fprintf (src," case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (CONS), codeStr); } else fprintf (src," case MAKE_TAG_ID (%s, %s, %s):\n", classStr, formStr, codeStr); } else { if (tag->form == ANY_FORM) { fprintf (src," case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (PRIM), DetermineCode(tag, NULL, 1));//RWC;tag->code); fprintf (src," case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (CONS), DetermineCode(tag, NULL, 1));//RWC;tag->code); } else fprintf (src," case MAKE_TAG_ID (%s, %s, %s):\n", classStr, formStr, DetermineCode(tag, NULL, 1));//RWC;tag->code); } AsnListFirst (tags); AsnListNext (tags); /* set curr ptr to 2nd elmt */ FOR_REST_LIST_ELMT (tag, tags) { classStr = Class2ClassStr (tag->tclass); codeStr = DetermineCode(tag, NULL, 0);//RWC;Code2UnivCodeStr (tag->code); formStr = Form2FormStr (tag->form); if (stoleChoiceTags) { if (tag->tclass == UNIV) { if (tag->form == ANY_FORM) { fprintf (src," case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (PRIM), codeStr); fprintf (src," case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (CONS), codeStr); } else fprintf (src," case MAKE_TAG_ID (%s, %s, %s):\n", classStr, formStr, codeStr); } else { codeStr = DetermineCode(tag, NULL, 1); if (tag->form == ANY_FORM) { fprintf (src," case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (PRIM), codeStr);//RWC;tag->code); fprintf (src," case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (CONS), codeStr);//RWC;tag->code); } else fprintf (src," case MAKE_TAG_ID (%s, %s, %s):\n", classStr, formStr, codeStr);//RWC;tag->code); } } else { tagLevel = initialTagLevel +1; if (tag->form == ANY_FORM) { fprintf (src," tagId%d = %sDecTag (b, &totalElmtsLen%d, env);\n", tagLevel, GetEncRulePrefix(), totalLevel); if (tag->tclass == UNIV) { fprintf (src,"if ((tagId%d != MAKE_TAG_ID (%s, %s, %s)) &&\n", tagLevel, classStr, Form2FormStr (PRIM), codeStr); fprintf (src," (tagId%d != MAKE_TAG_ID (%s, %s, %s)))\n", tagLevel, classStr, Form2FormStr (CONS), codeStr); } else { codeStr = DetermineCode(tag, NULL, 1); fprintf (src,"if ((tagId%d != MAKE_TAG_ID (%s, %s, %s)) &&\n", tagLevel, classStr, Form2FormStr (PRIM), codeStr);//RWC;tag->code); fprintf (src," (tagId%d != MAKE_TAG_ID (%s, %s, %s)))\n", tagLevel, classStr, Form2FormStr (CONS), codeStr);//RWC;tag->code); } } else { if (tag->tclass == UNIV) fprintf (src,"if ((tagId%d = %sDecTag (b, &totalElmtsLen%d, env)) != MAKE_TAG_ID (%s, %s, %s))\n", tagLevel, GetEncRulePrefix(), totalLevel, classStr, formStr, codeStr); else { codeStr = DetermineCode(tag, NULL, 1); fprintf (src,"if ((tagId%d = %sDecTag (b, &totalElmtsLen%d, env)) != MAKE_TAG_ID (%s, %s, %s))\n", tagLevel, GetEncRulePrefix(), totalLevel, classStr, formStr, codeStr); } } fprintf (src," {\n"); fprintf (src," Asn1Error (\"Unexpected Tag\\n\");\n"); fprintf (src," longjmp (env, %d);\n", (int)(*longJmpValG)--); fprintf (src," }\n\n"); fprintf (src," elmtLen%d = %sDecLen (b, &totalElmtsLen%d, env);\n", ++elmtLevel, GetEncRulePrefix(), totalLevel); } } } MakeChoiceIdValueRef (genDecCRulesG, td, t, e->type, varName, choiceIdVarName); fprintf (src, " %s = %s;\n", choiceIdVarName, ctri->choiceIdSymbol); MakeVarPtrRef (genDecCRulesG, td, t, e->type, varName, tmpVarName); PrintElmtAllocCode (src, e->type, tmpVarName); PrintCElmtDecodeCode (src, td, t, e->type, elmtLevel, totalLevel, tagLevel, varName, tmpVarName, stoleChoiceTags); /* * this is slightly diff from set/seq since * no loop checking for eoc (set) and no next elmt (seq) * so should check elmtLen0 for EOC if nec * (therefore (initialElmtLevel-1) instead of initialElmtLevel) * * must check for another EOC for ANYs * Since the any decode routines * decode their own first tag/len pair */ if ((builtinType == BASICTYPE_ANY) || (builtinType == BASICTYPE_ANYDEFINEDBY)) PrintEocDecoders (src, elmtLevel, initialElmtLevel-1, itemLenVarNameG, totalLevel, decodedLenVarNameG); /* * must check for another EOC for tagged CHOICEs * since the choice decoder routines do not check * for an EOC on the choice's overall length - * they are only passed the tag/len of the choice's * component. */ else if ((builtinType == BASICTYPE_CHOICE) && (!stoleChoiceTags) && ((tags != NULL) && !LIST_EMPTY (tags))) PrintEocDecoders (src, elmtLevel, initialElmtLevel-1, itemLenVarNameG, totalLevel, decodedLenVarNameG); else PrintEocDecoders (src, elmtLevel-1, initialElmtLevel-1, itemLenVarNameG, totalLevel, decodedLenVarNameG); FreeTags (tags); fprintf (src," break;\n\n"); /* reset curr list node to value remember at beg of loop */ SET_CURR_LIST_NODE (t->basicType->a.choice, tmp); } /* end for */ fprintf (src," default:\n"); fprintf (src," Asn1Error (\"ERROR - unexpected tag in CHOICE\\n\");\n"); fprintf (src," longjmp (env, %d);\n",(int)(*longJmpValG)--); fprintf (src," break;\n"); fprintf (src, " } /* end switch */\n"); } /* PrintCChoiceDecodeCode */ /*static void PrintCLenDecodingCode PARAMS ((f), FILE *f) { fprintf (f, " itemLen += %sDecDefLen (b, itemLen);", GetEncRulePrefix()); } PrintCLenDecodingCode */ esnacc-ng-1.8.1/compiler/back-ends/c-gen/gen-enc.c000066400000000000000000001162521302010526100214660ustar00rootroot00000000000000/* * compiler/back-ends/c-gen/gen-enc.c - routines for printing c encoders from type trees * * Mike Sample * 91/09/26 * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/back-ends/c-gen/gen-enc.c,v 1.18 2004/03/25 19:20:16 gronej Exp $ * $Log: gen-enc.c,v $ * Revision 1.18 2004/03/25 19:20:16 gronej * fixed some linux warnings * * Revision 1.17 2004/03/12 18:51:20 gronej * updated c-library to error on extension additions as it does with untagged elements * * Revision 1.16 2004/01/14 19:07:53 gronej * Updated Compiler to accept and process relative-oid's * * Revision 1.15 2003/08/04 10:35:23 colestor * Updated several improperly referenced "b" buffer parameters when dealing with * ANY load/unloads (encode/decodes). This code has never been tested in the * "C" library. * * Revision 1.14 2003/07/31 18:33:23 colestor * Updated to reflect newly added ANY processing as AsnOcts. All built code will * now compile directly. * * Revision 1.13 2003/07/30 19:01:40 colestor * (RWC)Added ANY (not ANY DEFINED BY) default to newly added * SetAnyTypeUnknown(...). (UNTESTED) * * Revision 1.12 2003/07/28 11:13:51 colestor * Changes to complete handing of the "--snacc namespace" compiler directive. * Also, updates to handle ASN.1 constant integer tag designations for C++/C. * * Revision 1.11 2003/07/07 14:53:38 nicholar * Eliminated headers and cleaned up include references * * Revision 1.10 2003/04/29 21:03:24 leonberp * integerated Deepak's changes for IOB support * * Revision 1.9 2003/02/21 18:58:03 leonberp * removed for loop from around Asn1fFree(bufs) * * Revision 1.8 2002/10/22 14:39:40 mcphersc * Added modified DER encoding snacc generated code * * Revision 1.7 2002/10/21 17:15:43 mcphersc * fixed long int * * Revision 1.6 2002/09/16 17:34:54 mcphersc * Fixed warnings * * Revision 1.5 2002/09/04 17:59:33 vracarl * got rid of c++ comments * * Revision 1.4 2002/01/18 16:13:13 vracarl * fixed code to put in missing .bitLen code * * Revision 1.3 2000/10/24 14:54:47 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.2 2000/10/16 18:10:42 rwc * removed most warnings from C++-lib, some C-lib. * * Revision 1.1.1.1 2000/08/21 20:36:05 leonberp * First CVS Version of SNACC. * * Revision 1.5 1997/10/23 01:15:55 povey * Fixed bug where default values weren't checked properly before encoding * * Revision 1.4 1997/08/28 07:26:08 povey * Changes to support DER encoding/decoding * * Revision 1.3.1.1 1997/08/20 23:14:41 povey * * Revision 1.3 1995/07/25 18:42:24 rj * file name has been shortened for redundant part: c-gen/gen-c-enc -> c-gen/gen-enc. * * changed `_' to `-' in file names. * * Revision 1.2 1994/09/01 00:23:10 rj * snacc_config.h and other superfluous .h files removed. * * Revision 1.1 1994/08/28 09:48:24 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ /* Deepak: Formatting improved as required on 11/Feb/2003 */ #include "asn-incl.h" #include "asn1module.h" #include "rules.h" #include "util.h" #include "tag-util.h" #include "snacc-util.h" #include "enc-rules.h" EncRulesType GetEncRulesType(); void PrintConstraintValueCheckingCode PROTO ((FILE *src, TypeDef *td, Type *t, NamedType *nt)); //static int moduleImplicitTagsG; static CRules *genEncCRulesG; static char* bufNameG = "b"; extern char *valueArgNameG; char *encodedLenVarNameG = "totalLen"; char *itemLenNameG = "itemLen"; char *listComponentNameG = "component"; char *listLenNameG = "listLen"; char *returnTypeG = "AsnLen"; extern char *bufTypeNameG; extern char *lenTypeNameG; extern char *tagTypeNameG; extern char *envTypeNameG; void PrintCValueInstantiation PROTO ((FILE *hdr, CRules *r, Value *v)); /* non-exported prototypes */ static void PrintCEncoderPrototype PROTO ((FILE *hdr, TypeDef *td)); static void PrintCEncoderDeclaration PROTO ((FILE *src, TypeDef *td)); static void PrintCEncoderDefine PROTO ((FILE *src, TypeDef *td)); static void PrintCEncoderLocals PROTO ((FILE *src, TypeDef *td)); static void PrintCElmtsEncodeCode PROTO ((FILE *src, TypeDef *td, Type *parent, NamedTypeList *e, int level, char *varName)); static void PrintCElmtEncodeCode PROTO ((FILE *src, TypeDef *td, Type *parent, NamedType *e, int level, char *varName)); static void PrintCListEncoderCode PROTO ((FILE *src, TypeDef *td, Type *t, int level, char *varName)); static void PrintCChoiceEncodeCode PROTO ((FILE *src, TypeDef *td, Type *t, int level, char *varName)); static void PrintCTagAndLenEncodingCode PROTO ((FILE *src, TypeDef *td, Type *t)); static void PrintEocEncoders PROTO ((FILE *src, TypeDef *td, Type *t)); static void PrintCLenEncodingCode PROTO ((FILE *f, int isCons, int isShort)); static void PrintCTagAndLenList PROTO ((FILE *src, Type *t,TagList *tg)); // Deepak:18/Apr/2003 static void PrintCMacroElmtsEncodeCode PROTO ((FILE *src, TypeDef *td, Type *parent, MacroType *mt, int level, char *varName)); static void PrintCRosOperationElmtsEncodeCode PROTO ((FILE *src, TypeDef *td, Type *parent, MacroType *mt, RosOperationMacroType *op, int level, char *varName)); // Deepak: 31/Mar/2003 // Following 4 func's are similar to that in gen-dec.c static void PrintCEncoderTableConsType PROTO ((FILE *src, FILE *hdr, Module *m, TypeDef *td, Type *t, NamedType *nt)); static void PrintCEncoderTableConsBasicType PROTO ((FILE *src, FILE *hdr, Module *m, TypeDef *td, Type *t, NamedType *nt, BasicType *bt)); static void PrintCEncoderTableConsElmtTypes PROTO ((FILE *src, FILE *hdr, Module *m, TypeDef *td, NamedTypeList *e)); static void PrintCEncoderTableConsElmtType PROTO ((FILE *src, FILE *hdr, Module *m, TypeDef *td, NamedType *n)); void // Deepak: 25/Mar/2003 PrintCTableConstraintEncoder PARAMS ((src, hdr, m, td), FILE *src _AND_ FILE *hdr _AND_ Module *m _AND_ TypeDef *td) { fprintf (hdr, "%s %s%s_TableCons(%s %s,%s *v);\n", returnTypeG, GetEncRulePrefix(), td->cTypeDefInfo->encodeRoutineName, bufTypeNameG, bufNameG, td->cTypeDefInfo->cTypeName); fprintf (hdr, "\n"); fprintf (src, "%s %s%s_TableCons(%s %s,%s *v)\n", returnTypeG, GetEncRulePrefix(), td->cTypeDefInfo->encodeRoutineName, bufTypeNameG, bufNameG, td->cTypeDefInfo->cTypeName); fprintf (src, "{\n"); fprintf (src, "\t%s totalLen = 0;\n", returnTypeG); fprintf (src, "\t%s itemLen = 0;\n", returnTypeG); fprintf (src, "\t%s index;\n", returnTypeG); fprintf (src, "\n"); // Check each field here PrintCEncoderTableConsType(src, hdr, m, td, td->type, NULL); fprintf (src, "\treturn totalLen;\n"); fprintf (src,"} /* %s%s_TableCons */", GetEncRulePrefix(), td->cTypeDefInfo->encodeRoutineName); fprintf (src,"\n\n"); } /* PrintCTableConstraintEncoder */ static void // Deepak: 25/Mar/2003 PrintCEncoderTableConsType PARAMS ((src, hdr, m, td, t, nt), FILE *src _AND_ FILE *hdr _AND_ Module *m _AND_ TypeDef *td _AND_ Type *t _AND_ NamedType *nt) { if(t == NULL) return; PrintCEncoderTableConsBasicType(src, hdr, m, td, t, nt, t->basicType); } /* PrintCEncoderTableConsType */ static void // Deepak: 25/Mar/2003 PrintCEncoderTableConsBasicType PARAMS ((src, hdr, m, td, t, nt, bt), FILE *src _AND_ FILE *hdr _AND_ Module *m _AND_ TypeDef *td _AND_ Type *t _AND_ NamedType *nt _AND_ BasicType *bt) { if(bt == NULL) return; switch (bt->choiceId) { case BASICTYPE_SEQUENCET: // Deepak: added on 29/Nov/2002 case BASICTYPE_SEQUENCE: case BASICTYPE_SET: case BASICTYPE_CHOICE: // Deepak: process the elements in sequence etc here. PrintCEncoderTableConsElmtTypes (src, hdr, m, td, bt->a.set); break; case BASICTYPE_SEQUENCEOF: case BASICTYPE_SETOF: //TypeLinkType (m, currMod, head, bt->a.setOf); break; case BASICTYPE_INTEGER: PrintConstraintValueCheckingCode(src, td, t, nt); break; case BASICTYPE_OBJECTCLASSFIELDTYPE: // if(nt->type->basicType->choiceId == 0) { char* objSetName = t->tableConstraint->objSetAssignment->objectSetName; char* typeName = nt->type->typeName; fprintf (src, "\tif(%s[index].m.%sPresent)\n", objSetName, typeName); fprintf (src, "\t{\n"); fprintf (src, "\t\titemLen = %s[index].m.encode%s(%s,%s[index].%s);\n", objSetName, typeName, bufNameG, objSetName, typeName); fprintf (src, "\t\tv->%s.octetLen = itemLen;\n", nt->fieldName); fprintf (src, "\t\tv->%s.octs = Asn1Alloc(itemLen);\n", nt->fieldName); fprintf (src, "\t\tmemcpy(v->%s.octs,b->dataStart,itemLen);\n", nt->fieldName); fprintf (src, "\t\ttotalLen += itemLen;\n"); fprintf (src, "\t}\n"); fprintf (src, "\n"); } break; default: break; } } /* PrintCEncoderTableConsBasicType */ static void // Deepak: 25/Mar/2003 PrintCEncoderTableConsElmtTypes PARAMS ((src, hdr, m, td, e), FILE *src _AND_ FILE *hdr _AND_ Module *m _AND_ TypeDef *td _AND_ NamedTypeList *e) { NamedType *n; FOR_EACH_LIST_ELMT (n, e) { PrintCEncoderTableConsElmtType (src, hdr, m, td, n); } } /* PrintCEncoderTableConsElmtTypes */ static void // Deepak: 25/Mar/2003 PrintCEncoderTableConsElmtType PARAMS ((src, hdr, m, td, n), FILE *src _AND_ FILE *hdr _AND_ Module *m _AND_ TypeDef *td _AND_ NamedType *n) { if(n->type->tableConstraint) { fprintf (src, "\t/* Check %s */\n", n->fieldName); PrintCEncoderTableConsType (src, hdr, m, td, n->type, n); } } /* PrintCEncoderTableConsElmtType */ void PrintCEncoder PARAMS ((src, hdr, r, m, td), FILE *src _AND_ FILE *hdr _AND_ CRules *r _AND_ Module *m _AND_ TypeDef *td) { CTDI *ctdi; TagList *tags = NULL; Tag *tag; char *formStr; char *classStr; int tagLen; int stoleChoiceTags; EncRulesType* encoding; char *pszCode=NULL; ctdi = td->cTypeDefInfo; if (!ctdi->genEncodeRoutine) return; /* Generate encoders for each encoding rule required */ encoding = GetEncRules(); while (SetEncRules(*encoding)) { encoding++; /* * if is type that refs another pdu type or lib type * without generating a new type via tagging or named elmts * print define to the hdr file * (a type is a pdu by default if it is ref'd by an ANY) */ if (!IsNewType (td->type) && (!IsTypeRef (td->type) || (IsTypeRef (td->type) && (td->type->basicType->a.localTypeRef->link->cTypeDefInfo->isPdu || ((td->type->basicType->a.localTypeRef->link->anyRefs != NULL) && !LIST_EMPTY (td->type->basicType->a.localTypeRef->link->anyRefs)))))) { fprintf(hdr,"#define %s%s\t%s%s\n", GetEncRulePrefix(), td->cTypeDefInfo->encodeRoutineName, GetEncRulePrefix(), td->type->cTypeRefInfo->encodeRoutineName); return; } fprintf(hdr, "%s %s%s(%s b,%s *v);\n\n", lenTypeNameG, GetEncRulePrefix(), ctdi->encodeRoutineName, bufTypeNameG, ctdi->cTypeName); fprintf(src, "%s %s%s(", lenTypeNameG, GetEncRulePrefix(), ctdi->encodeRoutineName); fprintf(src, "%s b,",bufTypeNameG); fprintf(src, "%s *v)\n",ctdi->cTypeName); fprintf(src, "{\n"); fprintf(src, " %s l=0;\n", lenTypeNameG); PrintEocEncoders (src, td, td->type); fprintf (src, " l = %s%sContent (b,v);\n", GetEncRulePrefix(), ctdi->encodeRoutineName); /* encode each tag/len pair if any */ tags = GetTags (td->type, &stoleChoiceTags); if (! stoleChoiceTags) { FOR_EACH_LIST_ELMT_RVS (tag, tags) { classStr = Class2ClassStr (tag->tclass); if (tag->form == ANY_FORM) tag->form = PRIM; formStr = Form2FormStr (tag->form); tagLen = TagByteLen (tag->code); if (tag->form == CONS) fprintf (src, " l += %sEncConsLen(b,l);\n", GetEncRulePrefix()); else fprintf (src, " l += %sEncDefLen(b,l);\n", GetEncRulePrefix()); if (tag->tclass == UNIV) pszCode = DetermineCode(tag, &tagLen, 0); else pszCode = DetermineCode(tag, &tagLen, 1); fprintf (src, " l += %sEncTag%d(b,%s,%s,%s);\n", GetEncRulePrefix(), tagLen, classStr, formStr, pszCode); } } fprintf (src, " return l;\n"); fprintf (src, "} /* %s%s */\n\n", GetEncRulePrefix(), ctdi->encodeRoutineName); FreeTags (tags); } } /* PrintCEncoder */ void PrintCContentEncoder PARAMS ((src, hdr, r, m, td), FILE *src _AND_ FILE *hdr _AND_ CRules *r _AND_ Module *m _AND_ TypeDef *td) { CTDI *ctdi; CTypeId rhsTypeId; /* cTypeId of the type that defined this typedef */ EncRulesType* encoding; genEncCRulesG = r; ctdi = td->cTypeDefInfo; if (!ctdi->genEncodeRoutine) return; rhsTypeId = td->type->cTypeRefInfo->cTypeId; /* Generate encoders for each encoding rule required */ encoding = GetEncRules(); while (SetEncRules(*encoding)) { encoding++; switch(rhsTypeId) { case C_ANY: fprintf (hdr, "/* ANY - Fix Me! */\n"); /* * Note - ANY's don't have the 'Content' suffix cause they * encode their tags and lengths */ fprintf(hdr, "#define %s%s\t%s%s\n", GetEncRulePrefix(), td->cTypeDefInfo->encodeRoutineName, GetEncRulePrefix(), td->type->cTypeRefInfo->encodeRoutineName); /* fprintf(hdr, "#define %s%s( b, v) ", GetEncRulePrefix(), td->cTypeDefInfo->encodeRoutineName); fprintf (hdr, "%s%s (b, v)", GetEncRulePrefix(), td->type->cTypeRefInfo->encodeRoutineName); */ break; case C_LIB: case C_TYPEREF: PrintCEncoderDefine (hdr, td); fprintf (hdr,"\n"); break; case C_CHOICE: PrintCEncoderPrototype (hdr, td); PrintCEncoderDeclaration (src, td); fprintf (src,"{\n"); PrintCEncoderLocals (src, td); fprintf (src,"\n\n"); // Call Enc_TableCons function here /* if(td->bHasTableConstraint) { fprintf (src,"\tif(!%s%s_TableCons(b, v))\n", GetEncRulePrefix(), td->cTypeDefInfo->encodeRoutineName); fprintf (src,"\t\treturn 0;\n\n"); } */ PrintCChoiceEncodeCode (src, td, td->type, FIRST_LEVEL, valueArgNameG); fprintf (src,"\treturn %s;\n\n", encodedLenVarNameG); fprintf (src,"} /* %s%sContent */", GetEncRulePrefix(), td->cTypeDefInfo->encodeRoutineName); fprintf (hdr,"\n\n"); fprintf (src,"\n\n"); break; case C_STRUCT: PrintCEncoderPrototype (hdr, td); PrintCEncoderDeclaration (src, td); fprintf (src,"{\n"); PrintCEncoderLocals (src, td); fprintf (src,"\n\n"); // Call Enc_TableCons function here /* if(td->bHasTableConstraint) { fprintf (src,"\tif(!%s%s_TableCons(b, v))\n", GetEncRulePrefix(), td->cTypeDefInfo->encodeRoutineName); fprintf (src,"\treturn 0;\n"); } */ PrintCElmtsEncodeCode (src, td, td->type, td->type->basicType->a.set, FIRST_LEVEL, valueArgNameG); fprintf (src,"\treturn %s;\n\n", encodedLenVarNameG); fprintf (src,"} /* %s%sContent */", GetEncRulePrefix(), td->cTypeDefInfo->encodeRoutineName); fprintf (hdr,"\n\n"); fprintf (src,"\n\n"); break; case C_LIST: PrintCEncoderPrototype (hdr, td); fprintf (hdr,"\n\n"); PrintCEncoderDeclaration (src, td); fprintf (src,"{\n"); PrintCEncoderLocals (src, td); fprintf (src,"\n\n"); // Call Enc_TableCons function here // if(td->bHasTableConstraint) // { // fprintf (src,"\tif(!%s%s_TableCons(b, v))\n", GetEncRulePrefix(), td->cTypeDefInfo->encodeRoutineName); // fprintf (src,"\treturn 0;\n"); // } PrintCListEncoderCode (src, td, td->type, FIRST_LEVEL, valueArgNameG); fprintf (src,"\treturn %s;\n\n", listLenNameG); fprintf (src,"} /* %s%sContent */", GetEncRulePrefix(), td->cTypeDefInfo->encodeRoutineName); fprintf (src,"\n\n"); break; case C_MACROTYPE: PrintCEncoderPrototype (hdr, td); PrintCEncoderDeclaration (src, td); fprintf (src,"{\n"); PrintCEncoderLocals (src, td); fprintf (src,"\n\n"); PrintCMacroElmtsEncodeCode (src, td, td->type, td->type->basicType->a.macroType, FIRST_LEVEL, valueArgNameG); fprintf (src,"\treturn %s;\n\n", encodedLenVarNameG); fprintf (src,"} /* %s%sContent */", GetEncRulePrefix(), td->cTypeDefInfo->encodeRoutineName); fprintf (hdr,"\n\n"); fprintf (src,"\n\n"); break; case C_NO_TYPE: /* fprintf (src," sorry, unsupported type \n\n"); */ break; default: fprintf (errFileG, "PrintCEncoder: ERROR - unknown c type id\n"); break; } } m = m; /* AVOIDS warning. */ } /* PrintCContentEncoder */ /* * Prints prototype for encode routine in hdr file */ static void PrintCEncoderPrototype PARAMS ((hdr, td), FILE *hdr _AND_ TypeDef *td) { CTDI *ctdi; ctdi = td->cTypeDefInfo; //fprintf (hdr,"%s %s%sContent PROTO ((%s b, %s *v));", returnTypeG, GetEncRulePrefix(), ctdi->encodeRoutineName, bufTypeNameG, ctdi->cTypeName); fprintf (hdr,"%s %s%sContent(%s b,%s *v);", returnTypeG, GetEncRulePrefix(), ctdi->encodeRoutineName, bufTypeNameG, ctdi->cTypeName); } /* PrintCEncoderPrototype */ /* * Prints declarations of encode routine for the given type def */ static void PrintCEncoderDeclaration PARAMS ((src, td), FILE *src _AND_ TypeDef *td) { CTDI *ctdi; ctdi = td->cTypeDefInfo; // fprintf (src,"%s\n%s%sContent PARAMS ((b, v),\n%s b _AND_\n%s *v)\n", returnTypeG, GetEncRulePrefix(), ctdi->encodeRoutineName, bufTypeNameG, ctdi->cTypeName);ctdi = td->cTypeDefInfo; fprintf (src,"%s %s%sContent(%s b,%s *v)\n", returnTypeG, GetEncRulePrefix(), ctdi->encodeRoutineName, bufTypeNameG, ctdi->cTypeName); } /* PrintCEncoderDeclaration */ /* * makes a define for type refs or primitive type renaming * EG: * TypeX ::= INTEGER --> #define BerEncodeTypeX(b,v) BerEncodeInteger(b,v) * TypeX ::= TypeY --> #define BerEncodeTypeX(b,v) BerEncodeTypeY(b,v) */ static void PrintCEncoderDefine PARAMS ((hdr, td), FILE *hdr _AND_ TypeDef *td) { fprintf(hdr, "#define %s%sContent %s%sContent", GetEncRulePrefix(), td->cTypeDefInfo->encodeRoutineName, GetEncRulePrefix(), td->type->cTypeRefInfo->encodeRoutineName); /* fprintf(hdr, "#define %s%sContent( b, v) ", GetEncRulePrefix(), td->cTypeDefInfo->encodeRoutineName); fprintf (hdr, "%s%sContent (b, v)", GetEncRulePrefix(), td->type->cTypeRefInfo->encodeRoutineName); */ } /* PrintCEncoderDefine */ static void PrintCEncoderLocals PARAMS ((src, td), FILE *src _AND_ TypeDef *td) { fprintf (src, "\tAsnLen %s = 0;\n", encodedLenVarNameG); fprintf (src, "\tAsnLen %s;\n", itemLenNameG); fprintf (src, "\tAsnLen %s;\n", listLenNameG); fprintf (src, "\tvoid *%s;", listComponentNameG); td = td; /* AVOIDS warning. */ } /* PrintCEncoderLocals */ /* Compare the tags of two NamedTypes */ static int ElmtsTagCmp(const void *a, const void *b) { NamedType **at = (NamedType **)a; NamedType **bt = (NamedType **)b; return CmpTags((*at)->type, (*bt)->type); } /* * runs through elmts backwards and prints * encoding code for each one */ static void PrintCElmtsEncodeCode PARAMS ((src, td, parent, elmts, level, varName), FILE *src _AND_ TypeDef *td _AND_ Type *parent _AND_ NamedTypeList *elmts _AND_ int level _AND_ char *varName) { NamedType *e; NamedType **elmtlist; int i=0; if (elmts == NULL) { fprintf (src,"/* ERROR? - expected elmts for this type*/\n"); return; } /* If the encoding rules to be used are DER and we are generating * an encoder for a SET, the SET must be encoded in tag order, therefore * we must sort the elements */ if (GetEncRulesType() == DER && parent->basicType->choiceId == BASICTYPE_SET) { /* Put all the elements in the array */ elmtlist = (NamedType **)Asn1Alloc(sizeof(NamedType *) * AsnListCount(elmts)); FOR_EACH_LIST_ELMT (e, elmts) { elmtlist[i]=e; i++; } /* Sort list */ qsort(elmtlist, i, sizeof(NamedType*), ElmtsTagCmp); /* Generate encoders (backwards) */ for (i--; i>=0; i--) { PrintCElmtEncodeCode (src, td, parent, elmtlist[i], level, varName); } /* Free list */ Asn1Free(elmtlist); } else { /* * remember! encoding "backwards" so recursively traverse * list backwards */ FOR_EACH_LIST_ELMT_RVS (e, elmts) { if(e->type->basicType->choiceId == BASICTYPE_OBJECTCLASSFIELDTYPE) { // Deepak: 01/Apr/2003 fprintf (src, "\t/*~~~~~~~~~~~~~~~~~~ Now encode the OpenType parameter here ~~~~~~~~~~~~~~~~~~*/\n"); PrintConstraintValueCheckingCode(src, td, e->type, e); fprintf (src, "\titemLen = %s[index].encode%s(b,&v->%s);\n", e->type->tableConstraint->objSetAssignment->objectSetName, e->type->typeName, e->fieldName); fprintf (src, "\titemLen += BEncConsLen(b,itemLen);\n"); // RWC;NOTE; FOR constant value name interpretation to a value for // RWC;NOTE; tags may have to be interpreted before the "%s[index]" // RWC;NOTE; is loaded. (NOT SURE YET!) fprintf (src, "\titemLen += BEncTag1(b,UNIV,PRIM,%s[index].tag);\n", e->type->tableConstraint->objSetAssignment->objectSetName); fprintf (src, "\ttotalLen += itemLen;\n"); fprintf (src, "\n"); fprintf (src, "\t/*~~~~~~~~~~~~~~~~~~ Till Here ~~~~~~~~~~~~~~~~~~*/\n"); fprintf (src, "\n"); continue; } PrintCElmtEncodeCode (src, td, parent, e, level, varName); } } } /* PrintCElmtsEncodeCode */ /* * Prints code for encoding the elmts of a SEQ or SET */ static void PrintCElmtEncodeCode PARAMS ((src, td, parent, e, level, varName), FILE *src _AND_ TypeDef *td _AND_ Type *parent _AND_ NamedType *e _AND_ int level _AND_ char *varName) { CTRI *ctri; char elmtVarRef[MAX_VAR_REF]; char idVarRef[MAX_VAR_REF]; enum BasicTypeChoiceId tmpTypeId; Type *tmpType; NamedType *idNamedType; Value* value; if ((e->type == NULL) || (e->type->cTypeRefInfo == NULL) || (e->type->extensionAddition) ) return; ctri = e->type->cTypeRefInfo; /* check if meant to be encoded */ if (!ctri->isEncDec) return; MakeVarPtrRef (genEncCRulesG, td, parent, e->type, varName, elmtVarRef); /* If we are currently using DER and the value of a component with the * DEFAULT qualifier is the same as the default value, then we should not * encode that value */ if (e->type->defaultVal != NULL) { if (GetEncRulesType() == DER) { fprintf (src, "\tif(%s (%s) && (", ctri->optTestRoutineName, elmtVarRef); if (GetBuiltinType (e->type) == BASICTYPE_BITSTRING) { fprintf (src, "(*%s).bitLen != ", elmtVarRef); } else { fprintf (src, "*%s != ", elmtVarRef); } /* Get default value */ switch(e->type->defaultVal->value->basicValue->choiceId) { case BASICVALUE_LOCALVALUEREF: value = e->type->defaultVal->value->basicValue->a.localValueRef->link->value; break; case BASICVALUE_IMPORTVALUEREF: value = e->type->defaultVal->value->basicValue->a.importValueRef->link->value; break; default: value = e->type->defaultVal->value; } PrintCValueInstantiation(src, genEncCRulesG, value); fprintf (src, " /* DEFAULT */))\n\t{\n"); } else { fprintf (src, "\tif(%s (%s))\n\t{\n", ctri->optTestRoutineName, elmtVarRef); } } if (e->type->optional && e->type->defaultVal == NULL) fprintf (src, "\tif(%s (%s))\n\t{\n", ctri->optTestRoutineName, elmtVarRef); PrintEocEncoders (src, td, e->type); switch(ctri->cTypeId) { case C_ANYDEFINEDBY: /* get type of 'defining' field (int/enum/oid)*/ idNamedType = e->type->basicType->a.anyDefinedBy->link; tmpTypeId = GetBuiltinType (idNamedType->type); if (tmpTypeId == BASICTYPE_OID || tmpTypeId == BASICTYPE_RELATIVE_OID) { MakeVarPtrRef (genEncCRulesG, td, parent, idNamedType->type, varName, idVarRef); fprintf (src, "\tSetAnyTypeByOid(%s,%s);\n", elmtVarRef, idVarRef); } else { /* want to ref int by value not ptr */ MakeVarValueRef (genEncCRulesG, td, parent, idNamedType->type, varName, idVarRef); fprintf (src, "\tSetAnyTypeByInt(%s,%s);\n", elmtVarRef, idVarRef); } /* ANY's enc's do tag and len so zap the Content suffix */ fprintf (src, "\t%s = %s%s(b,%s);\n", itemLenNameG, GetEncRulePrefix(), ctri->encodeRoutineName, elmtVarRef); break; case C_TYPEREF: tmpType = GetType (e->type); /* NOTE: ANY DEFINED BY must be directly in the parent (not ref)*/ if (tmpType->cTypeRefInfo->cTypeId != C_ANY) { if(tmpType->basicType->choiceId == BASICTYPE_ENUMERATED) // Deepak: 19/Apr/2003 only if added, fprintf (src, "\t%s = %s%sContent(b,(AsnInt *)%s);\n", itemLenNameG, GetEncRulePrefix(), ctri->encodeRoutineName, elmtVarRef); else fprintf (src, "\t%s = %s%sContent(b,%s);\n", itemLenNameG, GetEncRulePrefix(), ctri->encodeRoutineName, elmtVarRef); break; } else /* fall through */ case C_ANY: /* ANY's enc's do tag and len so zap the Content suffix */ //RWC;fprintf (src,"\t /* ANY - Fix Me! */\n"); fprintf (src,"\tSetAnyTypeUnknown(%s);\n", elmtVarRef); //RWC;fprintf (src,"\tSetAnyTypeBy\?\?\?(%s, \?\?\?);\n", elmtVarRef); fprintf (src,"\t%s = %s%s (b, %s);\n", itemLenNameG, GetEncRulePrefix(), "EncAsnAny"/*RWC;NOT VALID FOR C_TYPEREF;ctri->encodeRoutineName*/, elmtVarRef); break; case C_LIB: fprintf (src, "\t%s = %s%sContent(b,%s);\n", itemLenNameG, GetEncRulePrefix(), ctri->encodeRoutineName, elmtVarRef); break; case C_CHOICE: PrintCChoiceEncodeCode (src, td, e->type, level+1, elmtVarRef); break; case C_STRUCT: PrintCElmtsEncodeCode (src, td, e->type, e->type->basicType->a.set, level+1, elmtVarRef); break; case C_LIST: PrintCListEncoderCode (src, td, e->type, level+1, elmtVarRef); fprintf (src, "\t%s = %s;\n", itemLenNameG, listLenNameG); fprintf (src,"\n"); break; case C_NO_TYPE: break; // case C_OBJECTCLASSFIELDTYPE: // fprintf (src, "\t%s = %s%sContent (b, %s);\n", itemLenNameG, // GetEncRulePrefix(), "AsnOcts" /*ctri->encodeRoutineName*/, elmtVarRef); // break; default: fprintf (errFileG, "PrintCElmtEncodeCode: ERROR - unknown c type id\n"); break; } /*RWC;NOT ANY LONGER;if (ctri->cTypeId != C_ANY) / * ANY's do their own tag/lens */ { PrintCTagAndLenEncodingCode (src, td, e->type); fprintf (src,"\t%s += %s;\n", encodedLenVarNameG, itemLenNameG); } if (e->type->optional || (e->type->defaultVal != NULL)) fprintf (src, "\t}\n"); fprintf (src,"\n"); } /* PrintCElmtEncodeCode */ /* * checks for which macroType is there * then calls specific function for encoding of that macro */ static void PrintCMacroElmtsEncodeCode PARAMS ((src, td, parent, mt, level, varName), FILE *src _AND_ TypeDef *td _AND_ Type *parent _AND_ MacroType *mt _AND_ int level _AND_ char *varName) { if (mt == NULL) { fprintf (src,"/* ERROR? - expected macroType for this type*/\n"); return; } switch (mt->choiceId) { // This switch case copied from do-macros.c case MACROTYPE_ASNABSTRACTOPERATION: case MACROTYPE_ROSOPERATION: PrintCRosOperationElmtsEncodeCode (src, td, parent, mt, mt->a.rosOperation, level, varName); break; // Add code for other macro types here default: // Unsupported Macro Type break; } } /* PrintCMacroElmtsEncodeCode */ static void PrintCRosOperationElmtsEncodeCode PARAMS ((src, td, parent, mt, op, level, varName), FILE *src _AND_ TypeDef *td _AND_ Type *parent _AND_ MacroType *mt _AND_ RosOperationMacroType *op _AND_ int level _AND_ char *varName) { if(op->result != NULL) { PrintCElmtEncodeCode (src, td, parent, op->result, level, varName); } if(op->arguments != NULL) { PrintCElmtEncodeCode (src, td, parent, op->arguments, level, varName); } mt=mt; } /* PrintCRosOperationElmtsEncodeCode */ /* * Generates code for internally defined lists * eg: * TypeX = SET { foo INTEGER, bar SEQUENCE OF INTEGER } --> * BerEncodeTypeX (b, v) * { * ... * listLen = 0; * FOR_EACH_LIST_ELMT (component, v->bar) * { * itemLen = BerEncodeInteger (b, (int*) component); * itemLen+= EncodeLen (b, itemLen) * itemLen += ENCODE_TAG (b, INTEGER_TAG); * listLen += itemLen; * } * ... * } */ static void PrintCListEncoderCode PARAMS ((src, td, t, level, varName), FILE *src _AND_ TypeDef *td _AND_ Type *t _AND_ int level _AND_ char *varName) { CTRI *ctri; char *elmtVarRef = "component"; Type *tmpType; char *itemLenName=NULL; ctri = t->basicType->a.setOf->cTypeRefInfo; if (ctri == NULL) return; /* IF DER, and SET OF, we need to encode in order of the DER encodings * of the elements. This first bit stuffs each encoded elmt into an * array of bufs. */ if (GetEncRulesType() == DER && t->basicType->choiceId == BASICTYPE_SETOF) { /* Print extra locals */ fprintf(src, "\tEncodedElmt *bufs;\n"); fprintf(src, "\tExpBuf *xbufp;\n"); fprintf(src, "\tint i, len1;\n\n"); fprintf (src, "\tlistLen = 0;\n"); fprintf (src, "\t/* Encode elements and stuff them in an array */\n"); fprintf (src, "\tbufs = (EncodedElmt* ) Asn1Alloc(sizeof(EncodedElmt)*AsnListCount(%s));\n", varName); fprintf (src, "\tfor (i=0; i < AsnListCount(%s); i++) {\n", varName); fprintf (src, "\t xbufp = ExpBufAllocBufAndData();;\n"); fprintf (src, "\t ExpBufResetInWriteRvsMode(xbufp);// May not need - leave in for now \n "); fprintf (src, "\t ExpBuftoGenBuf(xbufp, &bufs[i].b);\n } \n"); fprintf (src, "\ti = 0;\n"); fprintf (src, "\tFOR_EACH_LIST_ELMT_RVS (component, %s)\n", varName); fprintf (src, "\t{\n"); itemLenName = itemLenNameG; itemLenNameG = "bufs[i].len"; bufNameG = "bufs[i].b"; } else { fprintf (src, "\tlistLen = 0;\n"); fprintf (src, "\tFOR_EACH_LIST_ELMT_RVS(component,%s)\n", varName); fprintf (src, "\t{\n"); bufNameG = "b"; } fflush (src); PrintEocEncoders (src, td, t->basicType->a.setOf); /* * need extra case here for SET OF typedef not just SET OF typeref */ switch(ctri->cTypeId) { case C_TYPEREF: tmpType = GetType (t->basicType->a.setOf); /* NOTE: ANY DEFINED BY must be directly in the parent (not ref)*/ if (tmpType->cTypeRefInfo->cTypeId != C_ANY) { fprintf (src, "\t%s = %s%sContent(%s,%s);\n", itemLenNameG, GetEncRulePrefix(), ctri->encodeRoutineName, bufNameG, elmtVarRef); break; } else /* fall through */ case C_ANY: /* ANY's enc's do tag and len so zap the Content suffix */ fprintf (src,"\t /* ANY - Fix Me! */\n"); fprintf (src,"\tSetAnyTypeUnknown(%s);\n", elmtVarRef); //RWC;fprintf (src, "\tSetAnyTypeBy???(%s,???);\n", elmtVarRef); fprintf (src, "\t%s = %s%s(%s,%s);\n", itemLenNameG, GetEncRulePrefix(), ctri->encodeRoutineName, bufNameG, elmtVarRef); break; default: fprintf (src, "\t%s = %s%sContent(%s,(%s*)%s);\n", itemLenNameG, GetEncRulePrefix(), ctri->encodeRoutineName, bufNameG, ctri->cTypeName, elmtVarRef); break; } PrintCTagAndLenEncodingCode (src, td, t->basicType->a.setOf); fprintf (src,"\n"); fprintf (src, "\t%s += %s;\n", listLenNameG, itemLenNameG); if (GetEncRulesType() == DER && t->basicType->choiceId == BASICTYPE_SETOF) { fprintf (src, "\t BufResetInReadMode(bufs[i].b);\n"); fprintf (src, "\t i++;\n"); } fprintf (src, "\t}\n"); if (GetEncRulesType() == DER && t->basicType->choiceId == BASICTYPE_SETOF) { /* Sort the encoded results in the array of bufs, then stuff everything * in the output buf */ fprintf (src, "\tlen1 = i;\n"); fprintf (src, "\t/* Sort elements */\n"); fprintf (src, "\tqsort(bufs, i, sizeof(EncodedElmt), EncodedElmtCmp);\n"); fprintf (src, "\tfor (i--; i>=0; i--) {\n"); fprintf (src, "\t\tchar *dst = (char *) Asn1Alloc(bufs[i].len);\n"); fprintf (src, "\t\tBufResetInReadMode(bufs[i].b);\n"); fprintf (src, "\t\tBufCopy(dst, bufs[i].b, bufs[i].len);\n"); fprintf (src, "\t\tBufPutSegRvs(b, dst, bufs[i].len);\n"); fprintf (src, "\t\tExpBufFreeBufAndData(bufs[i].b->spare);\n"); fprintf (src, "\t};\n"); fprintf (src, "\t/* Free the EncodedElmt's */\n"); fprintf (src, "\tAsn1Free(bufs);\n"); itemLenNameG = itemLenName; bufNameG = "b"; } level = level; /* AVOIDS warning. */ } /* PrintCListEncoderCode */ static void PrintCChoiceEncodeCode PARAMS ((src, td, t, level, varName), FILE *src _AND_ TypeDef *td _AND_ Type *t _AND_ int level _AND_ char *varName) { NamedType *e; CTRI *ctri; void *tmp; ctri = t->cTypeRefInfo; fprintf (src,"\tswitch(%s->%s)\n\t{\n", varName, ctri->choiceIdEnumFieldName); FOR_EACH_LIST_ELMT (e, t->basicType->a.choice) { tmp = (void*)CURR_LIST_NODE (t->basicType->a.choice); if (e->type == NULL) continue; ctri = e->type->cTypeRefInfo; if (ctri != NULL) fprintf (src, "\t\tcase %s:\n", ctri->choiceIdSymbol); else fprintf (src, "\t\tcase ????:\n"); PrintCElmtEncodeCode (src, td, t, e, level+1, varName); fprintf (src,"\tbreak;\n\n"); SET_CURR_LIST_NODE (t->basicType->a.choice, tmp); } fprintf (src, "\t}\n"); } /* PrintCChoiceEncodeCode */ /* * prints DecodeBerEocIfNec (b) for each constructed len * assoc with given type */ static void PrintEocEncoders PARAMS ((src, td, t), FILE *src _AND_ TypeDef *td _AND_ Type *t) { TagList *tl; Tag *tag; int stoleChoiceTags; /* * get all the tags on this type */ tl = (TagList*) GetTags (t, &stoleChoiceTags); /* * leave choice elmt tag enc to encoding routine */ if (!stoleChoiceTags) { FOR_EACH_LIST_ELMT (tag, tl) { if (tag->form == CONS) fprintf (src,"\t%sEncEocIfNec(b);\n", GetEncRulePrefix()); } } /* consTagCount = 0; if (!stoleChoiceTags) { FOR_EACH_LIST_ELMT (tag, tl) consTagCount++; } if (IsPrimitiveByDefOrRef (t)) consTagCount--; for (; consTagCount > 0; consTagCount--) fprintf (src,"\t%sEncEocIfNec (b);\n", GetEncRulePrefix()); */ FreeTags (tl); td = td; /*AVOIDS warning*/ } /* PrintEocEncoders */ /* * Recursively walks throught type refs printing lower lvl tags * first (since encoding is done backwards). * */ static void PrintCTagAndLenEncodingCode PARAMS ((src, td, t), FILE *src _AND_ TypeDef *td _AND_ Type *t) { TagList *tl; int stoleChoiceTags; /* * get all the tags on this type */ tl = (TagList*) GetTags (t, &stoleChoiceTags); /* * leave choice elmt tag enc to encoding routine */ if (!stoleChoiceTags) PrintCTagAndLenList (src, t, tl); FreeTags (tl); td = td; /*AVOIDS warning*/ } /* PrintCTagAndLenEncodingCode */ /* * prints last tag's encoding code first */ static void PrintCTagAndLenList PARAMS ((src, t, tagList), FILE *src _AND_ Type *t _AND_ TagList *tagList) { char *classStr; char *formStr; Tag *tg; int tagLen; enum BasicTypeChoiceId typesType; int isShort; if ((tagList == NULL) || LIST_EMPTY (tagList)) return; /* * efficiency hack - use simple length (1 byte) * encoded for type (almost) guaranteed to have * encoded lengths of 0 <= len <= 127 */ typesType = GetBuiltinType (t); if ((typesType == BASICTYPE_BOOLEAN) || (typesType == BASICTYPE_INTEGER) || (typesType == BASICTYPE_NULL) || (typesType == BASICTYPE_REAL) || (typesType == BASICTYPE_ENUMERATED)) isShort = 1; else isShort = 0; /* * since encoding backward encode tags backwards */ FOR_EACH_LIST_ELMT_RVS (tg, tagList) { classStr = Class2ClassStr (tg->tclass); if (tg->form == CONS) { formStr = Form2FormStr (CONS); PrintCLenEncodingCode (src, TRUE, isShort); } else /* PRIM or ANY_FORM */ { formStr = Form2FormStr (PRIM); PrintCLenEncodingCode (src, FALSE, isShort); } fprintf (src,"\n"); if (tg->code < 31) tagLen = 1; else if (tg->code < 128) tagLen = 2; else if (tg->code < 16384) tagLen = 3; else if (tg->code < 2097152) tagLen = 4; else tagLen = 5; fprintf (src," %s += %sEncTag%d(%s,%s,%s,%s);\n", itemLenNameG, GetEncRulePrefix(), tagLen, bufNameG, classStr, formStr, DetermineCode(tg, &tagLen, 0)); } } /* PrintCTagAndLenList */ /* * prints length encoding code. Primitives always use * definite length and constructors get "ConsLen" * which can be configured at compile to to be indefinite * or definite. Primitives can also be "short" (isShort is true) * in which case a fast macro is used to write the length. * Types for which isShort apply are: boolean, null and * (almost always) integer and reals */ static void PrintCLenEncodingCode PARAMS ((f, isCons, isShort), FILE *f _AND_ int isCons _AND_ int isShort) { /* fprintf (f, "\t%sER_ENCODE_DEF_LEN (b, itemLen, itemLen);", GetEncRulePrefix()); */ if (isCons) fprintf (f, "\t%s += %sEncConsLen(%s,%s);", itemLenNameG, GetEncRulePrefix(), bufNameG, itemLenNameG); else { if (isShort) { fprintf (f, "\t%sEncDefLenTo127(%s,%s);\n", GetEncRulePrefix(), bufNameG, itemLenNameG); fprintf (f, "\t%s++;", itemLenNameG); } else fprintf (f, "\t%s += %sEncDefLen(%s,%s);", itemLenNameG, GetEncRulePrefix(), bufNameG, itemLenNameG); } } /* PrintCLenEncodingCode */ esnacc-ng-1.8.1/compiler/back-ends/c-gen/gen-free.c000066400000000000000000000376621302010526100216510ustar00rootroot00000000000000/* * compiler/back-ends/c-gen/gen-free.c - routines for printing C hierachical free routines * * Mike Sample * 92/04 * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/back-ends/c-gen/gen-free.c,v 1.8 2004/03/25 19:20:16 gronej Exp $ * $Log: gen-free.c,v $ * Revision 1.8 2004/03/25 19:20:16 gronej * fixed some linux warnings * * Revision 1.7 2003/07/07 14:53:38 nicholar * Eliminated headers and cleaned up include references * * Revision 1.6 2003/04/29 21:02:57 leonberp * integerated Deepak's changes for IOB support * * Revision 1.5 2002/11/01 15:05:34 mcphersc * fixed compiler warnings and errors not caught by windows compiler * * Revision 1.4 2002/10/01 13:51:39 mcphersc * Modified snacc to accept either the -I import option or the original way to list the * asn modules on the command line * * Revision 1.3 2002/09/04 18:02:11 vracarl * got rid of c++ comments * * Revision 1.2 2000/10/24 14:54:47 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:36:05 leonberp * First CVS Version of SNACC. * * Revision 1.3 1995/07/25 18:42:47 rj * file name has been shortened for redundant part: c-gen/gen-c-free -> c-gen/gen-free. * * changed `_' to `-' in file names. * * Revision 1.2 1994/09/01 00:23:29 rj * snacc_config.h and other superfluous .h files removed. * * Revision 1.1 1994/08/28 09:48:26 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ /* Deepak: Formatting improved as required on 11/Feb/2003 */ #include #include "asn-incl.h" #include "asn1module.h" #include "mem.h" #include "define.h" #include "rules.h" #include "str-util.h" #include "util.h" #ifdef WIN32 //#pragma warning( disable : 4706 ) /* IGNORE assign w/in conditional expression. */ #endif extern FILE* errFileG; // Defined in snacc.c static char *returnTypeG = "void"; static char *valueArgNameG = "v"; static CRules *genFreeCRulesG; /* non-exported prototypes */ static void PrintCFreePrototype PROTO ((FILE *hdr, TypeDef *td)); static void PrintCFreeDeclaration PROTO ((FILE *src, TypeDef *td)); static void PrintCFreeDefine PROTO ((FILE *hdr, TypeDef *td)); static void PrintCFreeLocals PROTO ((FILE *src,TypeDef *td)); static void PrintCFreeElmts PROTO ((FILE *src, TypeDef *td, Type *parent, NamedTypeList *elmts, char *varName)); static void PrintCElmtFree PROTO ((FILE *src, TypeDef *td, Type *parent, Type *e, char *varName)); static void PrintCFreeListElmts PROTO ((FILE *src, TypeDef *td, Type *t, char *varName)); static void PrintCFreeListRoutineBody PROTO ((FILE *src, TypeDef *td, Type *t,char *varName)); /*static void PrintCFreeListDefine PROTO ((FILE *hdr,TypeDef *td));*/ static void PrintCFreeChoiceElmts PROTO ((FILE *src, TypeDef *td, Type *t, char *varName)); //Deepak: 18/Apr/2003 static void PrintCFreeMacroElmts PROTO ((FILE *src, TypeDef *td, Type *parent, MacroType *mt, char *varName)); static void PrintCRosOperationElmtsFree PROTO ((FILE *src, TypeDef *td, Type *parent, MacroType *elmts, RosOperationMacroType *op, char *varName)); void PrintCFree PARAMS ((src, hdr, r, mods, m, td), FILE *src _AND_ FILE *hdr _AND_ CRules *r _AND_ ModuleList *mods _AND_ Module *m _AND_ TypeDef *td) { CTDI *ctdi; CTypeId rhsTypeId; /* cTypeId of the type that defined this typedef */ genFreeCRulesG = r; ctdi = td->cTypeDefInfo; if((ctdi == NULL) || (td->type->cTypeRefInfo == NULL)) { fprintf (errFileG, "PrintCFree: ERROR - no type info\n"); return; } if(!ctdi->genFreeRoutine) return; rhsTypeId = td->type->cTypeRefInfo->cTypeId; switch(rhsTypeId) { case C_ANY: case C_ANYDEFINEDBY: case C_LIB: case C_TYPEREF: PrintCFreeDefine (hdr, td); fprintf (hdr,"\n"); break; case C_CHOICE: PrintCFreePrototype (hdr, td); PrintCFreeDeclaration (src, td); fprintf (src,"{\n"); PrintCFreeLocals (src, td); fprintf (src,"\tif(%s == NULL)\n", valueArgNameG); fprintf (src,"\t\treturn;\n"); PrintCFreeChoiceElmts (src, td, td->type, valueArgNameG); fprintf (src,"} /* %s */",td->cTypeDefInfo->freeRoutineName); fprintf (hdr,"\n\n"); fprintf (src,"\n\n"); break; case C_STRUCT: PrintCFreePrototype (hdr, td); PrintCFreeDeclaration (src, td); fprintf (src,"{\n"); PrintCFreeLocals (src, td); fprintf (src,"\tif(%s == NULL)\n", valueArgNameG); fprintf (src,"\t\treturn;\n"); PrintCFreeElmts (src, td, td->type, td->type->basicType->a.set, valueArgNameG); fprintf (src,"} /* %s */", td->cTypeDefInfo->freeRoutineName); fprintf (hdr,"\n\n"); fprintf (src,"\n\n"); break; case C_LIST: PrintCFreePrototype (hdr, td); PrintCFreeDeclaration (src, td); fprintf (src,"{\n"); PrintCFreeLocals (src, td); fprintf (src,"\tif(%s == NULL)\n", valueArgNameG); fprintf (src,"\t\treturn;\n"); PrintCFreeListRoutineBody (src, td, td->type, valueArgNameG); fprintf (src,"} /* %s */", td->cTypeDefInfo->freeRoutineName); fprintf (hdr,"\n\n"); fprintf (src,"\n\n"); break; case C_MACROTYPE: PrintCFreePrototype (hdr, td); PrintCFreeDeclaration (src, td); fprintf (src,"{\n"); PrintCFreeLocals (src, td); fprintf (src,"\tif(%s == NULL)\n", valueArgNameG); fprintf (src,"\t\treturn;\n"); PrintCFreeMacroElmts (src, td, td->type, td->type->basicType->a.macroType, valueArgNameG); fprintf (src,"} /* %s */", td->cTypeDefInfo->freeRoutineName); fprintf (hdr,"\n\n"); fprintf (src,"\n\n"); break; case C_NO_TYPE: break; default: fprintf (errFileG, "PrintCFree: ERROR - unknown c type id\n"); break; } m=m; mods=mods; /*AVOIDS warning*/ } /* PrintCFree */ static void PrintCFreeMacroElmts PARAMS ((src, td, parent, mt, varName), FILE *src _AND_ TypeDef *td _AND_ Type *parent _AND_ MacroType *mt _AND_ char *varName) { if(mt == NULL) { fprintf (src,"/* ERROR? - expected macroType for this type*/\n"); return; } switch (mt->choiceId) { // This switch case copied from do-macros.c case MACROTYPE_ASNABSTRACTOPERATION: case MACROTYPE_ROSOPERATION: PrintCRosOperationElmtsFree (src, td, parent, mt, mt->a.rosOperation, varName); break; // Add code for other macro types here default: // Unsupported Macro Type break; } //PrintCElmtFree (src, td, parent, e->type, varName); } /* PrintCFreeMacroElmts */ static void PrintCRosOperationElmtsFree PARAMS ((src, td, parent, mt, varName), FILE *src _AND_ TypeDef *td _AND_ Type *parent _AND_ MacroType *mt _AND_ RosOperationMacroType *op _AND_ char *varName) { if(op->arguments != NULL) { PrintCElmtFree (src, td, parent, op->arguments->type, varName); } if(op->result != NULL) { PrintCElmtFree (src, td, parent, op->result->type, varName); } mt=mt; } /* PrintCRosOperationElmtsFree */ /* * Prints prototype for encode routine in hdr file */ static void PrintCFreePrototype PARAMS ((hdr, td), FILE *hdr _AND_ TypeDef *td) { CTDI *ctdi; ctdi = td->cTypeDefInfo; //fprintf (hdr,"%s %s PROTO ((%s *v));\n", returnTypeG, ctdi->freeRoutineName, ctdi->cTypeName); fprintf (hdr,"%s %s(%s *v);\n", returnTypeG, ctdi->freeRoutineName, ctdi->cTypeName); } /* PrintCFreePrototype */ /* * Prints declarations of encode routine for the given type def */ static void PrintCFreeDeclaration PARAMS ((src, td), FILE *src _AND_ TypeDef *td) { CTDI *ctdi; ctdi = td->cTypeDefInfo; // fprintf (src,"%s\n%s PARAMS ((v),\n%s *v)\n", returnTypeG, ctdi->freeRoutineName, ctdi->cTypeName); fprintf (src,"%s %s(%s *v)\n", returnTypeG, ctdi->freeRoutineName, ctdi->cTypeName); } /* PrintCFreeDeclaration */ static void PrintCFreeDefine PARAMS ((hdr, td), FILE *hdr _AND_ TypeDef *td) { fprintf(hdr, "#define %s %s ", td->cTypeDefInfo->freeRoutineName, td->type->cTypeRefInfo->freeRoutineName); /* fprintf(hdr, "#define %s(v) ", td->cTypeDefInfo->freeRoutineName); fprintf (hdr, "%s (v)", td->type->cTypeRefInfo->freeRoutineName); */ } /* PrintCFreeDefine */ static void PrintCFreeLocals PARAMS ((src, td), FILE *src _AND_ TypeDef *td) { fprintf (src, "\n"); if((td->type->basicType->choiceId == BASICTYPE_SETOF) || (td->type->basicType->choiceId == BASICTYPE_SEQUENCEOF)) { fprintf (src,"\tAsnListNode *l;\n"); fprintf (src,"\tAsnListNode *tmp;\n"); } } /* PrintCFreeLocals */ static void PrintCFreeElmts PARAMS ((src, td, parent, elmts, varName), FILE *src _AND_ TypeDef *td _AND_ Type *parent _AND_ NamedTypeList *elmts _AND_ char *varName) { NamedType *e; if(elmts == NULL) { fprintf (src,"/* ERROR? - expected elmts for this type*/\n"); return; } FOR_EACH_LIST_ELMT (e, elmts) PrintCElmtFree (src, td, parent, e->type, varName); } /* PrintCFreeElmts */ /* * Prints code for encoding the elmts of a SEQ or SET */ static void PrintCElmtFree PARAMS ((src, td, parent, e, varName), FILE *src _AND_ TypeDef *td _AND_ Type *parent _AND_ Type *e _AND_ char *varName) { CTRI *ctri; char elmtVarRef[MAX_VAR_REF]; if((e == NULL) || (e->cTypeRefInfo == NULL)) return; ctri = e->cTypeRefInfo; /* build ref to the elmt */ MakeVarPtrRef (genFreeCRulesG, td, parent, e, varName, elmtVarRef); /* if optional then put in NULL check */ if(e->optional || (e->defaultVal != NULL)) fprintf (src, "\tif(%s (%s))\n {\n", ctri->optTestRoutineName, elmtVarRef); /* free contents of elmt first */ switch(ctri->cTypeId) { case C_ANY: case C_ANYDEFINEDBY: case C_LIB: case C_TYPEREF: fprintf (src,"\t%s%s;", ctri->freeRoutineName, elmtVarRef); break; case C_LIST: PrintCFreeListElmts (src, td, e, elmtVarRef); break; /* * this follwing shouldn't happen since embedded * choices/struct are moved to separate typedefs * in normalize.c. */ case C_CHOICE: PrintCFreeChoiceElmts (src, td, e, elmtVarRef); break; case C_STRUCT: PrintCFreeElmts (src, td, e, e->basicType->a.set, elmtVarRef); break; case C_MACROTYPE: break; case C_NO_TYPE: break; default: fprintf (errFileG, "PrintCElmtFree: ERROR - unknown c type id\n"); break; } /* free elmt itself if it is ref'd by ptr */ if(ctri->isPtr) fprintf (src,"\n\tAsn1Free (%s);\n",elmtVarRef); /* write closing brkt for NULL check for optional elmts */ if(e->optional || (e->defaultVal != NULL)) fprintf (src, "\n\t}\n"); fprintf (src,"\n"); } /* PrintCElmtFree */ /*static void PrintCFreeListDefine PARAMS ((hdr, td), FILE *hdr _AND_ TypeDef *td) { fprintf(hdr, "#define %s(v) ", td->cTypeDefInfo->freeRoutineName); fprintf (hdr, "ASN1_FREE_LIST (v, %s)", td->type->cTypeRefInfo->freeRoutineName); }*/ static void PrintCFreeListRoutineBody PARAMS ((src, td, t, varName), FILE *src _AND_ TypeDef *td _AND_ Type *t _AND_ char *varName) { Type *e; CTRI *ctri; char *elmtVarRef; fprintf (src,"\tfor (l = FIRST_LIST_NODE (%s); l != NULL; )\n", varName); fprintf (src,"\t{\n"); e = t->basicType->a.setOf; ctri = e->cTypeRefInfo; elmtVarRef = "(l->data)"; switch(ctri->cTypeId) { case C_ANY: case C_LIB: case C_TYPEREF: fprintf (src,"\t\t%s (%s);\n", ctri->freeRoutineName, elmtVarRef); break; case C_LIST: PrintCFreeListElmts (src, td, e, elmtVarRef); break; /* * this follwing shouldn't happen since embedded * choices/struct are moved to separate typedefs * in normalize.c. */ case C_CHOICE: PrintCFreeChoiceElmts (src, td, e, elmtVarRef); break; case C_STRUCT: PrintCFreeElmts (src, td, e, e->basicType->a.set, elmtVarRef); break; case C_MACROTYPE: break; case C_NO_TYPE: break; default: fprintf (errFileG, "PrintCElmtFree: ERROR - unknown c type id\n"); break; } fprintf (src,"\t\ttmp = l->next;\n"); fprintf (src,"\t\tAsn1Free (l->data);\n"); fprintf (src,"\t\tAsn1Free (l);\n"); fprintf (src,"\t\tl = tmp;\n"); fprintf (src,"\t}\n"); } static void PrintCFreeListElmts PARAMS ((src, td, t, varName), FILE *src _AND_ TypeDef *td _AND_ Type *t _AND_ char *varName) { Type *e; CTRI *ctri; char *elmtVarRef; fprintf (src,"\t{\n"); fprintf (src,"\t\tAsnListNode *l;\n"); fprintf (src,"\t\tAsnListNode *tmp;\n"); fprintf (src,"\t\tfor (l = FIRST_LIST_NODE (%s); l != NULL; )\n", varName); fprintf (src,"\t\t{\n"); e = t->basicType->a.setOf; ctri = e->cTypeRefInfo; elmtVarRef = "(l->data)"; switch(ctri->cTypeId) { case C_LIB: case C_TYPEREF: fprintf (src,"\t\t%s (%s);\n", ctri->freeRoutineName, elmtVarRef); break; case C_LIST: PrintCFreeListElmts (src, td, e, elmtVarRef); break; /* * this follwing shouldn't happen since embedded * choices/struct are moved to separate typedefs * in normalize.c. */ case C_CHOICE: PrintCFreeChoiceElmts (src, td, e, elmtVarRef); break; case C_STRUCT: PrintCFreeElmts (src, td, e, e->basicType->a.set, elmtVarRef); break; case C_MACROTYPE: break; case C_NO_TYPE: break; default: fprintf (errFileG, "PrintCElmtFree: ERROR - unknown c type id\n"); break; } fprintf (src,"\t\t tmp = l->next;\n"); fprintf (src,"\t\t Asn1Free (l->data);\n"); fprintf (src,"\t\t Asn1Free (l);\n"); fprintf (src,"\t\t l = tmp;\n"); fprintf (src,"\t\t}\n"); fprintf (src,"\t}\n"); } /* PrintCFreeListELmts */ static void PrintCFreeChoiceElmts PARAMS ((src, td, t, varName), FILE *src _AND_ TypeDef *td _AND_ Type *t _AND_ char *varName) { NamedType *e; CTRI *ctri; void *tmp; ctri = t->cTypeRefInfo; fprintf (src,"\tswitch(%s->%s)\n {\n", varName, ctri->choiceIdEnumFieldName); FOR_EACH_LIST_ELMT (e, t->basicType->a.choice) { tmp = (void*)CURR_LIST_NODE (t->basicType->a.choice); if(e->type == NULL) continue; ctri = e->type->cTypeRefInfo; if(e->type->cTypeRefInfo == NULL) fprintf (src, "\t case ????:\n"); else if(ctri->isPtr) { fprintf (src, "\t case %s:\n", ctri->choiceIdSymbol); PrintCElmtFree (src, td, t, e->type, varName); fprintf (src,"\tbreak;\n\n"); } SET_CURR_LIST_NODE (t->basicType->a.choice, tmp); } fprintf (src, "\t}\n"); } esnacc-ng-1.8.1/compiler/back-ends/c-gen/gen-print.c000066400000000000000000000361471302010526100220610ustar00rootroot00000000000000/* * compiler/back-ends/c-gen/gen-print.c - routines for printing C hierachical print routines * * Mike Sample * 92/04 * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/back-ends/c-gen/gen-print.c,v 1.8 2004/01/22 20:03:02 nicholar Exp $ */ #include "asn-incl.h" #include "asn1module.h" #include "rules.h" #include "util.h" #include "snacc-util.h" static char *returnTypeG = "void"; static char *valueArgNameG = "v"; static char *fileTypeNameG = "FILE*"; static char *indentTypeNameG = "unsigned int"; static CRules *genPrintCRulesG; /* non-exported prototypes */ static void PrintCPrintPrototype PROTO ((FILE *hdr, TypeDef *td)); static void PrintCPrintDeclaration PROTO ((FILE *src, TypeDef *td)); static void PrintCPrintDefine PROTO ((FILE *hdr, TypeDef *td)); static void PrintCPrintLocals PROTO ((FILE *src,TypeDef *td)); /* static void PrintCPrintElmts PROTO ((FILE *src, TypeDef *td, Type *parent, NamedTypeList *elmts, char *varName)); */ static void PrintCChoiceElmtPrint PROTO ((FILE *src, TypeDef *td, Type *parent, NamedTypeList *elmts, NamedType *e, char *varName)); static void PrintCElmtPrintWithIndent PROTO ((FILE *src, TypeDef *td, Type *parent, NamedTypeList *elmts, NamedType *e, char *varName, int allOpt)); static void PrintCChoicePrintRoutine PROTO ((FILE *src, FILE *hdr, CRules *r, ModuleList *mods, Module *m, TypeDef *td)); static void PrintCSetPrintRoutine PROTO ((FILE *src, FILE *hdr, CRules *r, ModuleList *mods, Module *m, TypeDef *td)); static void PrintCSeqPrintRoutine PROTO ((FILE *src, FILE *hdr, CRules *r, ModuleList *mods, Module *m, TypeDef *td)); static void PrintCSeqOfPrintRoutine PROTO ((FILE *src, FILE *hdr, CRules *r, ModuleList *mods, Module *m, TypeDef *td)); static void PrintCSetOfPrintRoutine PROTO ((FILE *src, FILE *hdr, CRules *r, ModuleList *mods, Module *m, TypeDef *td)); void PrintCPrinter PARAMS ((src, hdr, r, mods, m, td), FILE *src _AND_ FILE *hdr _AND_ CRules *r _AND_ ModuleList *mods _AND_ Module *m _AND_ TypeDef *td) { if ((td->cTypeDefInfo == NULL) || !(td->cTypeDefInfo->genPrintRoutine)) return; genPrintCRulesG = r; switch (td->type->basicType->choiceId) { case BASICTYPE_IMPORTTYPEREF: /* type references */ case BASICTYPE_LOCALTYPEREF: case BASICTYPE_BOOLEAN: /* library type */ case BASICTYPE_REAL: /* library type */ case BASICTYPE_OCTETSTRING: /* library type */ case BASICTYPE_NULL: /* library type */ case BASICTYPE_OID: /* library type */ case BASICTYPE_RELATIVE_OID: case BASICTYPE_INTEGER: /* library type */ /* case BASICTYPE_BIGINT: */ /* library type */ case BASICTYPE_BITSTRING: /* library type */ case BASICTYPE_ENUMERATED: /* library type */ case BASICTYPE_ANYDEFINEDBY: /* ANY types */ case BASICTYPE_ANY: case BASICTYPE_NUMERIC_STR: case BASICTYPE_PRINTABLE_STR: case BASICTYPE_IA5_STR: case BASICTYPE_BMP_STR: case BASICTYPE_UNIVERSAL_STR: case BASICTYPE_UTF8_STR: case BASICTYPE_T61_STR: case BASICTYPE_VISIBLE_STR: case BASICTYPE_GENERALIZEDTIME: case BASICTYPE_UTCTIME: PrintCPrintDefine (hdr, td); fprintf (hdr, "\n\n"); break; case BASICTYPE_SETOF: PrintCSetOfPrintRoutine (src, hdr, r, mods, m, td); break; case BASICTYPE_SEQUENCEOF: PrintCSeqOfPrintRoutine (src, hdr, r, mods, m, td); break; case BASICTYPE_CHOICE: PrintCChoicePrintRoutine (src, hdr, r, mods, m, td); break; case BASICTYPE_SET: PrintCSetPrintRoutine (src, hdr, r, mods, m, td); break; case BASICTYPE_SEQUENCE: PrintCSeqPrintRoutine (src, hdr, r, mods, m, td); break; default: break; } } /* PrintCPrint */ /* * Prints prototype for encode routine in hdr file */ static void PrintCPrintPrototype PARAMS ((hdr, td), FILE *hdr _AND_ TypeDef *td) { CTDI *ctdi; ctdi = td->cTypeDefInfo; fprintf (hdr,"%s %s PROTO ((%s f, %s *v, %s indent));\n", returnTypeG, ctdi->printRoutineName, fileTypeNameG, ctdi->cTypeName, indentTypeNameG); } /* PrintCPrintPrototype */ /* * Prints declarations of encode routine for the given type def */ static void PrintCPrintDeclaration PARAMS ((src, td), FILE *src _AND_ TypeDef *td) { CTDI *ctdi; ctdi = td->cTypeDefInfo; fprintf (src,"%s\n%s PARAMS ((f, v, indent),\n%s f _AND_\n%s *v _AND_" "\n%s indent)\n", returnTypeG, ctdi->printRoutineName, fileTypeNameG, ctdi->cTypeName, indentTypeNameG); } /* PrintCPrintDeclaration */ static void PrintCPrintDefine PARAMS ((hdr, td), FILE *hdr _AND_ TypeDef *td) { fprintf(hdr, "#define %s %s", td->cTypeDefInfo->printRoutineName, td->type->cTypeRefInfo->printRoutineName); /* fprintf(hdr, "#define %s(f, v, indent) ", td->cTypeDefInfo->printRoutineName); fprintf (hdr, "%s (f, v, indent)", td->type->cTypeRefInfo->printRoutineName); */ } /* PrintCPrintDefine */ static void PrintCPrintLocals PARAMS ((src, td), FILE *src _AND_ TypeDef *td) { /* none yet */ td = td; src = src; /*AVOIDS warning.*/ } /* PrintCPrintLocals */ /* static void PrintCPrintElmts PARAMS ((src, td, parent, elmts, varName), FILE *src _AND_ TypeDef *td _AND_ Type *parent _AND_ NamedTypeList *elmts _AND_ char *varName) { NamedType *e; FOR_EACH_LIST_ELMT (e, elmts) PrintCElmtPrint (src, td, parent, elmts, e, varName); } PrintCPrintElmts */ /* * Prints code for printing a CHOICE element * */ static void PrintCChoiceElmtPrint PARAMS ((src, td, parent, elmts, e, varName), FILE *src _AND_ TypeDef *td _AND_ Type *parent _AND_ NamedTypeList *elmts _AND_ NamedType *e _AND_ char *varName) { char elmtVarRef[MAX_VAR_REF]; /* build ref to the elmt */ MakeVarPtrRef (genPrintCRulesG, td, parent, e->type, varName, elmtVarRef); if (e->fieldName != NULL) fprintf (src, "\t\tfprintf (f, \"%s \");\n", e->fieldName); fprintf (src, "\t\t%s (f, %s, indent);\n", e->type->cTypeRefInfo->printRoutineName, elmtVarRef); elmts = elmts; /*AVOIDS warning.*/ } /* PrintCChoiceElmtPrint */ /* * Prints code for printing an elmt of a SEQ or SET * * Does funny things to print commas correctly * eg for the following type * Foo ::= SET * { * A, --> print A ",\n" * B, B ",\n" * C OPTIONAL, C ",\n" if C present * D, D ",\n" * E, E ",\n" * F, F <- nothing after last non-opt * before tail opts. * G OPTIONAL, ",\n" G * H OPTIONAL ",\n" H "\n" * } */ static void PrintCElmtPrintWithIndent PARAMS ((src, td, parent, elmts, e, varName, allOpt), FILE *src _AND_ TypeDef *td _AND_ Type *parent _AND_ NamedTypeList *elmts _AND_ NamedType *e _AND_ char *varName _AND_ int allOpt) { CTRI *ctri; char elmtVarRef[MAX_VAR_REF]; int inTailOpts; const char* tabStr = "\t"; ctri = e->type->cTypeRefInfo; /* this assumes the elmts->curr == e */ inTailOpts = IsTailOptional (elmts); /* build ref to the elmt */ MakeVarPtrRef (genPrintCRulesG, td, parent, e->type, varName, elmtVarRef); /* if optional then put in NULL check */ if (e->type->optional || (e->type->defaultVal != NULL)) { fprintf (src, "\tif (%s (%s))\n {\n", ctri->optTestRoutineName, elmtVarRef); tabStr = "\t\t"; } if (allOpt) { if (e != FIRST_LIST_ELMT (elmts)) { fprintf (src, "%sif (!nonePrinted)\n", tabStr); fprintf (src, "%s\tfprintf (f, \",\\n\");\n", tabStr); } fprintf (src, "%snonePrinted = FALSE;\n", tabStr); } else if ((inTailOpts) && (e != FIRST_LIST_ELMT (elmts))) fprintf (src, "%sfprintf (f, \",\\n\");\n", tabStr); fprintf (src, "%sIndent (f, indent + 1);\n", tabStr); if (e->fieldName != NULL) fprintf (src, "%sfprintf (f, \"%s \");\n", tabStr, e->fieldName); fprintf (src, "%s%s (f, %s, indent + 1);\n", tabStr, e->type->cTypeRefInfo->printRoutineName, elmtVarRef); if ((e != LAST_LIST_ELMT (elmts)) && (!inTailOpts) && (!NextIsTailOptional (elmts))) fprintf (src, "%sfprintf (f, \",\\n\");\n", tabStr); /* write closing brkt for NULL check for optional elmts */ if (e->type->optional || (e->type->defaultVal != NULL)) fprintf (src, "\t}\n"); } /* PrintCElmtPrintWithIndent */ static void PrintCChoicePrintRoutine PARAMS ((src, hdr, r, mods, m, td), FILE *src _AND_ FILE *hdr _AND_ CRules *r _AND_ ModuleList *mods _AND_ Module *m _AND_ TypeDef *td) { NamedType *e; PrintCPrintPrototype (hdr, td); PrintCPrintDeclaration (src, td); fprintf (src, "{\n"); PrintCPrintLocals (src, td); fprintf (src, "\tswitch (%s->%s)\n", valueArgNameG, td->type->cTypeRefInfo->choiceIdEnumFieldName); fprintf (src, "\t{\n"); FOR_EACH_LIST_ELMT (e, td->type->basicType->a.choice) { fprintf (src, "\tcase %s:\n",e->type->cTypeRefInfo->choiceIdSymbol); PrintCChoiceElmtPrint (src, td, td->type, td->type->basicType->a.choice, e, valueArgNameG); fprintf (src, "\t\tbreak;\n\n"); } fprintf (src, "\t}\n"); fprintf (src,"} /* %s */\n\n", td->cTypeDefInfo->printRoutineName); m = m; mods = mods; r = r; /*AVOIDS warning.*/ } /* PrintCChoicePrintRoutine */ static void PrintCSetPrintRoutine PARAMS ((src, hdr, r, mods, m, td), FILE *src _AND_ FILE *hdr _AND_ CRules *r _AND_ ModuleList *mods _AND_ Module *m _AND_ TypeDef *td) { NamedType *e; int allOpt; PrintCPrintPrototype (hdr, td); PrintCPrintDeclaration (src, td); fprintf (src, "{\n"); PrintCPrintLocals (src, td); allOpt = AllElmtsOptional (td->type->basicType->a.set); /* * print extra local variable so commas are handled correctly * when all elements are optional */ if (allOpt) fprintf (src, "\tint nonePrinted = TRUE;\n\n"); fprintf (src, "\tif (%s == NULL)\n", valueArgNameG); fprintf (src, "\t\treturn;\n\n"); fprintf (src, "\tfprintf (f,\"{ -- SET --\\n\");\n\n"); FOR_EACH_LIST_ELMT (e, td->type->basicType->a.set) { PrintCElmtPrintWithIndent (src, td, td->type, td->type->basicType->a.set, e, valueArgNameG, allOpt); } fprintf (src, "\tfprintf (f, \"\\n\");\n"); fprintf (src, "\tIndent (f, indent);\n"); fprintf (src, "\tfprintf (f, \"}\");\n"); fprintf (src, "} /* %s */\n\n", td->cTypeDefInfo->printRoutineName); m = m; mods = mods;r = r; /*AVOIDS warning.*/ } /* PrintCSetPrintRoutine */ static void PrintCSeqPrintRoutine PARAMS ((src, hdr, r, mods, m, td), FILE *src _AND_ FILE *hdr _AND_ CRules *r _AND_ ModuleList *mods _AND_ Module *m _AND_ TypeDef *td) { NamedType *e; int allOpt; PrintCPrintPrototype (hdr, td); PrintCPrintDeclaration (src, td); fprintf (src, "{\n"); PrintCPrintLocals (src, td); allOpt = AllElmtsOptional (td->type->basicType->a.set); /* * print extra local variable so commas are handled correctly * when all elements are optional */ if (allOpt) fprintf (src, "\tint nonePrinted = TRUE;\n\n"); fprintf (src, "\tif (%s == NULL)\n", valueArgNameG); fprintf (src, "\t\treturn;\n\n"); fprintf (src, "\tfprintf (f, \"{ -- SEQUENCE --\\n\");\n\n"); FOR_EACH_LIST_ELMT (e, td->type->basicType->a.sequence) { PrintCElmtPrintWithIndent (src, td, td->type, td->type->basicType->a.sequence, e, valueArgNameG, allOpt); } fprintf (src, "\tfprintf (f, \"\\n\");\n"); fprintf (src, "\tIndent (f, indent);\n"); fprintf (src, "\tfprintf (f, \"}\");\n"); fprintf (src, "} /* %s */\n\n", td->cTypeDefInfo->printRoutineName); m = m;mods = mods;r = r; /*AVOIDS warning.*/ } /* PrintCSeqPrintRoutine */ static void PrintCSetOfPrintRoutine PARAMS ((src, hdr, r, mods, m, td), FILE *src _AND_ FILE *hdr _AND_ CRules *r _AND_ ModuleList *mods _AND_ Module *m _AND_ TypeDef *td) { PrintCPrintPrototype (hdr, td); PrintCPrintDeclaration (src, td); fprintf (src, "{\n"); PrintCPrintLocals (src, td); fprintf (src, "\t%s *tmp;\n", td->type->basicType->a.setOf->cTypeRefInfo->cTypeName); fprintf (src, "\tif (%s == NULL)\n", valueArgNameG); fprintf (src, "\t\treturn;\n"); fprintf (src, "\tfprintf (f, \"{ -- SET OF -- \\n\");\n"); fprintf (src, "\tFOR_EACH_LIST_ELMT (tmp, %s)\n", valueArgNameG); fprintf (src, "\t{\n"); fprintf (src, "\t\tIndent (f, indent + 1);\n"); fprintf (src, "\t\t%s (f, tmp, indent + 1);\n", td->type->basicType->a.setOf->cTypeRefInfo->printRoutineName); fprintf (src, "\t\tif (tmp != (%s*)LAST_LIST_ELMT (%s))\n", td->type->basicType->a.setOf->cTypeRefInfo->cTypeName, valueArgNameG); fprintf (src, "\t\t\tfprintf (f, \",\\n\");\n"); fprintf (src, "\t}\n"); fprintf (src, "\tfprintf (f, \"\\n\");\n"); fprintf (src, "\tIndent (f, indent);\n"); fprintf (src, "\tfprintf (f, \"}\");\n"); fprintf (src, "} /* %s */\n\n", td->cTypeDefInfo->printRoutineName); m = m;mods = mods;r = r; /*AVOIDS warning.*/ } /* PrintCSetOfPrintRoutine */ static void PrintCSeqOfPrintRoutine PARAMS ((src, hdr, r, mods, m, td), FILE *src _AND_ FILE *hdr _AND_ CRules *r _AND_ ModuleList *mods _AND_ Module *m _AND_ TypeDef *td) { PrintCPrintPrototype (hdr, td); PrintCPrintDeclaration (src, td); fprintf (src, "{\n"); PrintCPrintLocals (src, td); fprintf (src, "\t%s *tmp;\n", td->type->basicType->a.setOf->cTypeRefInfo->cTypeName); fprintf (src, "\tif (%s == NULL)\n", valueArgNameG); fprintf (src, "\t\treturn;\n"); fprintf (src, "\tfprintf (f, \"{ -- SEQUENCE OF -- \\n\");\n"); fprintf (src, "\tFOR_EACH_LIST_ELMT (tmp, %s)\n", valueArgNameG); fprintf (src, "\t{\n"); fprintf (src, "\t\tIndent (f, indent+ 1);\n"); fprintf (src, "\t\t%s (f, tmp, indent + 1);\n", td->type->basicType->a.setOf->cTypeRefInfo->printRoutineName); fprintf (src, "\t\tif (tmp != (%s*)LAST_LIST_ELMT (%s))\n", td->type->basicType->a.setOf->cTypeRefInfo->cTypeName, valueArgNameG); fprintf (src, "\t\t\tfprintf (f, \",\\n\");\n"); fprintf (src, "\t}\n"); fprintf (src, "\tfprintf (f, \"\\n\");\n"); fprintf (src, "\tIndent (f, indent);\n"); fprintf (src, "\tfprintf (f, \"}\");\n"); fprintf (src, "} /* %s */\n\n", td->cTypeDefInfo->printRoutineName); m=m;mods=mods;r=r; /*AVOIDS warning.*/ } /* PrintCSeqOfPrintRoutine */ esnacc-ng-1.8.1/compiler/back-ends/c-gen/gen-type.c000066400000000000000000000411101302010526100216700ustar00rootroot00000000000000/* * compiler/back-ends/c-gen/gen-type.c - routines for printing c types from ASN.1 from type trees * * Mike Sample * 91/09/26 * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/back-ends/c-gen/gen-type.c,v 1.7 2004/03/25 19:20:16 gronej Exp $ * $Log: gen-type.c,v $ * Revision 1.7 2004/03/25 19:20:16 gronej * fixed some linux warnings * * Revision 1.6 2003/07/07 14:53:38 nicholar * Eliminated headers and cleaned up include references * * Revision 1.5 2003/04/29 21:02:36 leonberp * integerated Deepak's changes for IOB support * * Revision 1.4 2002/09/16 17:35:01 mcphersc * Fixed warnings * * Revision 1.3 2002/09/04 18:02:11 vracarl * got rid of c++ comments * * Revision 1.2 2000/10/24 14:54:47 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:36:05 leonberp * First CVS Version of SNACC. * * Revision 1.3 1995/07/25 18:43:44 rj * file name has been shortened for redundant part: c-gen/gen-c-type -> c-gen/gen-type. * * changed `_' to `-' in file names. * * Revision 1.2 1994/09/01 00:23:58 rj * snacc_config.h and other superfluous .h files removed. * * Revision 1.1 1994/08/28 09:48:31 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include #include #include "asn-incl.h" #include "asn1module.h" #include "rules.h" #include "str-util.h" #include "print.h" // Deepak: 26/Mar/2003 extern char *valueArgNameG; extern char *bufTypeNameG; extern char *lenTypeNameG; extern char *tagTypeNameG; extern char *returnTypeG; /* non-exported prototypes */ static void PrintCType PROTO ((FILE *f, CRules *r, Module *m, TypeDef *td, Type *parent, Type *t)); static void PrintCStructElmts PROTO ((FILE *f, CRules *r, Module *m, TypeDef *td, Type *parent, Type *t)); static void PrintCChoiceIdEnum PROTO ((FILE *f, CRules *r, Module *m, TypeDef *td, Type *parent, Type *t)); static void PrintCChoiceUnion PROTO ((FILE *f, CRules *r, Module *m, TypeDef *td, Type *parent, Type *t)); static void PrintCChoiceTypeDef PROTO ((FILE *f, CRules *r, Module *m, TypeDef *td)); static void PrintTypeComment PROTO ((FILE *f, TypeDef *head, Type *t)); static void PrintPreTypeDefStuff PROTO ((FILE *f, CRules *r, Module *m, TypeDef *td, Type *parent, Type *t)); // Deepak: 11/Mar/2003 static void PrintCObjectClassElmts PROTO ((FILE *f, CRules *r, Module *m, TypeDef *td, Type *parent, Type *t)); // Deepak: 17/Apr/2003 static void PrintCMacroTypeElmts PROTO ((FILE *f, CRules *r, Module *m, TypeDef *td, Type *parent, Type *t)); static void PrintCMacroRosOperationElmts PROTO ((FILE *f, CRules *r, Module *m, TypeDef *td, Type *parent, Type *t, RosOperationMacroType *op)); void PrintCTypeDef PARAMS ((f, r, m, td), FILE *f _AND_ CRules *r _AND_ Module *m _AND_ TypeDef *td) { CTRI *ctri; CTDI *ctdi; Type *t; ctdi = td->cTypeDefInfo; if ((ctdi == NULL) || (!ctdi->genTypeDef)) return; t = td->type; ctri = t->cTypeRefInfo; PrintPreTypeDefStuff (f, r, m, td, NULL, t); switch (ctri->cTypeId) { case C_TYPEREF: case C_LIB: case C_ANY: case C_ANYDEFINEDBY: case C_LIST: // Deepak: following three stmts writes the equivalent C code in header file. fprintf (f, "typedef "); PrintCType (f, r, m, td, NULL, t); // Deepak: Prints Basic ASN Data Type like NumericString or PrintableString or ENUMERATED etc... fprintf (f, " %s;", ctdi->cTypeName); // Deepak: Prints User Defined ASN Data Type like Order-number, Item-code etc... PrintTypeComment (f, td, t); // Deepak: actual asn code line is written in comments here fprintf (f, "\n\n"); break; case C_CHOICE: PrintCChoiceTypeDef (f, r, m, td); break; case C_STRUCT: fprintf (f, "typedef "); fprintf (f,"%s %s", "struct", t->cTypeRefInfo->cTypeName); PrintTypeComment (f, td, t); fprintf (f,"\n{\n"); PrintCStructElmts (f, r, m, td, NULL, t); fprintf (f, "} %s;", ctdi->cTypeName); fprintf (f, "\n\n"); break; case C_OBJECTCLASS: // Deepak: 11/Mar/2003 fprintf (f, "typedef "); fprintf (f,"%s %s", "struct", t->cTypeRefInfo->cTypeName); PrintTypeComment (f, td, t); fprintf (f,"\n{\n"); PrintCObjectClassElmts (f, r, m, td, NULL, t); fprintf (f, "} %s;", ctdi->cTypeName); fprintf (f, "\n\n"); break; case C_MACROTYPE: fprintf (f, "typedef "); fprintf (f,"%s %s", "struct", t->cTypeRefInfo->cTypeName); PrintTypeComment (f, td, t); fprintf (f,"\n{\n"); PrintCMacroTypeElmts (f, r, m, td, NULL, t); fprintf (f, "} %s;", ctdi->cTypeName); fprintf (f, "\n\n"); break; default: break; /* else do nothing - some unprocessed or unknown type (macros etc) */ } } /* PrintCTypeDef */ static void PrintCType PARAMS ((f, r, m, td, parent, t), FILE *f _AND_ CRules *r _AND_ Module *m _AND_ TypeDef *td _AND_ Type *parent _AND_ Type *t) { CTRI *ctri; CNamedElmt *n; ctri = t->cTypeRefInfo; if (ctri == NULL) return; if(t->basicType->choiceId == BASICTYPE_OBJECTCLASSFIELDTYPE) { // Deepak: 01/Apr/2003 fprintf (f,"void* "); return; } switch (ctri->cTypeId) { case C_TYPEREF: /* * put struct in front of def if * defined from a struct type (set/seq/choice) * but only if not a ref of a ref */ if ((t->basicType->a.localTypeRef->link->type->cTypeRefInfo->cTypeId == C_STRUCT)|| (t->basicType->a.localTypeRef->link->type->cTypeRefInfo->cTypeId == C_CHOICE)) { fprintf (f,"struct "); } fprintf (f,"%s", ctri->cTypeName); if (ctri->isPtr) fprintf (f,"*"); break; case C_ANY: fprintf (f,"/* ANY- Fix Me ! */\n"); case C_ANYDEFINEDBY: case C_LIST: case C_LIB: fprintf (f,"%s", ctri->cTypeName); /* * print enum constant defs */ if ((ctri->cNamedElmts != NULL) && (t->basicType->choiceId == BASICTYPE_ENUMERATED)) { fprintf (f, "\n {\n"); FOR_EACH_LIST_ELMT (n, ctri->cNamedElmts) { fprintf (f," %s = %d", n->name, n->value); if (n != (CNamedElmt*)LAST_LIST_ELMT (ctri->cNamedElmts)) fprintf (f,","); fprintf (f,"\n"); } fprintf (f, " }"); } if (ctri->isPtr) fprintf (f,"*"); break; default: break; /* nothing */ } parent = parent;td = td;m = m;r = r; /*AVOIDS warning.*/ } /* PrintCType */ static void PrintCStructElmts PARAMS ((f, r, m, td, parent, t), FILE *f _AND_ CRules *r _AND_ Module *m _AND_ TypeDef *td _AND_ Type *parent _AND_ Type *t) { CTRI *ctri; NamedType *et; NamedTypeList *elmts; elmts = t->basicType->a.sequence; if ((elmts == NULL) || (LIST_EMPTY (elmts))) { fprintf (f, " char unused; /* empty ASN1 SET/SEQ - not used */\n"); } FOR_EACH_LIST_ELMT (et, elmts) { ctri = et->type->cTypeRefInfo; fprintf (f,"\t"); /* cheap, fixed indent */ PrintCType (f, r, m, td, t, et->type); fprintf (f, " %s;", ctri->cFieldName); // Deepak: identifier of the structure PrintTypeComment (f, td, et->type); // Deepak: actual asn code line is written in comments here fprintf (f, "\n"); } parent = parent; /*AVOIDS warning.*/ } /* PrintCStructElmts */ static void // Deepak: 17/Apr/2003 PrintCMacroTypeElmts PARAMS ((f, r, m, td, parent, t), FILE *f _AND_ CRules *r _AND_ Module *m _AND_ TypeDef *td _AND_ Type *parent _AND_ Type *t) { switch (t->basicType->a.macroType->choiceId) { // This switch case copied from do-macros.c case MACROTYPE_ASNABSTRACTOPERATION: case MACROTYPE_ROSOPERATION: PrintCMacroRosOperationElmts (f, r, m, td, parent, t, t->basicType->a.macroType->a.rosOperation); break; // Other Macro Types are not supported as for now as per changes done on 17/Apr/2003 // Add code for other macro types here default: // Unsupported Macro Type break; } parent=parent; /*AVOIDS warning.*/ } /* PrintCMacroTypeElmts */ static void // Deepak: 17/Apr/2003 PrintCMacroRosOperationElmts PARAMS ((f, r, m, td, parent, t, op), FILE *f _AND_ CRules *r _AND_ Module *m _AND_ TypeDef *td _AND_ Type *parent _AND_ Type *t _AND_ RosOperationMacroType *op) { CTRI *ctri; NamedType *et; int digit = 1; if (op->arguments != NULL) { et = op->arguments; if(et->type->basicType->choiceId == BASICTYPE_LOCALTYPEREF) { ctri = et->type->cTypeRefInfo; fprintf (f,"\t"); /* cheap, fixed indent */ PrintCType (f, r, m, NULL, NULL, et->type); ctri->cFieldName = et->type->basicType->a.localTypeRef->typeName; ctri->cFieldName[0] = (char)tolower (ctri->cFieldName[0]); AppendDigit (ctri->cFieldName, digit++); fprintf (f, " %s;", ctri->cFieldName); // Deepak: identifier of the structure PrintTypeComment (f, td, et->type); // Deepak: actual asn code line is written in comments here fprintf (f, "\n"); } } if (op->result != NULL) { et = op->result; if(et->type->basicType->choiceId == BASICTYPE_LOCALTYPEREF) { ctri = et->type->cTypeRefInfo; fprintf (f,"\t"); /* cheap, fixed indent */ PrintCType (f, r, m, NULL, NULL, et->type); ctri->cFieldName = et->type->basicType->a.localTypeRef->typeName; ctri->cFieldName[0] = (char)tolower (ctri->cFieldName[0]); AppendDigit (ctri->cFieldName, digit++); fprintf (f, " %s;", ctri->cFieldName); // Deepak: identifier of the structure PrintTypeComment (f, td, et->type); // Deepak: actual asn code line is written in comments here fprintf (f, "\n"); } } parent=parent; t=t; } /* PrintCMacroRosOperationElmts */ static void // Deepak: 11/Mar/2003 PrintCObjectClassElmts PARAMS ((f, r, m, td, parent, t), FILE *f _AND_ CRules *r _AND_ Module *m _AND_ TypeDef *td _AND_ Type *parent _AND_ Type *t) { CTRI *ctri; NamedType *et; NamedTypeList *elmts; int bOptionalElmtsStructWritten = FALSE; elmts = t->basicType->a.objectclass->classdef; if ((elmts == NULL) || (LIST_EMPTY (elmts))) { fprintf (f, " char unused; /* empty ASN1 SET/SEQ - not used */\n"); } // for struct enum of optional variables // Deepak: 14/Mar/2003 FOR_EACH_LIST_ELMT (et, elmts) { if(et->type->optional) { if(!bOptionalElmtsStructWritten) { bOptionalElmtsStructWritten = TRUE; fprintf (f,"\tstruct {\n"); } fprintf (f,"\t\tunsigned int %sPresent : 1;\n", et->fieldName); } } if(bOptionalElmtsStructWritten) fprintf (f,"\t} m;\n\n"); FOR_EACH_LIST_ELMT (et, elmts) { ctri = et->type->cTypeRefInfo; /* ======== Deepak: 17/Mar/2003 Print Encode/Decode Functions for BASICTYPE_UNKNOWN ========*/ if(et->type->basicType->choiceId == BASICTYPE_UNKNOWN) { fprintf (f, "\n /* ========== %s: BASICTYPE_UNKNOWN ========== */\n", ctri->cFieldName); //fprintf (f, "\tchar* %sName;\n", ctri->cFieldName); fprintf (f, "\tvoid* %s;\n", ctri->cFieldName); fprintf (f, "\t%s %sSize;\n", returnTypeG, ctri->cFieldName); fprintf (f, "\t%s (*encode%s) (%s b, void *%s);\n", returnTypeG, ctri->cFieldName, bufTypeNameG, valueArgNameG); fprintf (f, "\t%s (*decode%s) (%s b, %s tagId0, %s elmtLen0, void *%s, %s *bytesDecoded);\n", returnTypeG, ctri->cFieldName, bufTypeNameG, tagTypeNameG, lenTypeNameG, valueArgNameG, lenTypeNameG); continue; } /* ======== Till here ======== */ fprintf (f,"\t"); /* cheap, fixed indent */ PrintCType (f, r, m, td, t, et->type); fprintf (f, " %s;", ctri->cFieldName); // Deepak: identifier of the structure PrintTypeComment (f, td, et->type); // Deepak: actual asn code line is written in comments here fprintf (f, "\n"); } // fprintf (f, "\tAsnInt tagId;\n"); parent=parent; /*AVOIDS warning.*/ } /* PrintCObjectClassElmts */ static void PrintCChoiceIdEnum PARAMS ((f, r, m, td, parent, t), FILE *f _AND_ CRules *r _AND_ Module *m _AND_ TypeDef *td _AND_ Type *parent _AND_ Type *t) { NamedType *et; NamedType *last=NULL; CTRI *ctri; ctri = t->cTypeRefInfo; fprintf (f, " enum %s\n {\n", ctri->choiceIdEnumName); if ((t->basicType->a.choice != NULL) && !(LIST_EMPTY (t->basicType->a.choice))) last = (NamedType*)LAST_LIST_ELMT (t->basicType->a.choice); FOR_EACH_LIST_ELMT (et, t->basicType->a.choice) { ctri = et->type->cTypeRefInfo; fprintf (f," %s", ctri->choiceIdSymbol); if (et == last) fprintf (f, "\n"); else fprintf (f, ",\n"); } ctri = t->cTypeRefInfo; fprintf (f, " } %s;", ctri->choiceIdEnumFieldName); parent = parent;td = td;m = m;r = r; /*AVOIDS warning.*/ } /* PrintCChoiceIdEnum */ static void PrintCChoiceUnion PARAMS ((f, r, m, td, parent, t), FILE *f _AND_ CRules *r _AND_ Module *m _AND_ TypeDef *td _AND_ Type *parent _AND_ Type *t) { CTRI *ctri; ctri = t->cTypeRefInfo; fprintf (f," union %s\n {\n", ctri->cTypeName); PrintCStructElmts (f, r, m, td, parent, t); fprintf (f, " }"); } /* PrintCChoiceUnion */ static void PrintCChoiceTypeDef PARAMS ((f, r, m, td), FILE *f _AND_ CRules *r _AND_ Module *m _AND_ TypeDef *td) { CTRI *ctri; char *choiceName; Type *t; t = td->type; ctri = t->cTypeRefInfo; choiceName = td->cTypeDefInfo->cTypeName; fprintf (f, "typedef "); fprintf (f, "struct %s", choiceName); PrintTypeComment (f, td, t); fprintf (f,"\n{\n"); PrintCChoiceIdEnum (f, r, m, td, NULL, t); fprintf (f,"\n"); PrintCChoiceUnion (f, r, m, td, NULL, t); fprintf (f, " %s;", ctri->cFieldName); fprintf (f,"\n} %s;\n\n", choiceName); } /* PrintCChoiceDef */ /* * used to print snippet of the defining ASN.1 after the * C type. */ static void PrintTypeComment PARAMS ((f, td, t), FILE *f _AND_ TypeDef *td _AND_ Type *t) { fprintf (f," /* "); SpecialPrintType (f, td, t); fprintf (f," */"); } /* * print any #defines for integers/bits with named elements * (currenly only the first option will fire due to the * steps taken in normalize.c) */ static void PrintPreTypeDefStuff PARAMS ((f, r, m, td, parent, t), FILE *f _AND_ CRules *r _AND_ Module *m _AND_ TypeDef *td _AND_ Type *parent _AND_ Type *t) { CTRI *ctri; NamedType *et; CNamedElmt *n; ctri = td->type->cTypeRefInfo; /* * print defined stmts for non enumerated type with named elmts */ if ((ctri->cNamedElmts != NULL) && (t->basicType->choiceId != BASICTYPE_ENUMERATED)) { FOR_EACH_LIST_ELMT (n, ctri->cNamedElmts) { fprintf(f, "\n#define %s %d", n->name, n->value); } fprintf (f, "\n\n"); } else if ((t->basicType->choiceId == BASICTYPE_SET) || (t->basicType->choiceId == BASICTYPE_SEQUENCE) || (t->basicType->choiceId == BASICTYPE_CHOICE)) { FOR_EACH_LIST_ELMT (et, t->basicType->a.set) PrintPreTypeDefStuff (f, r, m, td, t, et->type); } else if ((t->basicType->choiceId == BASICTYPE_SETOF) || (t->basicType->choiceId == BASICTYPE_SEQUENCEOF)) { PrintPreTypeDefStuff (f, r, m, td, t, t->basicType->a.setOf); } parent = parent; /*AVOIDS warning.*/ } /* PrintPreTypeDefStuff */ esnacc-ng-1.8.1/compiler/back-ends/c-gen/gen-vals.c000066400000000000000000000200341302010526100216560ustar00rootroot00000000000000/* * compiler/back-ends/c-gen/gen-vals.c - prints ASN.1 values in C format * * * MS Feb 92 * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/back-ends/c-gen/gen-vals.c,v 1.7 2004/01/14 19:07:53 gronej Exp $ * $Log: gen-vals.c,v $ * Revision 1.7 2004/01/14 19:07:53 gronej * Updated Compiler to accept and process relative-oid's * * Revision 1.6 2003/07/28 14:28:56 colestor * Updated for "C" builds to properly load integer constant references in tag designations. * Initialization was leaving the entire value blank, causing an error. * * Revision 1.5 2003/07/07 14:53:38 nicholar * Eliminated headers and cleaned up include references * * Revision 1.4 2003/04/29 21:01:38 leonberp * integerated Deepak's changes for IOB support * * Revision 1.3 2002/09/16 17:35:04 mcphersc * Fixed warnings * * Revision 1.2 2000/10/24 14:54:48 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:36:05 leonberp * First CVS Version of SNACC. * * Revision 1.4 1997/08/28 07:26:09 povey * Changes to support DER encoding/decoding * * Revision 1.3.1.1 1997/08/20 23:14:41 povey * * Revision 1.3 1995/07/25 18:44:12 rj * file name has been shortened for redundant part: c-gen/gen-c-vals -> c-gen/gen-vals. * * changed `_' to `-' in file names. * * Revision 1.2 1994/09/01 00:24:18 rj * snacc_config.h removed. * * Revision 1.1 1994/08/28 09:48:33 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include "asn-incl.h" #include "asn1module.h" #include "rules.h" #include "str-util.h" void PrintCValueInstantiation PROTO ((FILE *hdr, CRules *r, Value *v)); void PrintCOidValue PROTO ((FILE *f, CRules *r, AsnOid *oid)); static void PrintValueDefsName PROTO ((FILE *f, CRules *r, ValueDef *v)); static void PrintValueDefsType PROTO ((FILE *f, CRules *r, ValueDef *v)); void PrintCValueDef PARAMS ((src, r, v), FILE *src _AND_ CRules *r _AND_ ValueDef *v) { /* just do oid's, ints and bools for now */ /* Commented the below condition to allow Some More ValueDefs */ /* if ((v->value->basicValue->choiceId != BASICVALUE_OID) && (v->value->basicValue->choiceId != BASICVALUE_INTEGER) && (v->value->basicValue->choiceId != BASICVALUE_BOOLEAN)) return; */ /* * put instantiation in src file */ PrintValueDefsType (src, r, v); fprintf (src," "); PrintValueDefsName (src, r, v); fprintf (src," = "); PrintCValueInstantiation (src, r, v->value); fprintf (src,";\n"); } /* PrintCValueDef */ void PrintCValueExtern PARAMS ((hdr, r, v), FILE *hdr _AND_ CRules *r _AND_ ValueDef *v) { /* just do oid's, ints and bools for now */ /* modified for more types Deepak: 17/Mar/2003 */ /* if ((v->value->basicValue->choiceId != BASICVALUE_OID) && (v->value->basicValue->choiceId != BASICVALUE_INTEGER) && (v->value->basicValue->choiceId != BASICVALUE_BOOLEAN)) return; */ /* * put extern declaration in hdr file */ fprintf (hdr,"extern "); PrintValueDefsType (hdr, r, v); fprintf (hdr," "); PrintValueDefsName (hdr, r, v); fprintf (hdr,";\n"); } /* PrintCValueExtern */ void PrintCValueInstantiation PARAMS ((f, r, v), FILE *f _AND_ CRules *r _AND_ Value *v) { /* needs work - just do ints, bools and oids for now */ switch (v->basicValue->choiceId) { case BASICVALUE_OID: PrintCOidValue (f, r, v->basicValue->a.oid); break; case BASICVALUE_INTEGER: fprintf (f, "%d", v->basicValue->a.integer); break; case BASICVALUE_BOOLEAN: if (v->basicValue->a.boolean) fprintf (f, "TRUE"); else fprintf (f, "FALSE"); break; /* modified for more types Deepak: 17/Mar/2003 */ /* Also add in func PrintValueDefsType(...) */ case BASICVALUE_ASCIITEXT: fprintf (f, "%s", r->typeConvTbl[BASICTYPE_PRINTABLE_STR].cTypeName); break; case BASICVALUE_LOCALVALUEREF: if (v->basicValue->a.localValueRef && v->basicValue->a.localValueRef->link && v->basicValue->a.localValueRef->link->value && v->basicValue->a.localValueRef->link->value->basicValue) { int iValue=500; // WILL indicate a problem on source creation... if (v->basicValue->a.localValueRef->link->value->basicValue->choiceId == BASICVALUE_INTEGER) { iValue = v->basicValue->a.localValueRef->link-> value->basicValue->a.integer; } // IF Integer else if (v->basicValue->a.localValueRef->link->value->basicValue->choiceId == BASICVALUE_LOCALVALUEREF) { ValueRef *pvalueRef=NULL; if (v->basicValue->a.localValueRef->link->value->basicValue->choiceId == BASICVALUE_LOCALVALUEREF) { pvalueRef = v->basicValue->a.localValueRef->link->value->basicValue->a.localValueRef; if (pvalueRef->link->value && pvalueRef->link->value->basicValue && pvalueRef->link->value->basicValue->choiceId == BASICVALUE_INTEGER) iValue = pvalueRef->link->value->basicValue->a.integer; } // END IF LOCALVALUEREF (recursed) } // END IF LOCALVALUEREF under LCOALVALUEREF fprintf (f, "%d", iValue); } // END if LocalValueRef type. break; default: break; } } static void PrintValueDefsName PARAMS ((f, r, v), FILE *f _AND_ CRules *r _AND_ ValueDef *v) { char *cName; cName = Asn1ValueName2CValueName (v->definedName); fprintf (f, "%s", cName); Free (cName); r = r; /*AVOIDS warning.*/ } static void PrintValueDefsType PARAMS ((f, r, v), FILE *f _AND_ CRules *r _AND_ ValueDef *v) { /* needs work - just do ints bools and oid's for now */ switch (v->value->basicValue->choiceId) { case BASICVALUE_OID: fprintf (f, "%s", r->typeConvTbl[BASICTYPE_OID].cTypeName); break; case BASICVALUE_RELATIVE_OID: fprintf (f, "%s", r->typeConvTbl[BASICTYPE_RELATIVE_OID].cTypeName); break; case BASICVALUE_INTEGER: fprintf (f, "%s", r->typeConvTbl[BASICTYPE_INTEGER].cTypeName); break; case BASICVALUE_BOOLEAN: fprintf (f, "%s", r->typeConvTbl[BASICTYPE_BOOLEAN].cTypeName); break; /* modified for more types Deepak: 17/Mar/2003 */ /* Also add in func PrintCValueInstantiation(...) */ case BASICVALUE_ASCIITEXT: fprintf (f, "%s", r->typeConvTbl[BASICTYPE_PRINTABLE_STR].cTypeName); break; // case BASICVALUE_VALUENOTATION: // fprintf (f, "%s", r->typeConvTbl[BASICTYPE_PRINTABLE_STR].cTypeName); // break; default: break; } } /* * given an AOID, a c value is produced. * This is used for turning ASN.1 OBJECT ID values * into usable c values. * * eg for the oid { 0 1 2 } (in AOID format) * * { * 2, * "\1\2" * } * is produced. */ void PrintCOidValue PARAMS ((f, r, oid), FILE *f _AND_ CRules *r _AND_ AsnOid *oid) { int i; fprintf (f, "{ "); fprintf (f, "%d, ",(int)oid->octetLen); fprintf (f, "\""); /* print encoded oid string in C's 'octal' escape format */ for (i = 0; i < (int)(oid->octetLen); i++) fprintf (f, "\\%o", (unsigned char)oid->octs[i]); fprintf (f, "\""); fprintf (f, " }"); r = r; /*AVOIDS warning.*/ } /* PrintCOidValue */ esnacc-ng-1.8.1/compiler/back-ends/c-gen/kwd.c000066400000000000000000000045341302010526100207360ustar00rootroot00000000000000/* * compiler/back-ends/c-gen/kwd.c - routines for determining whether a given str is a C keyword * * NOTE: this was hacked up really quickly. It uses a slow linear * search. A much better approach is to use a hash tbl. * * MS 92 * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/back-ends/c-gen/kwd.c,v 1.2 2003/07/07 14:53:38 nicholar Exp $ * $Log: kwd.c,v $ * Revision 1.2 2003/07/07 14:53:38 nicholar * Eliminated headers and cleaned up include references * * Revision 1.1.1.1 2000/08/21 20:36:05 leonberp * First CVS Version of SNACC. * * Revision 1.4 1995/07/25 18:45:38 rj * file name has been shortened for redundant part: c-gen/c-kwd -> c-gen/kwd. * * Revision 1.3 1994/10/08 03:48:06 rj * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long. * * Revision 1.2 1994/09/01 00:20:28 rj * snacc_config.h removed; more portable .h file inclusion. * * Revision 1.1 1994/08/28 09:48:13 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include "config.h" #include "snacc.h" #if STDC_HEADERS || HAVE_STRING_H #include #else #include #endif /* * last elmt must be NULL. * key words grabbed from K&R 2nd Ed */ static char *cKWdG[] = { "auto", "break", "case", "char", "const", "continue", "default", "do", "double", "else", "enum", "extern", "float", "for", "goto", "if", "int", "long", "register", "return", "short", "signed", "sizeof", "static", "struct", "switch", "typedef", "union", "unsigned", "void", "volatile", "while", NULL }; /* * returns non-zero if the given str is a C key word */ int IsCKeyWord PARAMS ((str), char *str) { int i; for (i=0; (cKWdG[i] != NULL) && (strcmp (cKWdG[i],str) != 0); i++) ; return cKWdG[i] != NULL; } esnacc-ng-1.8.1/compiler/back-ends/c-gen/rules.c000066400000000000000000000553721302010526100213110ustar00rootroot00000000000000/* * compiler/back-ends/c-gen/rules.c - initialized c rule structure * inits a table that contains info about * converting each ASN.1 type to C type * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/back-ends/c-gen/rules.c,v 1.9 2004/03/12 18:51:20 gronej Exp $ * $Log: rules.c,v $ * Revision 1.9 2004/03/12 18:51:20 gronej * updated c-library to error on extension additions as it does with untagged elements * * Revision 1.8 2004/01/14 19:07:53 gronej * Updated Compiler to accept and process relative-oid's * * Revision 1.7 2003/07/30 00:52:34 colestor * Modified "UTCTIme" reference to "UTCTime" to properly reference built-in type. * (Failed on "C" builds). * * Revision 1.6 2003/07/29 11:26:55 nicholar * Fixed EXTERNAL rules * * Revision 1.5 2003/07/07 14:53:38 nicholar * Eliminated headers and cleaned up include references * * Revision 1.4 2003/04/29 21:00:59 leonberp * integerated Deepak's changes for IOB support * * Revision 1.3 2002/05/20 19:39:12 leonberp * fixed typo * * Revision 1.2 2002/05/20 13:20:34 leonberp * removed bogus copy constructors, operator=, and made constructors inline for C++ String classes * * Revision 1.1.1.1 2000/08/21 20:36:05 leonberp * First CVS Version of SNACC. * * Revision 1.3 1995/07/25 18:46:34 rj * file name has been shortened for redundant part: c-gen/c-rules -> c-gen/rules. * * Revision 1.2 1994/09/01 00:24:35 rj * snacc_config.h removed. * * Revision 1.1 1994/08/28 09:48:35 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include "asn-incl.h" #include "asn1module.h" #include "rules.h" /* * (see rule.h and asn1module.h) * */ // Deepak: ~~~~~~~~~~~~~ Notes 30/Nov/2002 ~~~~~~~~~~~~~~~ // Any new initialization should be added to the following whenever a new type is added to struct BasicType. // so whatever is added here, should be at the same place as in the BasicType initialization in asn1module.h CRules cRulesG = { 4, "choiceId", "ChoiceId", "a", "ChoiceUnion", TRUE, "Print", "Enc", "Dec", "Free", { { BASICTYPE_UNKNOWN, C_NO_TYPE, NULL, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, "NOT_NULL", "unknown", NULL, NULL, NULL, NULL, FALSE, FALSE, FALSE, FALSE, FALSE }, { BASICTYPE_BOOLEAN, C_LIB, "AsnBool", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, "NOT_NULL", "bool", "PrintAsnBool", "EncAsnBool", "DecAsnBool", "FreeAsnBool", TRUE, TRUE, TRUE, TRUE, TRUE }, { BASICTYPE_INTEGER, C_LIB, "AsnInt", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, "NOT_NULL", "int", "PrintAsnInt", "EncAsnInt", "DecAsnInt", "FreeAsnInt", TRUE, TRUE, TRUE, TRUE, TRUE }, { BASICTYPE_BITSTRING, C_LIB, "AsnBits", FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, "ASNBITS_PRESENT", "bits", "PrintAsnBits", "EncAsnBits", "DecAsnBits", "FreeAsnBits", TRUE, TRUE, TRUE, TRUE, TRUE }, { BASICTYPE_OCTETSTRING, C_LIB, "AsnOcts", FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, "ASNOCTS_PRESENT", "octs", "PrintAsnOcts", "EncAsnOcts", "DecAsnOcts", "FreeAsnOcts", TRUE, TRUE, TRUE, TRUE, TRUE }, { BASICTYPE_NULL, C_LIB, "AsnNull", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, "NOT_NULL", "null", "PrintAsnNull", "EncAsnNull", "DecAsnNull", "FreeAsnNull", TRUE, TRUE, TRUE, TRUE, TRUE }, { BASICTYPE_OID, C_LIB, "AsnOid", FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, "ASNOID_PRESENT", "oid", "PrintAsnOid", "EncAsnOid", "DecAsnOid", "FreeAsnOid", TRUE, TRUE, TRUE, TRUE, TRUE }, { BASICTYPE_REAL, C_LIB, "AsnReal", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, "NOT_NULL", "real", "PrintAsnReal", "EncAsnReal", "DecAsnReal", "FreeAsnReal", TRUE, TRUE, TRUE, TRUE, TRUE }, { BASICTYPE_ENUMERATED, C_LIB, "enum", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, "NOT_NULL", "enum", "PrintAsnEnum", "EncAsnEnum", "DecAsnEnum", "FreeAsnEnum", TRUE, TRUE, TRUE, TRUE, TRUE }, { BASICTYPE_SEQUENCE, C_STRUCT, "struct", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, "NOT_NULL", "seq", NULL, NULL, NULL, NULL, TRUE, TRUE, TRUE, TRUE, TRUE }, { BASICTYPE_SEQUENCEOF, C_LIST, "AsnList", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, "NOT_NULL", "list", NULL, NULL, NULL, NULL, TRUE, TRUE, TRUE, TRUE, TRUE }, { BASICTYPE_SET, C_STRUCT, "struct", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, "NOT_NULL", "set", NULL, NULL, NULL, NULL, TRUE, TRUE, TRUE, TRUE, TRUE }, { BASICTYPE_SETOF, C_LIST, "AsnList", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, "NOT_NULL", "list", NULL, NULL, NULL, NULL, TRUE, TRUE, TRUE, TRUE, TRUE }, { BASICTYPE_CHOICE, C_CHOICE, NULL, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, "NOT_NULL", "choice", NULL, NULL, NULL, NULL, TRUE, TRUE, TRUE, TRUE, TRUE }, { BASICTYPE_SELECTION, C_NO_TYPE, NULL, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, "NOT_NULL", "selection", NULL, NULL, NULL, NULL, TRUE, TRUE, TRUE, TRUE, TRUE }, { BASICTYPE_COMPONENTSOF, C_NO_TYPE, NULL, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, "NOT_NULL", "compsOf", NULL, NULL, NULL, NULL, TRUE, TRUE, TRUE, TRUE, TRUE }, { BASICTYPE_ANY, C_ANY, "AsnAny", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, "ASNANY_PRESENT", "any", "PrintAsnAny", "EncAsnAny", "DecAsnAny", "FreeAsnAny", TRUE, TRUE, TRUE, TRUE, TRUE }, { BASICTYPE_ANYDEFINEDBY, C_ANYDEFINEDBY, "AsnAnyDefinedBy", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, "ASNANY_PRESENT", "anyDefBy", "PrintAsnAnyDefinedBy", "EncAsnAnyDefinedBy", "DecAsnAnyDefinedBy", "FreeAsnAnyDefinedBy", TRUE, TRUE, TRUE, TRUE, TRUE }, { BASICTYPE_LOCALTYPEREF, C_TYPEREF, NULL, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, "NOT_NULL", "t", NULL, NULL, NULL, NULL, TRUE, TRUE, TRUE, TRUE, TRUE }, { BASICTYPE_IMPORTTYPEREF, C_TYPEREF, NULL, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, "NOT_NULL", "t", NULL, NULL, NULL, NULL, TRUE, TRUE, TRUE, TRUE, TRUE }, { BASICTYPE_MACROTYPE, C_MACROTYPE, // C_NO_TYPE, // Deepak: 17/Apr/2003 NULL, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, "NOT_NULL", "macroType", NULL, NULL, NULL, NULL, TRUE,// FALSE, // Deepak: 17/Apr/2003 TRUE,// FALSE, // Deepak: 17/Apr/2003 TRUE,// FALSE, // Deepak: 17/Apr/2003 TRUE,// FALSE, // Deepak: 17/Apr/2003 TRUE // FALSE // Deepak: 17/Apr/2003 }, { BASICTYPE_MACRODEF, C_NO_TYPE, NULL, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, "NOT_NULL", "macroDef", NULL, NULL, NULL, NULL, FALSE, FALSE, FALSE, FALSE, FALSE }, { BASICTYPE_NUMERIC_STR, C_LIB, "NumericString", FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, "ASNOCTS_PRESENT", "octs", "PrintAsnOcts", "EncNumericString", "DecNumericString", "FreeAsnOcts", TRUE, TRUE, TRUE, TRUE, TRUE }, { BASICTYPE_PRINTABLE_STR, C_LIB, "PrintableString", FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, "ASNOCTS_PRESENT", "octs", "PrintAsnOcts", "EncPrintableString", "DecPrintableString", "FreeAsnOcts", TRUE, TRUE, TRUE, TRUE, TRUE }, { BASICTYPE_UNIVERSAL_STR, C_LIB, "UniversalString", FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, "ASNOCTS_PRESENT", "octs", "PrintAsnOcts", "EncUniversalString", "DecUniversalString", "FreeAsnOcts", TRUE, TRUE, TRUE, TRUE, TRUE }, { BASICTYPE_IA5_STR, C_LIB, "IA5String", FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, "ASNOCTS_PRESENT", "octs", "PrintAsnOcts", "EncIA5String", "DecIA5String", "FreeAsnOcts", TRUE, TRUE, TRUE, TRUE, TRUE }, { BASICTYPE_BMP_STR, C_LIB, "BMPString", FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, "ASNOCTS_PRESENT", "octs", "PrintAsnOcts", "EncBMPString", "DecBMPString", "FreeAsnOcts", TRUE, TRUE, TRUE, TRUE, TRUE }, { BASICTYPE_UTF8_STR, C_LIB, "UTF8String", FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, "ASNOCTS_PRESENT", "octs", "PrintAsnOcts", "EncUTF8String", "DecUTF8String", "FreeAsnOcts", TRUE, TRUE, TRUE, TRUE, TRUE }, /* UTCTime */ { BASICTYPE_UTCTIME, C_LIB, "UTCTime", FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, "ASNOCTS_PRESENT", "octs", "PrintAsnOcts", "EncUTCTime", "DecUTCTime", "FreeAsnOcts", TRUE, TRUE, TRUE, TRUE, TRUE }, /* GeneralizedTime */ { BASICTYPE_GENERALIZEDTIME, C_LIB, "GeneralizedTime", FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, "ASNOCTS_PRESENT", "octs", "PrintAsnOcts", "EncGeneralizedTime", "DecGeneralizedTime", "FreeAsnOcts", TRUE, TRUE, TRUE, TRUE, TRUE }, /* GraphicString */ { BASICTYPE_GRAPHIC_STR, C_LIB, "GraphicString", FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, "ASNOCTS_PRESENT", "octs", "PrintAsnOcts", "EncGraphicString", "DecGraphicString", "FreeAsnOcts", TRUE, TRUE, TRUE, TRUE, TRUE }, /* VisibleString */ { BASICTYPE_VISIBLE_STR, C_LIB, "VisibleString", FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, "ASNOCTS_PRESENT", "octs", "PrintAsnOcts", "EncVisibleString", "DecVisibleString", "FreeAsnOcts", TRUE, TRUE, TRUE, TRUE, TRUE }, /* GeneralString */ { BASICTYPE_GENERAL_STR, C_LIB, "GeneralString", FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, "ASNOCTS_PRESENT", "octs", "PrintAsnOcts", "EncGeneralString", "DecGeneralString", "FreeAsnOcts", TRUE, TRUE, TRUE, TRUE, TRUE }, /* ObjectDescriptor */ { BASICTYPE_OBJECTDESCRIPTOR, C_LIB, "ObjectDescriptor", FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, "ASNOCTS_PRESENT", "octs", "PrintAsnOcts", "EncObjectDescriptor", "DecObjectDescriptor", "FreeAsnOcts", TRUE, TRUE, TRUE, TRUE, TRUE }, /* VideotexString */ { BASICTYPE_VIDEOTEX_STR, C_LIB, "VideotexString", FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, "ASNOCTS_PRESENT", "octs", "PrintAsnOcts", "EncVideotexString", "DecVideotexString", "FreeAsnOcts", TRUE, TRUE, TRUE, TRUE, TRUE }, /* TeletexString */ { BASICTYPE_T61_STR, C_LIB, "TeletexString", FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, "ASNOCTS_PRESENT", "octs", "PrintAsnOcts", "EncTeletexString", "DecTeletexString", "FreeAsnOcts", TRUE, TRUE, TRUE, TRUE, TRUE }, /* EXTERNAL */ { BASICTYPE_EXTERNAL, C_LIB, "EXTERNAL", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, "NOT_NULL", "ext", "PrintEXTERNAL", "EncEXTERNAL", "DecEXTERNAL", "FreeEXTERNAL", TRUE, TRUE, TRUE, TRUE, TRUE }, /* REN -- 3 July 2003 -- This next type will need C back-end modifications Added to complete array */ { BASICTYPE_OCTETCONTAINING, C_LIB, "AsnOcts", FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, "ASNOCTS_PRESENT", "octs", "PrintAsnOcts", "EncAsnOcts", "DecAsnOcts", "FreeAsnOcts", TRUE, TRUE, TRUE, TRUE, TRUE }, /* REN -- 3 July 2003 -- This next type will need C back-end modifications. Added to complete array */ { BASICTYPE_BITCONTAINING, C_LIB, "AsnBits", FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, "ASNBITS_PRESENT", "bits", "PrintAsnBits", "EncAsnBits", "DecAsnBits", "FreeAsnBits", TRUE, TRUE, TRUE, TRUE, TRUE }, { BASICTYPE_RELATIVE_OID, C_LIB, "AsnRelativeOid", FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, "ASNRELATIVEOID_PRESENT", "oid", "PrintAsnRelativeOid", "EncAsnRelativeOid", "DecAsnRelativeOid", "FreeAsnRelativeOid", TRUE, TRUE, TRUE, TRUE, TRUE }, { BASICTYPE_EXTENSION, C_LIB, "AsnExtension", FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, "ASNEXTENSION_PRESENT", "extension", "PrintAsnExtension", "EncAsnExtension", "DecAsnExtension", "FreeAsnExtension", TRUE, TRUE, TRUE, TRUE, TRUE }, // Deepak: 30/Nov/2002, read Note above { BASICTYPE_SEQUENCET, C_STRUCT, "struct", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, "NOT_NULL", "seq", NULL, NULL, NULL, NULL, TRUE, TRUE, TRUE, TRUE, TRUE }, { // Deepak: 11/Dec/2002 BASICTYPE_OBJECTCLASS, C_OBJECTCLASS, //C_NO_TYPE, "struct", //NULL, FALSE, // isPdu FALSE, // isEncDec FALSE, // isPtrForTypeDef TRUE, // TRUE, // isPtrForTypeRef TRUE, // FALSE, // isPtrInChoice TRUE, // FALSE, // isPtrForOpt; "NOT_NULL", "objectclass", NULL, NULL, NULL, NULL, FALSE, FALSE, FALSE, FALSE, TRUE }, //*/ { // Deepak: 04/Feb/2003 BASICTYPE_OBJECTCLASSFIELDTYPE, C_OBJECTCLASSFIELDTYPE, "AsnOcts", // 31/Mar/2003 NULL, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, "NOT_NULL", "octs", // 31/Mar/2003 "objectClassFieldType", "PrintAsnOcts", // 31/Mar/2003 NULL, "EncAsnOcts", // 31/Mar/2003 NULL, "DecAsnOcts", // 31/Mar/2003 NULL, "FreeAsnOcts", // 31/Mar/2003 NULL, TRUE, TRUE, TRUE, TRUE, TRUE } } }; esnacc-ng-1.8.1/compiler/back-ends/c-gen/rules.h000066400000000000000000000037021302010526100213040ustar00rootroot00000000000000/* * compiler/back-ends/c-gen/rules.h * * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/back-ends/c-gen/rules.h,v 1.2 2003/07/07 14:53:38 nicholar Exp $ * $Log: rules.h,v $ * Revision 1.2 2003/07/07 14:53:38 nicholar * Eliminated headers and cleaned up include references * * Revision 1.1.1.1 2000/08/21 20:36:05 leonberp * First CVS Version of SNACC. * * Revision 1.3 1995/07/25 18:46:35 rj * file name has been shortened for redundant part: c-gen/c-rules -> c-gen/rules. * * Revision 1.2 1994/10/08 03:48:16 rj * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long. * * Revision 1.1 1994/08/28 09:48:36 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ /* see asn1module.h for CTDI (C type def info) */ typedef struct CRules { int maxDigitsToAppend; char *choiceIdFieldName; /* name of choiceId field */ char *choiceIdEnumSuffix; /* suffix for choiceId enum def name */ char *choiceUnionFieldName; /* what the name of the choice's union is */ char *choiceUnionDefSuffix; /* suffix for choice union def name */ int capitalizeNamedElmts; char *printRoutineBaseName; /* eg if "Print" -> PrintFoo (..) */ char *encodeRoutineBaseName; char *decodeRoutineBaseName; char *freeRoutineBaseName; CTDI typeConvTbl[BASICTYPE_OBJECTCLASSFIELDTYPE + 1]; } CRules; extern CRules cRulesG; esnacc-ng-1.8.1/compiler/back-ends/c-gen/type-info.c000066400000000000000000001037251302010526100220650ustar00rootroot00000000000000/* * compiler/back-ends/c-gen/type-info.c - fills in c type information * * MS 91/92 * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/back-ends/c-gen/type-info.c,v 1.9 2004/03/25 19:20:16 gronej Exp $ * $Log: type-info.c,v $ * Revision 1.9 2004/03/25 19:20:16 gronej * fixed some linux warnings * * Revision 1.8 2003/07/31 18:33:23 colestor * Updated to reflect newly added ANY processing as AsnOcts. All built code will * now compile directly. * * Revision 1.7 2003/07/14 21:07:34 nicholar * Changed how parser handles --snacc directives. Added namespace option. * * Revision 1.6 2003/07/07 14:53:38 nicholar * Eliminated headers and cleaned up include references * * Revision 1.5 2003/04/29 21:00:53 leonberp * integerated Deepak's changes for IOB support * * Revision 1.4 2002/09/16 17:35:06 mcphersc * Fixed warnings * * Revision 1.3 2002/09/04 18:02:17 vracarl * got rid of c++ comments * * Revision 1.2 2000/10/24 14:54:48 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:36:05 leonberp * First CVS Version of SNACC. * * Revision 1.3 1995/07/25 18:47:45 rj * changed `_' to `-' in file names. * * Revision 1.2 1994/09/01 00:26:44 rj * snacc_config.h removed. * * Revision 1.1 1994/08/28 09:48:42 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include #include #include "asn-incl.h" #include "asn1module.h" #include "snacc-util.h" #include "str-util.h" #include "rules.h" static DefinedObj *definedNamesG; /* * All Typedefs, union,struct & enum Tags, and definedvalues (enum consts) * are assumed to share the same name space - this list is used to * assure uniqueness. (actually 4 name spaces in C - see pg 227 KR 2nd Ed) */ /* unexported prototypes */ static void FillCTypeDefInfo PROTO ((CRules *r, Module *m, TypeDef *td)); static void FillCFieldNames PROTO ((CRules *r, NamedTypeList *firstSibling)); static void FillCTypeRefInfo PROTO ((CRules *r, Module *m, TypeDef *head, Type *t, CTypeId parentTypeId)); static void FillCStructElmts PROTO ((CRules *r, Module *m, TypeDef *head, NamedTypeList *t)); static void FillCChoiceElmts PROTO ((CRules *r, Module *m, TypeDef *head, NamedTypeList *first)); static int IsCPtr PROTO ((CRules *r, TypeDef *td, Type *t, CTypeId parentTypeId)); const char* GetDirectiveName(SnaccDirectiveEnum dirType); static void ParseTypeDefAttribs PROTO ((CTDI *ctdi, SnaccDirectiveList *attrList)); static void ParseTypeRefAttribs PROTO ((CTRI *ctri, SnaccDirectiveList *attrList)); static void FillCTDIDefaults PROTO ((CRules *r, CTDI *ctdi, TypeDef *td)); /* * allocates and fills all the "cTypeDefInfo" for each type def * and "cTypeRefInfo" for each type in the given modules. * Also does the useful types module if it is not null. */ void FillCTypeInfo PARAMS ((r, modList), CRules *r _AND_ ModuleList *modList) { TypeDef *td; Module *m; /* * go through each module's type defs and fill * in the C type and enc/dec routines etc */ definedNamesG = NewObjList(); FOR_EACH_LIST_ELMT (m, modList) { FOR_EACH_LIST_ELMT (td, m->typeDefs) FillCTypeDefInfo (r, m, td); } /* * now that type def info is filled in * set up set/seq/list/choice elements that ref * those definitions */ FOR_EACH_LIST_ELMT (m, modList) { FOR_EACH_LIST_ELMT (td, m->typeDefs) FillCTypeRefInfo (r, m, td, td->type, C_TYPEDEF); } /* * modules compiled together (ie one call to snacc with * multiple args) likely to be C compiled together so * need a unique routines/types/defines/enum values * since assuming they share same name space. * All Typedefs, union, struct & enum Tags, and defined values * (enum consts), #define names * are assumed to share the same name space */ FreeDefinedObjs (&definedNamesG); } /* FillCTypeInfo */ /* * allocates and fills structure holding C type definition information * fo the given ASN.1 type definition. Does not fill CTRI for contained * types etc. */ void FillCTypeDefInfo PARAMS ((r, m, td), CRules *r _AND_ Module *m _AND_ TypeDef *td) { int len; char *tmpName; CTDI *ctdi; /* * if CTDI is present this type def has already been 'filled' */ if (td->cTypeDefInfo != NULL) return; ctdi = td->cTypeDefInfo = MT (CTDI); ctdi->cTypeId = C_TYPEDEF; /* get default type def attributes from table for type on rhs of ::= */ FillCTDIDefaults (r, ctdi, td); /* * if defined by a ref to another type definition fill in that type * def's CTDI so can inherit (actully completly replace default * attributes) from it */ if ((td->type->basicType->choiceId == BASICTYPE_LOCALTYPEREF) || (td->type->basicType->choiceId == BASICTYPE_IMPORTTYPEREF)) { /* * Fill in CTDI for defining type if nec. * this works for importTypeRef as well since both a.localTypeRef * and a.importTypeRef are of type TypeRef */ FillCTypeDefInfo (r, td->type->basicType->a.localTypeRef->module, td->type->basicType->a.localTypeRef->link); memcpy (ctdi, td->type->basicType->a.localTypeRef->link->cTypeDefInfo, sizeof (CTDI)); } /* * Zap default names for routines/type with NULL so * can determine if the --snacc attributes specified any */ ctdi->cTypeName = NULL; ctdi->printRoutineName = NULL; ctdi->encodeRoutineName = NULL; ctdi->decodeRoutineName = NULL; ctdi->freeRoutineName = NULL; /* * check for any "--snacc" attributes that overide the current * ctdi fields */ ParseTypeDefAttribs (ctdi, td->attrList); /* If BigInt's used, then reset the default type def attributes */ /* if (ctdi->asn1TypeId == BASICTYPE_BIGINT) { td->type->basicType->choiceId = BASICTYPE_BIGINT; } */ /* * generate c typename for this type def if not given by * --snacc attributes */ if (ctdi->cTypeName == NULL) { tmpName = Asn1TypeName2CTypeName (td->definedName); len = strlen (tmpName); ctdi->cTypeName = Malloc (len + r->maxDigitsToAppend + 1); strcpy (ctdi->cTypeName, tmpName); Free (tmpName); /* * make sure c type def name is unique * (no need to check if cTypeName was specified by --snacc attribs) */ MakeCStrUnique (definedNamesG, ctdi->cTypeName,r->maxDigitsToAppend, 1); DefineObj (&definedNamesG, ctdi->cTypeName); } /* * make names for encoder,decoder, print and free routines * (if not already set by --snacc attributes */ if (ctdi->encodeRoutineName == NULL) { ctdi->encodeRoutineName = Malloc (strlen (ctdi->cTypeName) + strlen (r->encodeRoutineBaseName) + 1); strcpy (ctdi->encodeRoutineName, r->encodeRoutineBaseName); strcat (ctdi->encodeRoutineName, ctdi->cTypeName); } if (ctdi->decodeRoutineName == NULL) { ctdi->decodeRoutineName = Malloc (strlen (ctdi->cTypeName) + strlen (r->decodeRoutineBaseName) + 1); strcpy (ctdi->decodeRoutineName, r->decodeRoutineBaseName); strcat (ctdi->decodeRoutineName, ctdi->cTypeName); } if (ctdi->printRoutineName == NULL) { ctdi->printRoutineName = Malloc (strlen (ctdi->cTypeName) + strlen (r->printRoutineBaseName) + 1); strcpy (ctdi->printRoutineName, r->printRoutineBaseName); strcat (ctdi->printRoutineName, ctdi->cTypeName); } if (ctdi->freeRoutineName == NULL) { ctdi->freeRoutineName = Malloc (strlen (ctdi->cTypeName) + strlen (r->freeRoutineBaseName) + 1); strcpy (ctdi->freeRoutineName, r->freeRoutineBaseName); strcat (ctdi->freeRoutineName, ctdi->cTypeName); } m = m; /*AVOIDS warning.*/ } /* FillCTypeDefInfo */ static void FillCTypeRefInfo PARAMS ((r, m, head, t, parentTypeId), CRules *r _AND_ Module *m _AND_ TypeDef *head _AND_ Type *t _AND_ CTypeId parentTypeId) { CTRI *ctri; CTDI *tmpCtdi; ValueDef *namedElmt; CNamedElmt *cne; CNamedElmt **cneHndl; char *elmtName; char *unionName; enum BasicTypeChoiceId basicTypeId; int len; /* * you must check for cycles yourself before calling this */ if (t->cTypeRefInfo == NULL) { ctri = MT (CTRI); t->cTypeRefInfo = ctri; } else ctri = t->cTypeRefInfo; basicTypeId = t->basicType->choiceId; tmpCtdi = &r->typeConvTbl[basicTypeId]; // Deepak: 31/Mar/2003 // change typeId here so that C_OBJECTCLASSFIELDTYPE could automatically behave as C_LIB if(tmpCtdi->cTypeId == C_OBJECTCLASSFIELDTYPE) tmpCtdi->cTypeId = C_LIB; /* get base type def info from the conversion table in the rules */ /* if the cTypeId is C_LIB, nothing more needs to be done */ ctri->cTypeId = tmpCtdi->cTypeId; ctri->cTypeName = tmpCtdi->cTypeName; ctri->optTestRoutineName = tmpCtdi->optTestRoutineName; ctri->printRoutineName = tmpCtdi->printRoutineName; ctri->encodeRoutineName = tmpCtdi->encodeRoutineName; ctri->decodeRoutineName = tmpCtdi->decodeRoutineName; ctri->freeRoutineName = tmpCtdi->freeRoutineName; ctri->isEncDec = tmpCtdi->isEncDec; if (ctri->cTypeId == C_ANY) { /*RWC;fprintf (errFileG, "Warning - generated code for the \"ANY\" type in type \"%s\" will need modification by YOU.", head->definedName); fprintf (errFileG, " The source files will have a \"/\ * ANY - Fix Me! * /\" comment before related code.\n\n");*RWC;*/ } /* * convert named elmts to C. * check for name conflict with other defined Types/Names/Values */ if ((basicTypeId == BASICTYPE_INTEGER || basicTypeId == BASICTYPE_ENUMERATED || basicTypeId == BASICTYPE_BITSTRING) && !(LIST_EMPTY (t->basicType->a.integer))) /* if ((basicTypeId == BASICTYPE_INTEGER || basicTypeId == BASICTYPE_ENUMERATED || basicTypeId == BASICTYPE_BITSTRING) && !(LIST_EMPTY (t->basicType->a.integer))) */ { ctri->cNamedElmts = AsnListNew (sizeof (void *)); FOR_EACH_LIST_ELMT (namedElmt, t->basicType->a.integer) { cneHndl = (CNamedElmt **)AsnListAppend (ctri->cNamedElmts); cne = *cneHndl = MT (CNamedElmt); elmtName = Asn1ValueName2CValueName (namedElmt->definedName); len = strlen (elmtName); cne->name = Malloc (len + 1 + r->maxDigitsToAppend); strcpy (cne->name, elmtName); Free (elmtName); /* not very efficient */ if (namedElmt->value->basicValue->choiceId == BASICVALUE_INTEGER) cne->value = namedElmt->value->basicValue->a.integer; else { fprintf (errFileG, "Warning: unlinked defined value using -9999999\n"); cne->value = -9999999; } if (r->capitalizeNamedElmts) Str2UCase (cne->name, len); /* * append digits until there is not name conflict * if nec */ MakeCStrUnique (definedNamesG, cne->name, r->maxDigitsToAppend, 1); DefineObj (&definedNamesG, cne->name); } } /* * Fill in c type name, routines, ptr attibutes etc */ if (r->typeConvTbl[basicTypeId].cTypeId == C_TYPEREF) { /* * don't do this anymore - it cause problems since FillTypeDef * changes name ie ORName -> ORName1 and other type use new name * * don't define type or print/enc/dec/free routines * if typedef name is the same as the defining type ref name * in P2: ORName ::= P1.ORName if ((parentTypeId == C_TYPEDEF) && (strcmp (head->definedName, t->basicType->a.localTypeRef->typeName) == 0)) { tmpCtdi = head->cTypeDefInfo; tmpCtdi->genPrintRoutine = FALSE; tmpCtdi->genEncodeRoutine = FALSE; tmpCtdi->genDecodeRoutine = FALSE; tmpCtdi->genFreeRoutine = FALSE; tmpCtdi->genTypeDef = FALSE; } */ /* * grab type name from link (link is the def of the * the ref'd type) */ if (t->basicType->a.localTypeRef->link != NULL) { /* inherit attributes from referenced type */ tmpCtdi= t->basicType->a.localTypeRef->link->cTypeDefInfo; ctri->cTypeName = tmpCtdi->cTypeName; ctri->printRoutineName = tmpCtdi->printRoutineName; ctri->encodeRoutineName = tmpCtdi->encodeRoutineName; ctri->decodeRoutineName = tmpCtdi->decodeRoutineName; ctri->freeRoutineName = tmpCtdi->freeRoutineName; ctri->isEncDec = tmpCtdi->isEncDec; ctri->optTestRoutineName = tmpCtdi->optTestRoutineName; } else { /* * guess type and routine names */ fprintf (errFileG, "Assuming C Type and Routine names for unresolved type ref \"%s\"\n", t->basicType->a.localTypeRef->typeName); ctri->cTypeName = Asn1TypeName2CTypeName (t->basicType->a.localTypeRef->typeName); ctri->printRoutineName = Malloc (strlen (r->printRoutineBaseName) + strlen (ctri->cTypeName) + 1); strcpy (ctri->printRoutineName, r->printRoutineBaseName); strcat (ctri->printRoutineName, ctri->cTypeName); ctri->encodeRoutineName = Malloc (strlen (r->encodeRoutineBaseName)+ strlen (ctri->cTypeName) + 1); strcpy (ctri->encodeRoutineName, r->encodeRoutineBaseName); strcat (ctri->encodeRoutineName, ctri->cTypeName); ctri->decodeRoutineName = Malloc (strlen (r->decodeRoutineBaseName)+ strlen (ctri->cTypeName) + 1); strcpy (ctri->decodeRoutineName, r->decodeRoutineBaseName); strcat (ctri->decodeRoutineName, ctri->cTypeName); ctri->freeRoutineName = Malloc (strlen (ctri->cTypeName) + strlen (r->freeRoutineBaseName) + 1); strcpy (ctri->freeRoutineName, r->freeRoutineBaseName); strcat (ctri->freeRoutineName, ctri->cTypeName); } } // Deepak: 05/Feb/2003 #ifdef DEEPAK else if (r->typeConvTbl[basicTypeId].cTypeId == C_OBJECTCLASSFIELDTYPE) { /* * grab type name from link (link is the def of the * the ref'd type) */ if (t->basicType->a.localTypeRef->namedTypeLink != NULL) { /* inherit attributes from referenced type */ /* tmpCtdi= t->basicType->a.localTypeRef->namedTypeLink->type->cTypeRefInfo; ctri->cTypeName = tmpCtdi->cTypeName; ctri->printRoutineName = tmpCtdi->printRoutineName; ctri->encodeRoutineName = tmpCtdi->encodeRoutineName; ctri->decodeRoutineName = tmpCtdi->decodeRoutineName; ctri->freeRoutineName = tmpCtdi->freeRoutineName; ctri->isEncDec = tmpCtdi->isEncDec; ctri->optTestRoutineName = tmpCtdi->optTestRoutineName; */ } else { /* * guess type and routine names */ fprintf (errFileG, "Assuming C Type and Routine names for unresolved type ref \"%s\"\n", t->basicType->a.localTypeRef->typeName); ctri->cTypeName = Asn1TypeName2CTypeName (t->basicType->a.localTypeRef->typeName); ctri->printRoutineName = Malloc (strlen (r->printRoutineBaseName) + strlen (ctri->cTypeName) + 1); strcpy (ctri->printRoutineName, r->printRoutineBaseName); strcat (ctri->printRoutineName, ctri->cTypeName); ctri->encodeRoutineName = Malloc (strlen (r->encodeRoutineBaseName)+ strlen (ctri->cTypeName) + 1); strcpy (ctri->encodeRoutineName, r->encodeRoutineBaseName); strcat (ctri->encodeRoutineName, ctri->cTypeName); ctri->decodeRoutineName = Malloc (strlen (r->decodeRoutineBaseName)+ strlen (ctri->cTypeName) + 1); strcpy (ctri->decodeRoutineName, r->decodeRoutineBaseName); strcat (ctri->decodeRoutineName, ctri->cTypeName); ctri->freeRoutineName = Malloc (strlen (ctri->cTypeName) + strlen (r->freeRoutineBaseName) + 1); strcpy (ctri->freeRoutineName, r->freeRoutineBaseName); strcat (ctri->freeRoutineName, ctri->cTypeName); } } #endif // DEEPAK else if (r->typeConvTbl[basicTypeId].cTypeId == C_OBJECTCLASS) { // Deepak: 11/Mar/2003 //FillCTypeRefInfo (r, m, head, t->basicType->a.objectclass->classdef, C_LIST); unionName = Malloc (strlen (head->cTypeDefInfo->cTypeName) +1); strcpy (unionName, head->cTypeDefInfo->cTypeName); ctri->cTypeName = unionName; FillCStructElmts (r, m, head, t->basicType->a.objectclass->classdef); // Deepak: All the elements in this structure are filled here. FillCFieldNames (r, t->basicType->a.objectclass->classdef); // Deepak: All the identifiers are stored over here. } else if (r->typeConvTbl[basicTypeId].cTypeId == C_LIST) { /* * List types (SET OF/ SEQ OF) * fill in component type */ FillCTypeRefInfo (r, m, head, t->basicType->a.setOf, C_LIST); } else if (r->typeConvTbl[basicTypeId].cTypeId == C_CHOICE) { /* * Choice - set up choice Id elmt names, choiceid enum name * choiceid enum fieldName, choice union name. * this will only be the first type in the typedef * ie will not be embedded (those are turned into type * refs in nomalize.c) */ /* * make union name (tag) from enclosing typedefs name plus "Choice" * put in the cTypeName part. (the typeDef name is already unique * but make sure union tag/name does not conflict with other types) */ len = strlen (head->cTypeDefInfo->cTypeName); unionName = (char*) Malloc (len + strlen (r->choiceUnionDefSuffix) + r->maxDigitsToAppend + 1); strcpy (unionName, head->cTypeDefInfo->cTypeName); strcat (unionName, r->choiceUnionDefSuffix); MakeCStrUnique (definedNamesG, unionName, r->maxDigitsToAppend, 1); DefineObj (&definedNamesG, unionName); ctri->cTypeName = unionName; ctri->choiceIdEnumName = Malloc (len + strlen (r->choiceIdEnumSuffix) + r->maxDigitsToAppend + 1); strcpy (ctri->choiceIdEnumName, head->cTypeDefInfo->cTypeName); strcat (ctri->choiceIdEnumName, r->choiceIdEnumSuffix); MakeCStrUnique (definedNamesG, ctri->choiceIdEnumName, r->maxDigitsToAppend, 1); DefineObj (&definedNamesG, ctri->choiceIdEnumName); ctri->choiceIdEnumFieldName = r->choiceIdFieldName; /* "choiceId" */ ctri->cFieldName = r->choiceUnionFieldName; /* "a" */ /* * must fill field names BEFORE filling choice elmts * (allows better naming for choice ids */ FillCFieldNames (r, t->basicType->a.choice); FillCChoiceElmts (r, m, head, t->basicType->a.choice); } else if (r->typeConvTbl[basicTypeId].cTypeId == C_STRUCT) { /* * SETs and SEQUENCEs */ /* * make struct name (tag) (the typeDef name is already unique) * the same as the enclosing typeDef */ unionName = Malloc (strlen (head->cTypeDefInfo->cTypeName) +1); strcpy (unionName, head->cTypeDefInfo->cTypeName); ctri->cTypeName = unionName; FillCStructElmts (r, m, head, t->basicType->a.set); // Deepak: All the elements in this structure are filled here. FillCFieldNames (r, t->basicType->a.set); // Deepak: All the identifiers are stored over here. } else if (r->typeConvTbl[basicTypeId].cTypeId == C_MACROTYPE) { // Deepak: 17/Apr/2003 /* * Macro Types */ /* * make struct name (tag) (the typeDef name is already unique) * the same as the enclosing typeDef */ unionName = Malloc (strlen (head->cTypeDefInfo->cTypeName) +1); strcpy (unionName, head->cTypeDefInfo->cTypeName); ctri->cTypeName = unionName; switch(t->basicType->a.macroType->choiceId) { case MACROTYPE_ASNABSTRACTOPERATION: case MACROTYPE_ROSOPERATION: if(t->basicType->a.macroType->a.rosOperation->arguments != NULL) FillCTypeRefInfo (r, m, head, t->basicType->a.macroType->a.rosOperation->arguments->type, C_MACROTYPE); if(t->basicType->a.macroType->a.rosOperation->result != NULL) FillCTypeRefInfo (r, m, head, t->basicType->a.macroType->a.rosOperation->result->type, C_MACROTYPE); break; default: break; } } /* * figure out whether this is a ptr based on the enclosing * type (if any) and optionality/default */ ctri->isPtr = (unsigned char)IsCPtr (r, head, t, parentTypeId); // ????? check for C_MACROTYPE /* let user overide any defaults with the --snacc attributes */ ParseTypeRefAttribs (ctri, t->attrList); /* Check for bigint conversion */ /* if (strcmp(ctri->cTypeName, "AsnBigInt") == 0) { t->basicType->choiceId = BASICTYPE_BIGINT; } */ } /* FillCTypeRefInfo */ static void FillCStructElmts PARAMS ((r, m, head, elmts), CRules *r _AND_ Module *m _AND_ TypeDef *head _AND_ NamedTypeList *elmts) { NamedType *et; FOR_EACH_LIST_ELMT (et, elmts) // Take struct elements one by one. { FillCTypeRefInfo (r, m, head, et->type, C_STRUCT); } } /* FillCStructElmts */ /* * Figures out non-conflicting enum names for the * choice id's */ static void FillCChoiceElmts PARAMS ((r, m, head, elmts), CRules *r _AND_ Module *m _AND_ TypeDef *head _AND_ NamedTypeList *elmts) { NamedType *et; int idCount = 0; CTRI *ctri; char *firstName; char *secondName; int len; /* * fill in type info for elmt types first */ FOR_EACH_LIST_ELMT (et, elmts) FillCTypeRefInfo (r, m, head, et->type, C_CHOICE); /* * set choiceId Symbol & value * eg * Car ::= CHOICE { typedef struct Car { * chev ChevCar, -> enum CarChoiceId { * ford FordCar CAR_CHEV, <- typename_fieldName * toyota ToyotaCar CAR_FORD, * } CAR_TOYOTA } choiceId; * union CarChoiceUnion { * ChevCar *chev; * FordCar *ford; * ToyotaCar *toyota; } a; * } */ FOR_EACH_LIST_ELMT (et, elmts) { ctri = et->type->cTypeRefInfo; if (ctri == NULL) continue; /* wierd type */ ctri->choiceIdValue = idCount++; firstName = Asn1TypeName2CTypeName (head->cTypeDefInfo->cTypeName); secondName = ctri->cFieldName; ctri->choiceIdSymbol = Malloc (strlen (firstName) + strlen (secondName) + 2 + r->maxDigitsToAppend); strcpy (ctri->choiceIdSymbol, firstName); strcat (ctri->choiceIdSymbol, "_"); strcat (ctri->choiceIdSymbol, secondName); Free (firstName); len = strlen (ctri->choiceIdSymbol); if (r->capitalizeNamedElmts) Str2UCase (ctri->choiceIdSymbol, len); MakeCStrUnique (definedNamesG, ctri->choiceIdSymbol, r->maxDigitsToAppend, 0); DefineObj (&definedNamesG, ctri->choiceIdSymbol); } } /* FillCChoiceElmts */ /* * takes a list of "sibling" (eg same level in a structure) * ElmtTypes and fills sets up the c field names in * the CTypeRefInfo struct */ static void FillCFieldNames PARAMS ((r, elmts), CRules *r _AND_ NamedTypeList *elmts) { NamedType *et; CTRI *ctri; DefinedObj *fieldNames; char *tmpName; char *asn1FieldName; char *cFieldName; fieldNames = NewObjList(); /* * Initialize fieldname data * allocate (if nec) and fill in CTRI fieldname if poss * from asn1 field name. leave blank otherwise */ FOR_EACH_LIST_ELMT (et, elmts) { ctri = et->type->cTypeRefInfo; if (ctri == NULL) { ctri = MT (CTRI); et->type->cTypeRefInfo = ctri; } if (et->fieldName != NULL) { asn1FieldName = et->fieldName; ctri->cFieldName = Asn1FieldName2CFieldName (asn1FieldName); DefineObj (&fieldNames, ctri->cFieldName); } } FOR_EACH_LIST_ELMT (et, elmts) { ctri = et->type->cTypeRefInfo; /* * generate field names for those without them */ if (ctri->cFieldName == NULL) { if ((et->type->basicType->choiceId == BASICTYPE_LOCALTYPEREF) || (et->type->basicType->choiceId == BASICTYPE_IMPORTTYPEREF)) { /* * take ref'd type name as field name * convert first let to lower case */ tmpName = et->type->basicType->a.localTypeRef->link->cTypeDefInfo->cTypeName; tmpName = Asn1TypeName2CTypeName (tmpName); cFieldName = Malloc (strlen (tmpName) + r->maxDigitsToAppend +1); strcpy (cFieldName, tmpName); Free (tmpName); if (isupper (cFieldName[0])) cFieldName[0] = (char)tolower (cFieldName[0]); } else { /* * get default field name for this type */ tmpName = r->typeConvTbl[et->type->basicType->choiceId].defaultFieldName; cFieldName = Malloc (strlen (tmpName) + r->maxDigitsToAppend +1); strcpy (cFieldName, tmpName); if (isupper (cFieldName[0])) cFieldName[0] = (char)tolower (cFieldName[0]); } MakeCStrUnique (fieldNames, cFieldName, r->maxDigitsToAppend, 1); DefineObj (&fieldNames, cFieldName); ctri->cFieldName = cFieldName; } } FreeDefinedObjs (&fieldNames); } /* FillCFieldNames */ /* * returns true if this c type for this type should be * be ref'd as a ptr */ static int IsCPtr PARAMS ((r, td, t, parentCTypeId), CRules *r _AND_ TypeDef *td _AND_ Type *t _AND_ CTypeId parentCTypeId) { CTDI *ctdi; int retVal = FALSE; /* * inherit ptr attriubutes from ref'd type if any * otherwise grab lib c type def from the CRules */ if ((t->basicType->choiceId == BASICTYPE_LOCALTYPEREF) || (t->basicType->choiceId == BASICTYPE_IMPORTTYPEREF)) { ctdi = t->basicType->a.localTypeRef->link->cTypeDefInfo; } else ctdi = &r->typeConvTbl[GetBuiltinType (t)]; if ((parentCTypeId == C_TYPEDEF) && (ctdi->isPtrForTypeDef)) retVal = TRUE; else if ((parentCTypeId == C_STRUCT) && (ctdi->isPtrForTypeRef)) retVal = TRUE; // Deepak: 18/Apr/2003 else if ((parentCTypeId == C_MACROTYPE) && (ctdi->isPtrForTypeRef)) retVal = TRUE; else if ((parentCTypeId == C_CHOICE) && (ctdi->isPtrInChoice)) retVal = TRUE; else if (((t->optional) || (t->defaultVal != NULL)) && (ctdi->isPtrForOpt)) retVal = TRUE; td = td; /*AVOIDS warning.*/ return retVal; } /* IsCPtr */ #define BAD_VALUE(attrValue, attrType)\ fprintf (errFileG, "Warning: ignoring attribute with improper value (%s/%s)\n",\ attrType, attrValue) /* * attrList is a list of strings that hold attribute value * pairs. A list is used in case the attr/value pairs are * given in multiple ASN.1 comments around the type. */ void ParseTypeDefAttribs PARAMS ((ctdi, attrList), CTDI *ctdi _AND_ SnaccDirectiveList *attrList) { SnaccDirective* pDirective; if (attrList == NULL) return; FOR_EACH_LIST_ELMT (pDirective, attrList) { switch (pDirective->type) { case ASN1_TypeID: ctdi->asn1TypeId = pDirective->value.asnTypeVal; break; case C_TypeID: ctdi->cTypeId = pDirective->value.cTypeVal; break; case C_TypeName: ctdi->cTypeName = pDirective->value.stringVal; break; case IsPDU: ctdi->isPdu = pDirective->value.boolVal; break; case IsPtrForTypeDef: ctdi->isPtrForTypeDef = pDirective->value.boolVal; break; case IsPtrForTypeRef: ctdi->isPtrForTypeRef = pDirective->value.boolVal; break; case IsPtrInChoice: ctdi->isPtrInChoice = pDirective->value.boolVal; break; case IsPtrForOpt: ctdi->isPtrForOpt = pDirective->value.boolVal; break; case OptionalTestRoutineName: ctdi->optTestRoutineName = pDirective->value.stringVal; break; case DefaultFieldName: ctdi->defaultFieldName = pDirective->value.stringVal; break; case PrintRoutineName: ctdi->printRoutineName = pDirective->value.stringVal; break; case EncodeRoutineName: ctdi->encodeRoutineName = pDirective->value.stringVal; break; case DecodeRoutineName: ctdi->decodeRoutineName = pDirective->value.stringVal; break; case FreeRoutineName: ctdi->freeRoutineName = pDirective->value.stringVal; break; case IsEncDec: ctdi->isEncDec = pDirective->value.boolVal; break; case GenTypeDef: ctdi->genTypeDef = pDirective->value.boolVal; break; case GenPrintRoutine: ctdi->genPrintRoutine = pDirective->value.boolVal; break; case GenEncodeRoutine: ctdi->genEncodeRoutine = pDirective->value.boolVal; break; case GenDecodeRoutine: ctdi->genDecodeRoutine = pDirective->value.boolVal; break; case GenFreeRoutine: ctdi->genFreeRoutine = pDirective->value.boolVal; break; default: fprintf (errFileG, "Warning: ignoring unrecognized type def attribute '%s'\n", GetDirectiveName(pDirective->type)); } } /* end for */ } /* ParseTypeDefAttribs */ void ParseTypeRefAttribs PARAMS ((ctri, attrList), CTRI *ctri _AND_ SnaccDirectiveList *attrList) { SnaccDirective* pDirective; if (attrList == NULL) return; FOR_EACH_LIST_ELMT (pDirective, attrList) { switch (pDirective->type) { case C_TypeID: ctri->cTypeId = pDirective->value.cTypeVal; break; case C_TypeName: ctri->cTypeName = pDirective->value.stringVal; break; case C_FieldName: ctri->cFieldName = pDirective->value.stringVal; break; case IsPtr: ctri->isPtr = pDirective->value.boolVal; break; case ChoiceIdValue: ctri->choiceIdValue = pDirective->value.integerVal; break; case ChoiceIdSymbol: ctri->choiceIdSymbol = pDirective->value.stringVal; break; case ChoiceIdEnumName: ctri->choiceIdEnumName = pDirective->value.stringVal; break; case ChoiceIdEnumFieldName: ctri->choiceIdEnumFieldName = pDirective->value.stringVal; break; case OptionalTestRoutineName: ctri->optTestRoutineName = pDirective->value.stringVal; break; case PrintRoutineName: ctri->printRoutineName = pDirective->value.stringVal; break; case EncodeRoutineName: ctri->encodeRoutineName = pDirective->value.stringVal; break; case DecodeRoutineName: ctri->decodeRoutineName = pDirective->value.stringVal; break; case FreeRoutineName: ctri->freeRoutineName = pDirective->value.stringVal; break; case IsEncDec: ctri->isEncDec = pDirective->value.boolVal; break; case IsBigInt: if (pDirective->value.boolVal) { ctri->cTypeName = "AsnBigInt"; ctri->printRoutineName = "PrintAsnBigInt"; ctri->encodeRoutineName = "EncAsnBigInt"; ctri->decodeRoutineName = "DecAsnBigInt"; ctri->freeRoutineName = "FreeAsnBigInt"; } break; default: fprintf (errFileG, "Warning: ignoring unrecognized type def attribute '%s'\n", GetDirectiveName(pDirective->type)); } } /* end of for loop */ } /* ParseTypeRefAttribs */ /* fill given ctdi with defaults from table for given typedef */ void FillCTDIDefaults PARAMS ((r, ctdi, td), CRules *r _AND_ CTDI *ctdi _AND_ TypeDef *td) { CTDI *tblCtdi; int typeIndex; typeIndex = GetBuiltinType (td->type); if (typeIndex < 0) return; tblCtdi = &r->typeConvTbl[typeIndex]; memcpy (ctdi, tblCtdi, sizeof (CTDI)); } const char* GetDirectiveName(SnaccDirectiveEnum dirType) { switch (dirType) { case ASN1_TypeID: return "asn1TypeId"; case C_TypeID: return "cTypeId"; case C_TypeName: return "cTypeName"; case C_FieldName: return "cFieldName"; case IsPDU: return "isPdu"; case IsPtr: return "isPtr"; case IsPtrForTypeDef: return "isPtrForTypeDef"; case IsPtrForTypeRef: return "isPtrForTypeRef"; case IsPtrInChoice: return "isPtrInChoice"; case IsPtrForOpt: return "isPtrForOpt"; case OptionalTestRoutineName: return "optTestRoutineName"; case DefaultFieldName: return "defaultFieldName"; case PrintRoutineName: return "printRoutineName"; case EncodeRoutineName: return "encodeRoutineName"; case DecodeRoutineName: return "decodeRoutineName"; case FreeRoutineName: return "freeRoutineName"; case IsEncDec: return "isEncDec"; case GenTypeDef: return "genTypeDef"; case GenPrintRoutine: return "genPrintRoutine"; case GenEncodeRoutine: return "genEncodeRoutine"; case GenDecodeRoutine: return "genDecodeRoutine"; case GenFreeRoutine: return "genFreeRoutine"; case ChoiceIdSymbol: return "choiceIdSymbol"; case ChoiceIdValue: return "choiceIdValue"; case ChoiceIdEnumName: return "choiceIdEnumName"; case ChoiceIdEnumFieldName: return "choiceIdEnumFieldName"; case IsBigInt: return "isBigInt"; default: return ""; } } esnacc-ng-1.8.1/compiler/back-ends/c-gen/type-info.h000066400000000000000000000043151302010526100220650ustar00rootroot00000000000000/* * compiler/back-ends/c-gen/type-info.h - fills in c type information * * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/back-ends/c-gen/type-info.h,v 1.1.1.1 2000/08/21 20:36:05 leonberp Exp $ * $Log: type-info.h,v $ * Revision 1.1.1.1 2000/08/21 20:36:05 leonberp * First CVS Version of SNACC. * * Revision 1.3 1995/07/25 18:47:46 rj * changed `_' to `-' in file names. * * Revision 1.2 1994/10/08 03:48:20 rj * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long. * * Revision 1.1 1994/08/28 09:48:43 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ /* typedef struct CNamedElmt { struct CNamedElmt *next; int value; char *name; } CNamedElmt; typedef struct CTypeInfo { CTypeId cTypeId; char *cFieldName; char *cTypeName; int isPtr; int isEndCType; CNamedElmt *cNamedElmts; int choiceIdValue; char *choiceIdSymbol; char *choiceIdEnumName; char *choiceIdEnumFieldName; char *printRoutineName; char *encodeRoutineName; char *decodeRoutineName; } CTypeInfo; */ /* * allows upto 9999 unamed fields of the same type in a single structure * or 9999 values (diff asn1 scopes -> global c scope) with same name */ /* #define MAX_C_FIELD_NAME_DIGITS 4 #define MAX_C_VALUE_NAME_DIGITS 4 #define MAX_C_TYPE_NAME_DIGITS 4 #define MAX_C_ROUTINE_NAME_DIGITS 4 */ void PrintCTypeInfo PROTO ((FILE *f, Type *t)); void FillCTypeInfo PROTO ((CRules *r, ModuleList *m)); esnacc-ng-1.8.1/compiler/back-ends/c-gen/util.c000066400000000000000000000145501302010526100211250ustar00rootroot00000000000000/* * compiler/back-ends/c-gen/util.c - utilities for generating C encoders and decoders * * MS 91/11/04 * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/back-ends/c-gen/util.c,v 1.5 2003/07/29 21:06:06 colestor Exp $ * $Log: util.c,v $ * Revision 1.5 2003/07/29 21:06:06 colestor * Added "env" reference back to "C" generated code. * * Revision 1.4 2003/04/29 20:59:55 leonberp * integerated Deepak's changes for IOB support * * Revision 1.3 2002/09/16 17:35:09 mcphersc * Fixed warnings * * Revision 1.2 2000/10/24 14:54:48 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:36:05 leonberp * First CVS Version of SNACC. * * Revision 1.4 1997/08/28 07:26:10 povey * Changes to support DER encoding/decoding * * Revision 1.3.1.1 1997/08/20 23:14:41 povey * * Revision 1.3 1995/07/25 18:48:38 rj * changed `_' to `-' in file names. * * Revision 1.2 1994/09/01 00:26:52 rj * snacc_config.h removed. * * Revision 1.1 1994/08/28 09:48:44 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include #include "asn-incl.h" #include "asn1module.h" #include "rules.h" #include "snacc-util.h" #include "enc-rules.h" #include "util.h" #include void MakeVarPtrRef PARAMS ((r, td, parent, fieldType, parentVarName, newVarName), CRules *r _AND_ TypeDef *td _AND_ Type *parent _AND_ Type *fieldType _AND_ char *parentVarName _AND_ char *newVarName) { CTRI *ctri; ctri = fieldType->cTypeRefInfo; /* always put in brackets to save future referencing hassles */ strcpy (newVarName, "("); /* make ref'd field into a ptr by taking it's addr if nec */ if (!ctri->isPtr) strcat (newVarName, "&"); /* start with ref to parent */ strcat (newVarName, parentVarName); /* ref this field */ if ((td->type == parent) || (parent->cTypeRefInfo->isPtr)) strcat (newVarName, "->"); else strcat (newVarName, "."); /* ref choice union field if nec */ if (parent->basicType->choiceId == BASICTYPE_CHOICE) { strcat (newVarName, r->choiceUnionFieldName); strcat (newVarName, "."); } strcat (newVarName, ctri->cFieldName); strcat (newVarName, ")"); } /* MakeVarPtrRef */ void MakeVarValueRef PARAMS ((r, td, parent, fieldType, parentVarName, newVarName), CRules *r _AND_ TypeDef *td _AND_ Type *parent _AND_ Type *fieldType _AND_ char *parentVarName _AND_ char *newVarName) { CTRI *ctri; ctri = fieldType->cTypeRefInfo; /* always put in brackets to save future referencing hassles */ strcpy (newVarName, "("); /* make ref'd field into a value by de-referencing if nec */ if (ctri->isPtr) strcat (newVarName, "*"); /* start with ref to parent */ strcat (newVarName, parentVarName); /* ref this field */ if ((td->type == parent) || (parent->cTypeRefInfo->isPtr)) strcat (newVarName, "->"); else strcat (newVarName, "."); /* ref choice union field if nec */ if (parent->basicType->choiceId == BASICTYPE_CHOICE) { strcat (newVarName, r->choiceUnionFieldName); strcat (newVarName, "."); } strcat (newVarName, ctri->cFieldName); strcat (newVarName, ")"); } /* MakeVarValueRef */ void MakeChoiceIdValueRef PARAMS ((r, td, parent, fieldType, parentVarName, newVarName), CRules *r _AND_ TypeDef *td _AND_ Type *parent _AND_ Type *fieldType _AND_ char *parentVarName _AND_ char *newVarName) { /* always put in brackets to save future referencing hassles */ strcpy (newVarName, "("); /* start with ref to parent */ strcat (newVarName, parentVarName); /* ref this field */ if ((td->type == parent) || (parent->cTypeRefInfo->isPtr)) strcat (newVarName, "->"); else strcat (newVarName, "."); strcat (newVarName, parent->cTypeRefInfo->choiceIdEnumFieldName); strcat (newVarName, ")"); r = r; /*AVOIDS warning.*/ } /* MakeChoiceIdValueRef */ void PrintElmtAllocCode PARAMS ((src, type, varRefPtrName), FILE *src _AND_ Type *type _AND_ char *varRefPtrName) { CTRI *ctri1; CTRI *ctri2; Type *t; t = GetType (type); ctri1 = type->cTypeRefInfo; ctri2 = t->cTypeRefInfo; if (ctri1->isPtr) { if (ctri2->cTypeId == C_LIST) fprintf (src, "\t%s = AsnListNew(sizeof(char*));\n", varRefPtrName); else fprintf (src, "\t%s = (%s*)Asn1Alloc(sizeof(%s));\n", varRefPtrName, ctri1->cTypeName, ctri1->cTypeName); //fprintf (src," CheckAsn1Alloc (%s, env);\n", varRefPtrName); //fprintf (src," CheckAsn1Alloc (%s);\n", varRefPtrName); // Deepak: 18/Apr/2003 Not Required } } /* PrintElmtAllocCode */ /* * prints code to decode EOCs for the lengths that go with extra tagging * maxLenLevel - the highest used length variable (ie 2 for elmtLen2) * minLenLevel - the lowest valid length variable (ie 0 for elmtLen0) * lenBaseVarName - len var name sans number (ie elmtLen for elmtLen2) * totalLevel - current level for the running total * totalBaseName - total var name sans number * (ie totalElmtLen for totalElmtLen1) */ void PrintEocDecoders PARAMS ((f, maxLenLevel, minLenLevel, lenBaseVarName, totalLevel, totalBaseVarName), FILE *f _AND_ int maxLenLevel _AND_ int minLenLevel _AND_ char *lenBaseVarName _AND_ int totalLevel _AND_ char *totalBaseVarName) { int i; for (i = maxLenLevel; i > minLenLevel; i--) { fprintf (f,"\tif (%s%d == INDEFINITE_LEN)\n", lenBaseVarName, i); fprintf (f," %sDecEoc (b, &%s%d, env);\n", GetEncRulePrefix(), totalBaseVarName, totalLevel); //RWC;fprintf (f,"\t\t%sDecEoc(b,&%s%d);\n", GetEncRulePrefix(), totalBaseVarName, totalLevel); } } /* PrintEocDeocoders */ esnacc-ng-1.8.1/compiler/back-ends/c-gen/util.h000066400000000000000000000037071302010526100211340ustar00rootroot00000000000000/* * compiler/back-ends/c-gen/util.c - C encoder/decode related utility routines * * MS 91/11/04 * * Copyright (C) 1992 Michael Sample and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/back-ends/c-gen/util.h,v 1.1.1.1 2000/08/21 20:36:05 leonberp Exp $ * $Log: util.h,v $ * Revision 1.1.1.1 2000/08/21 20:36:05 leonberp * First CVS Version of SNACC. * * Revision 1.3.1.1 1997/08/20 23:14:41 povey * * * Revision 1.3 1995/07/25 18:48:39 rj * changed `_' to `-' in file names. * * Revision 1.2 1994/10/08 03:48:21 rj * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long. * * Revision 1.1 1994/08/28 09:48:45 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #define FIRST_LEVEL 1 /* must be 1 or greater */ #define MAX_VAR_REF 512 /* max chars for ref'ing a var eg v->foo->bar.x->v*/ void MakeVarPtrRef PROTO ((CRules *r, TypeDef *td, Type *parent, Type *fieldType, char *parentVarName, char *newVarName)); void MakeVarValueRef PROTO ((CRules *r, TypeDef *td, Type *parent, Type *fieldType, char *parentVarName, char *newVarName)); void MakeChoiceIdValueRef PROTO ((CRules *r, TypeDef *td, Type *parent, Type *fieldType, char *parentVarName, char *newVarName)); void PrintElmtAllocCode PROTO ((FILE *f, Type *type, char *varPtrRefName)); void PrintEocDecoders PROTO ((FILE *f, int maxLenLevel, int minLenLevel, char *lenBaseVarName, int totalLevel, char *totalBaseVarName)); esnacc-ng-1.8.1/compiler/back-ends/cond.c000066400000000000000000000040371302010526100201010ustar00rootroot00000000000000/* * compiler/back_ends/cond.c - generate conditional include for C(++) hdr files * * MS 92 * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/back-ends/cond.c,v 1.4 2003/07/07 14:54:24 nicholar Exp $ * $Log: cond.c,v $ * Revision 1.4 2003/07/07 14:54:24 nicholar * Eliminated headers and cleaned up include references * * Revision 1.3 2002/06/21 15:18:44 leonberp * fixed exception bugs * * Revision 1.2 2000/10/24 14:54:43 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:36:04 leonberp * First CVS Version of SNACC. * * Revision 1.1 1995/07/25 19:13:49 rj * PrintConditionalIncludeOpen() and PrintConditionalIncludeClose() moved from back-ends/c-gen/gen-code.[ch]. * */ #include #include "mem.h" #include "asn-incl.h" void PrintConditionalIncludeOpen PARAMS ((f, fileName), FILE *f _AND_ char *fileName) { int i; char *hdrFileDefSym = Strdup(fileName); for (i = 0; i < (int)strlen (hdrFileDefSym); i++) if (hdrFileDefSym[i] == '-' || hdrFileDefSym[i] == '.' || hdrFileDefSym[i] == '\\' || hdrFileDefSym[i] == '/') hdrFileDefSym[i] = '_'; fprintf (f, "#ifndef %s_h\n", hdrFileDefSym); fprintf(f, "#define %s_h\n\n\n", hdrFileDefSym); free(hdrFileDefSym); } /* PrintConditionalIncludeOpen */ void PrintConditionalIncludeClose PARAMS ((f, fileName), FILE *f _AND_ char *fileName) { fprintf (f, "\n#endif /* conditional include of %s */\n", fileName); } /* PrintConditionalIncludeClose */ esnacc-ng-1.8.1/compiler/back-ends/idl-gen/000077500000000000000000000000001302010526100203255ustar00rootroot00000000000000esnacc-ng-1.8.1/compiler/back-ends/idl-gen/gen-any.c000066400000000000000000000207601302010526100220340ustar00rootroot00000000000000/* * compiler/back_ends/idl_gen/gen_any.c * * prints Routine to initialize the ANY Hash table. The * ANY Hash table maps the OBJECT IDENTIFIERS or INTEGERS * to the correct decoding routines. * * Also prints an enum to identify each ANY mapping. * * MS 92 * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/back-ends/idl-gen/gen-any.c,v 1.6 2004/04/06 15:13:41 gronej Exp $ * $Log: gen-any.c,v $ * Revision 1.6 2004/04/06 15:13:41 gronej * *** empty log message *** * * Revision 1.5 2003/07/07 14:51:57 nicholar * Eliminated headers and cleaned up include references * * Revision 1.4 2002/10/30 13:41:51 mcphersc * modified anyid * * Revision 1.3 2002/09/04 18:02:28 vracarl * got rid of c++ comments * * Revision 1.2 2000/10/24 14:54:48 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:36:04 leonberp * First CVS Version of SNACC. * * Revision 1.1 1997/01/01 20:25:32 rj * first draft * */ #include "asn-incl.h" #include "asn1module.h" #include "str-util.h" #include "rules.h" #include "lib-types.h" static int anyEnumValG = 0; void PrintIDLAnyEnum PROTO ((FILE *idl, Module *m, IDLRules *r)); void PrintIDLAnyHashInitRoutine PROTO ((FILE *idl, ModuleList *mods, Module *m, IDLRules *r)); void PrintIDLAnyCode PARAMS ((idl, r, mods, m), FILE *idl _AND_ IDLRules *r _AND_ ModuleList *mods _AND_ Module *m) { if (!m->hasAnys) return; PrintIDLAnyEnum (idl, m, r); #if 0 PrintIDLAnyHashInitRoutine (idl, mods, m, r); #endif mods=mods; /*AVOIDS warning.*/ } /* PrintAnyCode */ void PrintIDLAnyEnum PARAMS ((idl, m, r), FILE *idl _AND_ Module *m _AND_ IDLRules *r) { TypeDef *td; AnyRef *ar; AnyRefList *arl; int firstPrinted = TRUE; int i; char *modName; modName = Asn1TypeName2CTypeName (m->modId->name); fprintf (idl,"typedef enum %sAnyId\n", modName); fprintf (idl,"{\n"); /* do any lib types */ for (i = BASICTYPE_BOOLEAN; i < BASICTYPE_MACRODEF; i++) { arl = LIBTYPE_GET_ANY_REFS (i); if (arl != NULL) { FOR_EACH_LIST_ELMT (ar, arl) { if (!firstPrinted) fprintf (idl,",\n"); fprintf (idl," %s = %d", ar->anyIdName, anyEnumValG); anyEnumValG++; firstPrinted = FALSE; } } } FOR_EACH_LIST_ELMT (td, m->typeDefs) { if (td->anyRefs != NULL) { FOR_EACH_LIST_ELMT (ar, td->anyRefs) { if (!firstPrinted) fprintf (idl,",\n"); fprintf (idl," %s = %d", ar->anyIdName, anyEnumValG); anyEnumValG++; firstPrinted = FALSE; } } } if (firstPrinted) /* none have been printed */ fprintf (idl,"/* NO INTEGER or OBJECT IDENTIFIER to ANY type relationships were defined (via MACROs or other mechanism) */\n ??? \n"); fprintf (idl,"\n} %sAnyId;\n\n\n", modName); Free (modName); r=r; /*AVOIDS warning.*/ } /* PrintAnyEnum */ #if 0 void PrintIDLAnyHashInitRoutine PARAMS ((idl, mods, m, r), FILE *idl _AND_ ModuleList *mods _AND_ Module *m _AND_ IDLRules *r) { TypeDef *td; AnyRefList *arl; AnyRef *ar; IDLTDI *idltdi; int i; int j; enum BasicTypeChoiceId typeId; int installedSomeHashes = FALSE; /* print InitAny class src file */ fprintf (src,"// this class will automatically intialize the any hash tbl\n"); fprintf (src,"class InitAny\n"); fprintf (src,"{\n"); fprintf (src," public:\n"); fprintf (src," InitAny();\n"); fprintf (src,"};\n\n"); fprintf (src,"static InitAny anyInitalizer;\n"); /* print constructor method that build hash tbl to src file*/ fprintf (src,"InitAny::InitAny()\n"); fprintf (src,"{\n"); /* first print value for OID's */ /* do any lib types first */ i = 0; for (j = BASICTYPE_BOOLEAN; j < BASICTYPE_MACRODEF; j++) { arl = LIBTYPE_GET_ANY_REFS (j); if (arl != NULL) { FOR_EACH_LIST_ELMT (ar, arl) { installedSomeHashes = TRUE; if (ar->id->choiceId == OIDORINT_OID) { fprintf (src," %s oid%d", r->typeConvTbl[BASICTYPE_OID].className, i++); PrintIDLOidValue (src, r, ar->id->a.oid); fprintf (src,";\n"); } else if (ar->id->choiceId == OIDORINT_INTID) { fprintf (src," %s int%d", r->typeConvTbl[BASICTYPE_INTEGER].className, i++); PrintIDLIntValue (src, r, ar->id->a.intId); fprintf (src,";\n"); } } } } FOR_EACH_LIST_ELMT (td, m->typeDefs) { if (td->anyRefs != NULL) { idltdi = td->idlTypeDefInfo; FOR_EACH_LIST_ELMT (ar, td->anyRefs) { installedSomeHashes = TRUE; if (ar->id->choiceId == OIDORINT_OID) { fprintf (src," %s oid%d", r->typeConvTbl[BASICTYPE_OID].className, i++); PrintIDLOidValue (src, r, ar->id->a.oid); fprintf (src,";\n"); } else if (ar->id->choiceId == OIDORINT_INTID) { fprintf (src," %s int%d", r->typeConvTbl[BASICTYPE_INTEGER].className, i++); PrintIDLIntValue (src, r, ar->id->a.intId); fprintf (src,";\n"); } } } } /* now print hash init calls */ i = 0; for (j = BASICTYPE_BOOLEAN; j < BASICTYPE_MACRODEF; j++) { arl = LIBTYPE_GET_ANY_REFS (j); if (arl != NULL) { FOR_EACH_LIST_ELMT (ar, arl) { if (ar->id->choiceId == OIDORINT_OID) fprintf (src," AsnAny::InstallAnyByOid (oid%d, %s, new %s);\n", i++, ar->anyIdName, r->typeConvTbl[j].className); else fprintf (src," AsnAny::InstallAnyByInt (int%d, %s, new %s);\n", i++, ar->anyIdName, r->typeConvTbl[j].className); } } } FOR_EACH_LIST_ELMT (td, m->typeDefs) { if (td->anyRefs != NULL) { FOR_EACH_LIST_ELMT (ar, td->anyRefs) { idltdi = td->idlTypeDefInfo; if (ar->id->choiceId == OIDORINT_OID) fprintf (src," AsnAny::InstallAnyByOid (oid%d, %s, new %s);\n", i++, ar->anyIdName, idltdi->className); else fprintf (src," AsnAny::InstallAnyByInt (int%d, %s, new %s);\n", i++, ar->anyIdName, idltdi->className); } } } if (!installedSomeHashes) { fprintf (src," /* Since no INTEGER/OID to ANY type relations were defined\n"); fprintf (src," * (usually done via MACROs) you must manually do the code\n"); fprintf (src," * to fill the hash tbl.\n"); fprintf (src," * if the ids are INTEGER use the following:\n"); fprintf (src," * AsnAny::InstallAnyByInt (3, ??_ANY_ID, new );\n"); fprintf (src," * if the ids are OBJECT IDENTIFIERs use the following:\n"); fprintf (src," * AsnAny::InstallAnyByOid (OidValue, ??_ANY_ID, new );\n"); fprintf (src," * put the ??_ANY_IDs in the AnyId enum.\n\n"); fprintf (src," * For example if you have some thing like\n"); fprintf (src," * T1 ::= SEQUENCE { id INTEGER, ANY DEFINED BY id }\n"); fprintf (src," * and the id 1 maps to the type BOOLEAN use the following:\n"); fprintf (src," * AsnAny::InstallAnyByInt (1, SOMEBOOL_ANY_ID, new AsnBool);\n"); fprintf (src," */\n ???????\n"); /* generate compile error */ } fprintf (src,"} /* InitAny::InitAny */\n\n\n"); } /* PrintAnyHashInitRoutine */ #endif esnacc-ng-1.8.1/compiler/back-ends/idl-gen/gen-code.c000066400000000000000000000400111302010526100221460ustar00rootroot00000000000000/* * compiler/back_ends/idl_gen/gen_idl_code.c - routines for printing CORBA IDL code from type trees * * assumes that the type tree has already been run through the * IDL type generator (idl_gen/types.c). * * Mike Sample * 92 * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * Copyright © 1995 Robert Joop * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/back-ends/idl-gen/gen-code.c,v 1.9 2004/03/25 19:20:16 gronej Exp $ * $Log: gen-code.c,v $ * Revision 1.9 2004/03/25 19:20:16 gronej * fixed some linux warnings * * Revision 1.8 2004/01/14 19:07:53 gronej * Updated Compiler to accept and process relative-oid's * * Revision 1.7 2003/07/17 15:16:28 nicholar * Fixed bugs related to removing headers. * * Revision 1.6 2003/07/07 14:51:57 nicholar * Eliminated headers and cleaned up include references * * Revision 1.5 2002/10/21 17:15:34 mcphersc * fixed long int * * Revision 1.4 2002/09/16 17:53:46 mcphersc * iFixed warnings * * Revision 1.3 2002/09/04 18:02:28 vracarl * got rid of c++ comments * * Revision 1.2 2000/10/24 14:54:48 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:36:04 leonberp * First CVS Version of SNACC. * * Revision 1.2 1997/03/13 09:15:21 wan * Improved dependency generation for stupid makedepends. * Corrected PeekTag to peek into buffer only as far as necessary. * Added installable error handler. * Fixed small glitch in idl-code generator (Markku Savela ). * * Revision 1.1 1997/01/01 20:25:34 rj * first draft * */ #include "snacc.h" #if STDC_HEADERS || HAVE_STRING_H #include #else #include #endif #include #include "asn-incl.h" #include "asn1module.h" #include "rules.h" #include "snacc-util.h" #include "print.h" /* Function Prototypes */ void PrintConditionalIncludeOpen PROTO ((FILE *f, char *fileName)); void PrintConditionalIncludeClose PROTO ((FILE *f, char *fileName)); void PrintIDLValueDef PROTO ((FILE *idl, IDLRules *r, ValueDef *v)); void PrintIDLValueDefsName PROTO ((FILE *f, IDLRules *r, ValueDef *v)); static long longJmpValG = -100; /*\[sep]--------------------------------------------------------------------------------------------------------------------------*/ static void PrintComment PARAMS ((idl, m), FILE *idl _AND_ Module *m) { long t; t = time (0); fprintf (idl, "// NOTE: this is a machine generated file -- editing not recommended\n"); fprintf (idl, "//\n"); fprintf (idl, "// %s -- IDL for ASN.1 module %s\n", m->idlFileName, m->modId->name); fprintf (idl, "//\n"); fprintf (idl, "// This file was generated by snacc on %s", ctime (&t)); fprintf (idl, "// UBC snacc written by Mike Sample\n"); fprintf (idl, "// IDL generator written by Robert Joop\n"); fprintf (idl, "\n"); } /* PrintComment */ /*\[sep]--------------------------------------------------------------------------------------------------------------------------*/ static void PrintIncludes PARAMS ((idl, mods, m), FILE *idl _AND_ ModuleList *mods _AND_ Module *m) { void *tmp; Module *currMod; fprintf (idl, "#include \"ASN1Types.idl\"\n"); fprintf (idl, "#include \"BitString.idl\"\n"); tmp = (void *)CURR_LIST_NODE (mods); /* remember curr loc */ FOR_EACH_LIST_ELMT (currMod, mods) fprintf (idl, "#include \"%s\"\n", currMod->idlFileName); SET_CURR_LIST_NODE (mods, tmp); m=m; /*AVOIDS warning.*/ } /* PrintIncludes */ /*\[sep]--------------------------------------------------------------------------------------------------------------------------*/ static void PrintTypeDecl PARAMS ((f, td), FILE *f _AND_ TypeDef *td) { switch (td->type->basicType->choiceId) { case BASICTYPE_COMPONENTSOF: case BASICTYPE_SELECTION: case BASICTYPE_UNKNOWN: case BASICTYPE_MACRODEF: case BASICTYPE_MACROTYPE: return; /* do nothing */ case BASICTYPE_ENUMERATED: if (IsNewType (td->type)) fprintf (f, " enum %s;\n", td->idlTypeDefInfo->typeName); break; default: if (IsNewType (td->type)) fprintf (f, " struct %s;\n", td->idlTypeDefInfo->typeName); } } /* PrintTypeDecl */ /*\[sep]--------------------------------------------------------------------------------------------------------------------------*/ static void PrintIDLTypeAndName PARAMS ((idl, mods, m, r, td, parent, t), FILE *idl _AND_ ModuleList *mods _AND_ Module *m _AND_ IDLRules *r _AND_ TypeDef *td _AND_ Type *parent _AND_ Type *t) { if (t->optional) fprintf (idl, "union %sOptional switch (boolean) { case True: %s %s; };\n", t->idlTypeRefInfo->typeName, t->idlTypeRefInfo->typeName, t->idlTypeRefInfo->fieldName); else fprintf (idl, "%s %s;\n", t->idlTypeRefInfo->typeName, t->idlTypeRefInfo->fieldName); #if 0 if (t->idlTypeRefInfo->isPtr) fprintf (idl, "*"); #endif parent=parent;td=td;r=r;m=m;mods=mods; /*AVOIDS warning.*/ } /* PrintIDLTypeAndName */ /*\[sep]--------------------------------------------------------------------------------------------------------------------------*/ /* * prints typedef or new class given an ASN.1 type def of a primitive type * or typeref. Uses inheritance to cover re-tagging and named elmts. */ static void PrintIDLSimpleDef PARAMS ((idl, r, td), FILE *idl _AND_ IDLRules *r _AND_ TypeDef *td) { int hasNamedElmts; CNamedElmt *n; fprintf (idl, " /* "); SpecialPrintType (idl, td, td->type); fprintf (idl, " */\n"); if ((hasNamedElmts = HasNamedElmts (td->type)) != FALSE) { int tlen = strlen (td->idlTypeDefInfo->typeName) - strlen (r->typeSuffix); switch (GetBuiltinType (td->type)) { case BASICTYPE_INTEGER: fprintf (idl, " typedef %s %s;\n", td->type->idlTypeRefInfo->typeName, td->idlTypeDefInfo->typeName); FOR_EACH_LIST_ELMT (n, td->type->idlTypeRefInfo->namedElmts) fprintf (idl, " const %s %.*s_%s = %d;\n", td->idlTypeDefInfo->typeName, tlen, td->idlTypeDefInfo->typeName, n->name, n->value); break; case BASICTYPE_ENUMERATED: fprintf (idl, " enum %s\n", td->idlTypeDefInfo->typeName); fprintf (idl, " {\n"); FOR_EACH_LIST_ELMT (n, td->type->idlTypeRefInfo->namedElmts) { char comma = (char)((n != (CNamedElmt *)LAST_LIST_ELMT (td->type->idlTypeRefInfo->namedElmts)) ? ',' : ' '); fprintf (idl, " %s%c // (original value = %d)\n", n->name, comma, n->value); } fprintf (idl, " };\n"); break; case BASICTYPE_BITSTRING: fprintf (idl, " typedef %s %s;\n", td->type->idlTypeRefInfo->typeName, td->idlTypeDefInfo->typeName); FOR_EACH_LIST_ELMT (n, td->type->idlTypeRefInfo->namedElmts) fprintf (idl, " const unsigned long %.*s_%s = %d;\n", tlen, td->idlTypeDefInfo->typeName, n->name, n->value); break; default: fprintf (idl, " \?\?\?!\n"); } } else fprintf (idl, " typedef %s %s;\n\n", td->type->idlTypeRefInfo->typeName, td->idlTypeDefInfo->typeName); } /* PrintIDLSimpleDef */ /*\[sep]--------------------------------------------------------------------------------------------------------------------------*/ static void PrintIDLChoiceDefCode PARAMS ((idl, mods, m, r, td, parent, choice), FILE *idl _AND_ ModuleList *mods _AND_ Module *m _AND_ IDLRules *r _AND_ TypeDef *td _AND_ Type *parent _AND_ Type *choice) { NamedType *e; /* put class spec in idl file */ /* write out choiceId enum type */ fprintf (idl, " enum %s%s\n", td->idlTypeDefInfo->typeName, r->choiceEnumSuffix); fprintf (idl, " {\n"); FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) { fprintf (idl, " %s", e->type->idlTypeRefInfo->choiceIdSymbol); if (e != (NamedType *)LAST_LIST_ELMT (choice->basicType->a.choice)) fprintf (idl, ",\n"); else fprintf (idl, "\n"); } fprintf (idl, " };\n\n"); /* write out the choice element anonymous union */ fprintf (idl, " union %s switch (%s%s)\n", td->idlTypeDefInfo->typeName, td->idlTypeDefInfo->typeName, r->choiceEnumSuffix); fprintf (idl, " {\n"); FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) { #if 0 fprintf (idl, " case %s: %s %s;\n", e->type->idlTypeRefInfo->choiceIdSymbol, e->type->idlTypeRefInfo->typeName, e->type->idlTypeRefInfo->fieldName); #else fprintf (idl, " case %s: ", e->type->idlTypeRefInfo->choiceIdSymbol); PrintIDLTypeAndName (idl, mods, m, r, td, choice, e->type); #endif } fprintf (idl, " };\n\n"); parent=parent; /*AVOIDS warning.*/ } /* PrintIDLChoiceDefCode */ /*\[sep]--------------------------------------------------------------------------------------------------------------------------*/ static void PrintIDLSeqDefCode PARAMS ((idl, mods, m, r, td, parent, seq), FILE *idl _AND_ ModuleList *mods _AND_ Module *m _AND_ IDLRules *r _AND_ TypeDef *td _AND_ Type *parent _AND_ Type *seq) { NamedType *e; /* put class spec in idl file */ fprintf (idl, " struct %s\n", td->idlTypeDefInfo->typeName); fprintf (idl, " {\n"); /* write out the sequence elmts */ FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence) { fprintf (idl, " "); PrintIDLTypeAndName (idl, mods, m, r, td, seq, e->type); } /* close struct definition */ fprintf (idl, " };\n\n\n"); parent=parent; /*AVOIDS warning.*/ } /* PrintIDLSeqDefCode */ /*\[sep]--------------------------------------------------------------------------------------------------------------------------*/ static void PrintIDLSetDefCode PARAMS ((idl, mods, m, r, td, parent, set), FILE *idl _AND_ ModuleList *mods _AND_ Module *m _AND_ IDLRules *r _AND_ TypeDef *td _AND_ Type *parent _AND_ Type *set) { NamedType *e; /* put class spec in idl file */ fprintf (idl, " struct %s\n", td->idlTypeDefInfo->typeName); fprintf (idl, " {\n"); /* write out the set elmts */ FOR_EACH_LIST_ELMT (e, set->basicType->a.set) { fprintf (idl, " "); PrintIDLTypeAndName (idl, mods, m, r, td, set, e->type); } fprintf (idl, " };\n\n"); parent=parent; /*AVOIDS warning.*/ } /* PrintIDLSetDefCode */ /*\[sep]--------------------------------------------------------------------------------------------------------------------------*/ static void PrintCxxSetOfDefCode PARAMS ((idl, mods, m, r, td, parent, setOf), FILE *idl _AND_ ModuleList *mods _AND_ Module *m _AND_ IDLRules *r _AND_ TypeDef *td _AND_ Type *parent _AND_ Type *setOf) { char *lcn; /* list class name */ char *ecn; /* (list) elmt class name */ lcn = td->idlTypeDefInfo->typeName; ecn = setOf->basicType->a.setOf->idlTypeRefInfo->typeName; fprintf (idl, " typedef sequence<%s> %s;\n", ecn, lcn); parent=parent;r=r;m=m;mods=mods; /*AVOIDS warning.*/ } /* PrintCxxSetOfDefCode */ /*\[sep]--------------------------------------------------------------------------------------------------------------------------*/ static void PrintCxxAnyDefCode PARAMS ((idl, mods, m, r, td, parent, any), FILE *idl _AND_ ModuleList *mods _AND_ Module *m _AND_ IDLRules *r _AND_ TypeDef *td _AND_ Type *parent _AND_ Type *any) { fprintf (idl, " /* "); SpecialPrintType (idl, td, td->type); fprintf (idl, " */\n"); fprintf (idl, " typedef %s %s;\n\n", td->type->idlTypeRefInfo->typeName, td->idlTypeDefInfo->typeName); any=any;parent=parent;r=r;m=m;mods=mods; /*AVOIDS warning.*/ } /* PrintCxxAnyDefCode */ /*\[sep]--------------------------------------------------------------------------------------------------------------------------*/ static void PrintIDLTypeDefCode PARAMS ((idl, mods, m, r, td), FILE *idl _AND_ ModuleList *mods _AND_ Module *m _AND_ IDLRules *r _AND_ TypeDef *td) { switch (td->type->basicType->choiceId) { case BASICTYPE_BOOLEAN: /* library type */ case BASICTYPE_REAL: /* library type */ case BASICTYPE_OCTETSTRING: /* library type */ case BASICTYPE_NULL: /* library type */ case BASICTYPE_OID: /* library type */ case BASICTYPE_RELATIVE_OID: case BASICTYPE_INTEGER: /* library type */ case BASICTYPE_BITSTRING: /* library type */ case BASICTYPE_ENUMERATED: /* library type */ PrintIDLSimpleDef (idl, r, td); break; case BASICTYPE_SEQUENCEOF: /* list types */ case BASICTYPE_SETOF: PrintCxxSetOfDefCode (idl, mods, m, r, td, NULL, td->type); break; case BASICTYPE_IMPORTTYPEREF: /* type references */ case BASICTYPE_LOCALTYPEREF: /* * if this type has been re-tagged then * must create new class instead of using a typedef */ PrintIDLSimpleDef (idl, r, td); break; case BASICTYPE_ANYDEFINEDBY: /* ANY types */ case BASICTYPE_ANY: /* fprintf (errFileG, " ANY types require modification. "); fprintf (errFileG, " The source files will have a \" ANY - Fix Me! \" comment before related code.\n\n"); */ PrintCxxAnyDefCode (idl, mods, m, r, td, NULL, td->type); break; case BASICTYPE_CHOICE: PrintIDLChoiceDefCode (idl, mods, m, r, td, NULL, td->type); break; case BASICTYPE_SET: PrintIDLSetDefCode (idl, mods, m, r, td, NULL, td->type); break; case BASICTYPE_SEQUENCE: PrintIDLSeqDefCode (idl, mods, m, r, td, NULL, td->type); break; case BASICTYPE_COMPONENTSOF: case BASICTYPE_SELECTION: case BASICTYPE_UNKNOWN: case BASICTYPE_MACRODEF: case BASICTYPE_MACROTYPE: /* do nothing */ break; default: break; } } /* PrintIDLTypeDefCode */ /*\[sep]--------------------------------------------------------------------------------------------------------------------------*/ void PrintIDLCode PARAMS ((idl, mods, m, r, longJmpVal), FILE *idl _AND_ ModuleList *mods _AND_ Module *m _AND_ IDLRules *r _AND_ long longJmpVal _AND_ int printValues) { TypeDef *td; ValueDef *vd; longJmpValG = longJmpVal; PrintComment (idl, m); PrintConditionalIncludeOpen (idl, m->idlFileName); PrintIncludes (idl, mods, m); fprintf (idl, "\n"); fprintf (idl, "module %s\n{\n\n", m->idlname); fprintf (idl, " //----------------------------------------------------------------------------\n"); fprintf (idl, " // type declarations:\n\n"); FOR_EACH_LIST_ELMT (td, m->typeDefs) PrintTypeDecl (idl, td); fprintf (idl, "\n"); if (printValues) { fprintf (idl, " //----------------------------------------------------------------------------\n"); fprintf (idl, " // value definitions:\n\n"); FOR_EACH_LIST_ELMT (vd, m->valueDefs) PrintIDLValueDef (idl, r, vd); fprintf (idl, "\n"); } fprintf (idl, " //----------------------------------------------------------------------------\n"); fprintf (idl, " // type definitions:\n\n"); #if 0 PrintIDLAnyCode (idl, r, mods, m); #endif FOR_EACH_LIST_ELMT (td, m->typeDefs) { PrintIDLTypeDefCode (idl, mods, m, r, td); fputc ('\n', idl); } fprintf (idl, "}; // end of module %s\n", m->idlname); PrintConditionalIncludeClose (idl, m->idlFileName); } /* PrintIDLCode */ /*\[banner "EOF"]-----------------------------------------------------------------------------------------------------------------*/ esnacc-ng-1.8.1/compiler/back-ends/idl-gen/gen-vals.c000066400000000000000000000125551302010526100222150ustar00rootroot00000000000000/* * compiler/back_ends/idl_gen/gen_vals.c - prints ASN.1 values in IDL format * * MS 92 * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/back-ends/idl-gen/gen-vals.c,v 1.5 2004/01/14 19:07:53 gronej Exp $ * $Log: gen-vals.c,v $ * Revision 1.5 2004/01/14 19:07:53 gronej * Updated Compiler to accept and process relative-oid's * * Revision 1.4 2003/07/17 15:16:28 nicholar * Fixed bugs related to removing headers. * * Revision 1.3 2002/09/16 17:53:50 mcphersc * Fixed warnings * * Revision 1.2 2000/10/24 14:54:48 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:36:04 leonberp * First CVS Version of SNACC. * * Revision 1.1 1997/01/01 20:25:36 rj * first draft * */ #include "asn-incl.h" #include "asn1module.h" #include "str-util.h" #include "rules.h" /* non-exported routines' prototypes */ static void PrintIDLIntValue PROTO ((FILE *f, IDLRules *r, AsnInt v)); static void PrintIDLOidValue PROTO ((FILE *f, IDLRules *r, AsnOid *v)); static void PrintIDLValuesClass PROTO ((FILE *f, IDLRules *r, Value *v)); static void PrintIDLValueDefsName PROTO ((FILE *f, IDLRules *r, ValueDef *v)); static void PrintIDLValueInstatiation PROTO ((FILE *f, IDLRules *r, Value *v)); void PrintIDLValueDef PARAMS ((idl, r, v), FILE *idl _AND_ IDLRules *r _AND_ ValueDef *v) { /* just do oid's, ints and bools for now */ if ((v->value->basicValue->choiceId != BASICVALUE_OID) && (v->value->basicValue->choiceId != BASICVALUE_INTEGER) && (v->value->basicValue->choiceId != BASICVALUE_BOOLEAN)) return; /* * put instantiation in idl file */ fprintf (idl, " const "); PrintIDLValuesClass (idl, r, v->value); fprintf (idl, " "); PrintIDLValueDefsName (idl, r, v); fprintf (idl, " = "); PrintIDLValueInstatiation (idl, r, v->value); fprintf (idl, ";\n\n"); } /* PrintIDLValueDef */ static void PrintIDLValueDefsName PARAMS ((f, r, v), FILE *f _AND_ IDLRules *r _AND_ ValueDef *v) { char *cName; cName = Asn1ValueName2CValueName (v->definedName); fprintf (f, "%s", cName); Free (cName); r=r; /*AVOIDS warning.*/ } void PrintIDLValuesClass PARAMS ((f, r, v), FILE *f _AND_ IDLRules *r _AND_ Value *v) { /* needs work - just do ints bools and oid's for now */ switch (v->basicValue->choiceId) { case BASICVALUE_OID: fprintf (f, "%s", r->typeConvTbl[BASICTYPE_OID].typeName); break; case BASICVALUE_RELATIVE_OID: fprintf (f, "%s", r->typeConvTbl[BASICTYPE_RELATIVE_OID].typeName); break; case BASICVALUE_INTEGER: fprintf (f, "%s", r->typeConvTbl[BASICTYPE_INTEGER].typeName); break; case BASICVALUE_BOOLEAN: fprintf (f, "%s", r->typeConvTbl[BASICTYPE_BOOLEAN].typeName); break; default: break; } } void PrintIDLValueInstatiation PARAMS ((f, r, v), FILE *f _AND_ IDLRules *r _AND_ Value *v) { /* needs work - just do oids, ints and bools for now */ switch (v->basicValue->choiceId) { case BASICVALUE_OID: PrintIDLOidValue (f, r, v->basicValue->a.oid); break; case BASICVALUE_INTEGER: PrintIDLIntValue (f, r, v->basicValue->a.integer); break; case BASICVALUE_BOOLEAN: fprintf (f, v->basicValue->a.boolean ? "TRUE" : "FALSE"); break; default: break; } } /* * given an AOID, c++ AOID constructors params are produced. * This is used for turning ASN.1 OBJECT ID values * into usable c++ values. * * eg for the oid { 0 1 2 } (in AOID format) * (0,1,2) * is produced. */ void PrintIDLOidValue PARAMS ((f, r, v), FILE *f _AND_ IDLRules *r _AND_ AsnOid *v) { unsigned short int firstArcNum; unsigned long int arcNum; int i; fprintf (f, "("); /* un-munge first two arc numbers */ for (arcNum = 0, i=0; (i < (int)v->octetLen) && (v->octs[i] & 0x80);i++) arcNum = (arcNum << 7) + (v->octs[i] & 0x7f); arcNum = (arcNum << 7) + (v->octs[i] & 0x7f); i++; firstArcNum = (unsigned short)(arcNum/40); if (firstArcNum > 2) firstArcNum = 2; fprintf (f, "%u, %u", firstArcNum, (int)(arcNum - (firstArcNum * 40))); for (; i < (int)v->octetLen; ) { for (arcNum = 0; (i < (int)v->octetLen) && (v->octs[i] & 0x80);i++) arcNum = (arcNum << 7) + (v->octs[i] & 0x7f); arcNum = (arcNum << 7) + (v->octs[i] & 0x7f); i++; fprintf (f, ", %u", (unsigned int)arcNum); } fprintf (f, ")"); r=r; /*AVOIDS warning.*/ } /* PrintIDLOidValue */ void PrintIDLIntValue PARAMS ((f, r, v), FILE *f _AND_ IDLRules *r _AND_ AsnInt v) { fprintf (f, "%d", v); r=r; /*AVOIDS warning.*/ } /* PrintIDLIntValue */ esnacc-ng-1.8.1/compiler/back-ends/idl-gen/rules.c000066400000000000000000000152351302010526100216310ustar00rootroot00000000000000/* * compiler/back_ends/idl_gen/rules.c - initialized c rule structure * inits a table that contains info about * converting each ASN.1 type to an IDL type * * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/back-ends/idl-gen/rules.c,v 1.2 2004/01/14 19:07:53 gronej Exp $ * $Log: rules.c,v $ * Revision 1.2 2004/01/14 19:07:53 gronej * Updated Compiler to accept and process relative-oid's * * Revision 1.1.1.1 2000/08/21 20:36:04 leonberp * First CVS Version of SNACC. * * Revision 1.1 1997/01/01 20:25:38 rj * first draft * * Revision 1.3 1994/10/08 03:47:49 rj */ #include "asn-incl.h" #include "asn1module.h" #include "rules.h" IDLRules idlRulesG = { 4, "", "_T", "Choice", "a", "ChoiceUnion", FALSE, { { BASICTYPE_UNKNOWN, "???", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, "NOT_NULL", "unknown" }, { BASICTYPE_BOOLEAN, "BOOLEAN", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "bool" }, { BASICTYPE_INTEGER, "INTEGER", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "integer" }, { BASICTYPE_BITSTRING, "BitString", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "bits" }, { BASICTYPE_OCTETSTRING, "OctetString", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "octs" }, { BASICTYPE_NULL, "NULL", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "null" }, { BASICTYPE_OID, "ObjectIdentifier", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "oid" }, { BASICTYPE_REAL, "REAL", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "real" }, { BASICTYPE_ENUMERATED, "???", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "enumeration" }, { BASICTYPE_SEQUENCE, NULL, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, "NOT_NULL", "seq" }, { BASICTYPE_SEQUENCEOF, "AsnList", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "seqOf" }, { BASICTYPE_SET, NULL, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, "NOT_NULL", "set" }, { BASICTYPE_SETOF, "AsnList", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "setOf" }, { BASICTYPE_CHOICE, NULL, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, "NOT_NULL", "choice" }, { BASICTYPE_SELECTION, NULL, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "foo" }, { BASICTYPE_COMPONENTSOF, NULL, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "bar" }, { BASICTYPE_ANY, "any", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "any" }, { BASICTYPE_ANYDEFINEDBY, "any", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "anyDefBy" }, { BASICTYPE_LOCALTYPEREF, NULL, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "foo" }, { BASICTYPE_IMPORTTYPEREF, NULL, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "bar" }, { BASICTYPE_MACROTYPE, NULL, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "foo" }, { BASICTYPE_MACRODEF, NULL, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "foo" }, { BASICTYPE_RELATIVE_OID, "RelativeOid", FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, "NOT_NULL", "RelativeOid" } } }; esnacc-ng-1.8.1/compiler/back-ends/idl-gen/rules.h000066400000000000000000000023611302010526100216320ustar00rootroot00000000000000/* * compiler/back_ends/idl_gen/rules.h * * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/back-ends/idl-gen/rules.h,v 1.2 2004/01/14 19:07:53 gronej Exp $ * $Log: rules.h,v $ * Revision 1.2 2004/01/14 19:07:53 gronej * Updated Compiler to accept and process relative-oid's * * Revision 1.1.1.1 2000/08/21 20:36:04 leonberp * First CVS Version of SNACC. * * Revision 1.1 1997/01/01 20:25:39 rj * first draft * * Revision 1.2 1994/10/08 03:47:50 rj */ /* see ../../core/asn1module.h for IDLTDI (C++ type def info) */ typedef struct IDLRules { int maxDigitsToAppend; char *typePrefix, *typeSuffix; char *choiceEnumSuffix; char *choiceUnionFieldName; /* what the name of the choice's union is */ char *choiceUnionName; /* name (tag) for choice union def name */ int capitalizeNamedElmts; IDLTDI typeConvTbl[BASICTYPE_RELATIVE_OID + 1]; } IDLRules; extern IDLRules idlRulesG; esnacc-ng-1.8.1/compiler/back-ends/idl-gen/types.c000066400000000000000000000460171302010526100216450ustar00rootroot00000000000000/* * compiler/back_ends/idl_gen/types.c - fills in IDL type information * * MS 91/92 * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/back-ends/idl-gen/types.c,v 1.7 2004/03/25 19:20:16 gronej Exp $ * $Log: types.c,v $ * Revision 1.7 2004/03/25 19:20:16 gronej * fixed some linux warnings * * Revision 1.6 2004/01/14 19:07:53 gronej * Updated Compiler to accept and process relative-oid's * * Revision 1.5 2003/07/07 14:51:57 nicholar * Eliminated headers and cleaned up include references * * Revision 1.4 2002/09/16 17:53:53 mcphersc * Fixed warnings * * Revision 1.3 2002/09/04 18:02:27 vracarl * got rid of c++ comments * * Revision 1.2 2000/10/24 14:54:49 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:36:04 leonberp * First CVS Version of SNACC. * * Revision 1.1 1997/01/01 20:25:40 rj * first draft * */ #include #include #include "asn-incl.h" #include "asn1module.h" #include "snacc-util.h" #include "str-util.h" #include "rules.h" static DefinedObj *definedNamesG; /* unexported prototypes */ void FillIDLTypeDefInfo PROTO ((IDLRules *r, Module *m, TypeDef *td)); static void FillIDLFieldNames PROTO ((IDLRules *r, NamedTypeList *firstSibling)); static void FillIDLTypeRefInfo PROTO ((IDLRules *r, Module *m, TypeDef *td, Type *parent, Type *t)); static void FillIDLStructElmts PROTO ((IDLRules *r, Module *m, TypeDef *td, Type *parent, NamedTypeList *t)); static void FillIDLChoiceElmts PROTO ((IDLRules *r, Module *m, TypeDef *td, Type *parent, NamedTypeList *first)); static int IsIDLPtr PROTO ((IDLRules *r, TypeDef *td, Type *parent, Type *t)); void FillIDLTDIDefaults PROTO ((IDLRules *r, IDLTDI *ctdi, TypeDef *td)); /* * allocates and fills all the idlTypeInfos * in the type trees for every module in the list */ void FillIDLTypeInfo PARAMS ((r, modList), IDLRules *r _AND_ ModuleList *modList) { TypeDef *td; Module *m; /* * go through each module's type defs and fill * in the C type and enc/dec routines etc */ definedNamesG = NULL; FOR_EACH_LIST_ELMT (m, modList) { FOR_EACH_LIST_ELMT (td, m->typeDefs) FillIDLTypeDefInfo (r, m, td); } /* * now that type def info is filled in * set up set/seq/list/choice elements that ref * those definitions */ FOR_EACH_LIST_ELMT (m, modList) { FOR_EACH_LIST_ELMT (td, m->typeDefs) FillIDLTypeRefInfo (r, m, td, NULL, td->type); } /* * modules compiled together (ie one call to snacc with * multiple args) likely to be C compiled together so * need a unique routines/types/defines/enum values * since assuming they share same name space. * All Typedefs, union, struct & enum Tags, and defined values * (enum consts), #define names * are assumed to share the same name space */ /* done with checking for name conflicts */ FreeDefinedObjs (&definedNamesG); } /* FillIDLTypeInfo */ /* * allocates and fills structure holding C type definition information * fo the given ASN.1 type definition. Does not fill CTRI for contained * types etc. */ void FillIDLTypeDefInfo PARAMS ((r, m, td), IDLRules *r _AND_ Module *m _AND_ TypeDef *td) { char *tmpName; IDLTDI *idltdi; /* * if IDLTDI is present this type def has already been 'filled' */ if (td->idlTypeDefInfo != NULL) return; idltdi = MT (IDLTDI); td->idlTypeDefInfo = idltdi; /* get default type def attributes from table for type on rhs of ::= */ FillIDLTDIDefaults (r, idltdi, td); /* * if defined by a ref to another type definition fill in that type * def's IDLTDI so can inherit (actully completly replace default * attributes) from it */ if ((td->type->basicType->choiceId == BASICTYPE_LOCALTYPEREF) || (td->type->basicType->choiceId == BASICTYPE_IMPORTTYPEREF)) { /* * Fill in IDLTDI for defining type if nec. * this works for importTypeRef as well since both a.localTypeRef * and a.importTypeRef are of type TypeRef */ FillIDLTypeDefInfo (r, td->type->basicType->a.localTypeRef->module, td->type->basicType->a.localTypeRef->link); tmpName = idltdi->typeName; /* save typeName */ /* copy all type def info and restore name related stuff - hack*/ *idltdi = *td->type->basicType->a.localTypeRef->link->idlTypeDefInfo; idltdi->typeName = tmpName; /* restore typeName */ } /* * check for any "--snacc" attributes that overide the current * idltdi fields * UNDEFINED FOR C++ ParseTypeDefAttribs (idltdi, td->attrList); */ m=m; /*AVOIDS warning.*/ } /* FillIDLTypeDefInfo */ static void FillIDLTypeRefInfo PARAMS ((r, m, td, parent, t), IDLRules *r _AND_ Module *m _AND_ TypeDef *td _AND_ Type *parent _AND_ Type *t) { IDLTRI *idltri; IDLTDI *tmpidltdi; ValueDef *namedElmt; CNamedElmt *cne; CNamedElmt **cneHndl; char *elmtName; int len; enum BasicTypeChoiceId basicTypeId; /* * you must check for cycles yourself before calling this */ if (t->idlTypeRefInfo == NULL) { idltri = MT (IDLTRI); t->idlTypeRefInfo = idltri; } else idltri = t->idlTypeRefInfo; basicTypeId = t->basicType->choiceId; tmpidltdi = &r->typeConvTbl[basicTypeId]; /* get base type def info from the conversion table in the rules */ idltri->isEnc = tmpidltdi->isEnc; idltri->typeName = tmpidltdi->typeName; idltri->optTestRoutineName = tmpidltdi->optTestRoutineName; /* * convert named elmts to IDL names. * check for name conflict with other defined Types/Names/Values */ if ((basicTypeId == BASICTYPE_INTEGER || basicTypeId == BASICTYPE_ENUMERATED || basicTypeId == BASICTYPE_BITSTRING) && !(LIST_EMPTY (t->basicType->a.integer))) { idltri->namedElmts = AsnListNew (sizeof (void *)); FOR_EACH_LIST_ELMT (namedElmt, t->basicType->a.integer) { cneHndl = (CNamedElmt **)AsnListAppend (idltri->namedElmts); cne = *cneHndl = MT (CNamedElmt); elmtName = Asn1ValueName2CValueName (namedElmt->definedName); #if 0 if (basicTypeId == BASICTYPE_BITSTRING) #endif { len = strlen (elmtName); cne->name = Malloc (len + 1 + r->maxDigitsToAppend); strcpy (cne->name, elmtName); } #if 0 else { len = strlen (idltri->typeName) + 7 + strlen (elmtName); cne->name = Malloc (len + 1 + r->maxDigitsToAppend); strcpy (cne->name, idltri->typeName); strcat (cne->name, "Choice_"); strcat (cne->name, elmtName); } #endif Free (elmtName); /* not very efficient */ if (namedElmt->value->basicValue->choiceId == BASICVALUE_INTEGER) cne->value = namedElmt->value->basicValue->a.integer; else { fprintf (errFileG, "Warning: unlinked defined value. Using -9999999\n"); cne->value = -9999999; } if (r->capitalizeNamedElmts) Str2UCase (cne->name, len); /* * append digits if enum value name is a keyword */ MakeCxxStrUnique (definedNamesG, cne->name, r->maxDigitsToAppend, 1); DefineObj (&definedNamesG, cne->name); } } /* fill in rest of type info depending on the type */ switch (basicTypeId) { case BASICTYPE_BOOLEAN: /* library types */ case BASICTYPE_INTEGER: case BASICTYPE_BITSTRING: case BASICTYPE_OCTETSTRING: case BASICTYPE_NULL: case BASICTYPE_OID: case BASICTYPE_RELATIVE_OID: case BASICTYPE_REAL: case BASICTYPE_ENUMERATED: /* don't need to do anything else */ break; case BASICTYPE_SEQUENCEOF: /* list types */ case BASICTYPE_SETOF: /* fill in component type */ FillIDLTypeRefInfo (r, m, td, t, t->basicType->a.setOf); break; case BASICTYPE_IMPORTTYPEREF: /* type references */ case BASICTYPE_LOCALTYPEREF: /* * grab class name from link (link is the def of the * the ref'd type) */ if (t->basicType->a.localTypeRef->link != NULL) { /* inherit attributes from referenced type */ tmpidltdi= t->basicType->a.localTypeRef->link->idlTypeDefInfo; idltri->typeName = tmpidltdi->typeName; idltri->isEnc = tmpidltdi->isEnc; idltri->optTestRoutineName = tmpidltdi->optTestRoutineName; } break; case BASICTYPE_ANYDEFINEDBY: /* ANY types */ break; /* these are handled now */ case BASICTYPE_ANY: #if 0 PrintErrLoc (m->asn1SrcFileName, t->lineNo); fprintf (errFileG, "Warning - generated code for the \"ANY\" type in type \"%s\" will need modification by YOU.", td->definedName); fprintf (errFileG, " The source files will have a \"/* ANY - Fix Me! */\" comment before related code.\n\n"); #endif break; case BASICTYPE_CHOICE: /* * must fill field names BEFORE filling choice elmts * (allows better naming for choice ids) */ FillIDLFieldNames (r, t->basicType->a.choice); FillIDLChoiceElmts (r, m, td, t, t->basicType->a.choice); break; case BASICTYPE_SET: case BASICTYPE_SEQUENCE: FillIDLStructElmts (r, m, td, t, t->basicType->a.set); FillIDLFieldNames (r, t->basicType->a.set); break; case BASICTYPE_COMPONENTSOF: case BASICTYPE_SELECTION: fprintf (errFileG, "Compiler error - COMPONENTS OF or SELECTION type slipped through normalizing phase.\n"); break; case BASICTYPE_UNKNOWN: case BASICTYPE_MACRODEF: case BASICTYPE_MACROTYPE: /* do nothing */ break; default: break; } /* * figure out whether this is a ptr based on the enclosing * type (if any) and optionality/default */ idltri->isPtr = (unsigned char)IsIDLPtr (r, td, parent, t); /* let user overide any defaults with the --snacc attributes */ /* undefined for C++ ParseTypeRefAttribs (ctri, t->attrList); */ } /* FillIDLTypeRefInfo */ static void FillIDLStructElmts PARAMS ((r, m, td, parent, elmts), IDLRules *r _AND_ Module *m _AND_ TypeDef *td _AND_ Type *parent _AND_ NamedTypeList *elmts) { NamedType *et; FOR_EACH_LIST_ELMT (et, elmts) { FillIDLTypeRefInfo (r, m, td, parent, et->type); } } /* FillIDLStructElmts */ /* * Figures out non-conflicting enum names for the * choice id's */ static void FillIDLChoiceElmts PARAMS ((r, m, td, parent, elmts), IDLRules *r _AND_ Module *m _AND_ TypeDef *td _AND_ Type *parent _AND_ NamedTypeList *elmts) { NamedType *et; int idCount = 0; IDLTRI *idltri; int len; /* * fill in type info for elmt types first */ FOR_EACH_LIST_ELMT (et, elmts) FillIDLTypeRefInfo (r, m, td, parent, et->type); /* * set choiceId Symbol & value * eg * Car ::= CHOICE { enum CarChoice { * chev ChevCar, carChoice_chev, * ford FordCar, carChoice_ford, * toyota ToyotaCar carChoice_toyota * } }; * union Car switch (CarChoice) { * ChevCar *chev; * FordCar *ford; * ToyotaCar *toyota; }; * }; * NOTE that the union is anonymous */ FOR_EACH_LIST_ELMT (et, elmts) { idltri = et->type->idlTypeRefInfo; if (idltri == NULL) continue; /* wierd type */ idltri->choiceIdValue = idCount++; len = strlen (td->idlTypeDefInfo->typeName) + strlen (idltri->fieldName); idltri->choiceIdSymbol = Malloc (len + 6 + 1); strcpy (idltri->choiceIdSymbol, td->idlTypeDefInfo->typeName); strcat (idltri->choiceIdSymbol, "Choice_"); strcat (idltri->choiceIdSymbol, idltri->fieldName); if (r->capitalizeNamedElmts) Str2UCase (idltri->choiceIdSymbol, len); Str2LCase (idltri->choiceIdSymbol, 1); } } /* FillIDLChoiceElmts */ /* * takes a list of "sibling" (eg same level in a structure) * ElmtTypes and fills sets up the c field names in * the IDLTRI struct */ static void FillIDLFieldNames PARAMS ((r, elmts), IDLRules *r _AND_ NamedTypeList *elmts) { NamedType *et; IDLTRI *idltri; DefinedObj *fieldNames; int len; char *tmpName; char *asn1FieldName; char *cFieldName; /* * Initialize fieldname data * allocate (if nec) and fill in CTRI fieldname if poss * from asn1 field name. leave blank otherwise */ fieldNames = NewObjList(); FOR_EACH_LIST_ELMT (et, elmts) { idltri = et->type->idlTypeRefInfo; if (idltri == NULL) { idltri = MT (IDLTRI); et->type->idlTypeRefInfo = idltri; } if (et->fieldName != NULL) { /* * can assume that the field names are * distinct because they have passed the * error checking step. * However, still call MakeCxxStrUnique * to change any field names that * conflict with C++ keywords */ asn1FieldName = et->fieldName; tmpName = Asn1FieldName2CFieldName (asn1FieldName); idltri->fieldName = Malloc (strlen (tmpName) + 1 + r->maxDigitsToAppend); strcpy (idltri->fieldName, tmpName); Free (tmpName); /* old idltri->fieldName = Asn1FieldName2CFieldName (asn1FieldName); */ MakeCxxStrUnique (fieldNames, idltri->fieldName, r->maxDigitsToAppend, 1); DefineObj (&fieldNames, idltri->fieldName); } } FOR_EACH_LIST_ELMT (et, elmts) { idltri = et->type->idlTypeRefInfo; /* * generate field names for those without them */ if (idltri->fieldName == NULL) { if ((et->type->basicType->choiceId == BASICTYPE_LOCALTYPEREF) || (et->type->basicType->choiceId == BASICTYPE_IMPORTTYPEREF)) { /* * take ref'd type name as field name * convert first let to lower case */ tmpName = et->type->basicType->a.localTypeRef->link->idlTypeDefInfo->typeName; tmpName = Asn1TypeName2CTypeName (tmpName); cFieldName = Malloc (strlen (tmpName) + r->maxDigitsToAppend +1); strcpy (cFieldName, tmpName); Free (tmpName); if (isupper (cFieldName[0])) cFieldName[0] = (char)tolower (cFieldName[0]); } else { /* * get default field name for this type */ tmpName = r->typeConvTbl[et->type->basicType->choiceId].defaultFieldName; cFieldName = Malloc (strlen (tmpName) + r->maxDigitsToAppend +1); strcpy (cFieldName, tmpName); if (isupper (cFieldName[0])) cFieldName[0] = (char)tolower (cFieldName[0]); } len = strlen (cFieldName); /* * try to use just the type name (with lower case first char). * if that is already used in this type or a C++ keyword, * append ascii digits to field name until unique * in this type */ MakeCxxStrUnique (fieldNames, cFieldName, r->maxDigitsToAppend, 1); DefineObj (&fieldNames, cFieldName); idltri->fieldName = cFieldName; } } FreeDefinedObjs (&fieldNames); } /* FillIDLFieldNames */ /* * returns true if this c type for this type should be * be ref'd as a ptr */ static int IsIDLPtr PARAMS ((r, td, parent, t), IDLRules *r _AND_ TypeDef *td _AND_ Type *parent _AND_ Type *t) { IDLTDI *idltdi; int retVal = FALSE; /* * inherit ptr attriubutes from ref'd type if any * otherwise grab lib c type def from the IDLRules */ if ((t->basicType->choiceId == BASICTYPE_LOCALTYPEREF) || (t->basicType->choiceId == BASICTYPE_IMPORTTYPEREF)) { idltdi = t->basicType->a.localTypeRef->link->idlTypeDefInfo; } else idltdi = &r->typeConvTbl[GetBuiltinType (t)]; /* no parent means t is the root of a typedef */ if ((parent == NULL) && (idltdi->isPtrForTypeDef)) retVal = TRUE; else if ((parent != NULL) && ((parent->basicType->choiceId == BASICTYPE_SET) || (parent->basicType->choiceId == BASICTYPE_SEQUENCE)) && (idltdi->isPtrInSetAndSeq)) retVal = TRUE; else if ((parent != NULL) && ((parent->basicType->choiceId == BASICTYPE_SETOF) || (parent->basicType->choiceId == BASICTYPE_SEQUENCEOF)) && (idltdi->isPtrInList)) retVal = TRUE; else if ((parent != NULL) && (parent->basicType->choiceId == BASICTYPE_CHOICE) && (idltdi->isPtrInChoice)) retVal = TRUE; else if (((t->optional) || (t->defaultVal != NULL)) && (idltdi->isPtrForOpt)) retVal = TRUE; return retVal; td=td; /*AVOIDS warning.*/ } /* IsIDLPtr */ /* fill given idltdi with defaults from table for given typedef */ void FillIDLTDIDefaults PARAMS ((r, idltdi, td), IDLRules *r _AND_ IDLTDI *idltdi _AND_ TypeDef *td) { IDLTDI *tblidltdi; int typeIndex; char *tmpName; typeIndex = GetBuiltinType (td->type); if (typeIndex < 0) return; tblidltdi = &r->typeConvTbl[typeIndex]; memcpy (idltdi, tblidltdi, sizeof (IDLTDI)); /* make sure class name is unique wrt to previously defined classes */ tmpName = Asn1TypeName2CTypeName (td->definedName); idltdi->typeName = Malloc (strlen (tmpName) + 2 + r->maxDigitsToAppend +1); strcpy (idltdi->typeName, tmpName); if (tblidltdi->asn1TypeId != BASICTYPE_CHOICE) strcat (idltdi->typeName, "_T"); Free (tmpName); MakeCxxStrUnique (definedNamesG, idltdi->typeName, r->maxDigitsToAppend, 1); DefineObj (&definedNamesG, idltdi->typeName); } /* FillIDLTDIDefaults */ esnacc-ng-1.8.1/compiler/back-ends/str-util.c000066400000000000000000000355231302010526100207450ustar00rootroot00000000000000/* * compiler/back_ends/c_gen/str_util.c - bunch of ASN.1/C string utilities * * * Mike Sample * 91/08/12 * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/back-ends/str-util.c,v 1.10 2004/03/22 20:04:06 gronej Exp $ * $Log: str-util.c,v $ * Revision 1.10 2004/03/22 20:04:06 gronej * took IBM references out of the code (to the best of our knowledge, we don't use any of it anymore) * * Revision 1.9 2003/07/07 14:54:24 nicholar * Eliminated headers and cleaned up include references * * Revision 1.8 2002/09/16 16:56:31 mcphersc * iFixed warnings * * Revision 1.7 2002/09/05 17:43:16 vracarl * got rid of c++ comments * * Revision 1.6 2002/07/11 18:46:19 leonberp * change MakeFileName to only return filename from path * * Revision 1.5 2001/07/12 19:34:18 leonberp * Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. * * Revision 1.4 2001/05/07 15:05:40 mcphersc * Added sub argument to the -C option to allow for .cpp file extension. * Use -C cpp option for .cpp file extensions * * Revision 1.3 2000/11/01 17:49:52 sfl * UPDATED to fix removal of "char pathname[1024];" for #ifdef build on Unix * (removed from PC based on warning implying unused; necessary on Unix based * on #ifdef; replaced with #ifdef to avoid PC warning). * * Revision 1.2 2000/10/24 14:54:43 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:36:04 leonberp * First CVS Version of SNACC. * * Revision 1.4 1995/07/25 18:13:31 rj * include string(s).h * * by default, snacc now derives output file names from the .asn1 input file name instead of the module name. * the global keepbaseG variable switches between the two behaviours. * * additional filename generator for idl backend. * * changed `_' to `-' in file names. * * Revision 1.3 1994/10/08 03:48:17 rj * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long. * * Revision 1.2 1994/09/01 00:25:31 rj * snacc_config.h removed; more portable .h file inclusion. * * Revision 1.1 1994/08/28 09:48:37 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include "asn-incl.h" #include #if HAVE_UNISTD_H #include /* for pathconf (..) */ #endif #if STDC_HEADERS || HAVE_STRING_H #include #else #include #endif #include #include "asn1module.h" #include "c-gen/rules.h" #include "c-gen/type-info.h" #include "str-util.h" #define DIGIT_TO_ASCII( d) (((d) % 10) + '0') int IsCKeyWord PROTO ((char *str)); int IsCxxKeyWord PROTO ((char *str)); int keepbaseG = TRUE; /* * allocates new and returns a copy of the given * string with '-'s (dashes) replaced by '_'s (underscores) */ char * Asn1TypeName2CTypeName PARAMS ((aName), char *aName) { char *retVal; if (aName == NULL) return NULL; retVal = Malloc (strlen (aName) + 1); strcpy (retVal, aName); Dash2Underscore (retVal, strlen (retVal)); return retVal; } /* Asn1TypeName2CTypeName */ /* * allocates new str and returns a copy of the given * string with '-'s (dashes) replaced by '_'s (underscores) */ char * Asn1FieldName2CFieldName PARAMS ((aName), char *aName) { char *retVal; if (aName == NULL) return NULL; retVal = Malloc (strlen (aName) + 1); strcpy (retVal, aName); Dash2Underscore (retVal, strlen (retVal)); return retVal; } /* Asn1FieldName2CFieldName */ /* * allocates new str and returns a copy of the given * string with '-'s (dashes) replaced by '_'s (underscores) */ char * Asn1ValueName2CValueName PARAMS ((aName), char *aName) { char *retVal; if (aName == NULL) return NULL; retVal = Malloc (strlen (aName) + 1); strcpy (retVal, aName); Dash2Underscore (retVal, strlen (retVal)); return retVal; } /* Asn1FieldName2CFieldName */ /* * allocates and returns a string with all of * the caps from the given string */ char * GetCaps PARAMS ((str), char *str) { int i, j; char *retVal; if (str == NULL) return NULL; retVal = Malloc (strlen (str) + 1); for (j = 0, i = 0; i < (int)strlen (str); i++) { if (isupper (str[i])) retVal[j++] = str[i]; } retVal[j] = '\0'; /* null terminate */ return retVal; } /* GetCaps */ /* * allocates and returns a string with all of * the caps and digits from the given string */ char * GetCapsAndDigits PARAMS ((str), char *str) { int i, j; char *retVal; if (str == NULL) return NULL; retVal = Malloc (strlen (str) + 1); for (j = 0, i = 0; i < (int)strlen (str); i++) { if ((isupper (str[i])) || (isdigit (str[i]))) retVal[j++] = str[i]; } retVal[j] = '\0'; /* null terminate */ return retVal; } /* GetCapsAndDigits */ /* * replaces lowercase chars in given str * with upper case version * NOTE: modifies given str */ void Str2UCase PARAMS ((str, len), char *str _AND_ int len) { int i; for (i=0; i < len; i++) { if (islower (str[i])) str[i] = (char)toupper (str[i]); } } /* Str2UCase */ /* * replaces uppercase chars in given str * with lower case version * NOTE: modifies given str */ void Str2LCase PARAMS ((str, len), char *str _AND_ int len) { int i; for (i=0; i < len; i++) { if (isupper (str[i])) str[i] = (char)tolower (str[i]); } } /* Str2LCase */ /* * replace dash chars in given str * with underscores * NOTE: modifies given str */ void Dash2Underscore PARAMS ((str, len), char *str _AND_ int len) { int i; for (i=0; i < len; i++) { if (str[i] == '-') str[i] = '_'; } } /* Dash2Underscore */ /* * tacks on the ascii version of the given digit * at the end of the given str. * NOTE: make sure the str you give has enough space * for the digits */ void AppendDigit PARAMS ((str, digit), char *str _AND_ int digit) { int high = 1000000000; int currDigit; int value; char digitStr[20]; /* arbitrary length > max */ if (digit < 0) digit *= -1; currDigit = 0; while (high > 0) { value = digit / high; if (value != 0) digitStr[currDigit++]= (char)DIGIT_TO_ASCII (value); digit = digit % high; high = high/10; } if (currDigit == 0) strcat (str, "0"); else { digitStr[currDigit] = '\0'; /* null terminate */ strcat (str, digitStr); } } /* AppendDigit */ /* * given a defined object list containing null termintated strs, * a str to be made unique wrt to the list by adding digits to the * end, the max number of digits to add and the digit to start * at, str is modified to be unique. It is not added to the * defined object list. The given str must have enough spare, * allocated chars after it's null terminator to hold maxDigits * more characters. * Only appends digits if the string is not unique or is a C keyword. * * Eg MakeCStrUnique ({ "Foo", "Bar" }, "Foo\0 ", 3, 1) * modifies the the Str "Foo" to "Foo1" */ void MakeCStrUnique PARAMS ((nameList, str, maxDigits, startingDigit), DefinedObj *nameList _AND_ char *str _AND_ int maxDigits _AND_ int startingDigit) { int digit, len, maxDigitVal; if (ObjIsDefined (nameList, str, StrObjCmp) || IsCKeyWord (str)) { for (maxDigitVal = 1; maxDigits > 0; maxDigits--) maxDigitVal *= 10; len = strlen (str); digit = startingDigit; do { str[len] = '\0'; AppendDigit (str, digit++); } while (ObjIsDefined (nameList, str, StrObjCmp) && (digit < maxDigitVal)); } } /* MakeCStrUnique */ /* * same as MakeCStrUnique except checks against C++ keywords */ void MakeCxxStrUnique PARAMS ((nameList, str, maxDigits, startingDigit), DefinedObj *nameList _AND_ char *str _AND_ int maxDigits _AND_ int startingDigit) { int digit, len, maxDigitVal; if (ObjIsDefined (nameList, str, StrObjCmp) || IsCxxKeyWord (str)) { for (maxDigitVal = 1; maxDigits > 0; maxDigits--) maxDigitVal *= 10; len = strlen (str); digit = startingDigit; do { str[len] = '\0'; AppendDigit (str, digit++); } while (ObjIsDefined (nameList, str, StrObjCmp) && (digit < maxDigitVal)); } } /* MakeCxxStrUnique */ static char *OutputDirectoryName; void StoreOutputDirectory PARAMS ((directory), const char *directory) { size_t len = strlen(directory); free(OutputDirectoryName); if (directory[len-1] != '/') { fprintf(stderr, "W: Output '%s' does not end with '/'. Adding.\n", directory); OutputDirectoryName = Malloc(len+2); memcpy(OutputDirectoryName, directory, len); OutputDirectoryName[len] = '/'; OutputDirectoryName[len+1] = '\0'; } else { OutputDirectoryName = Strdup(directory); } } /* * if (keepbaseG) * { * strip leading path and trailing suffix * } * else * { * allocates and returns a base file name generated from * the module's name. May shorten the name if the * expected length exceed the systems max path component length * (eg to support SYS V 14 char filename len limit) * } * Base file name is used as the base name for the generated C source files. */ char * MakeBaseFileName PARAMS ((refName), const char *refName) { char *retVal; if (keepbaseG) { char *base, *dot; int stublen; if ((base = strrchr (refName, '/')) != NULL) base++; else base = (char *)refName; if ((dot = strrchr (base, '.')) != NULL) stublen = dot - base; else stublen = strlen (base); retVal = Malloc (stublen+1); memcpy (retVal, base, stublen); retVal[stublen] = '\0'; } else { int fNameLen; int cpyLen; int maxPathComponentLen; #ifdef _PC_NAME_MAX char pathName[1024]; #endif # define MAX_SUFFIX_LEN 4 /* .c, .h, .cpp */ extern int maxFileNameLenG; /* declared in snacc.c */ /* * if the user has not given the max file name len * via the -mf option, * find the max filename len (ala POSIX method) * if possible. Otherwise hardwire it to 14 * to support underpowered OSes */ if (maxFileNameLenG > 2) maxPathComponentLen = maxFileNameLenG; else #ifdef _PC_NAME_MAX maxPathComponentLen = pathconf (getcwd (pathName, 1024), _PC_NAME_MAX); #else maxPathComponentLen = 14; #endif retVal = (char *)Malloc (strlen (refName) +1); fNameLen = strlen (refName) + MAX_SUFFIX_LEN; if ((fNameLen > maxPathComponentLen) && (maxPathComponentLen != -1)) { cpyLen = maxPathComponentLen - MAX_SUFFIX_LEN; /* don't allow trailing dash */ if (refName[cpyLen-1] == '-') cpyLen--; strncpy (retVal, refName, cpyLen); retVal[cpyLen] = '\0'; } else strcpy (retVal, refName); } if (OutputDirectoryName && strlen(OutputDirectoryName)) { char *oldRetVal = Strdup(retVal); size_t retValLen = strlen(retVal) + strlen(OutputDirectoryName) + 1; retVal = Realloc(retVal, retValLen); memcpy(retVal, OutputDirectoryName, strlen(OutputDirectoryName)); memcpy(retVal+strlen(OutputDirectoryName), oldRetVal, strlen(oldRetVal)+1); Free(oldRetVal); } return retVal; } /* MakeBaseFileName */ const char * FileNameOnly(const char *path) { int i = strlen(path); for (; i != 0; i--) { if (path[i] == '\\' || path[i] == '/') { i++; break; } } return &path[i]; } /* * given a module name and a suffix, the * suffix is appended to the module name * and the whole string is put into lower case * and underscores are inserted in likely places * (ie MTSAbstractSvc.h -> mts_abstract_svc.h) */ char * MakeFileName PARAMS ((refName, suffix), const char *refName _AND_ const char *suffix) { char *fName; if (keepbaseG) { const char *fn = FileNameOnly(refName); size_t baselen = strlen (fn); size_t sufflen = strlen (suffix); fName = Malloc (baselen + sufflen + 1); memcpy (fName, fn, baselen); memcpy (fName+baselen, suffix, sufflen); fName[baselen+sufflen] = '\0'; } else { int fNameLen; #define MAX_UNDERSCORE 10 fName = Malloc (strlen (refName) + strlen (suffix) + 1); strcpy (fName, refName); strcat (fName, suffix); fNameLen = strlen (fName); /* * convert dashes to underscores, add spaces */ Dash2Underscore (fName, fNameLen); /* * remove the next two lines if you uncomment the * following underscore inserter */ Str2LCase (fName, fNameLen - strlen (suffix)); } if (OutputDirectoryName && strlen(OutputDirectoryName)) { char *oldRetVal = Strdup(fName); size_t retValLen = strlen(fName) + strlen(OutputDirectoryName) + 1; fName = Realloc(fName, retValLen); memcpy(fName, OutputDirectoryName, strlen(OutputDirectoryName)); memcpy(fName+strlen(OutputDirectoryName), oldRetVal, strlen(oldRetVal)+1); Free(oldRetVal); } return fName; } /* MakeFileName */ char * MakeCHdrFileName PARAMS ((refName), const char *refName) { return MakeFileName (refName, ".h"); } char * MakeCSrcFileName PARAMS ((refName), const char *refName) { return MakeFileName (refName, ".c"); } char * MakeCxxHdrFileName PARAMS ((refName), const char *refName) { return MakeFileName (refName, ".h"); } char * MakeCxxSrcFileName PARAMS ((refName), const char *refName) { return MakeFileName (refName, ".cpp"); } #if IDL char * MakeIDLFileName PARAMS ((refName), const char *refName) { return MakeFileName (refName, ".idl"); } #endif esnacc-ng-1.8.1/compiler/back-ends/str-util.h000066400000000000000000000054541302010526100207520ustar00rootroot00000000000000/* * compiler/back_ends/c_gen/str_util.h * * Mike Sample * 91/08/12 * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/back-ends/str-util.h,v 1.3 2004/03/22 20:04:06 gronej Exp $ * $Log: str-util.h,v $ * Revision 1.3 2004/03/22 20:04:06 gronej * took IBM references out of the code (to the best of our knowledge, we don't use any of it anymore) * * Revision 1.2 2003/07/07 14:54:24 nicholar * Eliminated headers and cleaned up include references * * Revision 1.1.1.1 2000/08/21 20:36:04 leonberp * First CVS Version of SNACC. * * Revision 1.3 1995/07/25 18:13:55 rj * by default, snacc now derives output file names from the .asn1 input file name instead of the module name. * the global keepbaseG variable switches between the two behaviours. * * additional filename generator for idl backend. * * changed `_' to `-' in file names. * * Revision 1.2 1994/10/08 03:48:18 rj * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long. * * Revision 1.1 1994/08/28 09:48:38 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include "define.h" char *Asn1TypeName2CTypeName PROTO ((char *aName)); char *Asn1FieldName2CFieldName PROTO ((char *aName)); char *Asn1ValueName2CValueName PROTO ((char *aName)); char *GetCaps PROTO ((char *str)); char *GetCapsAndDigits PROTO ((char *str)); void Str2UCase PROTO ((char *str, int len)); void Str2LCase PROTO ((char *str, int len)); void Dash2Underscore PROTO ((char *str, int len)); void AppendDigit PROTO ((char *str, int digit)); void MakeCStrUnique PROTO ((DefinedObj *nameList, char *str, int maxDigits, int startingDigit)); void MakeCxxStrUnique PROTO ((DefinedObj *nameList, char *str, int maxDigits, int startingDigit)); extern int keepbaseG; void StoreOutputDirectory PROTO ((const char *directory)); char *MakeBaseFileName PROTO ((const char *moduleName)); char *MakeFileName PROTO ((const char *moduleName, const char *suffix)); char *MakeCHdrFileName PROTO ((const char *moduleName)); char *MakeCSrcFileName PROTO ((const char *moduleName)); char *MakeCxxHdrFileName PROTO ((const char *moduleName)); char *MakeCxxSrcFileName PROTO ((const char *moduleName)); #if IDL char *MakeIDLFileName PROTO ((const char *moduleName)); #endif esnacc-ng-1.8.1/compiler/back-ends/tag-util.c000066400000000000000000000406271302010526100207110ustar00rootroot00000000000000/* * compiler/back_ends/c_gen/tag_util.c - utilities for dealing with tags * * MS 92 * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/back-ends/tag-util.c,v 1.7 2003/07/28 11:13:51 colestor Exp $ * $Log: tag-util.c,v $ * Revision 1.7 2003/07/28 11:13:51 colestor * Changes to complete handing of the "--snacc namespace" compiler directive. * Also, updates to handle ASN.1 constant integer tag designations for C++/C. * * Revision 1.6 2003/07/07 14:54:24 nicholar * Eliminated headers and cleaned up include references * * Revision 1.5 2002/10/23 10:21:23 mcphersc * changed BUF_TYPE to GenBuf * * Revision 1.4 2002/09/16 16:56:35 mcphersc * Fixed warnings * * Revision 1.3 2002/05/15 14:53:10 leonberp * added support for new basicTypes to compiler * * Revision 1.2 2000/10/24 14:54:43 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:36:04 leonberp * First CVS Version of SNACC. * * Revision 1.3 1995/07/25 18:15:28 rj * changed `_' to `-' in file names. * * Revision 1.2 1994/09/01 00:26:07 rj * snacc_config.h and other superfluous .h files removed. * * Revision 1.1 1994/08/28 09:48:39 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include #include "asn-incl.h" #include "asn1module.h" #include "mem.h" #include "define.h" #include "lib-types.h" #include "c-gen/rules.h" #include "c-gen/type-info.h" #include "str-util.h" #include "snacc-util.h" #include "c-gen/util.h" #include "tag-util.h" #include "print.h" #include #ifdef WIN32 #pragma warning( disable : 4706 ) // IGNORE assign w/in conditional expression. #endif /* * returns the tags for the given type (stops at next type definition). * if no tags have been grabbed yet and an untagged CHOICE is encountered, * all of the CHOICE's top level tags are returned and the stoleChoiceTags * flag is set. If the type has no tags an empty list is returned, not * NULL. * * ASSUMES: tag list's and implicit flags have been adjusted according * to module level IMPLICIT/EXPLICIT-TAGS and type level * IMPLICIT/EXPLICIT tagging. * * EXAMPLE: * * typeX ::= SEQUENCE SomeChoice ::= CHOICE * { { * foo [0] INTEGER, [0] INTEGER, * bar SomeChoice, [1] BOOLEAN, * bell [1] IMPLICIT BOOLEAN, [2] IA5String * gumby [2] SomeChoice, } poki SomeOtherChoice * } * * SomeOtherChoice ::= [APPLICATION 99] CHOICE { ....} * * GetTags (foo's type) --> CNTX 0, UNIV INTEGER_TAG_CODE stoleChoiceTags = FALSE * GetTags (bar) --> CNTX 0, CNTX 1, CNTX 2 (SomeChoice Elmt's first Tags) * stoleChoiceTags = TRUE * GetTags (bell) --> CNTX 1 stoleChoiceTags = FALSE * GetTags (gumby) --> CNTX 2 stoleChoiceTags = FALSE * GetTags (poki) --> APPLICATION 99 stoleChoiceTags = FALSE * * MS 92/03/04 Added tag form information */ TagList* GetTags PARAMS ((t, stoleChoiceTags), Type *t _AND_ int *stoleChoiceTags) { Tag *tag; TagList *tl; TagList *retVal; Tag *last; Tag *tagCopy; Tag **tagHndl; int implicitRef; int stoleChoicesAgain; NamedType *e; tl = t->tags; if (tl != NULL) AsnListFirst (tl); retVal = (TagList*) AsnListNew (sizeof (void*)); implicitRef = FALSE; *stoleChoiceTags = FALSE; for (;;) { /* * go through tag list local to this type if any */ FOR_REST_LIST_ELMT (tag, tl) { tagCopy = (Tag*)Malloc (sizeof (Tag)); memcpy (tagCopy, tag, sizeof (Tag)); tagHndl = (Tag**)AsnListAppend (retVal); *tagHndl = tagCopy; } /* * follow tags of referenced types */ if ((t->basicType->choiceId == BASICTYPE_LOCALTYPEREF) || (t->basicType->choiceId == BASICTYPE_IMPORTTYPEREF)) { if (!implicitRef) implicitRef = t->implicit; if (t->basicType->a.localTypeRef->link == NULL) { fprintf (errFileG,"ERROR - unresolved type ref, cannot get tags for decoding>\n"); break; } t = t->basicType->a.localTypeRef->link->type; tl = t->tags; if (tl != NULL) { AsnListFirst (tl); /* set curr ptr to first node */ if ((!LIST_EMPTY (tl)) && implicitRef) { AsnListNext (tl); implicitRef = FALSE; } } } /* * if untagged choice and no tags found yet */ else if ((t->basicType->choiceId == BASICTYPE_CHOICE) && (LIST_EMPTY (retVal))) { /* * Return list of top level tags from this choice * and set "stoleChoiceTags" bool param */ if (implicitRef) fprintf (errFileG,"ERROR - IMPLICITLY Tagged CHOICE\n"); *stoleChoiceTags = TRUE; FOR_EACH_LIST_ELMT (e, t->basicType->a.choice) { stoleChoicesAgain = FALSE; tl = GetTags (e->type, &stoleChoicesAgain); if (tl == NULL) break; AsnListFirst (tl); if (stoleChoicesAgain) { FOR_EACH_LIST_ELMT (tag, tl) { tagCopy = (Tag*)Malloc (sizeof (Tag)); memcpy (tagCopy, tag, sizeof (Tag)); tagHndl = (Tag**)AsnListAppend (retVal); *tagHndl = tagCopy; } } else { tag = (Tag*)FIRST_LIST_ELMT (tl); tagCopy = (Tag*)Malloc (sizeof (Tag)); memcpy (tagCopy, tag, sizeof (Tag)); tagHndl = (Tag**)AsnListAppend (retVal); *tagHndl = tagCopy; } FreeTags (tl); } break; /* exit for loop */ } else break; /* exit for loop */ } if (!*stoleChoiceTags && (retVal != NULL) && !LIST_EMPTY (retVal)) { last = (Tag*)LAST_LIST_ELMT (retVal); FOR_EACH_LIST_ELMT (tag, retVal) { tag->form = CONS; } last->form = LIBTYPE_GET_TAG_FORM (GetBuiltinType (t)); } AsnListFirst (retVal); return retVal; } /* GetTags */ void FreeTags PARAMS ((tl), TagList *tl) { Tag *tag; AsnListNode *listNode; AsnListNode *ln; /* free tags */ FOR_EACH_LIST_ELMT (tag, tl) { Free (tag); } /* free list nodes */ for (ln = FIRST_LIST_NODE (tl); ln != NULL; ) { listNode = ln; ln = ln->next; Free (listNode); } /* free list head */ Free (tl); } /* FreeTags */ /* * Returns the number of tags that GetTags would return for * the same type. */ int CountTags PARAMS ((t), Type *t) { int tagCount; Tag *tag; TagList *tl; int implicitRef; tl = t->tags; if (tl != NULL) AsnListFirst (tl); tagCount = 0; implicitRef = FALSE; for (;;) { /* * go through tag list local to this type if any */ FOR_REST_LIST_ELMT (tag, tl) { tagCount++; } /* * follow tags of referenced types */ if ((t->basicType->choiceId == BASICTYPE_LOCALTYPEREF) || (t->basicType->choiceId == BASICTYPE_IMPORTTYPEREF)) { if (!implicitRef) implicitRef = t->implicit; if (t->basicType->a.localTypeRef->link == NULL) { fprintf (errFileG,"ERROR - unresolved type ref, cannot get tags for decoding>\n"); break; } t = t->basicType->a.localTypeRef->link->type; tl = t->tags; if (tl != NULL) { AsnListFirst (tl); /* set curr ptr to first node */ if ((!LIST_EMPTY (tl)) && implicitRef) { AsnListNext (tl); implicitRef = FALSE; } } } else break; } return tagCount; } /* CountTags */ unsigned long TagByteLen PARAMS ((tagCode), unsigned long tagCode) { unsigned long tagLen; if (tagCode < 31) tagLen = 1; else if (tagCode < 128) tagLen = 2; else if (tagCode < 16384) tagLen = 3; else if (tagCode < 2097152) tagLen = 4; else tagLen = 5; return tagLen; } /* TagByteLen */ char* Class2ClassStr PARAMS ((class), int class) { switch (class) { case UNIV: return "UNIV"; break; case APPL: return "APPL"; break; case CNTX: return "CNTX"; break; case PRIV: return "PRIV"; break; default: return "UNKNOWN"; break; } } /* Class2ClassStr */ char* Form2FormStr PARAMS ((form), BER_FORM form) { switch (form) { case PRIM: return "PRIM"; break; case CONS: return "CONS"; break; default: return "UNKNOWN"; break; } } /* Form2FormStr */ char* Code2UnivCodeStr PARAMS ((code), BER_UNIV_CODE code) { switch (code) { case BOOLEAN_TAG_CODE: return "BOOLEAN_TAG_CODE"; case INTEGER_TAG_CODE: return "INTEGER_TAG_CODE"; case BITSTRING_TAG_CODE: return "BITSTRING_TAG_CODE"; case OCTETSTRING_TAG_CODE: return "OCTETSTRING_TAG_CODE"; case NULLTYPE_TAG_CODE: return "NULLTYPE_TAG_CODE"; case OID_TAG_CODE: return "OID_TAG_CODE"; case OD_TAG_CODE: return "OD_TAG_CODE"; case EXTERNAL_TAG_CODE: return "EXTERNAL_TAG_CODE"; case REAL_TAG_CODE: return "REAL_TAG_CODE"; case ENUM_TAG_CODE: return "ENUM_TAG_CODE"; case SEQ_TAG_CODE: return "SEQ_TAG_CODE"; case SET_TAG_CODE: return "SET_TAG_CODE"; case NUMERICSTRING_TAG_CODE: return "NUMERICSTRING_TAG_CODE"; case PRINTABLESTRING_TAG_CODE: return "PRINTABLESTRING_TAG_CODE"; case TELETEXSTRING_TAG_CODE: return "TELETEXSTRING_TAG_CODE"; case VIDEOTEXSTRING_TAG_CODE: return "VIDEOTEXSTRING_TAG_CODE"; case IA5STRING_TAG_CODE: return "IA5STRING_TAG_CODE"; case UTCTIME_TAG_CODE: return "UTCTIME_TAG_CODE"; case GENERALIZEDTIME_TAG_CODE: return "GENERALIZEDTIME_TAG_CODE"; case GRAPHICSTRING_TAG_CODE: return "GRAPHICSTRING_TAG_CODE"; case VISIBLESTRING_TAG_CODE: return "VISIBLESTRING_TAG_CODE"; case GENERALSTRING_TAG_CODE: return "GENERALSTRING_TAG_CODE"; case UNIVERSALSTRING_TAG_CODE: return "UNIVERSALSTRING_TAG_CODE"; case BMPSTRING_TAG_CODE: return "BMPSTRING_TAG_CODE"; case UTF8STRING_TAG_CODE: return "UTF8STRING_TAG_CODE"; default: { /* if the universal type is not known then just return the * unvisersal tag code. This is useful for defining new types * in local modules w/o having to modify the compiler. */ static char retstring[256]; snacc_snprintf(retstring, 256, "%d", code); return retstring; } } } /* TagId2FormStr */ /* Compare the tags of two types */ int CmpTags PARAMS((a, b), Type *a _AND_ Type *b) { TagList *t1; TagList *t2; Tag *tg1; Tag *tg2; int stoleChoiceTags; unsigned tagBuf1[256]; unsigned tagBuf2[256]; int len1; int len2; int cmp; int min; t1 = GetTags(a, &stoleChoiceTags); t2 = GetTags(b, &stoleChoiceTags); len1 = 0; len2 = 0; /* Get tags for item 1 */ FOR_EACH_LIST_ELMT(tg1, t1) { tagBuf1[len1++] = MAKE_TAG_ID(tg1->tclass, tg1->form, tg1->code); if (len1 == 256) { /* XXX Can do better than this */ fprintf(errFileG, "CmpTags: Tag length too long"); abort(); } } /* Get tags for item2 */ FOR_EACH_LIST_ELMT(tg2, t2) { tagBuf2[len2++] = MAKE_TAG_ID(tg2->tclass, tg2->form, tg2->code); if (len2 == 256) { /* XXX Can do better than this */ fprintf(errFileG, "CmpTags: Tag length too long"); abort(); } } /* Compare results */ min = (len1 > len2)?len2:len1; cmp = memcmp(tagBuf1, tagBuf2, min * sizeof(unsigned)); if (cmp != 0) { return cmp; } else { return len1 - len2; } } // // char *DetermineCode(Tag *tag, int *ptagLen, int bJustIntegerFlag) { static char retstring[256]; char *codeStr=NULL; int iValue=500; // WILL indicate a problem on source creation... memset(retstring, 0, sizeof(retstring)); if (tag->valueRef == NULL) { if (!bJustIntegerFlag) { codeStr = Code2UnivCodeStr (tag->code); } else { sprintf(retstring, "%d", tag->code); codeStr = retstring; } // END IF bJustIntegerFlag if (ptagLen) { *ptagLen = TagByteLen(tag->code); } } else { if (tag->valueRef && tag->valueRef->basicValue && tag->valueRef->basicValue->choiceId == BASICVALUE_LOCALVALUEREF && tag->valueRef->basicValue->a.localValueRef && tag->valueRef->basicValue->a.localValueRef->link && tag->valueRef->basicValue->a.localValueRef->link->value && tag->valueRef->basicValue->a.localValueRef->link->value->basicValue) { if (tag->valueRef->basicValue->a.localValueRef->link->value->basicValue->choiceId == BASICVALUE_INTEGER) { iValue = tag->valueRef->basicValue->a.localValueRef->link-> value->basicValue->a.integer; } // IF Integer else if (tag->valueRef->basicValue->a.localValueRef->link->value->basicValue->choiceId == BASICVALUE_LOCALVALUEREF) { ValueRef *pvalueRef=NULL; if (tag->valueRef->basicValue->a.localValueRef->link->value->basicValue->choiceId == BASICVALUE_LOCALVALUEREF) { pvalueRef = tag->valueRef->basicValue->a.localValueRef->link->value->basicValue->a.localValueRef; if (pvalueRef->link->value && pvalueRef->link->value->basicValue && pvalueRef->link->value->basicValue->choiceId == BASICVALUE_INTEGER) iValue = pvalueRef->link->value->basicValue->a.integer; } } // END IF Integer/Import else { printf("Tag value type NOT RECOGNIZED; COULD NOT RESOLVE tag integer!\n"); } } else if (tag->valueRef->basicValue->choiceId == BASICVALUE_IMPORTVALUEREF && tag->valueRef->basicValue->a.importValueRef && tag->valueRef->basicValue->a.importValueRef->link && tag->valueRef->basicValue->a.importValueRef->link->value && tag->valueRef->basicValue->a.importValueRef->link->value-> basicValue && tag->valueRef->basicValue->a.importValueRef->link->value-> basicValue->choiceId == BASICVALUE_INTEGER) { iValue = tag->valueRef->basicValue->a.importValueRef->link-> value->basicValue->a.integer; } sprintf(retstring, "%d", iValue); codeStr = retstring; if (ptagLen) { *ptagLen = TagByteLen(iValue); } } return(codeStr); } esnacc-ng-1.8.1/compiler/back-ends/tag-util.h000066400000000000000000000037571302010526100207210ustar00rootroot00000000000000/* * compiler/back_ends/c_gen/tag_util.h - utilities for dealing with tags * * MS 92 * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/back-ends/tag-util.h,v 1.3 2003/07/28 11:13:51 colestor Exp $ * $Log: tag-util.h,v $ * Revision 1.3 2003/07/28 11:13:51 colestor * Changes to complete handing of the "--snacc namespace" compiler directive. * Also, updates to handle ASN.1 constant integer tag designations for C++/C. * * Revision 1.2 2003/07/07 14:54:24 nicholar * Eliminated headers and cleaned up include references * * Revision 1.1.1.1 2000/08/21 20:36:04 leonberp * First CVS Version of SNACC. * * Revision 1.3 1995/07/25 18:15:29 rj * changed `_' to `-' in file names. * * Revision 1.2 1994/10/08 03:48:19 rj * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long. * * Revision 1.1 1994/08/28 09:48:40 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ TagList *GetTags PROTO ((Type *t, int *stoleChoiceTags)); void FreeTags PROTO ((TagList *tl)); int CountTags PROTO ((Type *t)); unsigned long int TagByteLen PROTO ((unsigned long int tagCode)); char *Class2ClassStr PROTO ((int class)); /* class defined in asn1module.h */ char *Form2FormStr PROTO ((BER_FORM form)); char *Code2UnivCodeStr PROTO ((BER_UNIV_CODE code)); int CmpTags PROTO ((Type *a, Type *b)); char *DetermineCode PROTO ((Tag *tag, int *ptagLen, int bJustIntegerFlag)); esnacc-ng-1.8.1/compiler/core/000077500000000000000000000000001302010526100161075ustar00rootroot00000000000000esnacc-ng-1.8.1/compiler/core/asn1module.h000066400000000000000000000754031302010526100203410ustar00rootroot00000000000000/* * compiler/core/asn1module.h * * "Asn1Module" ASN.1 module C type definitions and prototypes * * This .h file was by snacc on Sun Feb 7 23:38:26 1993 * * UBC snacc written compiler by Mike Sample *- editing not recommended */ #ifndef WIN32 #include #endif #ifndef _asn1module_h_ #define _asn1module_h_ typedef enum { PRESENT_CT = 0, ABSENT_CT = 1, EMPTY_CT = 2, OPTIONAL_CT = 3 } ConstraintEnum; /* ENUMERATED { PRESENT_CT (0), ABSENT_CT (1), EMPTY_CT (2), OPTIONAL_CT (3) } */ typedef enum { FULL_CT = 0, PARTIAL_CT = 1, SINGLE_CT = 2 } InnerSubtypeEnum; /* ENUMERATED { FULL_CT (0), PARTIAL_CT (1), SINGLE_CT (2) } */ typedef enum { SNMP_MANDATORY = 0, SNMP_OPTIONAL = 1, SNMP_OBSOLETE = 2, SNMP_DEPRECATED = 3 } SnmpObjectTypeMacroTypeEnum1; /* ENUMERATED { SNMP_MANDATORY (0), SNMP_OPTIONAL (1), SNMP_OBSOLETE (2), SNMP_DEPRECATED (3) } */ typedef enum { SNMP_READ_ONLY = 0, SNMP_READ_WRITE = 1, SNMP_WRITE_ONLY = 2, SNMP_NOT_ACCESSIBLE = 3 } SnmpObjectTypeMacroTypeEnum; /* ENUMERATED { SNMP_READ_ONLY (0), SNMP_READ_WRITE (1), SNMP_WRITE_ONLY (2), SNMP_NOT_ACCESSIBLE (3) } */ typedef enum { CONSUMER_PORT = 0, SUPPLIER_PORT = 1, SYMMETRIC_PORT = 2 } AsnPortEnum; /* ENUMERATED { CONSUMER_PORT (0), SUPPLIER_PORT (1), SYMMETRIC_PORT (2) } */ typedef enum { EXPORTS_ALL = 0, EXPORTS_NOTHING = 1, EXPORTS_SOME = 2 } ModuleEnum2; /* ENUMERATED { EXPORTS_ALL (0), EXPORTS_NOTHING (1), EXPORTS_SOME (2) } */ typedef enum { EXPLICIT_TAGS = 0, IMPLICIT_TAGS = 1, AUTOMATIC_TAGS = 2, } ModuleEnum1; /* ENUMERATED { EXPLICIT_TAGS (0), IMPLICIT_TAGS (1) } */ typedef enum { MOD_OK = 0, MOD_NOT_LINKED = 1, MOD_ERROR = 2 } ModuleEnum; /* ENUMERATED { MOD_OK (0), MOD_NOT_LINKED (1), MOD_ERROR (2) } */ typedef AsnInt AsnRefineMacroType; /* INTEGER */ typedef enum { MIN_INT = 0, MAX_INT = 1 } SpecialIntegerValue; /* ENUMERATED { MIN_INT (0), MAX_INT (1) } */ typedef enum { MINUS_INFINITY_REAL = 0, PLUS_INFINITY_REAL = 1 } SpecialRealValue; /* ENUMERATED { MINUS_INFINITY_REAL (0), PLUS_INFINITY_REAL (1) } */ typedef enum { C_CHOICE = 0, C_LIST = 1, C_ANY = 2, C_ANYDEFINEDBY = 3, C_LIB = 4, C_STRUCT = 5, C_TYPEREF = 6, C_NO_TYPE = 7, C_TYPEDEF = 8, C_OBJECTCLASSFIELDTYPE = 9, // Deepak: 05/Feb/2003 C_OBJECTCLASS = 10, // Deepak: 11/Mar/2003 C_MACROTYPE = 11 // Deepak: 17/Apr/2003 } CTypeId; /* ENUMERATED { C_CHOICE (0), C_LIST (1), C_ANY (2), C_ANYDEFINEDBY (3), C_LIB (4), C_STRUCT (5), C_TYPEREF (6), C_NO_TYPE (7), C_TYPEDEF (8), C_OBJECTCLASSFIELDTYPE (9), C_OBJECTCLASS (10), C_MACROTYPE (11) } */ typedef struct OidOrInt /* CHOICE */ { enum OidOrIntChoiceId { OIDORINT_OID, OIDORINT_INTID } choiceId; union OidOrIntChoiceUnion { AsnOid *oid; /* OBJECT IDENTIFIER */ AsnInt intId; /* INTEGER */ } a; } OidOrInt; typedef AsnList OidList; /* SEQUENCE OF OBJECT IDENTIFIER */ typedef char *MyString; /* PrintableString */ typedef struct ModuleId /* SEQUENCE */ { MyString name; /* MyString */ OID *oid; /* OBJECT IDENTIFIER OPTIONAL */ } ModuleId; typedef struct AnyRef /* SEQUENCE */ { MyString anyIdName; /* MyString */ struct OidOrInt *id; /* OidOrInt */ } AnyRef; typedef enum { ASN1_TypeID, /* ASN.1 type value */ C_TypeID, /* CTypeId value */ C_TypeName, /* String value */ C_FieldName, /* String value */ IsPDU, /* Boolean value */ IsPtr, /* Boolean value */ IsPtrForTypeDef, /* Boolean value */ IsPtrForTypeRef, /* Boolean value */ IsPtrInChoice, /* Boolean value */ IsPtrForOpt, /* Boolean value */ OptionalTestRoutineName, /* String value */ DefaultFieldName, /* String value */ PrintRoutineName, /* String value */ EncodeRoutineName, /* String value */ DecodeRoutineName, /* String value */ FreeRoutineName, /* String value */ IsEncDec, /* Boolean value */ GenTypeDef, /* Boolean value */ GenPrintRoutine, /* Boolean value */ GenEncodeRoutine, /* Boolean value */ GenDecodeRoutine, /* Boolean value */ GenFreeRoutine, /* Boolean value */ ChoiceIdSymbol, /* String value */ ChoiceIdValue, /* Integer value */ ChoiceIdEnumName, /* String value */ ChoiceIdEnumFieldName, /* String value */ IsBigInt /* Boolean value */ } SnaccDirectiveEnum; typedef AsnList SnaccDirectiveList; /* SEQUENCE OF SnaccDirective */ typedef AsnList AnyRefList; /* SEQUENCE OF AnyRef */ typedef MyString MacroDef; /* MyString */ typedef AsnList ImportModuleList; /* SEQUENCE OF ImportModule */ typedef AsnList ImportElmtList; /* SEQUENCE OF ImportElmt */ typedef AsnList TypeDefList; /* SEQUENCE OF TypeDef */ typedef AsnList TagList; /* SEQUENCE OF Tag */ typedef AsnList NamedTypeList; /* SEQUENCE OF NamedType */ typedef AsnList ValueList; /* SEQUENCE OF Value */ typedef AsnList TypeOrValueList; /* SEQUENCE OF TypeOrValue */ typedef AsnList AsnPortList; /* SEQUENCE OF AsnPort */ typedef AsnList SubtypeList; /* SEQUENCE OF Subtype */ typedef AsnList ConstraintList; /* SEQUENCE OF Constraint */ typedef AsnList ValueDefList; /* SEQUENCE OF ValueDef */ typedef struct ImportElmtChoice /* CHOICE */ { enum ImportElmtChoiceChoiceId { IMPORTELMTCHOICE_TYPE, IMPORTELMTCHOICE_VALUE } choiceId; union ImportElmtChoiceChoiceUnion { struct TypeDef *type; /* [0] IMPLICIT TypeDef */ struct ValueDef *value; /* [1] IMPLICIT ValueDef */ } a; } ImportElmtChoice; typedef AsnList ObjectAssignmentList; /* Deepak: 26/Feb/2003 List of ObjectAssignment constructs */ typedef AsnList ObjectSetAssignmentList;/* Deepak: 26/Feb/2003 List of ObjectAssignment constructs */ typedef struct Module /* SEQUENCE */ { ModuleEnum status; /* ModuleEnum */ struct ModuleId *modId; /* ModuleId */ ModuleEnum1 tagDefault; /* ModuleEnum1 */ MyString namespaceToUse; /* MyString */ ModuleEnum2 exportStatus; /* ModuleEnum2 */ ImportModuleList *imports; /* ImportModuleList */ TypeDefList *typeDefs; /* TypeDefList */ ValueDefList *valueDefs; /* ValueDefList */ ObjectAssignmentList *objAssignments; /* Deepak: 04/Mar/2003 */ ObjectSetAssignmentList *objSetAssignments; /* Deepak: 04/Mar/2003 */ AsnBool hasAnys; /* BOOLEAN */ AsnBool ImportedFlag; /* BOOLEAN */ AsnBool ImportUsed; /* BOOLEAN */ MyString asn1SrcFileName; /* MyString */ MyString cHdrFileName; /* MyString */ MyString cSrcFileName; /* MyString */ MyString cxxHdrFileName; /* MyString */ MyString cxxSrcFileName; /* MyString */ AsnBool isExtensible; /*BOOLEAN*/ MyString cxxname; /* only used when META is defined */ #if IDL MyString idlFileName; /* MyString */ MyString idlname; #endif } Module; typedef struct ImportModule /* SEQUENCE */ { struct ModuleId *modId; /* ModuleId */ ImportElmtList *importElmts; /* ImportElmtList */ struct Module *moduleRef; /* Module */ AsnInt lineNo; /* INTEGER */ } ImportModule; typedef struct ImportElmt /* SEQUENCE */ { struct ImportElmtChoice *resolvedRef; /* ImportElmtChoice OPTIONAL */ MyString name; /* MyString */ AsnBool privateScope; /* BOOLEAN */ AsnInt lineNo; /* INTEGER */ } ImportElmt; typedef struct TypeDef /* SEQUENCE */ { AsnBool exported; /* BOOLEAN */ AsnBool recursive; /* BOOLEAN */ AsnBool isPdu; /* BOOLEAN */ AsnBool bHasTableConstraint; /* BOOLEAN */ AsnInt localRefCount; /* INTEGER */ AsnInt importRefCount; /* INTEGER */ AsnInt tmpRefCount; /* INTEGER */ AsnBool visited; /* BOOLEAN */ MyString definedName; /* MyString */ struct Type *type; /* Type */ struct CTDI *cTypeDefInfo; /* CTDI */ struct CxxTDI *cxxTypeDefInfo; /* CxxTDI */ struct IDLTDI *idlTypeDefInfo; /* IDLTDI */ SnaccDirectiveList *attrList; /* SnaccDirectiveList */ TypeDefList *refList; /* TypeDefList */ AnyRefList *anyRefs; /* AnyRefList */ } TypeDef; typedef struct Tag /* SEQUENCE */ { AsnInt tclass; /* INTEGER */ AsnInt form; /* INTEGER */ AsnInt code; /* INTEGER */ AsnBool explicit; /* BOOLEAN */ struct Value *valueRef; /* Value */ } Tag; typedef AsnList MyStringList; typedef AsnList WithSyntaxList; // Deepak: 22/Feb/2003 List of WithSyntax constructs typedef struct ObjectClassDef // Deepak: 22/Feb/2003 { NamedTypeList* classdef; WithSyntaxList* withsyntax; }ObjectClassDef; typedef struct ObjectSetAssignment // Deepak: 26/Feb/2003 { AsnInt lineNo; /* INTEGER */ MyString objectSetName; MyString objectClassName; ObjectClassDef *objectClassDefLink; // Deepak: 26/Mar/2003 TypeOrValueList *objectNameList; /* List of MyString */ }ObjectSetAssignment; typedef struct TableConstraint { ObjectSetAssignment *objSetAssignment; // Deepak: 26/Mar/2003 //MyString objSetName; MyStringList *atNotations; }TableConstraint; typedef struct Type /* SEQUENCE */ { AsnBool optional; /* BOOLEAN */ AsnBool implicit; /* BOOLEAN */ TagList *tags; /* TagList */ struct NamedValue *defaultVal; /* [0] IMPLICIT NamedValue OPTIONAL */ struct Subtype *subtypes; /* [1] Subtype OPTIONAL */ struct BasicType *basicType; /* [2] BasicType */ AsnInt lineNo; /* INTEGER */ struct CTRI *cTypeRefInfo; /* CTRI */ struct CxxTRI *cxxTypeRefInfo; /* CxxTRI */ struct IDLTRI *idlTypeRefInfo; /* IDLTRI */ SnaccDirectiveList *attrList; /* SnaccDirectiveList */ struct TableConstraint *tableConstraint; // Deepak: 10/Mar/2003 MyString typeName; // Deepak: 26/Mar/2003 AsnBool extensionAddition; /* BOOLEAN */ } Type; typedef ValueDefList NamedNumberList; /* ValueDefList */ typedef struct TypeOrValue /* CHOICE */ { enum TypeOrValueChoiceId { TYPEORVALUE_TYPE, TYPEORVALUE_VALUE } choiceId; union TypeOrValueChoiceUnion { struct Type *type; /* [0] IMPLICIT Type */ struct Value *value; /* [1] IMPLICIT Value */ } a; } TypeOrValue; /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ typedef struct WithSyntax // Deepak: 22/Feb/2003 { MyString definedName; MyString typeName; AsnBool bOptional; AsnInt lineNo; /* INTEGER */ WithSyntaxList *parent; WithSyntaxList *subToken; // Deepak: 27/Mar/2003 }WithSyntax; typedef AsnList ObjectAssignmentFieldList; // Deepak: 25/Feb/2003 List of ObjectAssignmentField constructs typedef struct ObjectAssignmentField { MyString objectFieldName; MyString objectFieldNameWS; AsnBool bOptional; // Deepak: 22/Mar/2003 AsnBool bPresent; // Deepak: 22/Mar/2003 AsnBool bUnknownType; // Deepak: 22/Mar/2003 TypeOrValue* typeOrValue; AsnInt lineNo; /* INTEGER */ }ObjectAssignmentField; typedef struct ObjectAssignment // Deepak: 26/Feb/2003 { MyString objectName; MyString objectClassName; AsnBool bWithSyntaxPresent; AsnInt lineNo; /* INTEGER */ ObjectAssignmentFieldList *objectAssignmentField; }ObjectAssignment; // Deepak: 23/Apr/2003 // Parameterized Types Handling typedef struct ParameterList { int i; }ParameterList; typedef struct Parameter { int i; }Parameter; /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* Both the CTDI and CxxTDI arrays in the CRules and CxxRules structures, respectively, must also be initialized for any new types added here. The CRules and CxxRules structures reside in the rules.c files in the C and C++ compiler back-ends. The new type must appear in the same index in the array as its enum value here. */ typedef struct BasicType /* CHOICE */ { enum BasicTypeChoiceId { /* Index to CTDI & CxxTDI array */ BASICTYPE_UNKNOWN, /* 0 */ BASICTYPE_BOOLEAN, /* 1 */ BASICTYPE_INTEGER, /* 2 */ BASICTYPE_BITSTRING, /* 3 */ BASICTYPE_OCTETSTRING, /* 4 */ BASICTYPE_NULL, /* 5 */ BASICTYPE_OID, /* 6 */ BASICTYPE_REAL, /* 7 */ BASICTYPE_ENUMERATED, /* 8 */ BASICTYPE_SEQUENCE, /* 9 */ BASICTYPE_SEQUENCEOF, /* 10 */ BASICTYPE_SET, /* 11 */ BASICTYPE_SETOF, /* 12 */ BASICTYPE_CHOICE, /* 13 */ BASICTYPE_SELECTION, /* 14 */ BASICTYPE_COMPONENTSOF, /* 15 */ BASICTYPE_ANY, /* 16 */ BASICTYPE_ANYDEFINEDBY, /* 17 */ BASICTYPE_LOCALTYPEREF, /* 18 */ BASICTYPE_IMPORTTYPEREF,/* 19 */ BASICTYPE_MACROTYPE, /* 20 */ BASICTYPE_MACRODEF, /* 21 */ BASICTYPE_NUMERIC_STR, /* 22 */ BASICTYPE_PRINTABLE_STR,/* 23 */ BASICTYPE_UNIVERSAL_STR,/* 24 */ BASICTYPE_IA5_STR, /* 25 */ BASICTYPE_BMP_STR, /* 26 */ BASICTYPE_UTF8_STR, /* 27 */ BASICTYPE_UTCTIME, /* 28 */ BASICTYPE_GENERALIZEDTIME, /* 29 */ BASICTYPE_GRAPHIC_STR, /* 30 */ BASICTYPE_VISIBLE_STR, /* 31 aka ISO646String */ BASICTYPE_GENERAL_STR, /* 32 */ BASICTYPE_OBJECTDESCRIPTOR, /* 33 */ BASICTYPE_VIDEOTEX_STR, /* 34 */ BASICTYPE_T61_STR, /* 35 */ BASICTYPE_EXTERNAL, /* 36 */ BASICTYPE_OCTETCONTAINING, /* 37 */ BASICTYPE_BITCONTAINING, /* 38 */ BASICTYPE_RELATIVE_OID, /* 39 JKG: added 11/Jan/2004 */ BASICTYPE_EXTENSION, /*40 JKG: added 21/Jan/2004 */ BASICTYPE_SEQUENCET, /* 41 Deepak: read Note above */ BASICTYPE_OBJECTCLASS, /* 42 Deepak: added on 11/Dec/2002 */ BASICTYPE_OBJECTCLASSFIELDTYPE, /* 43 Deepak: added on 04/Feb/2003 */ } choiceId; union BasicTypeChoiceUnion { AsnNull unknown; /* [0] IMPLICIT NULL */ AsnNull boolean; /* [1] IMPLICIT NULL */ NamedNumberList *integer; /* [2] IMPLICIT NamedNumberList */ NamedNumberList *bitString; /* [3] IMPLICIT NamedNumberList */ AsnNull octetString; /* [4] IMPLICIT NULL */ AsnNull null; /* [5] IMPLICIT NULL */ AsnNull oid; /* [6] IMPLICIT NULL */ AsnNull real; /* [7] IMPLICIT NULL */ NamedNumberList *enumerated; /* [8] IMPLICIT NamedNumberList */ NamedTypeList *sequence; /* [9] IMPLICIT NamedTypeList */ struct Type *sequenceOf; /* [10] IMPLICIT Type */ NamedTypeList *set; /* [11] IMPLICIT NamedTypeList */ struct Type *setOf; /* [12] IMPLICIT Type */ NamedTypeList *choice; /* [13] IMPLICIT NamedTypeList */ struct SelectionType *selection; /* [14] IMPLICIT SelectionType */ struct Type *componentsOf; /* [15] IMPLICIT Type */ AsnNull any; /* [16] IMPLICIT NULL */ struct AnyDefinedByType *anyDefinedBy; /* [17] IMPLICIT AnyDefinedByType */ struct TypeRef *localTypeRef; /* [19] IMPLICIT TypeRef */ struct TypeRef *importTypeRef; /* [20] IMPLICIT TypeRef */ struct MacroType *macroType; /* [21] MacroType */ MacroDef macroDef; /* [22] IMPLICIT MacroDef */ struct Type *stringContaining; /* OCTET STRING CONTAINING Type */ AsnNull relativeOID; /*JKG added 11/Jan/2004 */ void *voidPtr; /* catch all */ NamedTypeList *sequencet; // Deepak: 30/Nov/2002 // NamedTypeList *objectclass; // Deepak: 11/Dec/2002 ObjectClassDef *objectclass; // Deepak: 22/Feb/2003 } a; } BasicType; typedef struct { SnaccDirectiveEnum type; union { enum BasicTypeChoiceId asnTypeVal; CTypeId cTypeVal; AsnBool boolVal; unsigned int integerVal; char* stringVal; } value; } SnaccDirective; typedef struct MacroType /* CHOICE */ { enum MacroTypeChoiceId { MACROTYPE_ROSOPERATION, MACROTYPE_ROSERROR, MACROTYPE_ROSBIND, MACROTYPE_ROSUNBIND, MACROTYPE_ROSASE, MACROTYPE_ROSAC, MACROTYPE_MTSASEXTENSION, MACROTYPE_MTSASEXTENSIONS, MACROTYPE_MTSASEXTENSIONATTRIBUTE, MACROTYPE_MTSASTOKEN, MACROTYPE_MTSASTOKENDATA, MACROTYPE_MTSASSECURITYCATEGORY, MACROTYPE_ASNOBJECT, MACROTYPE_ASNPORT, MACROTYPE_ASNREFINE, MACROTYPE_ASNABSTRACTBIND, MACROTYPE_ASNABSTRACTUNBIND, MACROTYPE_ASNABSTRACTOPERATION, MACROTYPE_ASNABSTRACTERROR, MACROTYPE_AFALGORITHM, MACROTYPE_AFENCRYPTED, MACROTYPE_AFPROTECTED, MACROTYPE_AFSIGNATURE, MACROTYPE_AFSIGNED, MACROTYPE_SNMPOBJECTTYPE } choiceId; union MacroTypeChoiceUnion { struct RosOperationMacroType *rosOperation; /* [0] IMPLICIT RosOperationMacroType */ struct RosErrorMacroType *rosError; /* [1] IMPLICIT RosErrorMacroType */ struct RosBindMacroType *rosBind; /* [2] IMPLICIT RosBindMacroType */ struct RosBindMacroType *rosUnbind; /* [3] IMPLICIT RosBindMacroType */ struct RosAseMacroType *rosAse; /* [4] IMPLICIT RosAseMacroType */ struct RosAcMacroType *rosAc; /* [5] IMPLICIT RosAcMacroType */ struct MtsasExtensionMacroType *mtsasExtension; /* [6] IMPLICIT MtsasExtensionMacroType */ struct MtsasExtensionsMacroType *mtsasExtensions; /* [7] IMPLICIT MtsasExtensionsMacroType */ struct MtsasExtensionAttributeMacroType *mtsasExtensionAttribute; /* [8] IMPLICIT MtsasExtensionAttributeMacroType */ struct MtsasTokenMacroType *mtsasToken; /* [9] IMPLICIT MtsasTokenMacroType */ struct MtsasTokenDataMacroType *mtsasTokenData; /* [10] IMPLICIT MtsasTokenDataMacroType */ struct MtsasSecurityCategoryMacroType *mtsasSecurityCategory; /* [11] IMPLICIT MtsasSecurityCategoryMacroType */ struct AsnObjectMacroType *asnObject; /* [12] IMPLICIT AsnObjectMacroType */ struct AsnPortMacroType *asnPort; /* [13] IMPLICIT AsnPortMacroType */ AsnRefineMacroType asnRefine; /* [14] IMPLICIT AsnRefineMacroType */ struct AsnAbstractBindMacroType *asnAbstractBind; /* [15] IMPLICIT AsnAbstractBindMacroType */ struct AsnAbstractBindMacroType *asnAbstractUnbind; /* [16] IMPLICIT AsnAbstractBindMacroType */ struct RosOperationMacroType *asnAbstractOperation; /* [17] IMPLICIT RosOperationMacroType */ struct RosErrorMacroType *asnAbstractError; /* [18] IMPLICIT RosErrorMacroType */ struct Type *afAlgorithm; /* [19] IMPLICIT Type */ struct Type *afEncrypted; /* [20] IMPLICIT Type */ struct Type *afProtected; /* [21] IMPLICIT Type */ struct Type *afSignature; /* [22] IMPLICIT Type */ struct Type *afSigned; /* [23] IMPLICIT Type */ struct SnmpObjectTypeMacroType *snmpObjectType; /* [24] IMPLICIT SnmpObjectTypeMacroType */ } a; } MacroType; typedef struct AnyDefinedByType /* SEQUENCE */ { MyString fieldName; /* MyString */ struct NamedType *link; /* NamedType OPTIONAL */ } AnyDefinedByType; typedef struct SelectionType /* SEQUENCE */ { MyString fieldName; /* MyString */ struct Type *typeRef; /* Type */ struct NamedType *link; /* NamedType OPTIONAL */ } SelectionType; typedef struct NamedType /* SEQUENCE */ { MyString fieldName; /* MyString */ struct Type *type; /* Type */ } NamedType; typedef struct TypeRef /* SEQUENCE */ { MyString typeName; /* MyString */ MyString moduleName; /* MyString */ struct Module *module; /* Module */ struct TypeDef *link; /* TypeDef */ struct NamedType *namedTypeLink; /* NamedType */ // Deepak: added on 05/Feb/2003 } TypeRef; typedef struct RosOperationMacroType /* SEQUENCE */ { struct NamedType *arguments; /* NamedType */ struct NamedType *result; /* NamedType */ TypeOrValueList *errors; /* [0] IMPLICIT TypeOrValueList OPTIONAL */ TypeOrValueList *linkedOps; /* [1] IMPLICIT TypeOrValueList OPTIONAL */ } RosOperationMacroType; typedef struct RosErrorMacroType /* SEQUENCE */ { struct NamedType *parameter; /* NamedType */ } RosErrorMacroType; typedef struct RosBindMacroType /* SEQUENCE */ { struct NamedType *argument; /* NamedType */ struct NamedType *result; /* NamedType */ struct NamedType *error; /* NamedType */ } RosBindMacroType; typedef struct RosAseMacroType /* SEQUENCE */ { ValueList *operations; /* ValueList */ ValueList *consumerInvokes; /* ValueList */ ValueList *supplierInvokes; /* ValueList */ } RosAseMacroType; typedef struct RosAcMacroType /* SEQUENCE */ { ValueList *nonRoElements; /* ValueList */ struct Type *bindMacroType; /* Type */ struct Type *unbindMacroType; /* Type */ struct Value *remoteOperations; /* Value */ ValueList *operationsOf; /* ValueList */ ValueList *initiatorConsumerOf; /* ValueList */ ValueList *responderConsumerOf; /* ValueList */ OidList *abstractSyntaxes; /* OidList */ } RosAcMacroType; typedef struct MtsasExtensionMacroType /* SEQUENCE */ { struct NamedType *elmtType; /* [0] IMPLICIT NamedType OPTIONAL */ struct Value *defaultValue; /* [1] IMPLICIT Value OPTIONAL */ AsnBool *criticalForSubmission; /* [2] IMPLICIT BOOLEAN OPTIONAL */ AsnBool *criticalForTransfer; /* [3] IMPLICIT BOOLEAN OPTIONAL */ AsnBool *criticalForDelivery; /* [4] IMPLICIT BOOLEAN OPTIONAL */ } MtsasExtensionMacroType; typedef struct MtsasExtensionsMacroType /* SEQUENCE */ { ValueList *extensions; /* ValueList */ } MtsasExtensionsMacroType; typedef struct MtsasExtensionAttributeMacroType /* SEQUENCE */ { struct Type *type; /* Type OPTIONAL */ } MtsasExtensionAttributeMacroType; typedef struct MtsasTokenMacroType /* SEQUENCE */ { struct Type *type; /* Type OPTIONAL */ } MtsasTokenMacroType; typedef struct MtsasTokenDataMacroType /* SEQUENCE */ { struct Type *type; /* Type OPTIONAL */ } MtsasTokenDataMacroType; typedef struct MtsasSecurityCategoryMacroType /* SEQUENCE */ { struct Type *type; /* Type OPTIONAL */ } MtsasSecurityCategoryMacroType; typedef struct AsnObjectMacroType /* SEQUENCE */ { AsnPortList *ports; /* AsnPortList OPTIONAL */ } AsnObjectMacroType; typedef struct AsnPort /* SEQUENCE */ { struct Value *portValue; /* Value */ AsnPortEnum portType; /* AsnPortEnum */ } AsnPort; typedef struct AsnPortMacroType /* SEQUENCE */ { TypeOrValueList *abstractOps; /* [0] IMPLICIT TypeOrValueList OPTIONAL */ TypeOrValueList *consumerInvokes; /* [1] IMPLICIT TypeOrValueList OPTIONAL */ TypeOrValueList *supplierInvokes; /* [2] IMPLICIT TypeOrValueList OPTIONAL */ } AsnPortMacroType; typedef struct AsnAbstractBindMacroType /* SEQUENCE */ { AsnPortList *ports; /* [0] IMPLICIT AsnPortList OPTIONAL */ struct Type *type; /* [1] IMPLICIT Type OPTIONAL */ } AsnAbstractBindMacroType; typedef struct SnmpObjectTypeMacroType /* SEQUENCE */ { struct Type *syntax; /* Type */ SnmpObjectTypeMacroTypeEnum access; /* SnmpObjectTypeMacroTypeEnum */ SnmpObjectTypeMacroTypeEnum1 status; /* SnmpObjectTypeMacroTypeEnum1 */ struct Value *description; /* [0] IMPLICIT Value OPTIONAL */ struct Value *reference; /* [1] IMPLICIT Value OPTIONAL */ TypeOrValueList *index; /* [2] IMPLICIT TypeOrValueList OPTIONAL */ struct Value *defVal; /* [3] IMPLICIT Value OPTIONAL */ } SnmpObjectTypeMacroType; typedef struct Subtype { enum SubtypeChoiceId { SUBTYPE_SINGLE, SUBTYPE_AND, SUBTYPE_OR, SUBTYPE_NOT } choiceId; union SubtypeChoiceUnion { struct SubtypeValue *single; /* [0] SubtypeValue */ SubtypeList *and; /* [1] IMPLICIT SubtypeList */ SubtypeList *or; /* [2] IMPLICIT SubtypeList */ struct Subtype *not; /* [3] Subtype */ } a; } Subtype; typedef struct { AsnBool valueInclusive; /* BOOLEAN */ struct Value *endValue; /* Value */ } ValueRangeEndpoint; typedef struct { ValueRangeEndpoint *lowerEndValue; ValueRangeEndpoint *upperEndValue; } ValueRangeSubtype; typedef struct SubtypeValue { enum SubtypeValueChoiceId { SUBTYPEVALUE_SINGLEVALUE, SUBTYPEVALUE_CONTAINED, SUBTYPEVALUE_VALUERANGE, SUBTYPEVALUE_PERMITTEDALPHABET, SUBTYPEVALUE_SIZECONSTRAINT, SUBTYPEVALUE_INNERSUBTYPE } choiceId; union SubtypeValueChoiceUnion { struct Value *singleValue; struct Type *contained; ValueRangeSubtype *valueRange; Subtype *permittedAlphabet; Subtype *sizeConstraint; struct InnerSubtype *innerSubtype; } a; } SubtypeValue; typedef struct InnerSubtype /* SEQUENCE */ { InnerSubtypeEnum constraintType; /* InnerSubtypeEnum */ ConstraintList *constraints; /* ConstraintList */ } InnerSubtype; typedef struct Constraint /* SEQUENCE */ { MyString fieldRef; /* MyString */ ConstraintEnum presenceConstraint; /* ConstraintEnum */ struct Subtype *valueConstraints; /* Subtype */ } Constraint; typedef struct ValueDef /* SEQUENCE */ { AsnBool exported; /* BOOLEAN */ MyString definedName; /* MyString */ struct Value *value; /* Value */ } ValueDef; typedef struct Value /* SEQUENCE */ { struct Type *type; /* Type OPTIONAL */ AsnInt valueType; /* INTEGER */ struct BasicValue *basicValue; /* BasicValue */ AsnInt lineNo; /* INTEGER */ } Value; typedef struct BasicValue /* CHOICE */ { enum BasicValueChoiceId { BASICVALUE_UNKNOWN, BASICVALUE_EMPTY, BASICVALUE_INTEGER, BASICVALUE_SPECIALINTEGER, BASICVALUE_LONGINTEGER, BASICVALUE_BOOLEAN, BASICVALUE_REAL, BASICVALUE_SPECIALREAL, BASICVALUE_ASCIITEXT, BASICVALUE_ASCIIHEX, BASICVALUE_ASCIIBITSTRING, BASICVALUE_OID, BASICVALUE_LINKEDOID, BASICVALUE_BERVALUE, BASICVALUE_PERVALUE, BASICVALUE_NAMEDVALUE, BASICVALUE_NULL, BASICVALUE_LOCALVALUEREF, BASICVALUE_IMPORTVALUEREF, BASICVALUE_VALUENOTATION, BASICVALUE_OBJECTASSIGNMENT, // Deepak: 24/Mar/2003 ????? perhaps will not be needed BASICVALUE_RELATIVE_OID } choiceId; union BasicValueChoiceUnion { AsnNull unknown; /* [0] IMPLICIT NULL */ AsnNull empty; /* [1] IMPLICIT NULL */ AsnInt integer; /* [2] IMPLICIT INTEGER */ SpecialIntegerValue specialInteger; /* [3] IMPLICIT SpecialIntegerValue */ AsnInt longInteger; /* [4] IMPLICIT INTEGER */ AsnBool boolean; /* [5] IMPLICIT BOOLEAN */ AsnReal real; /* [6] IMPLICIT REAL */ SpecialRealValue specialReal; /* [7] IMPLICIT SpecialRealValue */ AsnOcts *asciiText; /* [8] IMPLICIT OCTET STRING */ AsnOcts *asciiHex; /* [9] IMPLICIT OCTET STRING */ AsnOcts *asciiBitString; /* [10] IMPLICIT OCTET STRING */ AsnOid *oid; /* [11] IMPLICIT OBJECT IDENTIFIER */ OID *linkedOid; /* [12] IMPLICIT OBJECT IDENTIFIER */ AsnOcts *berValue; /* [13] IMPLICIT OCTET STRING */ AsnOcts *perValue; /* [14] IMPLICIT OCTET STRING */ struct NamedValue *namedValue; /* [15] IMPLICIT NamedValue */ AsnNull null; /* [16] IMPLICIT NULL */ struct ValueRef *localValueRef; /* [17] IMPLICIT ValueRef */ struct ValueRef *importValueRef; /* [18] IMPLICIT ValueRef */ AsnOcts *valueNotation; /* [19] IMPLICIT OCTET STRING */ ObjectAssignment *objAssignment; // Deepak: 24/Mar/2003 AsnRelativeOid *relativeOid; } a; } BasicValue; typedef struct ValueRef /* SEQUENCE */ { MyString valueName; /* MyString */ MyString moduleName; /* MyString */ struct ValueDef *link; /* ValueDef */ struct Module *module; /* Module */ } ValueRef; typedef struct NamedValue /* SEQUENCE */ { MyString fieldName; /* MyString */ struct Value *value; /* Value */ } NamedValue; typedef AsnList ModuleList; /* SEQUENCE OF Module */ typedef struct Modules /* [APPLICATION 0] IMPLICIT SEQUENCE */ { AsnInt creationTime; /* INTEGER */ ModuleList *modules; /* ModuleList */ } Modules; typedef AsnList NamedValueList; /* SEQUENCE OF NamedValue */ typedef struct CTDI /* SEQUENCE */ { enum BasicTypeChoiceId asn1TypeId; /* INTEGER */ CTypeId cTypeId; /* CTypeId */ MyString cTypeName; /* MyString */ AsnBool isPdu; /* BOOLEAN */ AsnBool isEncDec; /* BOOLEAN */ AsnBool isPtrForTypeDef; /* BOOLEAN */ AsnBool isPtrForTypeRef; /* BOOLEAN */ AsnBool isPtrInChoice; /* BOOLEAN */ AsnBool isPtrForOpt; /* BOOLEAN */ MyString optTestRoutineName; /* MyString */ MyString defaultFieldName; /* MyString */ MyString printRoutineName; /* MyString */ MyString encodeRoutineName; /* MyString */ MyString decodeRoutineName; /* MyString */ MyString freeRoutineName; /* MyString */ AsnBool genPrintRoutine; /* BOOLEAN */ AsnBool genEncodeRoutine; /* BOOLEAN */ AsnBool genDecodeRoutine; /* BOOLEAN */ AsnBool genFreeRoutine; /* BOOLEAN */ AsnBool genTypeDef; /* BOOLEAN */ } CTDI; typedef struct CNamedElmt /* SEQUENCE */ { MyString name; /* MyString */ AsnInt value; /* INTEGER */ } CNamedElmt; typedef struct CxxTDI /* SEQUENCE */ { enum BasicTypeChoiceId asn1TypeId; /* INTEGER */ MyString className; /* MyString */ AsnBool isPdu; /* BOOLEAN */ AsnBool isEnc; /* BOOLEAN */ AsnBool isPtrForTypeDef; /* BOOLEAN */ AsnBool isPtrForOpt; /* BOOLEAN */ AsnBool isPtrInChoice; /* BOOLEAN */ AsnBool isPtrInSetAndSeq; /* BOOLEAN */ AsnBool isPtrInList; /* BOOLEAN */ MyString optTestRoutineName; /* MyString */ MyString defaultFieldName; /* MyString */ } CxxTDI; typedef struct IDLTDI /* SEQUENCE */ { enum BasicTypeChoiceId asn1TypeId; /* INTEGER */ MyString typeName; /* MyString */ AsnBool isPdu; /* BOOLEAN */ AsnBool isEnc; /* BOOLEAN */ AsnBool isPtrForTypeDef; /* BOOLEAN */ AsnBool isPtrForOpt; /* BOOLEAN */ AsnBool isPtrInChoice; /* BOOLEAN */ AsnBool isPtrInSetAndSeq; /* BOOLEAN */ AsnBool isPtrInList; /* BOOLEAN */ MyString optTestRoutineName; /* MyString */ MyString defaultFieldName; /* MyString */ } IDLTDI; typedef AsnList CNamedElmts; /* SEQUENCE OF CNamedElmt */ typedef struct CxxTRI /* SEQUENCE */ { AsnBool isEnc; /* BOOLEAN */ MyString className; /* MyString */ MyString fieldName; /* MyString */ AsnBool isPtr; /* BOOLEAN */ CNamedElmts *namedElmts; /* CNamedElmts */ MyString choiceIdSymbol; /* MyString */ AsnInt choiceIdValue; /* INTEGER */ MyString optTestRoutineName; /* MyString */ } CxxTRI; typedef struct IDLTRI /* SEQUENCE */ { AsnBool isEnc; /* BOOLEAN */ MyString typeName; /* MyString */ MyString fieldName; /* MyString */ AsnBool isPtr; /* BOOLEAN */ CNamedElmts *namedElmts; /* CNamedElmts */ MyString choiceIdSymbol; /* MyString */ AsnInt choiceIdValue; /* INTEGER */ MyString optTestRoutineName; /* MyString */ } IDLTRI; typedef struct CTRI /* SEQUENCE */ { CTypeId cTypeId; /* CTypeId */ MyString cFieldName; /* MyString */ MyString cTypeName; /* MyString */ AsnBool isPtr; /* BOOLEAN */ CNamedElmts *cNamedElmts; /* CNamedElmts OPTIONAL */ AsnInt choiceIdValue; /* INTEGER */ MyString choiceIdSymbol; /* MyString */ MyString choiceIdEnumName; /* MyString */ MyString choiceIdEnumFieldName; /* MyString */ MyString optTestRoutineName; /* MyString */ MyString printRoutineName; /* MyString */ MyString encodeRoutineName; /* MyString */ MyString decodeRoutineName; /* MyString */ MyString freeRoutineName; /* MyString */ AsnBool isEncDec; /* BOOLEAN */ } CTRI; #endif /* conditional include of asn1module.h */ esnacc-ng-1.8.1/compiler/core/define.c000066400000000000000000000126741302010526100175170ustar00rootroot00000000000000/* * compiler/core/define.c - keeps a list of things that have been defined * and provided means for checking if something has been * defined * * MS 92 * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/core/define.c,v 1.5 2004/03/31 20:03:19 leonberp Exp $ * $Log: define.c,v $ * Revision 1.5 2004/03/31 20:03:19 leonberp * resolved many gcc compile warnings * * Revision 1.4 2003/07/07 14:50:13 nicholar * Eliminated headers and cleaned up include references * * Revision 1.3 2003/02/05 12:34:31 mcphersc * Added check for null to remove core dump in string compare * * Revision 1.2 2000/10/24 14:54:49 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:35:59 leonberp * First CVS Version of SNACC. * * Revision 1.4 1997/10/10 13:43:15 wan * Corrected bug in generic table decoder wrt. indefinite length elements * Corrected compiler access to freed memory (bug reported by Markku Savela) * Broke asnwish.c into two pieces so that one can build ones on wish * Added beredit tool (based on asnwish, allowes to edit BER messages) * * Revision 1.3 1995/07/25 19:41:21 rj * changed `_' to `-' in file names. * * Revision 1.2 1994/09/01 00:27:38 rj * snacc_config.h removed. * * Revision 1.1 1994/08/28 09:48:58 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include #include "asn-incl.h" #include "define.h" /* Function Prototypes */ int CompareOids PROTO ((OID *oid1, OID *oid2)); /* cmp routine for a null terminated string object type */ int StrObjCmp PARAMS ((s1, s2), void *s1 _AND_ void *s2) { if ((s1 == NULL) || (s2 == NULL)) return FALSE; if (strcmp ((char*)s1, (char*) s2) == 0) return TRUE; else return FALSE; } /* cmp routine for a integer object type */ int IntObjCmp PARAMS ((s1, s2), void *s1 _AND_ void *s2) { if (*((int*) s1) == *((int*) s2)) return TRUE; else return FALSE; } /* cmp routine for a OID object type */ int OidObjCmp PARAMS ((o1, o2), void *o1 _AND_ void *o2) { return CompareOids ((OID*)o1, (OID*)o2); } /* special cmp routine - compares the pointers themselves */ int ObjPtrCmp PARAMS ((s1, s2), void *s1 _AND_ void *s2) { if (s1 == s2) return TRUE; else return FALSE; } DefinedObj* NewObjList() { return NULL; } /* * puts the given object into the give object list * does not check for duplicates - you should do that * before calling this - if you care. */ void DefineObj PARAMS ((objListHndl, obj), DefinedObj **objListHndl _AND_ void *obj) { DefinedObj *new; new = MT (DefinedObj); new->obj = obj; /* insert new one at head */ new->next = *objListHndl; *objListHndl = new; } /* DefineObj */ /* * removes the first identical object from the list * - if you are allowing duplicates use another routine. * this only removes the first for efficiency reasons - all * current usage of the DefineObj stuff does not allow duplicates. */ void UndefineObj PARAMS ((objListHndl, obj, cmpRoutine), DefinedObj **objListHndl _AND_ void *obj _AND_ CmpObjsRoutine cmpRoutine) { DefinedObj *objListPtr; DefinedObj **prevHndl; objListPtr = *objListHndl; prevHndl = objListHndl; for ( ; objListPtr != NULL; objListPtr = *prevHndl) { if (cmpRoutine (objListPtr->obj, obj)) { /* found object, now remove it */ *prevHndl = objListPtr->next; Free (objListPtr); } else prevHndl = &objListPtr->next; } } /* UndefineObj */ /* * given an object list, an object and an object comparison routine, * ObjIsDefined returns non-zero if the given object is already in * the object list. The comparison routine should take two objects and * return non-zero if the objects are equivalent */ int ObjIsDefined (DefinedObj *objListPtr, void *obj, CmpObjsRoutine cmpRoutine) { for ( ; objListPtr != NULL; objListPtr = objListPtr->next) { if (cmpRoutine (objListPtr->obj, obj)) return TRUE; } return FALSE; } /* ObjIsDefined */ /* * Frees the list holding the defined objects. * Does not free the objects. */ void FreeDefinedObjs PARAMS ((objListHndl), DefinedObj **objListHndl) { DefinedObj *dO; DefinedObj *tmpDO; for (dO = *objListHndl; dO != NULL; ) { tmpDO = dO->next; Free (dO); dO = tmpDO; } *objListHndl = NULL; } /* FreeDefinedObjs */ /* * Frees the list holding the defined objects. * Does free the objects. */ void FreeDefinedObjsAndContent PARAMS ((objListHndl), DefinedObj **objListHndl) { DefinedObj *dO; DefinedObj *tmpDO; for (dO = *objListHndl; dO != NULL; ) { tmpDO = dO->next; Free (dO->obj); Free (dO); dO = tmpDO; } *objListHndl = NULL; } /* FreeDefinedObjs */ esnacc-ng-1.8.1/compiler/core/define.h000066400000000000000000000044601302010526100175160ustar00rootroot00000000000000/* * compiler/core/define.h * * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/core/define.h,v 1.4 2004/03/31 20:03:19 leonberp Exp $ * $Log: define.h,v $ * Revision 1.4 2004/03/31 20:03:19 leonberp * resolved many gcc compile warnings * * Revision 1.3 2001/07/12 19:34:27 leonberp * Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. * * Revision 1.2 2000/10/24 14:54:49 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:35:59 leonberp * First CVS Version of SNACC. * * Revision 1.2 1994/10/08 03:48:35 rj * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long. * * Revision 1.1 1994/08/28 09:48:59 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #ifndef _DefinedObjInclude #define _DefinedObjInclude typedef struct DefinedObj { void *obj; struct DefinedObj *next; } DefinedObj; typedef int (*CmpObjsRoutine) PROTO ((void *obj1, void *obj2)); typedef int (*FreeObjRoutine) PROTO ((void *obj)); int StrObjCmp PROTO ((void *s1, void *s2)); int IntObjCmp PROTO ((void *s1, void *s2)); int OidObjCmp PROTO ((void *o1, void *o2)); int ObjPtrCmp PROTO ((void *s1, void *s2)); DefinedObj *NewObjList(); void DefineObj PROTO ((DefinedObj **l, void *obj)); void UndefineObj PROTO ((DefinedObj **l, void *obj, CmpObjsRoutine cmpRoutine)); int ObjIsDefined (DefinedObj *l, void *obj, CmpObjsRoutine cmp); void FreeDefinedObjs PROTO ((DefinedObj **l)); void FreeDefinedObjsAndContent PROTO ((DefinedObj **l)); #endif esnacc-ng-1.8.1/compiler/core/dependency.c000066400000000000000000000525451302010526100204040ustar00rootroot00000000000000/* * compiler/core/dependency.c - sorts types/values in order of dependency. * typeDefs list is re-ordered * going from independent->dependent types * * this is done after all import linking is done * * Mike Sample * 91/08/12 * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/core/dependency.c,v 1.8 2004/03/25 19:20:16 gronej Exp $ * $Log: dependency.c,v $ * Revision 1.8 2004/03/25 19:20:16 gronej * fixed some linux warnings * * Revision 1.7 2003/07/07 14:50:13 nicholar * Eliminated headers and cleaned up include references * * Revision 1.6 2003/04/29 21:12:31 leonberp * integerated Deepak's changes for IOB support * * Revision 1.5 2002/10/21 17:15:18 mcphersc * fixed long int * * Revision 1.4 2002/09/04 18:23:08 vracarl * got rid of c++ comments * * Revision 1.3 2002/07/25 11:18:15 sfl * got rid of warnings * * Revision 1.1.1.1 2000/08/21 20:35:59 leonberp * First CVS Version of SNACC. * * Revision 1.4 1995/07/25 19:41:22 rj * changed `_' to `-' in file names. * * Revision 1.3 1994/10/08 03:48:37 rj * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long. * * Revision 1.2 1994/09/01 00:31:56 rj * snacc_config.h removed; dependency.h includet. * * Revision 1.1 1994/08/28 09:49:00 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include "asn-incl.h" #include "asn1module.h" /* Function Prototypes */ void BuildLocalRefList PROTO ((Type *t, TypeDefList *refList)); void BuildWeightedLocalRefList PROTO ((Type *t, TypeDefList *refList)); long GetElmtIndex PROTO ((TypeDef *td, TypeDefList *tdl)); int IsDefinedByLibraryType PROTO ((Type *t)); TypeDefList *RemoveAndSortIndependents PROTO ((TypeDefList *tdl)); void SortInterModuleDependencies PROTO ((ModuleList *m)); void SortTypeDefs PROTO ((TypeDefList *tdl)); void SortTypeDependencies PROTO ((Module *m)); /* void MoveAfter PROTO ((unsigned long currIndex, unsigned long afterIndex, AsnList *l)); */ extern FILE* errFileG; /* Pointer to file for reporting errors */ /* * Sorts type dependencies by reodering TypeDefs linear list * with least dependent types followed by dependent types */ void SortAllDependencies PARAMS ((modList), ModuleList *modList) { Module *m; FOR_EACH_LIST_ELMT (m, modList) { SortTypeDependencies (m); } /* SortInterModuleDependencies (modList); */ } /* SortAllDependencies */ /* * This attempts to sort the types in order of dependency * (least dependent --> dependent) * * This should only be called after the CTypeInfo or CxxTypeInfo * has been added to the types. * (the isPtr field is used to help determine ordering) * * Algorithm: (wierd!) * * First separte the ASN.1 type defs into 4 separate groups * * 1. Type defs that are defined directly from primitive/library types * eg Foo ::= INTEGER {one (1), two (2) } * * 2. Type defs reference no local types in a way that needs a * forward decl. of the ref'd type (ie ptr refs) * * 3. Type defs that reference local types in a way that needs * a previous decl of the ref'd type (ie non ptr refs for SET/SEQ * elmts) * * 4. Type defs that are not referenced by any local types * (hence no local types depend on them so they can go last) * * * The type defs in group 3 are further sorted by the SortTypeDefs routine * * Then all of the groups are merged in the order 1-2-3-4. * * Some wierd recursive types might cause problems... * * * MS 92 */ void SortTypeDependencies PARAMS ((m), Module *m) { TypeDef *curr; TypeDefList *prims; TypeDefList *noRefs; TypeDefList *refs; TypeDefList *notRefd; TypeDef **newElmtHndl; prims = AsnListNew (sizeof (void*)); noRefs = AsnListNew (sizeof (void*)); refs = AsnListNew (sizeof (void*)); notRefd = AsnListNew (sizeof (void*)); /* put each TypeDef in the appropriate list (1-4)*/ FOR_EACH_LIST_ELMT (curr, m->typeDefs) { curr->refList = NULL; if (IsDefinedByLibraryType (curr->type)) // Deepak: One Change Done Here... newElmtHndl = (TypeDef**) AsnListAppend (prims); else if (curr->localRefCount == 0) newElmtHndl = (TypeDef**) AsnListAppend (notRefd); else { /* get list of local types that this type def refs */ curr->refList = AsnListNew (sizeof (void*)); BuildLocalRefList (curr->type, curr->refList); if (LIST_EMPTY (curr->refList)) { newElmtHndl = (TypeDef**) AsnListAppend (noRefs); Free (curr->refList); curr->refList = NULL; } else newElmtHndl = (TypeDef**) AsnListAppend (refs); } *newElmtHndl = curr; } /* sort problem types */ SortTypeDefs (refs); /* free refList space */ FOR_EACH_LIST_ELMT (curr, refs) { if (curr->refList != NULL) { AsnListFree (curr->refList); curr->refList = NULL; } } /* * combine the typdef lists with the prims followed by the * types that don't reference other types * then prims, followed by composite types */ prims = AsnListConcat (prims, noRefs); prims = AsnListConcat (prims, refs); prims = AsnListConcat (prims, notRefd); AsnListFree (m->typeDefs); Free (noRefs); Free (refs); Free (notRefd); m->typeDefs = prims; } /* SortTypeDependencies */ /* * Attempt to sort modules in order of "depends on none" to * "depends on all" where a dependency is caused by importing * from another module. * cyclic dependencies are a pain */ /* * Not implemented yet... perhaps best left in user's hands * ie set it by the cmd line order */ /* void SortInterModuleDependencies PARAMS ((m), ModuleList *m) { } SortInterModuleDependencies */ /* * Given a non-empty TypeDef list, the refLists of TypeDefs * are used to divide the list into two lists, one list * that is sorted the order of dependency (independed-->dependent) * and the other list contains types that are mutually dependent * (recursive or depend on recursive types) * The sorted list is returned and the passed in list has those * TypeDefs that are now in the sorted list removed. */ TypeDefList* RemoveAndSortIndependents PARAMS ((tdl), TypeDefList *tdl) { TypeDef *last; TypeDef *currTd; TypeDef **tdHndl; TypeDef *tdRef; AsnListNode *nextListNode; long tdIndex; long lastSLCount; TypeDefList *subList; int keep; /* * iterate through the list making sub lists that don't depend * on the others in the active list. Join sub lists in order * and then deal with the active list if any */ lastSLCount = -1; /* just to start */ subList = AsnListNew (sizeof (void*)); if (LIST_EMPTY (tdl)) return subList; /* iterate through each type def in the tdl */ while ((LIST_COUNT (subList) > lastSLCount) && !LIST_EMPTY (tdl)) { lastSLCount = LIST_COUNT (subList); last = (TypeDef*)LAST_LIST_ELMT (tdl); SET_CURR_LIST_NODE (tdl, FIRST_LIST_NODE (tdl)); currTd = (TypeDef*)CURR_LIST_ELMT (tdl); while (1) { nextListNode = NEXT_LIST_NODE (tdl); keep = 0; /* * iterate through this type def's local type refs. * * if any type def in the current type's local type ref list * is in the tdl, then teh current type must remain in the tdl * because it depends on that type. */ FOR_EACH_LIST_ELMT (tdRef, currTd->refList) { /* don't worry about recursive refs to self */ if (tdRef != currTd) { /* * if the tdRef is not in tdl * GetElmtIndex will return < 0 * if the tdRef is in the tdl, then the * currTd must remain in the tdl. */ tdIndex = GetElmtIndex (tdRef, tdl); if (tdIndex >= 0) keep = 1; } } if (!keep) { /* append to sublist and remove for tdl */ tdHndl = (TypeDef**) AsnListAppend (subList); *tdHndl = currTd; AsnListRemove (tdl); } if (currTd == last) break; /* exit while */ if (nextListNode) SET_CURR_LIST_NODE (tdl, nextListNode); currTd = (TypeDef*)CURR_LIST_ELMT (tdl); } } return subList; } /* RemoveAndSortIndependents */ /* * Given a list of types that depend on each other, this attempts * to sort the list from independent--> most dependent. * * Kind of wierd algorithm * 1. first separate and sort out linearly dependent types and place in * a properly ordered list (RemoveAndSortIndependents) (call it "A") * * 2. if types with non-linear (recursive) dependencies remain, * divide them into two groups, recursive (call it "B")(see recursive.c) * and non-recursive (call it "C". The non-recursive ones will depend * on the recursive ones (otherwise step 1 would have grabbed 'em). * * 3. Sort the types in list C as done in step one - there should be * no problems (ie unsorted leftovers) since none of them are recursive. * * 4. For the recursive types in list B, re-do their refLists such that * any types ref'd by a Ptr are not included in the refList * (may have to update this wrt how the ref is used - * eg in an inline of the ref'ing type). Then sort as in Step 1. * Any types that could not be sorted have a definite problem and * compiliation problems will occur. (.. And the code generation * technique must be changed) * (for C only the SET OF and SEQ OF Types are stripped from this * since they are 'generic' - ie don't depend on the list elmt type) * * 5. re-combine all of the lists in order of dependency ie * A-B-(B's leftovers)-C * * (the stripped C lists go after 'A') */ void SortTypeDefs PARAMS ((tdl), TypeDefList *tdl) { TypeDef *last; TypeDef *currTd; TypeDef **tdHndl; AsnListNode *nextListNode; TypeDefList *subList; /* "A" */ TypeDefList *nonRec; TypeDefList *sortedRec; /* "B" */ TypeDefList *sortedNonRec; /* "C" */ TypeDefList *cLists; if ((tdl == NULL) || (LIST_EMPTY (tdl))) return; subList = RemoveAndSortIndependents (tdl); /* return if simple sort worked (no recursive types) */ if (LIST_EMPTY (tdl)) { *tdl = *subList; Free (subList); return; } /* * divide the remaining interdepedent types into * two groups recursive and non-recursive. * leave the recursive in the tdl and put the others in a new list. * The non-recursive ones obviously depend on the recursive * on since all of the simple type dependencies have been * dealt with by RemoveAndSortIndependents */ last = (TypeDef*)LAST_LIST_ELMT (tdl); SET_CURR_LIST_NODE (tdl, FIRST_LIST_NODE (tdl)); currTd = (TypeDef*)CURR_LIST_ELMT (tdl); nonRec = AsnListNew (sizeof (void*)); while (1) { nextListNode = NEXT_LIST_NODE (tdl); if (!currTd->recursive) { tdHndl = (TypeDef**)AsnListAppend (nonRec); *tdHndl = currTd; AsnListRemove (tdl); } if (currTd == last) break; /* exit while */ if (nextListNode) SET_CURR_LIST_NODE (tdl, nextListNode); currTd = (TypeDef*)CURR_LIST_ELMT (tdl); } /* sort the non-recusive types */ sortedNonRec = RemoveAndSortIndependents (nonRec); if (!LIST_EMPTY (nonRec)) { fprintf (errFileG, "SortTypeDefs: internal compiler error - non recursive type defs failed sort.\n"); sortedNonRec = AsnListConcat (sortedNonRec, nonRec); } Free (nonRec); /* * Remove list types from the list since they are generic. * put them in "cLists". * then re-do the dependency list for each type definition that * remain in the recursive list with weighting - ie types * that are ref'd as ptrs don't count. Then re-sort. */ if (tdl->last) { last = (TypeDef*)LAST_LIST_ELMT (tdl); } currTd = NULL; if (FIRST_LIST_NODE(tdl)) { SET_CURR_LIST_NODE (tdl, FIRST_LIST_NODE (tdl)); currTd = (TypeDef*)CURR_LIST_ELMT (tdl); } cLists = AsnListNew (sizeof (void*)); while (currTd) { nextListNode = NEXT_LIST_NODE (tdl); /* nuke old ref list */ AsnListFree (currTd->refList); currTd->refList = NULL; /* for C only, remove lists since they are generic */ if ((currTd->cTypeDefInfo != NULL) && ((currTd->type->basicType->choiceId == BASICTYPE_SETOF) || (currTd->type->basicType->choiceId == BASICTYPE_SEQUENCEOF))) { tdHndl = (TypeDef**)AsnListAppend (cLists); *tdHndl = currTd; AsnListRemove (tdl); } if (currTd == last) break; /* exit while */ SET_CURR_LIST_NODE (tdl, nextListNode); currTd = (TypeDef*)CURR_LIST_ELMT (tdl); } FOR_EACH_LIST_ELMT (currTd, tdl) { currTd->refList = AsnListNew (sizeof (void*)); BuildWeightedLocalRefList (currTd->type, currTd->refList); } sortedRec = RemoveAndSortIndependents (tdl); /* * now merge subLists and put in tdl: * tdl = cLists + sortedRec + impossible rec in tdl + sorted nonRec */ subList = AsnListConcat (subList, cLists); subList = AsnListConcat (subList, sortedRec); subList = AsnListConcat (subList, tdl); subList = AsnListConcat (subList, sortedNonRec); *tdl = *subList; Free (cLists); Free (subList); Free (sortedRec); Free (sortedNonRec); } /* SortTypeDefs */ /* * Builds list of TypeDefs in this module that the given type refs. * Does not follow type refs to include their type refs. */ void BuildLocalRefList PARAMS ((t, refList), Type *t _AND_ TypeDefList *refList) { NamedType *e; TypeDef **tdHndl; switch (t->basicType->choiceId) { case BASICTYPE_CHOICE: case BASICTYPE_SET: case BASICTYPE_SEQUENCE: FOR_EACH_LIST_ELMT (e, t->basicType->a.choice) { BuildLocalRefList (e->type, refList); } break; case BASICTYPE_OBJECTCLASS: // Deepak: 13/Mar/2003 FOR_EACH_LIST_ELMT (e, t->basicType->a.objectclass->classdef) { BuildLocalRefList (e->type, refList); } break; case BASICTYPE_SETOF: case BASICTYPE_SEQUENCEOF: BuildLocalRefList (t->basicType->a.setOf, refList); break; case BASICTYPE_LOCALTYPEREF: tdHndl = (TypeDef**)AsnListAppend (refList); *tdHndl = t->basicType->a.localTypeRef->link; break; /* * default: other types are not aggregate and * and can be ignored */ default: break; } } /* BuildLocalRefList */ /* * Builds list of TypeDefs in this module that the given type references. * Does not follow type refs to include their type refs. * Does not include types that are ref'd as ptrs since * If the target lang is C the type SET OF/SEQ OF types reference * are not counted due to the current 'genericness' of the C list type * (it doesn't need type info) * they shouldn't affect type ordering. */ void BuildWeightedLocalRefList PARAMS ((t, refList), Type *t _AND_ TypeDefList *refList) { NamedType *e; TypeDef **tdHndl; switch (t->basicType->choiceId) { case BASICTYPE_CHOICE: case BASICTYPE_SET: case BASICTYPE_SEQUENCE: FOR_EACH_LIST_ELMT (e, t->basicType->a.choice) { BuildWeightedLocalRefList (e->type, refList); } break; case BASICTYPE_SETOF: case BASICTYPE_SEQUENCEOF: /* * normalize makes embedded list defs into * separate type defs now so this clause will * not fire. (ie they will be a LOCAL_TYPEREF * to the removed list type instead) */ /* * list types for C don't really depend on * the component type (void*). So if the target lang * is C then can achieve better ordering * for ugly recursive defs by using this relaxation * (ie not including the component type in the ref list) */ if (t->cTypeRefInfo == NULL) BuildWeightedLocalRefList (t->basicType->a.setOf, refList); break; case BASICTYPE_LOCALTYPEREF: if (((t->cxxTypeRefInfo != NULL) && !(t->cxxTypeRefInfo->isPtr)) || ((t->cTypeRefInfo != NULL) && !(t->cTypeRefInfo->isPtr))) { tdHndl = (TypeDef**)AsnListAppend (refList); *tdHndl = t->basicType->a.localTypeRef->link; } break; default: break; /* * default: other types are not aggregate and * and can be ignored */ } } /* BuildWeightedLocalRefList */ /* * Returns the index (starting a 0 for the first elmt) * of the given td in the td list (tdl) * returns -1 if td is not in the list */ long GetElmtIndex PARAMS ((td, tdl), TypeDef *td _AND_ TypeDefList *tdl) { void *tmp; TypeDef *tmpTd; long index; index = 0; tmp = (void*) CURR_LIST_NODE (tdl); FOR_EACH_LIST_ELMT (tmpTd, tdl) { if (tmpTd == td) { SET_CURR_LIST_NODE (tdl, tmp); return index; } else index++; } SET_CURR_LIST_NODE (tdl, tmp); return -1; } /* GetElmtIndex */ /* * Attempts to order the types in tdl from independent-->most depenedent * uses insertion after TypeDef that the given type def depends on. * Hoky - doesn't work very well - differing results depending on * initial order NO LONGER USED void AttemptDependencySort PARAMS ((tdl), TypeDefList *tdl) { TypeDef *last; TypeDef *currTd; TypeDef **tdHndl; TypeDef *tdRef; AsnListNode *nextListNode; long tdIndex; long maxTdIndex; long currIndex; if (LIST_EMPTY (tdl)) return; last = (TypeDef*)LAST_LIST_ELMT (tdl); FOR_EACH_LIST_ELMT (currTd, tdl) { currTd->visited = FALSE; } SET_CURR_LIST_NODE (tdl, FIRST_LIST_NODE (tdl)); currTd = (TypeDef*)CURR_LIST_ELMT (tdl); while (1) { nextListNode = NEXT_LIST_NODE (tdl); if (!currTd->visited) { currTd->visited = TRUE; maxTdIndex = -1; FOR_EACH_LIST_ELMT (tdRef, currTd->refList) { tdIndex = GetElmtIndex (tdRef, tdl); if (tdIndex > maxTdIndex) maxTdIndex = tdIndex; } } currIndex = GetElmtIndex (currTd, tdl); if ((maxTdIndex >= 0) && (currIndex < maxTdIndex)) { MoveAfter (currIndex, maxTdIndex, tdl); } if (currTd == last) break; SET_CURR_LIST_NODE (tdl, nextListNode); currTd = (TypeDef*)CURR_LIST_ELMT (tdl); } } AttemptDependencySort */ /* * Moves list node at currIndex to after Node at afterIndex * in the given list l. Indexes start at 0 for the first elmt. * May confuse the 'curr' pointer of the list NO LONGER USED void MoveAfter PARAMS ((currIndex, afterIndex, l), unsigned long currIndex _AND_ unsigned long afterIndex _AND_ AsnList *l) { void *tmp; AsnListNode *nodeToMove; AsnListNode *afterNode; int i; if ((l == NULL) || (LIST_COUNT (l) <= currIndex) || (LIST_COUNT (l) <= afterIndex)) { fprintf (fHandle,"Internal compiler error - index confusion in MoveAfter\n"); return; } tmp = (void*) CURR_LIST_NODE (l); nodeToMove = l->first; for (i = 0; i < currIndex; i++) nodeToMove = nodeToMove->next; afterNode = l->first; for (i = 0; i < afterIndex; i++) afterNode = afterNode->next; pop out node to move if (nodeToMove->next) nodeToMove->next->prev = nodeToMove->prev; else l->last = nodeToMove->prev; if (nodeToMove->prev) nodeToMove->prev->next = nodeToMove->next; else l->first = nodeToMove->next; insert node to move after selected node nodeToMove->next = afterNode->next; nodeToMove->prev = afterNode; if (afterNode->next) afterNode->next->prev = nodeToMove; else l->last = nodeToMove; afterNode->next = nodeToMove; } MoveAfter */ esnacc-ng-1.8.1/compiler/core/do-macros.c000066400000000000000000000550741302010526100201520ustar00rootroot00000000000000/* * compiler/core/do_macros.c * * Runs through type and value def lists and does any processing nec. * for any macro encountered. * * Processing could consist of making stubs for OPERATION macro etc. * What is done is very environment dependent. * * You should change this file to match your environment. * * Any Type Defs hidden in a MACRO Type are popped into the normal * type def list and REFERENCED from the macro (instead of being * defined there) * * SNMP Objectype macro fills the ANY Ref lists so the id to ANY * type hash table is filled. * * Mike Sample * 91/12/12 * * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/core/do-macros.c,v 1.9 2003/07/18 18:13:02 nicholar Exp $ * $Log: do-macros.c,v $ * Revision 1.9 2003/07/18 18:13:02 nicholar * Removed most of Deepak's changes * * Revision 1.8 2003/07/07 14:50:13 nicholar * Eliminated headers and cleaned up include references * * Revision 1.7 2003/04/29 21:09:35 leonberp * integerated Deepak's changes for IOB support * * Revision 1.6 2002/09/17 10:47:14 mcphersc * Fixed warnings * * Revision 1.5 2002/09/16 16:49:17 mcphersc * Fixed warnings * * Revision 1.4 2002/09/04 18:23:07 vracarl * got rid of c++ comments * * Revision 1.3 2002/02/28 19:45:23 nicholar * Added calls to Dash2Underscore() to remove dashes in ANYs. * * Revision 1.2 2000/10/24 14:54:51 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:35:59 leonberp * First CVS Version of SNACC. * * Revision 1.3 1995/07/25 19:41:23 rj * changed `_' to `-' in file names. * * Revision 1.2 1994/09/01 00:32:28 rj * snacc_config.h removed; do_macros.h includet. * * Revision 1.1 1994/08/28 09:49:03 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include #include /* for islower() */ #include "asn-incl.h" #include "asn1module.h" #include "str-util.h" #include "snacc-util.h" #include "lib-types.h" /* Function Prototypes */ void AddAnyRefByOid PROTO ((AnyRefList **arl, char *enumIdName, AsnOid *oid)); void AddAnyRefByInt PROTO ((AnyRefList **arl, char *enumIdName, AsnInt intId)); void NormalizeValue PROTO ((Module *m, ValueDef *vd, Value *v, int quiet)); void ProcessMacrosInTypeDef PROTO ((Module *m, TypeDef *td)); void ProcessMacrosInValueDef PROTO ((Module *m, ValueDef *vd)); void ProcessMacrosInType PROTO ((Module *m, TypeDef *td, Type *t, ValueDef *v)); void ProcessMacrosInElmtTypes PROTO ((Module *m, TypeDef *td, NamedTypeList *e, ValueDef *v)); void ProcessMacrosInBasicType PROTO ((Module *m, TypeDef *td, Type *type, BasicType *bt, ValueDef *v)); void DefineType PROTO ((Module *m, TypeDef *td, Type *t, char *name)); void ProcessRosOperationMacroType PROTO ((Module *m, TypeDef *td, Type *t, BasicType *bt, RosOperationMacroType *op, ValueDef *v)); void ProcessRosErrorMacroType PROTO ((Module *m, TypeDef *td, Type *t, BasicType *bt, RosErrorMacroType *err, ValueDef *v)); void ProcessRosBindMacroType PROTO ((Module *m, TypeDef *td, Type *t, BasicType *bt, RosBindMacroType *bind, ValueDef *v)); void ProcessRosAseMacroType PROTO ((Module *m, TypeDef *td, Type *t, BasicType *bt, RosAseMacroType *ase, ValueDef *v)); void ProcessRosAcMacroType PROTO ((Module *m, TypeDef *td, Type *t, BasicType *bt, RosAcMacroType *ac, ValueDef *v)); void ProcessMtsasExtensionsMacroType PROTO ((Module *m, TypeDef *td, Type *t, BasicType *bt, MtsasExtensionsMacroType *exts, ValueDef *v)); void ProcessMtsasExtensionMacroType PROTO ((Module *m, TypeDef *td, Type *t, BasicType *bt, MtsasExtensionMacroType *ext, ValueDef *v)); void ProcessMtsasExtensionAttributeMacroType PROTO ((Module *m, TypeDef *td, Type *t, BasicType *bt, MtsasExtensionAttributeMacroType *ext, ValueDef *v)); void ProcessMtsasTokenMacroType PROTO ((Module *m, TypeDef *td, Type *t, BasicType *bt, MtsasTokenMacroType *tok, ValueDef *v)); void ProcessMtsasTokenDataMacroType PROTO ((Module *m, TypeDef *td, Type *t, BasicType *bt, MtsasTokenDataMacroType *tok, ValueDef *v)); void ProcessMtsasSecurityCategoryMacroType PROTO ((Module *m, TypeDef *td, Type *t, BasicType *bt, MtsasSecurityCategoryMacroType *sec, ValueDef *v)); void ProcessAsnObjectMacroType PROTO ((Module *m, TypeDef *td, Type *t, BasicType *bt, AsnObjectMacroType *obj, ValueDef *v)); void ProcessAsnPortMacroType PROTO ((Module *m, TypeDef *td, Type *t, BasicType *bt, AsnPortMacroType *p, ValueDef *v)); void ProcessAsnAbstractBindMacroType PROTO ((Module *m, TypeDef *td, Type *t, BasicType *bt, AsnAbstractBindMacroType *bind, ValueDef *v)); void ProcessSnmpObjectTypeMacroType PROTO ((Module *m, TypeDef *td, Type *t, BasicType *bt, SnmpObjectTypeMacroType *bind, ValueDef *v)); /* static TypeDef *snmpObjectSyntaxesG = NULL; */ /* * Hunts for macros in TypeDefs or ValueDefs and * might do something with them. */ void ProcessMacros PARAMS ((m), Module *m) { TypeDef *td; ValueDef *vd; /* * go through each type in typeList */ FOR_EACH_LIST_ELMT (td, m->typeDefs) { ProcessMacrosInTypeDef (m, td); } /* * go through each value in valueList and link */ FOR_EACH_LIST_ELMT (vd, m->valueDefs) { ProcessMacrosInValueDef (m, vd); } /* add snmp object syntaxes choice to typedef list */ /* tmpTypeDefHndl = (TypeDef**) AsnListAppend (m->typeDefs); *tmpTypeDefHndl = snmpObjectSyntaxesG; snmpObjectSyntaxesG = NULL; */ } /* ProcessMacros */ /* * Given an AnyRefList, char string for an enum Id, * and an OBJECT IDENTIFIER, * this routine puts the id and oid into the AnyRefList. * When the code is generated, the AnyInit routine for * the module to which the typeDef that owns the given AnyRefList * belongs, calls a routine that will cause the given oid to * hash to the TypeDef that owns the AnyRefList. * The enumId value at runtime is used for simple determination of * the ANY type by the user. */ void AddAnyRefByOid PARAMS ((arl, enumId, oid), AnyRefList **arl _AND_ char *enumId _AND_ AsnOid *oid) { AnyRef **anyRefHndl; if (*arl == NULL) *arl = AsnListNew (sizeof (void*)); anyRefHndl = (AnyRef**)AsnListAppend (*arl); *anyRefHndl = MT (AnyRef); (*anyRefHndl)->anyIdName = Malloc (strlen (enumId)+1); strcpy ((*anyRefHndl)->anyIdName, enumId); (*anyRefHndl)->id = MT (OidOrInt); (*anyRefHndl)->id->choiceId = OIDORINT_OID; (*anyRefHndl)->id->a.oid = MT (AsnOid); (*anyRefHndl)->id->a.oid->octs = Malloc (oid->octetLen); memcpy ((*anyRefHndl)->id->a.oid->octs, oid->octs, oid->octetLen); (*anyRefHndl)->id->a.oid->octetLen = oid->octetLen; } /* AddAnyRefByOid */ /* * Like AddAnyRefByOid except that an int maps to the type def * instead of an OBJECT IDENTIFIER */ void AddAnyRefByInt PARAMS ((arl, enumId, intId), AnyRefList **arl _AND_ char *enumId _AND_ AsnInt intId) { AnyRef **anyRefHndl; if (*arl == NULL) *arl = AsnListNew (sizeof (void*)); anyRefHndl = (AnyRef**)AsnListAppend (*arl); *anyRefHndl = MT (AnyRef); (*anyRefHndl)->anyIdName = Malloc (strlen (enumId)+1); strcpy ((*anyRefHndl)->anyIdName, enumId); (*anyRefHndl)->id = MT (OidOrInt); (*anyRefHndl)->id->choiceId = OIDORINT_INTID; (*anyRefHndl)->id->a.intId = intId; } /* AddAnyRefByInt */ void ProcessMacrosInValueDef PARAMS ((m, vd), Module *m _AND_ ValueDef *vd) { if (vd == NULL) return; /* turn linked oid's into encoded oids */ if (vd->value->basicValue->choiceId == BASICVALUE_LINKEDOID) NormalizeValue (m, vd, vd->value, FALSE); ProcessMacrosInType (m, NULL, vd->value->type, vd); } /* ProcessMacrosInValueDef */ void ProcessMacrosInTypeDef PARAMS ((m,td), Module *m _AND_ TypeDef *td) { if (td == NULL) return; ProcessMacrosInType (m, td, td->type, NULL); } /* ProcessMacrosInTypeDef */ void ProcessMacrosInType PARAMS ((m, td,t, v), Module *m _AND_ TypeDef *td _AND_ Type *t _AND_ ValueDef *v) { if (t == NULL) return; ProcessMacrosInBasicType (m, td, t, t->basicType, v); } /* ProcessMacrosInTypeDef */ void ProcessMacrosInElmtTypes PARAMS ((m, td, e, v), Module *m _AND_ TypeDef *td _AND_ NamedTypeList *e _AND_ ValueDef *v) { NamedType *nt; FOR_EACH_LIST_ELMT (nt, e) { ProcessMacrosInType (m, td, nt->type, v); } } /* ProcessElmtTypes */ void ProcessMacrosInBasicType PARAMS ((m,td,type,bt, v), Module *m _AND_ TypeDef *td _AND_ Type *type _AND_ BasicType *bt _AND_ ValueDef *v) { if (bt == NULL) return; switch (bt->choiceId) { case BASICTYPE_SEQUENCE: case BASICTYPE_SET: case BASICTYPE_CHOICE: ProcessMacrosInElmtTypes (m, td, bt->a.set,v); break; case BASICTYPE_SEQUENCEOF: case BASICTYPE_SETOF: ProcessMacrosInType (m, td, bt->a.setOf, v); break; case BASICTYPE_MACROTYPE: switch (bt->a.macroType->choiceId) { case MACROTYPE_ASNABSTRACTOPERATION: case MACROTYPE_ROSOPERATION: ProcessRosOperationMacroType (m, td, type, bt, bt->a.macroType->a.rosOperation, v); break; case MACROTYPE_ROSERROR: case MACROTYPE_ASNABSTRACTERROR: ProcessRosErrorMacroType (m, td, type, bt, bt->a.macroType->a.rosError, v); break; case MACROTYPE_ROSBIND: case MACROTYPE_ROSUNBIND: ProcessRosBindMacroType (m, td, type, bt, bt->a.macroType->a.rosBind,v); break; case MACROTYPE_ROSASE: ProcessRosAseMacroType (m, td, type, bt, bt->a.macroType->a.rosAse,v); break; case MACROTYPE_MTSASEXTENSIONS: ProcessMtsasExtensionsMacroType (m, td, type, bt, bt->a.macroType->a.mtsasExtensions,v); break; case MACROTYPE_MTSASEXTENSION: ProcessMtsasExtensionMacroType (m, td, type, bt, bt->a.macroType->a.mtsasExtension,v); break; case MACROTYPE_MTSASEXTENSIONATTRIBUTE: ProcessMtsasExtensionAttributeMacroType (m, td, type, bt, bt->a.macroType->a.mtsasExtensionAttribute,v); break; case MACROTYPE_MTSASTOKEN: ProcessMtsasTokenMacroType (m, td, type, bt, bt->a.macroType->a.mtsasToken,v); break; case MACROTYPE_MTSASTOKENDATA: ProcessMtsasTokenDataMacroType (m, td, type, bt, bt->a.macroType->a.mtsasTokenData,v); break; case MACROTYPE_MTSASSECURITYCATEGORY: ProcessMtsasSecurityCategoryMacroType (m, td, type, bt, bt->a.macroType->a.mtsasSecurityCategory,v); break; case MACROTYPE_ASNOBJECT: ProcessAsnObjectMacroType (m, td, type, bt, bt->a.macroType->a.asnObject,v); break; case MACROTYPE_ASNPORT: ProcessAsnPortMacroType (m, td, type, bt, bt->a.macroType->a.asnPort,v); break; case MACROTYPE_ASNABSTRACTBIND: case MACROTYPE_ASNABSTRACTUNBIND: ProcessAsnAbstractBindMacroType (m, td, type, bt, bt->a.macroType->a.asnAbstractBind,v); break; case MACROTYPE_AFALGORITHM: case MACROTYPE_AFENCRYPTED: case MACROTYPE_AFPROTECTED: case MACROTYPE_AFSIGNATURE: case MACROTYPE_AFSIGNED: break; case MACROTYPE_SNMPOBJECTTYPE: ProcessSnmpObjectTypeMacroType (m, td, type, bt, bt->a.macroType->a.snmpObjectType,v); break; default: /* ignore any others */ break; } default: /* the rest do not need processing */ break; } } /* ProcessMacrosInBasicType */ /* * Given a Type referenced in a macro, makes up a name and defines * the type iff the type is not a simple type ref or library type. * Returns the typedef of the type given type. (may be new may * be from the typeref if t was a local or import type ref) */ void DefineType PARAMS ((m, td, t, name), Module *m _AND_ TypeDef *td _AND_ Type *t _AND_ char *name) { int digit; TypeDef *newDef; TypeDef **tmpTypeDefHndl; Type *tmpType; if (IsNewType (t)) { newDef = (TypeDef*)Malloc (sizeof (TypeDef)); newDef->exported = FALSE; newDef->type = (Type*)Malloc (sizeof (Type)); memcpy (newDef->type, t, sizeof (Type)); newDef->definedName = Malloc (strlen (name) + 4); strcpy (newDef->definedName, name); if (islower (newDef->definedName[0])) newDef->definedName[0] = (char)toupper (newDef->definedName[0]); /* set up unique type name for new type */ for (digit = 0; (LookupType (m->typeDefs, newDef->definedName) != NULL); digit++) AppendDigit (newDef->definedName, digit); /* * now put new typedef at head of list */ tmpTypeDefHndl = (TypeDef**)AsnListPrepend (m->typeDefs); *tmpTypeDefHndl = newDef; /* convert macro's type def into a ref */ SetupType (&tmpType, BASICTYPE_LOCALTYPEREF, 0); memcpy (t, tmpType, sizeof (Type)); Free (tmpType); t->implicit = FALSE; t->basicType->a.localTypeRef = (TypeRef*)Malloc (sizeof (TypeRef)); t->basicType->a.localTypeRef->link = newDef; t->basicType->a.localTypeRef->module = m; t->basicType->a.localTypeRef->typeName = newDef->definedName; td = td; /*AVOIDS compiler warning.*/ } } /* DefineType */ void ProcessRosOperationMacroType PARAMS ((m, td, t, bt, op, v), Module *m _AND_ TypeDef *td _AND_ Type *t _AND_ BasicType *bt _AND_ RosOperationMacroType *op _AND_ ValueDef *v) { if (v == NULL) return; if (op->arguments != NULL) DefineType (m, td, op->arguments->type, v->definedName); if (op->result != NULL) DefineType (m, td, op->result->type, v->definedName); bt = bt; /*AVOIDS compiler warning.*/ t = t; } /* ProcessRosOperationMacroType */ void ProcessRosErrorMacroType PARAMS ((m, td, t, bt, err, v), Module *m _AND_ TypeDef *td _AND_ Type *t _AND_ BasicType *bt _AND_ RosErrorMacroType *err _AND_ ValueDef *v) { if (v == NULL) return; if ((err != NULL) && (err->parameter != NULL)) DefineType (m, td, err->parameter->type, v->definedName); bt = bt; /*AVOIDS compiler warning.*/ t = t; } /* ProcessRosErrorMacroType */ void ProcessRosBindMacroType PARAMS ((m, td, t, bt, bind, v), Module *m _AND_ TypeDef *td _AND_ Type *t _AND_ BasicType *bt _AND_ RosBindMacroType *bind _AND_ ValueDef *v) { if (v == NULL) return; if (bind != NULL) { DefineType (m, td, bind->argument->type, v->definedName); DefineType (m, td, bind->result->type, v->definedName); DefineType (m, td, bind->error->type, v->definedName); } bt = bt; /*AVOIDS compiler warning.*/ t = t; } /* ProcessRosBindMacroType */ void ProcessRosAseMacroType PARAMS ((m, td, t, bt, ase, v), Module *m _AND_ TypeDef *td _AND_ Type *t _AND_ BasicType *bt _AND_ RosAseMacroType *ase _AND_ ValueDef *v) { bt = bt; /*AVOIDS compiler warning.*/ t = t; td = td; m = m; ase = ase; v = v; /*AVOIDS compiler warning.*/ } /* ProcessRosAseMacroType */ void ProcessRosAcMacroType PARAMS ((m, td, t, bt, ac, v), Module *m _AND_ TypeDef *td _AND_ Type *t _AND_ BasicType *bt _AND_ RosAcMacroType *ac _AND_ ValueDef *v) { bt = bt; /*AVOIDS compiler warning.*/ t = t; v = v; ac = ac; td = td; m = m; } /* ProcessRosAcMacroType */ void ProcessMtsasExtensionsMacroType PARAMS ((m, td, t, bt, exts, v), Module *m _AND_ TypeDef *td _AND_ Type *t _AND_ BasicType *bt _AND_ MtsasExtensionsMacroType *exts _AND_ ValueDef *v) { bt = bt; /*AVOIDS compiler warning.*/ t = t; td = td; m = m; exts = exts; v = v; /*AVOIDS compiler warning.*/ } /* ProcessMtsasExtensionsMacroType */ void ProcessMtsasExtensionMacroType PARAMS ((m, td, t, bt, ext, v), Module *m _AND_ TypeDef *td _AND_ Type *t _AND_ BasicType *bt _AND_ MtsasExtensionMacroType *ext _AND_ ValueDef *v) { bt = bt; /*AVOIDS compiler warning.*/ t = t; td = td; m = m; v = v; ext = ext; } /* ProcessMtsasExtensionMacroType */ void ProcessMtsasExtensionAttributeMacroType PARAMS ((m, td, t, bt, ext, v), Module *m _AND_ TypeDef *td _AND_ Type *t _AND_ BasicType *bt _AND_ MtsasExtensionAttributeMacroType *ext _AND_ ValueDef *v) { bt = bt; /*AVOIDS compiler warning.*/ t = t; td = td; m = m; v = v; ext = ext; } /* ProcessMtsasExtensionAttributeMacroType */ void ProcessMtsasTokenMacroType PARAMS ((m, td, t, bt, tok, v), Module *m _AND_ TypeDef *td _AND_ Type *t _AND_ BasicType *bt _AND_ MtsasTokenMacroType *tok _AND_ ValueDef *v) { bt = bt; /*AVOIDS compiler warning.*/ t = t; td = td; m = m; v = v; tok = tok; } /* ProcessMtsasTokenMacroType */ void ProcessMtsasTokenDataMacroType PARAMS ((m, td, t, bt, tok, v), Module *m _AND_ TypeDef *td _AND_ Type *t _AND_ BasicType *bt _AND_ MtsasTokenDataMacroType *tok _AND_ ValueDef *v) { bt = bt; /*AVOIDS compiler warning.*/ t = t; td = td; m = m; v = v; tok = tok; } /* ProcessMtsasTokenDataMacroType */ void ProcessMtsasSecurityCategoryMacroType PARAMS ((m, td, t, bt, sec, v), Module *m _AND_ TypeDef *td _AND_ Type *t _AND_ BasicType *bt _AND_ MtsasSecurityCategoryMacroType *sec _AND_ ValueDef *v) { bt = bt; /*AVOIDS compiler warning.*/ t = t; td = td; m = m; v = v; sec = sec; } /* ProcessMtsasSecurityCategoryMacroType */ void ProcessAsnObjectMacroType PARAMS ((m, td, t, bt, obj, v), Module *m _AND_ TypeDef *td _AND_ Type *t _AND_ BasicType *bt _AND_ AsnObjectMacroType *obj _AND_ ValueDef *v) { bt = bt; /*AVOIDS compiler warning.*/ t = t; td = td; m = m; v = v ; obj = obj; } /* ProcessAsnObjectMacroType */ void ProcessAsnPortMacroType PARAMS ((m, td, t, bt, p, v), Module *m _AND_ TypeDef *td _AND_ Type *t _AND_ BasicType *bt _AND_ AsnPortMacroType *p _AND_ ValueDef *v) { bt = bt; /*AVOIDS compiler warning.*/ t = t; td = td; m = m; v = v; p = p; } /* ProcessAsnPortMacroType */ void ProcessAsnAbstractBindMacroType PARAMS ((m, td, t, bt, bind, v), Module *m _AND_ TypeDef *td _AND_ Type *t _AND_ BasicType *bt _AND_ AsnAbstractBindMacroType *bind _AND_ ValueDef *v) { bt = bt; /*AVOIDS compiler warning.*/ t = t; td = td; m = m; v = v; bind = bind; } /* ProcessAsnBindMacroType */ void ProcessSnmpObjectTypeMacroType PARAMS ((m, td, t, bt, ot, v), Module *m _AND_ TypeDef *td _AND_ Type *t _AND_ BasicType *bt _AND_ SnmpObjectTypeMacroType *ot _AND_ ValueDef *v) { NamedType *nt = NULL; char anyId[256]; AnyRefList **arlHndl; if ((ot != NULL) && (ot->syntax != NULL)) DefineType (m, td, ot->syntax, v->definedName); /* * add ANY ref stuff to type ref'd by this macro so it is * included in the ANY hash table. */ /* * do this since the SNMP spec doesn't have an ANY type * but uses the mechanism. (SNMP uses an OCTET STRING * where the 'ANY' value is */ m->hasAnys = TRUE; strcpy (anyId, v->definedName); Dash2Underscore (anyId, strlen (anyId)); strcat (anyId, "_ANY_ID"); arlHndl = GetAnyRefListHndl (ot->syntax); if (v->value->basicValue->choiceId == BASICVALUE_OID) AddAnyRefByOid (arlHndl, anyId, v->value->basicValue->a.oid); /* integer types are not allowed, but relax constraints anyway */ else AddAnyRefByInt (arlHndl, anyId, v->value->basicValue->a.integer); /* REN -- 1/12/98 -- Also need to add a reference to the global ref table for importTypeRefs since GetAnyRefListHndl() and AddAnyRefByInt() only adds the ref to the Type (basic or localTypeRef). Note: For imported Types, GetAnyRefListHndl() will never return a handle into the global ref table. */ /* Only add this type if it's an importTypeRef */ if ((ot->syntax != NULL) && (ot->syntax->basicType->choiceId == BASICTYPE_IMPORTTYPEREF)) { arlHndl = LIBTYPE_GET_ANY_REFS_HNDL(ot->syntax->basicType->choiceId); if (v->value->basicValue->choiceId == BASICVALUE_OID) AddAnyRefByOid (arlHndl, anyId, v->value->basicValue->a.oid); else AddAnyRefByInt (arlHndl, anyId, v->value->basicValue->a.integer); } /* REN -- end */ /* make a choice with all the object type elmts */ /* USING THE ANY HASH TABLE NOW if (snmpObjectSyntaxesG == NULL) { snmpObjectSyntaxesG = (TypeDef*) Malloc (sizeof (TypeDef)); SetupType (&snmpObjectSyntaxesG->type, BASICTYPE_CHOICE, 0); snmpObjectSyntaxesG->type->basicType->a.choice = AsnListNew (sizeof (void*)); snmpObjectSyntaxesG->definedName = "SnmpOpaqueTypes"; } */ /* NOT DONE ANYMORE * make each field in the choice the same as the object * types SYNTAX field type (adjusted by Define type) * make choice field name same as OBJ-TYPE value Defs name * * NOTE - using ptrs to type/fieldname, not duplicating them * this may cause freeing probs */ /* nt = MT (NamedType); nt->fieldName = v->definedName; nt->type = ot->syntax; tmpNtHndl = (NamedType**) AsnListAppend (snmpObjectSyntaxesG->type->basicType->a.choice); *tmpNtHndl = nt; */ bt=bt; /*AVOIDS compiler warning.*/ t = t; nt = nt; } /* ProcessSnmpObjectTypeMacro */ esnacc-ng-1.8.1/compiler/core/enc-rules.c000066400000000000000000000044721302010526100201570ustar00rootroot00000000000000/* * compiler/core/enc-rules.c * * utilities for dealing with different encoding rules * * AUTHOR: Dean Povey * DATE: 97/08/27 * * Copyright (C) 1997 Dean Povey and the Distributed Systems Technology Centre * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/core/enc-rules.c,v 1.2 2003/07/07 14:50:13 nicholar Exp $ * $Log: enc-rules.c,v $ * Revision 1.2 2003/07/07 14:50:13 nicholar * Eliminated headers and cleaned up include references * * Revision 1.1.1.1 2000/08/21 20:35:59 leonberp * First CVS Version of SNACC. * * Revision 1.1 1997/08/28 07:37:15 povey * Initial revision * * */ #if !defined(lint) static const char rcsid[] = "@(#)$RCSfile: enc-rules.c,v $ $Revision: 1.2 $"; #endif /* * Local file includes */ #include "enc-rules.h" #include "asn1module.h" #include "lib-types.h" /* Static variables. */ static EncRulesType rulesG; static char* prefixG; static EncRulesType rulesListG[3] = {NOP, NOP, NOP}; /* Set the encoding rule to be used */ int SetEncRules PARAMS ((encoding), EncRulesType encoding) { switch(encoding) { case BER: /* Basic Encoding Rules */ rulesG = BER; prefixG = "B"; /* Set the correct encodings */ SET_BER_LIBTYPE(); return 1; case DER: /* Distinguished Encoding Rules */ rulesG = DER; prefixG = "D"; /* Set the encodings for each lib type */ SET_DER_LIBTYPE(); return 1; default: /* No such rule */ return 0; } } /* Add an encoding to the list of encoders to generate */ void AddEncRules PARAMS((encoding), EncRulesType encoding) { if (rulesListG[0] == NOP) { rulesListG[0] = encoding; } else if (rulesListG[0] != encoding && rulesListG[1] == NOP) { rulesListG[1] = encoding; } else { /* Encoding must be already set */ return; } return; } /* Return a list of the encoders to generate */ EncRulesType *GetEncRules() { return rulesListG; } char* GetEncRulePrefix() { return prefixG; } EncRulesType GetEncRulesType() { return rulesG; } /***************************************************************/ /* end of FILE_C */ esnacc-ng-1.8.1/compiler/core/enc-rules.h000066400000000000000000000027461302010526100201660ustar00rootroot00000000000000/* * compiler/core/enc-rules.h * * Copyright (C) 1997 Dean Povey and the Distributed Systems Technology Centre * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/core/enc-rules.h,v 1.2 2001/07/12 19:34:28 leonberp Exp $ * $Log: enc-rules.h,v $ * Revision 1.2 2001/07/12 19:34:28 leonberp * Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. * * Revision 1.1.1.1 2000/08/21 20:35:59 leonberp * First CVS Version of SNACC. * * Revision 1.1 1997/08/28 07:37:15 povey * Initial revision * * Revision 1.3.1.1 1997/08/20 23:14:39 povey * */ #ifndef _enc_rules_h #define _enc_rules_h #if defined (__cplusplus) extern "C" { #endif #include "asn-incl.h" #if !defined(lint) static const char rcs_ENC_RULES_H[] = "@(#)$RCSfile: enc-rules.h,v $ $Revision: 1.2 $"; #endif /* Type of encoding rule being used */ typedef enum {BER, DER, NOP} EncRulesType; int SetEncRules PROTO((EncRulesType encoding)); EncRulesType *GetEncRules(); void AddEncRules PROTO((EncRulesType encoding)); char* GetEncRulePrefix PROTO (()); EncRulesType GetEncEncRulesType PROTO (()); #if defined (__cplusplus) } #endif /***************************************************************/ #endif /* _enc_rules_h */ esnacc-ng-1.8.1/compiler/core/err-chk.c000066400000000000000000001032331302010526100176100ustar00rootroot00000000000000/* * compiler/core/err_chk.c - Check for semantic errors an ASN.1 module * * The following are checked: * * - Components of CHOICE and SET types must have distinct tags. x * * - CHOICE, ANY, and ANY DEFINED BY types cannot be implicitly tagged. x * * - Type and value names within the same scope must be unique. x * * - Field names in a SET, SEQUENCE or CHOICE must be distinct. If * a CHOICE with no field name is embedded in a SET, SEQUENCE or CHOICE, * then the embedded CHOICE's field names must be distinct from its * parents to avoid ambiguity in value notation. x * * - An APPLICATION tag can only be used once per module. x (done in asn1.yacc) * * - Each value in a named bit (BIT STRINGs) or named number x * (INTEGERs and ENUMERATED) list must be different. * * - Each identifier in a named bit or named number list must be different. x * * - The tags on a series of one or more consecutive OPTIONAL or DEFAULT * SEQUENCE elements and the following element must be distinct. x * * link_types.c does the following three checks * A COMPONENTS OF type in a SET must reference a SET * A COMPONENTS OF type in a SEQUENCE must reference a SEQUENCE * SELECTION types must reference a field of a CHOICE type. * * - gives a warning if an ANY DEFINED BY type appears in a SET or * if and ANY DEFINED BY appears in a SEQUENCE before its identifier. * these cases make decoding difficult. * * ******* following are not done yet - need improved value proc. first***** * * - Each identifier in a BIT STRING value must from that BIT * STRING's named bit list. * * - SET or SEQUENCE values can be empty {} only if the SET or * SEQUENCE type was defined as empty or all of its elements are marked * as OPTIONAL or DEFAULT. * * Mike Sample * 92/07/13 * * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/core/err-chk.c,v 1.11 2004/04/06 15:13:41 gronej Exp $ * $Log: err-chk.c,v $ * Revision 1.11 2004/04/06 15:13:41 gronej * *** empty log message *** * * Revision 1.10 2004/03/31 20:03:19 leonberp * resolved many gcc compile warnings * * Revision 1.9 2004/01/14 19:07:52 gronej * Updated Compiler to accept and process relative-oid's * * Revision 1.8 2003/07/28 11:11:23 colestor * Changes to complete handing of the "--snacc namespace" compiler directive. * Also, updates to handle ASN.1 constant integer tag designations for C++/C. * * * Revision 1.7 2003/07/07 14:50:13 nicholar * Eliminated headers and cleaned up include references * * Revision 1.6 2003/04/29 21:09:12 leonberp * integerated Deepak's changes for IOB support * * Revision 1.5 2002/09/16 16:49:22 mcphersc * Fixed warnings * * Revision 1.4 2002/09/04 18:58:39 leonberp * Enhanced ANY DEFINED BY check to handle int, oid, enum, or choice of them. * * Revision 1.3 2002/09/04 18:23:07 vracarl * got rid of c++ comments * * Revision 1.2 2000/10/24 14:54:51 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:35:59 leonberp * First CVS Version of SNACC. * * Revision 1.3.1.1 1997/08/20 23:14:40 povey * * * Revision 1.3 1995/07/25 19:41:25 rj * changed `_' to `-' in file names. * * Revision 1.2 1994/09/01 00:33:02 rj * snacc_config.h removed; err_chk.h includet. * * Revision 1.1 1994/08/28 09:49:05 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include #include #include "asn-incl.h" #include "asn1module.h" #include "snacc-util.h" #include "define.h" typedef struct DefinedTag { Tag *tag; struct DefinedTag *next; } DefinedTag; typedef struct DefinedName { char *name; struct DefinedName *next; } DefinedName; static NamedType *badNamedType; // static DefinedName *fieldNames = NULL; int CountTags PROTO ((Type *t)); enum BasicTypeChoiceId ParanoidGetBuiltinType PARAMS ((t),Type *t); void ErrChkTypeDef PROTO ((Module *m, TypeDef *td)); void ErrChkType PROTO ((Module *m, TypeDef *td, Type *parent, NamedType *nt, Type *t)); void ErrChkElmtTypes PROTO ((Module *m, TypeDef *td, Type *parent, NamedTypeList *e)); void ErrChkBasicType PROTO ((Module *m, TypeDef *td, Type *parent, NamedType *nt, Type *type)); void ErrChkValueDef PROTO ((Module *m, ValueDef *vd)); void ErrChkValue PROTO ((Module *m, ValueDef *vd, Value *v)); int HasDistinctTags PROTO ((NamedTypeList *elmts)); int AddFirstTag PROTO ((DefinedObj **definedTags, Type *t)); void ChkFieldNames PROTO ((Module *m, TypeDef *td, Type *parent, NamedTypeList *elmts)); void ChkNamedNumbers PROTO ((Module *m, Type *t, NamedNumberList *n)); void ChkNamedBits PROTO ((Module *m, Type *t, NamedNumberList *n)); void ChkSeqTags PROTO ((Module *m, TypeDef *td, Type *t)); char *DetermineCode(Tag *tag, int *ptagLen, int bJustIntegerFlag); extern FILE* errFileG; /* Pointer to file for reporting errors */ /* return TRUE if the Tag *t1 and t2 are the same in class and code */ int TagObjCmp (void *vt1, void *vt2) { Tag *t1 = vt1; Tag *t2 = vt2; int iResult = 0; if (t1->valueRef == NULL && t2->valueRef == NULL) { iResult = (t1->tclass == t2->tclass && t1->code == t2->code); } else { // RWC;THEN we need to check further, may be indirectly referenced. // THIS logic assumes similar types, only Integer value returned... char *p1 = DetermineCode(t1, NULL, 1); if (p1) { char *p1Tmp = strdup(p1); // "static" memory, so 1 needs to be copied. char *p2 = DetermineCode(t2, NULL, 1); if (p2) if (strcmp(p1Tmp, p2) == 0) iResult = 1; free(p1Tmp); } // END IF p1 } return(iResult); } /* * Checks for errors listed above. * sets module status to MOD_ERROR if any errors occured */ void ErrChkModule PARAMS ((m), Module *m) { TypeDef *td; ValueDef *vd=NULL; DefinedObj *typeNames; DefinedObj *valueNames; ImportModule *impList; ImportElmt *impElmt; /* * go through each type in typeList */ typeNames = NewObjList(); FOR_EACH_LIST_ELMT (td, m->typeDefs) { /* first check for name conflicts */ if (ObjIsDefined (typeNames, td->definedName, StrObjCmp)) { PrintErrLoc (m->asn1SrcFileName, (long)td->type->lineNo); fprintf (errFileG, "ERROR - type \"%s\" is multiply defined.\n", td->definedName); m->status = MOD_ERROR; } else DefineObj (&typeNames, td->definedName); /* now check type def internals */ ErrChkTypeDef (m, td); } /* now check for name conflicts with imported types */ FOR_EACH_LIST_ELMT (impList, m->imports) { FOR_EACH_LIST_ELMT (impElmt, impList->importElmts) { if ((!impElmt->privateScope) && (isupper (impElmt->name[0]))) { if (ObjIsDefined (typeNames, impElmt->name, StrObjCmp)) { PrintErrLoc (m->asn1SrcFileName, (long)impElmt->lineNo); fprintf (errFileG, "ERROR - type \"%s\" is multiply defined.\n", impElmt->name); m->status = MOD_ERROR; } else DefineObj (&typeNames, impElmt->name); } } } FreeDefinedObjs (&typeNames); /* * go through each value for types */ valueNames = NewObjList(); FOR_EACH_LIST_ELMT (vd, m->valueDefs) { /* check for name conflict */ if (ObjIsDefined (valueNames, vd->definedName, StrObjCmp)) { PrintErrLoc (m->asn1SrcFileName, (long)vd->value->lineNo); fprintf (errFileG, "ERROR - value \"%s\" is multiply defined.\n", vd->definedName); m->status = MOD_ERROR; } else DefineObj (&valueNames, vd->definedName); /* check value internal info */ ErrChkValueDef (m, vd); } /* now check for name conflicts with imported values */ FOR_EACH_LIST_ELMT (impList, m->imports) { FOR_EACH_LIST_ELMT (impElmt, impList->importElmts) { if ((!impElmt->privateScope) && (islower (impElmt->name[0]))) { if (ObjIsDefined (valueNames, impElmt->name, StrObjCmp)) { PrintErrLoc (m->asn1SrcFileName, (long)impElmt->lineNo); fprintf (errFileG, "ERROR - value \"%s\" is multiply defined.\n", vd->definedName); m->status = MOD_ERROR; } else DefineObj (&valueNames, impElmt->name); } } } FreeDefinedObjs (&valueNames); } /* ErrChkModule */ void ErrChkTypeDef PARAMS ((m, td), Module *m _AND_ TypeDef *td) { if (td == NULL) return; ErrChkType (m, td, NULL, NULL, td->type); } /* ErrChkTypeDef */ void ErrChkType PARAMS ((m, td, parent, nt, t), Module *m _AND_ TypeDef *td _AND_ Type *parent _AND_ NamedType *nt _AND_ Type *t) { if (t == NULL) return; ErrChkBasicType (m, td, parent, nt, t); } /* ErrChkType */ void ErrChkElmtTypes PARAMS ((m, td, parent, e), Module *m _AND_ TypeDef *td _AND_ Type *parent _AND_ NamedTypeList *e) { NamedType *nt; /* * if starting new type aggregate type, * check that the field names are distinct * (goes 'through' un-named elements that are CHOICEs) */ if (td->type == parent) { ChkFieldNames (m, td, parent, e); } FOR_EACH_LIST_ELMT (nt, e) { ErrChkType (m, td, parent, nt, nt->type); } } /* ErrChkElmtTypes */ void ErrChkBasicType PARAMS ((m, td, parent, tnt, type), Module *m _AND_ TypeDef *td _AND_ Type *parent _AND_ NamedType *tnt _AND_ Type *type) { NamedType *nt=NULL; Type *refdType; enum BasicTypeChoiceId refdTypeId; if ((type == NULL) || (type->basicType == NULL)) return; switch (type->basicType->choiceId) { case BASICTYPE_LOCALTYPEREF: case BASICTYPE_IMPORTTYPEREF: /* * make sure that untagged CHOICE and ANY types * are not implicitly tagged */ refdTypeId = ParanoidGetBuiltinType (type); if ((type->implicit) && ((refdTypeId == BASICTYPE_CHOICE) || (refdTypeId == BASICTYPE_ANY) || (refdTypeId == BASICTYPE_ANYDEFINEDBY)) && (CountTags (type->basicType->a.localTypeRef->link->type) == 0)) { m->status = MOD_ERROR; PrintErrLoc (m->asn1SrcFileName, (long)type->lineNo); fprintf (errFileG, "ERROR - IMPLICITLY tagged CHOICE, ANY or ANY DEFINED BY type.\n"); } if ((parent != NULL) && ((refdTypeId == BASICTYPE_ANY) || (refdTypeId == BASICTYPE_ANYDEFINEDBY))) { /* * give a warning. It is stupid to have an ANY DEFINED * BY type in a SET since they are not ordered and hence * the ANY DEFINED BY type may need to be decoded before * its identifer which is very difficult */ if ((refdTypeId == BASICTYPE_ANYDEFINEDBY) && (parent->basicType->choiceId == BASICTYPE_SET)) { PrintErrLoc (m->asn1SrcFileName, (long)type->lineNo); fprintf (errFileG, "WARNING - ANY DEFINED BY in a SET needs to be decoded before its identifier. This is not guaranteed since SETs are not ordered. Use a SEQUENCE instead, if possible.\n"); } /* * give a warning. It is stupid to have an ANY DEFINED * BY type in a SEQUENCE before its identifier. * The ANY DEFINED BY type will need to be decoded before * its identifer which is very difficult. * tnt is the NamedType holding "type" */ if ((refdTypeId == BASICTYPE_ANYDEFINEDBY) && (tnt != NULL) && (parent->basicType->choiceId == BASICTYPE_SEQUENCE) && (GetAsnListElmtIndex (tnt, parent->basicType->a.sequence) < GetAsnListElmtIndex (type->basicType->a.anyDefinedBy->link, parent->basicType->a.sequence))) { PrintErrLoc (m->asn1SrcFileName, (long)type->lineNo); fprintf (errFileG, "WARNING - ANY DEFINED BY in SEQUENCE should appear before its identifier since the identifier must be decoded before the ANY DEFINED BY type.\n"); } if (parent->basicType->choiceId == BASICTYPE_SEQUENCE) nt = LAST_LIST_ELMT (parent->basicType->a.sequence); /* * untagged, optional ANYs are strange and will cause faulty * decoding code to be generated unless they are the last * elmt in a SEQUENCE. * (if they are the last elmt it is easy to check * for the presence of the ANY if definite lengths are used) * (must peek ahead for EOC otherwise) */ if (!((parent->basicType->choiceId == BASICTYPE_SEQUENCE) && (type == nt->type)) && (type->optional) && (CountTags (type) == 0)) { PrintErrLoc (m->asn1SrcFileName, (long)type->lineNo); fprintf (errFileG, "WARNING - untagged optional ANY encountered, the produced code will be wrong.\n"); } } break; case BASICTYPE_INTEGER: case BASICTYPE_ENUMERATED: ChkNamedNumbers (m, type, type->basicType->a.integer); break; case BASICTYPE_BITSTRING: ChkNamedBits (m, type, type->basicType->a.bitString); break; case BASICTYPE_SEQUENCEOF: case BASICTYPE_SETOF: ErrChkType (m, td, type, NULL, type->basicType->a.setOf); break; case BASICTYPE_SEQUENCE: ErrChkElmtTypes (m, td, type, type->basicType->a.sequence); /* * check that tags on one or more consecutive optional elmts * and following (if any) non-optional elmt are distinct */ ChkSeqTags (m, td, type); break; case BASICTYPE_OBJECTCLASS: // Deepak: 14/Mar/2003 ErrChkElmtTypes (m, td, type, type->basicType->a.objectclass->classdef); /* * check that tags on one or more consecutive optional elmts * and following (if any) non-optional elmt are distinct */ ChkSeqTags (m, td, type); // Deepak: ????? chk for Class Tags??? break; case BASICTYPE_CHOICE: /* CHOICE elements must have distinct tags */ if (!HasDistinctTags (type->basicType->a.choice)) { PrintErrLoc (m->asn1SrcFileName, (long)type->lineNo); fprintf (errFileG, "ERROR - tag conflict among the CHOICE elements.\n"); m->status = MOD_ERROR; } /* * untagged choices cannot be implicitily tagged * (this would make it impossible/difficult to figure out which * elmt of the choice was present when decoding) */ if (((type->tags == NULL) || LIST_EMPTY (type->tags)) && (type->implicit)) { PrintErrLoc (m->asn1SrcFileName, (long)type->lineNo); fprintf (errFileG, "ERROR - IMPLICITLy tagged CHOICE type.\n"); m->status = MOD_ERROR; } /* Check out each of the components */ ErrChkElmtTypes (m, td, type, type->basicType->a.choice); break; case BASICTYPE_ANYDEFINEDBY: /* for ANY DEFINED BY make sure id field is int or oid */ refdType = GetType (type->basicType->a.anyDefinedBy->link->type); if ((refdType->basicType->choiceId != BASICTYPE_INTEGER) && (refdType->basicType->choiceId != BASICTYPE_ENUMERATED) && (refdType->basicType->choiceId != BASICTYPE_OID) && (refdType->basicType->choiceId != BASICTYPE_RELATIVE_OID)) { if (refdType->basicType->choiceId == BASICTYPE_CHOICE) { NamedType* nt; FOR_EACH_LIST_ELMT(nt, refdType->basicType->a.choice) { enum BasicTypeChoiceId choiceId = nt->type->basicType->choiceId; if (choiceId != BASICTYPE_INTEGER && choiceId != BASICTYPE_ENUMERATED && choiceId != BASICTYPE_OID && choiceId != BASICTYPE_RELATIVE_OID) { PrintErrLoc(m->asn1SrcFileName, (long)type->lineNo); fprintf(errFileG, "ERROR - Field referenced by ANY DEFINED BY type must be of INTEGER or OBJECT IDENTIFIER type.\n"); m->status = MOD_ERROR; } } } else { PrintErrLoc (m->asn1SrcFileName, (long)type->lineNo); fprintf (errFileG, "ERROR - Field referenced by ANY DEFINED BY type must be of INTEGER or OBJECT IDENTIFIER type.\n"); m->status = MOD_ERROR; } } /* make sure id field is not optional */ if (type->basicType->a.anyDefinedBy->link->type->optional) { PrintErrLoc (m->asn1SrcFileName, (long)type->lineNo); fprintf (errFileG, "ERROR - Field referenced by ANY DEFINED BY cannot be optional.\n"); m->status = MOD_ERROR; } /* * give a warning. It is stupid to have an ANY DEFINED * BY type in a SET since they are not ordered and hence * the ANY DEFINED BY type may need to be decoded before * its identifer which is very difficult */ if ((parent != NULL) && (parent->basicType->choiceId == BASICTYPE_SET)) { PrintErrLoc (m->asn1SrcFileName, (long)type->lineNo); fprintf (errFileG, "WARNING - ANY DEFINED BY in a SET needs to be decoded before its identifier. This is not guaranteed since SETs are not ordered. Use a SEQUENCE instead, if possible.\n"); } /* * give a warning. It is stupid to have an ANY DEFINED * BY type in a SEQUENCE before its identifier. * The ANY DEFINED BY type will need to be decoded before * its identifer which is very difficult. * tnt is the NamedType holding "type" */ if ((parent != NULL) && (tnt != NULL) && (parent->basicType->choiceId == BASICTYPE_SEQUENCE) && (GetAsnListElmtIndex (tnt, parent->basicType->a.sequence) < GetAsnListElmtIndex (type->basicType->a.anyDefinedBy->link, parent->basicType->a.sequence))) { PrintErrLoc (m->asn1SrcFileName, (long)type->lineNo); fprintf (errFileG, "WARNING - ANY DEFINED BY in SEQUENCE should appear before its identifier since the identifier must be decoded before the ANY DEFINED BY type.\n"); } /* fall through - arrrrrg! */ case BASICTYPE_ANY: /* ANY cannot be implicitily tagged */ if (((type->tags == NULL) || LIST_EMPTY (type->tags)) && (type->implicit)) { PrintErrLoc (m->asn1SrcFileName, (long)type->lineNo); fprintf (errFileG, "ERROR - IMPLICITLy tagged ANY type.\n"); m->status = MOD_ERROR; } if (parent != NULL) { if (parent->basicType->choiceId == BASICTYPE_SEQUENCE) nt = LAST_LIST_ELMT (parent->basicType->a.sequence); /* * untagged, optional ANYs are strange and will cause faulty * decoding code to be generated unless they are the last * elmt in a SEQUENCE */ if (!((parent->basicType->choiceId == BASICTYPE_SEQUENCE) && (type == nt->type)) && (type->optional) && (CountTags (type) == 0)) { PrintErrLoc (m->asn1SrcFileName, (long)type->lineNo); fprintf (errFileG, "WARNING - untagged optional ANY encountered, the produced code will be wrong.\n"); } /* * if parent is SET or CHOICE then ANY or ANY DEFINED BY * should be tagged to help determine its presence * * NOTE: there are also probs with untagged ANYs in SEQs * where the ANY is preceeded by optional elmts * (err msg written in produced code) */ if (((parent->basicType->choiceId == BASICTYPE_SET) || (parent->basicType->choiceId == BASICTYPE_CHOICE)) && (CountTags (type) == 0)) { PrintErrLoc (m->asn1SrcFileName, (long)type->lineNo); fprintf (errFileG, "WARNING - untagged ANY in a SET or CHOICE, the produced code will be wrong.\n"); } } break; case BASICTYPE_SET: /* SET elements must have distinct tags */ if (!HasDistinctTags (type->basicType->a.set)) { PrintErrLoc (m->asn1SrcFileName, (long)type->lineNo); fprintf (errFileG, "ERROR - tag conflict among the SET elements.\n"); m->status = MOD_ERROR; } /* Check out each of the components */ ErrChkElmtTypes (m, td, type, type->basicType->a.set); break; default: /* the rest do not need checking */ break; } } /* ErrChkBasicType */ void ErrChkValueDef PARAMS ((m, vd), Module *m _AND_ ValueDef *vd) { ErrChkValue (m, vd, vd->value); } void ErrChkValue PARAMS ((m, vd, v), Module *m _AND_ ValueDef *vd _AND_ Value *v) { } /* * returns non-zero if the first tags on the elements * are all different. Otherwise 0 is returned * * algorithm: add each tag to a list, adding only if * not already in list. if there, free list * and return FALSE. if finished adding tags * and no duplicates occurred then return TRUE; */ int HasDistinctTags PARAMS ((elmts), NamedTypeList *elmts) { DefinedObj *tL; NamedType *e; tL = NewObjList(); FOR_EACH_LIST_ELMT (e, elmts) { if (!AddFirstTag (&tL, e->type)) { FreeDefinedObjs (&tL); badNamedType = e; return FALSE; } } FreeDefinedObjs (&tL); badNamedType = NULL; return TRUE; } /* HasDistinctTags */ /* * puts first tag of the given type into the defined tags list * returns FALSE if the tag was already in the defined tags list. * return TRUE otherwise */ int AddFirstTag PARAMS ((definedTags, t), DefinedObj **definedTags _AND_ Type *t) { Tag *tag; TagList *tl; int implicitRef; NamedType *e; tl = t->tags; if (tl != NULL) AsnListFirst (tl); implicitRef = FALSE; for (;;) { /* * get first tag from tag list local to this type if any */ if ((tl != NULL) && (CURR_LIST_NODE (tl) != NULL) && (CURR_LIST_ELMT (tl) != NULL)) { tag = (Tag*) CURR_LIST_ELMT (tl); if (ObjIsDefined (*definedTags, tag, TagObjCmp)) return FALSE; else { DefineObj (definedTags, tag); return TRUE; } } /* * follow tags of referenced types if no tags on this type */ if ((t->basicType->choiceId == BASICTYPE_LOCALTYPEREF) || (t->basicType->choiceId == BASICTYPE_IMPORTTYPEREF)) { if (!implicitRef) implicitRef = t->implicit; if (t->basicType->a.localTypeRef->link == NULL) { /* this should be found in the type link stage */ fprintf (errFileG, "ERROR - unresolved type ref, cannot get tags for decoding\n"); break; } t = t->basicType->a.localTypeRef->link->type; tl = t->tags; if (tl != NULL) { AsnListFirst (tl); /* set curr ptr to first node */ if ((!LIST_EMPTY (tl)) && implicitRef) { AsnListNext (tl); implicitRef = FALSE; } } } /* * if untagged choice and no tags found yet */ else if ((t->basicType->choiceId == BASICTYPE_CHOICE)) { /* * add top level tags from each choice elmt */ if (implicitRef) { fprintf (errFileG, "ERROR - IMPLICITLY Tagged CHOICE\n"); } FOR_EACH_LIST_ELMT (e, t->basicType->a.choice) { if (!AddFirstTag (definedTags, e->type)) return FALSE; } return TRUE; } else /* could be ANY type - assume correct tagging */ return TRUE; } return TRUE; } /* AddFirstTag */ /* * Prints Errors if the field names of the elements are * not distinct. * currently an endless recursion problem here * for recursive types involving CHOICEs - Fixed MS */ void ChkFieldNamesRec PARAMS ((m, td, parent, elmts, fieldNames, followedTypeRefs), Module *m _AND_ TypeDef *td _AND_ Type *parent _AND_ NamedTypeList *elmts _AND_ DefinedObj **fieldNames _AND_ DefinedObj **followedTypeRefs) { NamedType *e; Type *definingType; FOR_EACH_LIST_ELMT (e, elmts) { definingType = ParanoidGetType (e->type); if (e->fieldName != NULL) { if (ObjIsDefined (*fieldNames, e->fieldName, StrObjCmp)) { if (parent->basicType->a.choice == elmts) { PrintErrLoc (m->asn1SrcFileName, (long)e->type->lineNo); fprintf (errFileG, "WARNING - field name \"%s\" is used more than once in same value notation scope.\n", e->fieldName); } else { PrintErrLoc (m->asn1SrcFileName, (long)parent->lineNo); fprintf (errFileG, "WARNING - field name \"%s\" in embedded CHOICE conflicts with field name in type \"%s\".", e->fieldName, td->definedName); fprintf (errFileG, " This may lead to ambiguous value notation.\n"); } /* m->status = MOD_ERROR; */ } else DefineObj (fieldNames, e->fieldName); } /* * must include embedded CHOICE's field names * if it has no field name (this case is a reference to * a CHOICE) (fieldName is NULL) */ else if (((e->type->basicType->choiceId == BASICTYPE_LOCALTYPEREF) || (e->type->basicType->choiceId == BASICTYPE_IMPORTTYPEREF)) && (definingType->basicType->choiceId == BASICTYPE_CHOICE)) { /* stop if this is a recursive ref we have already checked */ if (!ObjIsDefined (*followedTypeRefs, e->type->basicType->a.localTypeRef->typeName, StrObjCmp)) { /* push this type name so we don't go through it again */ DefineObj (followedTypeRefs, e->type->basicType->a.localTypeRef->typeName); /* pass in field type not defining type as parent for line no*/ ChkFieldNamesRec (m, td, e->type, definingType->basicType->a.choice, fieldNames, followedTypeRefs); /* pop this type name since we're done checking it */ UndefineObj (followedTypeRefs, e->type->basicType->a.localTypeRef->typeName, StrObjCmp); } } /* this is an embedded CHOICE definition (fieldName is NULL) */ else if (e->type->basicType->choiceId == BASICTYPE_CHOICE) { ChkFieldNamesRec (m, td, e->type, /* pass in field type for line */ definingType->basicType->a.choice, fieldNames, followedTypeRefs); } } } /* ChkFieldNamesRec */ /* * wrapper for ChkFieldNamesRec * Checks that the field names of an aggregate type (CHOICE/SET/SEQ) * are distinct. Violations are printed to errFileG. */ void ChkFieldNames PARAMS ((m, td, parent, elmts), Module *m _AND_ TypeDef *td _AND_ Type *parent _AND_ NamedTypeList *elmts) { DefinedObj *fieldNames; DefinedObj *followedTypeRefs; fieldNames = NewObjList(); followedTypeRefs = NewObjList(); /* * first define the type itself as followed to prevent * infinintely checking it */ DefineObj (&followedTypeRefs, td->definedName); ChkFieldNamesRec (m, td, parent, elmts, &fieldNames, &followedTypeRefs); FreeDefinedObjs (&fieldNames); FreeDefinedObjs (&followedTypeRefs); } /* ChkFieldNames */ /* * make sure that the identifiers of the named numbers are unique * among themselves. * * also check that the values of the named numbers are unique * among themselves. */ void ChkNamedNumbers PARAMS ((m, t, n), Module *m _AND_ Type *t _AND_ NamedNumberList *n) { DefinedObj *ids; DefinedObj *nums; ValueDef *nn; Value *baseVal; if (n == NULL) return; ids = NewObjList(); nums = NewObjList(); FOR_EACH_LIST_ELMT (nn, n) { if (ObjIsDefined (ids, nn->definedName, StrObjCmp)) { PrintErrLoc (m->asn1SrcFileName, (long)t->lineNo); fprintf (errFileG, "ERROR - named numbers (%s) must have unique identifiers.\n", nn->definedName); } else DefineObj (&ids, nn->definedName); baseVal = GetValue (nn->value); if (baseVal->basicValue->choiceId != BASICVALUE_INTEGER) { PrintErrLoc (m->asn1SrcFileName, (long)t->lineNo); fprintf (errFileG, "ERROR - value format problem (%s)- named numbers must be integers.\n", nn->definedName); } else if (ObjIsDefined (nums, &baseVal->basicValue->a.integer, IntObjCmp)) { PrintErrLoc (m->asn1SrcFileName, (long)t->lineNo); fprintf (errFileG, "ERROR - named numbers (%s) must have unique values.\n", nn->definedName); } else DefineObj (&nums, &baseVal->basicValue->a.integer); } FreeDefinedObjs (&ids); FreeDefinedObjs (&nums); } /* ChkNamedNumbers */ /* * The same as ChkNamedNumbers except that the elmt values must be * > 0 (needed for BIT STRINGs) */ void ChkNamedBits PARAMS ((m, t, n), Module *m _AND_ Type *t _AND_ NamedNumberList *n) { ValueDef *vd; Value *baseVal; ChkNamedNumbers (m, t, n); FOR_EACH_LIST_ELMT (vd, n) { baseVal = GetValue (vd->value); if ((baseVal->basicValue->choiceId == BASICVALUE_INTEGER) && (baseVal->basicValue->a.integer < 0)) { PrintErrLoc (m->asn1SrcFileName, (long)t->lineNo); fprintf (errFileG, "ERROR - named bits (%s) must have positive values.\n", vd->definedName); } } } /* ChkNamedBits */ /* * check that tags on one or more consecutive optional elmts * and following (if any) non-optional elmt are distinct */ void ChkSeqTags PARAMS ((m, td, t), Module *m _AND_ TypeDef *td _AND_ Type *t) { DefinedObj *dO; NamedType *e; if (t->basicType->choiceId != BASICTYPE_SEQUENCE) return; dO = NewObjList(); FOR_EACH_LIST_ELMT (e, t->basicType->a.sequence) { /* if optional add tag */ if (e->type->optional || (e->type->defaultVal != NULL)) { if (!AddFirstTag (&dO, e->type)) { PrintErrLoc (m->asn1SrcFileName, (long)e->type->lineNo); fprintf (errFileG, "ERROR - one or more consecutive optional SEQUENCE elmements and the the following non-optional elmt (if any) must have distinct tags.\n"); m->status = MOD_ERROR; } } else if (dO != NULL) /* first non-opt after opt elmts */ { if (!AddFirstTag (&dO, e->type)) { PrintErrLoc (m->asn1SrcFileName, (long)e->type->lineNo); fprintf (errFileG, "ERROR - one or more consecutive optional SEQUENCE elmements and the the following non-optional elmt (if any) must have distinct tags.\n"); m->status = MOD_ERROR; } FreeDefinedObjs (&dO); dO = NewObjList(); } } FreeDefinedObjs (&dO); td = td; /* AVOIDS Compiler warnings.*/ } /* ChkSeqTags */ esnacc-ng-1.8.1/compiler/core/exports.c000066400000000000000000000077231302010526100177700ustar00rootroot00000000000000/* * compiler/core/exports.c * * ExportElmt list set up during parse. * (not kept in Module data struct) * * SetExports runs through type, value & macro defs and sets the * exported flag accordingly. * * The exportsParsed boolean means whether the symbol "EXPORTS" * was parsed - since if EXPORTS was parsed and the export list * is empty, NOTHING is exported, otherwise if the "EXPORTS" * symbol was not parsed (export list is empty) then EVERYTHING * is exported. If "EXPORTS" was parsed and the list is not * empty, then mark each item is the list as exported and the * rest (that are not in the list) as not exported. * * Mike Sample * 91/09/04 * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/core/exports.c,v 1.7 2004/04/06 15:13:41 gronej Exp $ * $Log: exports.c,v $ * Revision 1.7 2004/04/06 15:13:41 gronej * *** empty log message *** * * Revision 1.6 2003/07/07 14:50:13 nicholar * Eliminated headers and cleaned up include references * * Revision 1.5 2002/12/13 12:17:49 mcphersc * Fixed compiler warning * * Revision 1.4 2002/09/16 16:49:30 mcphersc * Fixed warnings * * Revision 1.3 2002/09/04 18:23:07 vracarl * got rid of c++ comments * * Revision 1.2 2000/10/24 14:54:51 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:36:00 leonberp * First CVS Version of SNACC. * * Revision 1.3 1995/07/25 19:41:27 rj * changed `_' to `-' in file names. * * Revision 1.2 1994/09/01 00:33:28 rj * snacc_config.h removed. * * Revision 1.1 1994/08/28 09:49:08 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include "asn-incl.h" #include "asn1module.h" #include "snacc-util.h" #include "exports.h" /* * called from main in snacc.c to set exported flags for * typeDefs and valueDefs in the given module */ void SetExports PARAMS ((m, e, exportsParsed), Module *m _AND_ ExportElmt *e _AND_ int exportsParsed) { TypeDef *td; ValueDef *vd; if (!exportsParsed) /* export everything */ { /* * set all typedefs', valuedefs' and macrodefs' exported flag */ m->exportStatus = EXPORTS_ALL; FOR_EACH_LIST_ELMT (td, m->typeDefs) { td->exported = TRUE; } FOR_EACH_LIST_ELMT (vd, m->valueDefs) { vd->exported = TRUE; } } else /* EXPORTS sym parsed */ { /* init every exports flag to false */ FOR_EACH_LIST_ELMT (td, m->typeDefs) { td->exported = FALSE; } FOR_EACH_LIST_ELMT (vd, m->valueDefs) { vd->exported = FALSE; } if (e == NULL) /* export nothing */ { m->exportStatus = EXPORTS_NOTHING; } else /* just export types/values in export list */ { m->exportStatus = EXPORTS_SOME; for (; e != NULL; e = e->next) { if ((td = LookupType (m->typeDefs, e->name)) != NULL) td->exported = TRUE; else if ((vd = LookupValue (m->valueDefs, e->name)) != NULL) vd->exported = TRUE; else { PrintErrLoc (m->asn1SrcFileName, (long)e->lineNo); fprintf (errFileG, "ERROR - exporting undefined type/value \"%s\"\n", e->name); } } } } } /* SetExports */ esnacc-ng-1.8.1/compiler/core/exports.h000066400000000000000000000035421302010526100177700ustar00rootroot00000000000000/* * compiler/core/exports.h - * * ExportElmt list set up during parse. * (not kept in Module data struct) * * SetExports runs through type, value & macro defs and sets the * exports flag accordingly. * * the exportsParsed boolean means whether the symbol "EXPORTS" * was parsed - since if EXPORTS was parsed and the export list * is empty, NOTHING is exported, otherwise if the "EXPORTS" * symbol was not parsed (export list is empty) then EVERYTHING * is exported * * Mike Sample * 91/09/04 * * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/core/exports.h,v 1.2 2001/07/12 19:34:28 leonberp Exp $ * $Log: exports.h,v $ * Revision 1.2 2001/07/12 19:34:28 leonberp * Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. * * Revision 1.1.1.1 2000/08/21 20:36:00 leonberp * First CVS Version of SNACC. * * Revision 1.2 1994/10/08 03:48:43 rj * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long. * * Revision 1.1 1994/08/28 09:49:09 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ typedef struct ExportElmt { char *name; long int lineNo; struct ExportElmt *next; } ExportElmt; void SetExports PROTO ((Module *m, ExportElmt *e, int exportsParsed)); esnacc-ng-1.8.1/compiler/core/gen-tbls.c000066400000000000000000000453271302010526100200010ustar00rootroot00000000000000/* * compiler/core/gen_tbls.c * * generates type tables and writes them to a file. * * MS * 93/02/07 * * Copyright (C) 1993 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/core/gen-tbls.c,v 1.8 2004/01/14 19:07:52 gronej Exp $ * $Log: gen-tbls.c,v $ * Revision 1.8 2004/01/14 19:07:52 gronej * Updated Compiler to accept and process relative-oid's * * Revision 1.7 2003/07/14 21:07:43 nicholar * Changed how parser handles --snacc directives. Added namespace option. * * Revision 1.6 2003/07/07 14:50:13 nicholar * Eliminated headers and cleaned up include references * * Revision 1.5 2002/12/05 15:16:26 nicholar * Fixed GenTypeTbls() to use GenBuf. * * Revision 1.4 2002/09/16 16:49:46 mcphersc * iFixed warnings * * Revision 1.3 2002/09/04 18:23:07 vracarl * got rid of c++ comments * * Revision 1.2 2000/10/24 14:54:51 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:36:00 leonberp * First CVS Version of SNACC. * * Revision 1.5 1997/06/19 09:17:16 wan * Added isPdu flag to tables. Added value range checks during parsing. * * Revision 1.4 1997/05/07 15:18:34 wan * Added (limited) size constraints, bitstring and enumeration names to tables * * Revision 1.3 1995/07/25 19:41:28 rj * changed `_' to `-' in file names. * * Revision 1.2 1994/09/01 00:33:41 rj * snacc_config.h removed. * * Revision 1.1 1994/08/28 09:49:10 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include #include "asn-incl.h" #include "asn1module.h" #include "tbl.h" int FlattenLinkedOid PARAMS ((o, asn1FileName, lineNo, quiet), OID *o _AND_ char *asn1FileName _AND_ AsnInt lineNo _AND_ int quiet); extern FILE* errFileG; // Defined in snacc.c const char* GetDirectiveName(SnaccDirectiveEnum dirType); /* non-exported routine protos */ void GenTypeDefIds PROTO ((TBL *tbl, Module *m)); int GenTblModule PROTO ((TBL *tbl, Module *m, TBLModule **newTbl)); int GenTblTypeDefs PROTO ((TBL *tbl, Module *m, TBLModule *tblMod)); int GenTblTypes PROTO ((TBL *tbl, Module *m, TBLModule *tblMod, TypeDef *td, TBLTypeDef *tblTd)); TBLType *GenTblTypesRec PROTO ((TBL *tbl,Module *m, TBLModule *tblMod, TypeDef *td, TBLTypeDef *tblTd, Type *t)); static int abortTblTypeDefG; static int tblTypesTotalG; static int tblTagsTotalG; static int tblStringsTotalG; static int tblStringLenTotalG; static int tableFileVersionG; void GenTypeTbls PARAMS ((mods, fileName, tableFileVersion), ModuleList *mods _AND_ char *fileName _AND_ int tableFileVersion) { TBL tbl; TBLModule *newTblMod; FILE *tblFile; GenBuf *buf; ExpBuf *expBuf, *tmpBuf; Module *m; tableFileVersionG = tableFileVersion; tbl.modules = AsnListNew (sizeof (void*)); tbl.totalNumModules = 0; tbl.totalNumTypeDefs = 0; tbl.totalNumTypes = 0; tbl.totalNumTags = 0; tbl.totalNumStrings = 0; tbl.totalLenStrings = 0; /* * Give each type def a unique id * Id is stored in TypeDef's "tmpRefCount" since * it was only used in the recursion pass. * Also updates tbl.totalNumModules and * tbl.totalNumTypeDefs appropriately */ FOR_EACH_LIST_ELMT (m, mods) { GenTypeDefIds (&tbl, m); } /* convert each module from parse format to simpler table format */ FOR_EACH_LIST_ELMT (m, mods) { if (!GenTblModule (&tbl, m, &newTblMod)) { fprintf (errFileG, "ERROR: type table generator failed for module \"%s\", so file \"%s\" will not be written.\n", m->modId->name, fileName); return; } } /* encode the TBLModules */ ExpBufInit (1024); expBuf = ExpBufAllocBufAndData(); ExpBuftoGenBuf(expBuf, &buf); BEncTBL (buf, &tbl); if (GenBufWriteError (buf)) { fprintf (errFileG, "ERROR: buffer write error during encoding of type table.\n"); ExpBufFreeBufAndDataList(expBuf); GenBufFree(buf); return; } /* open & truncate or create as file with given filename */ tblFile = fopen (fileName,"w"); if (tblFile == NULL) { fprintf (errFileG, "ERROR: Could not open file \"%s\" for the type table.\n", fileName); ExpBufFreeBufAndDataList(expBuf); GenBufFree(buf); return; } /* * go through buffer (s) and write encoded value * to opened file */ expBuf = ExpBufListFirstBuf(expBuf); for (tmpBuf = expBuf; tmpBuf != NULL; tmpBuf = tmpBuf->next) { fwrite (tmpBuf->dataStart, tmpBuf->dataEnd - tmpBuf->dataStart, 1, tblFile); } fclose (tblFile); ExpBufFreeBufAndDataList(expBuf); GenBufFree(buf); } /* GenTypeTbls */ /* * The typeDefIds start at zero. They are used as "portable" * pointers. Each TBLTypeDef has a unique typeDefId. * The typeDefIds in a given TBLModule will be consecutive * and increasing from the first typedef to the last. * * This routine gives each type def in the given module a unique * integer identifier. * This id is temporarily stored in the tmpRefCount field of the TypeDef * (in the big parse tree). The typeDefId is transfered * to the TBL data structure after this. * * tbl.totalNumModules and tbl.totalNumTypeDefs are updated. * * ASSUMES: that tbl->totalNumModules is initialized to zero * and that tbl->totalNumTypeDefs is initialized to zero * on the first call to this routine. * This allows subsequent calls to give out the proper ids * to the types in the next module. * * (the type ids range from 0 to tbl->totalNumTypeDefs-1 (inclusive)) */ void GenTypeDefIds PARAMS ((tbl,m), TBL *tbl _AND_ Module *m) { TypeDef *td; tbl->totalNumModules++; FOR_EACH_LIST_ELMT (td, m->typeDefs) { td->tmpRefCount = tbl->totalNumTypeDefs; tbl->totalNumTypeDefs++; } } /* GenTypeDefIds */ /* * builds a TBLModule from the given module and appends it to * the given TBL's module list. Also updates the TBLs * totals for modules, tags, typedefs and types. * Returns TRUE is succeeded. FALSE is failed. */ int GenTblModule PARAMS ((tbl, m, newTblMod), TBL *tbl _AND_ Module *m _AND_ TBLModule **newTblMod) { TBLModule **mHndl; TBLModule *tblMod; int eLen; mHndl = AsnListAppend (tbl->modules); tblMod = MT (TBLModule); *newTblMod = *mHndl = tblMod; /* copy the name */ tblMod->name.octetLen = strlen (m->modId->name); tblMod->name.octs = Malloc (tblMod->name.octetLen + 1); strcpy (tblMod->name.octs, m->modId->name); tbl->totalNumStrings++; tbl->totalLenStrings += tblMod->name.octetLen; /* copy the OBJECT IDENTIFIER (if any) */ if (m->modId->oid != NULL) { /* convert the (linked) OID into a (encoded) AsnOid */ /* RWC;10/16/00; UPDATED NULL,0,0 to avoid compiler error after proto added (??? UNTESTED ???).*/ if (FlattenLinkedOid (m->modId->oid, NULL, 0, 0 )) { eLen = EncodedOidLen (m->modId->oid); tblMod->id.octetLen = eLen; tblMod->id.octs = (char*)Malloc (eLen); BuildEncodedOid (m->modId->oid, &tblMod->id); tbl->totalNumStrings++; tbl->totalLenStrings += eLen; } } /* * useful defaults to false * (ie assume the it is not the usefultypes modules) */ tblMod->isUseful = FALSE; /* now copy each of the type defs */ return GenTblTypeDefs (tbl, m, tblMod); } /* GenTblModule */ /* * converts typeDefs in Module format to TBLModule format * returns TRUE for success, FALSE for failure. */ int GenTblTypeDefs PARAMS ((tbl, m, tblMod), TBL *tbl _AND_ Module *m _AND_ TBLModule *tblMod) { TypeDef *td; TBLTypeDef **tblTdHndl; TBLTypeDef *tblTd; SnaccDirective* pDirective; int isOk = TRUE; /* init to no errors */ tblMod->typeDefs = AsnListNew (sizeof (void*)); FOR_EACH_LIST_ELMT (td, m->typeDefs) { tblTd = MT (TBLTypeDef); /* set type def id */ tblTd->typeDefId = td->tmpRefCount; /* copy type def name */ tblTd->typeName.octetLen = strlen (td->definedName); tblTd->typeName.octs = Malloc (tblTd->typeName.octetLen + 1); strcpy (tblTd->typeName.octs, td->definedName); tbl->totalNumStrings++; tbl->totalLenStrings += tblTd->typeName.octetLen; /* if (td->isPdu) tblTd->isPdu = MT (AsnNull); */ FOR_EACH_LIST_ELMT (pDirective, td->attrList) { switch (pDirective->type) { case IsPtr: /* pDirective->value.boolVal; Nothing to set this to! */ break; default: fprintf (errFileG, "Warning: ignoring unrecognized type def attribute '%s'\n", GetDirectiveName(pDirective->type)); } } /* fill in type portion */ if (!GenTblTypes (tbl, m, tblMod, td, tblTd) && !abortTblTypeDefG) isOk = FALSE; /* * add TBLtypeDef to TBLModule * if no weird types were found * (weird types are skipped) */ if (!abortTblTypeDefG) { tblTdHndl = AsnListAppend (tblMod->typeDefs); *tblTdHndl = tblTd; tbl->totalNumTypes += tblTypesTotalG; tbl->totalNumTags += tblTagsTotalG; tbl->totalNumStrings += tblStringsTotalG; tbl->totalLenStrings += tblStringLenTotalG; } /* else could free it */ } return isOk; } /* GenTblTypeDefs */ /* * converts Module Type to a TBLModule Type. attaches converted * type info to the given tblTd. * Returns TRUE for success, FALSE for failure. */ int GenTblTypes PARAMS ((tbl, m, tblMod, td, tblTd), TBL *tbl _AND_ Module *m _AND_ TBLModule *tblMod _AND_ TypeDef *td _AND_ TBLTypeDef *tblTd) { abortTblTypeDefG = FALSE; tblTypesTotalG = 0; tblTagsTotalG = 0; tblStringsTotalG = 0; tblStringLenTotalG = 0; tblTd->type = GenTblTypesRec (tbl, m, tblMod, td, tblTd, td->type); if (tblTd->type == NULL) return FALSE; /* failed */ else return TRUE; } /* GenTblTypes */ BasicValue* GetTblValue PARAMS ((v), Value* v) { switch (v->basicValue->choiceId) { case BASICVALUE_INTEGER: return v->basicValue; default: return NULL; } } enum BasicTypeChoiceId GetTblBasicType PARAMS ((bt), BasicType* bt) { switch (bt->choiceId) { case BASICTYPE_LOCALTYPEREF: case BASICTYPE_IMPORTTYPEREF: return GetTblBasicType (bt->a.localTypeRef->link->type->basicType); default: return bt->choiceId; } } TBLType* GenTblTypesRec PARAMS ((tbl, m, tblMod, td, tblTd, t), TBL *tbl _AND_ Module *m _AND_ TBLModule *tblMod _AND_ TypeDef *td _AND_ TBLTypeDef *tblTd _AND_ Type *t) { TBLType *tblT; NamedType *e; TBLType **tblTHndl; Tag *tag; TBLTag **tblTagHndl; tblTypesTotalG++; tblT = MT (TBLType); tblT->content = MT (TBLTypeContent); switch (t->basicType->choiceId) { case BASICTYPE_BOOLEAN: tblT->typeId = TBL_BOOLEAN; tblT->content->choiceId = TBLTYPECONTENT_PRIMTYPE; break; case BASICTYPE_INTEGER: tblT->typeId = TBL_INTEGER; tblT->content->choiceId = TBLTYPECONTENT_PRIMTYPE; break; case BASICTYPE_BITSTRING: tblT->typeId = TBL_BITSTRING; tblT->content->choiceId = TBLTYPECONTENT_PRIMTYPE; /* tblT->values = GenTblValues(tbl,m,tblMod,t->basicType->a.bitString); */ break; case BASICTYPE_OCTETSTRING: tblT->typeId = TBL_OCTETSTRING; tblT->content->choiceId = TBLTYPECONTENT_PRIMTYPE; /* if (t->subtypes) tblT->constraint = GenTblValueRange(tbl, m, tblMod,t->subtypes,1); */ break; case BASICTYPE_NULL: tblT->typeId = TBL_NULL; tblT->content->choiceId = TBLTYPECONTENT_PRIMTYPE; break; case BASICTYPE_OID: tblT->typeId = TBL_OID; tblT->content->choiceId = TBLTYPECONTENT_PRIMTYPE; break; case BASICTYPE_RELATIVE_OID: tblT->typeId = TBL_RELATIVE_OID; tblT->content->choiceId = TBLTYPECONTENT_PRIMTYPE; break; case BASICTYPE_REAL: tblT->typeId = TBL_REAL; tblT->content->choiceId = TBLTYPECONTENT_PRIMTYPE; break; case BASICTYPE_ENUMERATED: tblT->typeId = TBL_ENUMERATED; tblT->content->choiceId = TBLTYPECONTENT_PRIMTYPE; /* tblT->values = GenTblValues(tbl,m,tblMod,t->basicType->a.enumerated); */ break; case BASICTYPE_SEQUENCE: tblT->typeId = TBL_SEQUENCE; tblT->content->choiceId = TBLTYPECONTENT_ELMTS; tblT->content->a.elmts = AsnListNew (sizeof (void*)); FOR_EACH_LIST_ELMT (e, t->basicType->a.sequence) { tblTHndl = AsnListAppend (tblT->content->a.elmts); *tblTHndl = GenTblTypesRec (tbl, m, tblMod, td, tblTd, e->type); if (*tblTHndl == NULL) break; if (e->fieldName != NULL) { (**tblTHndl).fieldName.octetLen = strlen (e->fieldName); (**tblTHndl).fieldName.octs = Malloc ((**tblTHndl).fieldName.octetLen + 1); strcpy ((**tblTHndl).fieldName.octs, e->fieldName); tblStringsTotalG++; tblStringLenTotalG += (**tblTHndl).fieldName.octetLen; } (**tblTHndl).optional = (unsigned char) ((e->type->optional) || (e->type->defaultVal != NULL)); } break; case BASICTYPE_SET: tblT->typeId = TBL_SET; tblT->content->choiceId = TBLTYPECONTENT_ELMTS; tblT->content->a.elmts = AsnListNew (sizeof (void*)); FOR_EACH_LIST_ELMT (e, t->basicType->a.set) { tblTHndl = AsnListAppend (tblT->content->a.elmts); *tblTHndl = GenTblTypesRec (tbl, m, tblMod, td, tblTd, e->type); if (*tblTHndl == NULL) break; if (e->fieldName != NULL) { (**tblTHndl).fieldName.octetLen = strlen (e->fieldName); (**tblTHndl).fieldName.octs = Malloc ((**tblTHndl).fieldName.octetLen + 1); strcpy ((**tblTHndl).fieldName.octs, e->fieldName); tblStringsTotalG++; tblStringLenTotalG += (**tblTHndl).fieldName.octetLen; } (**tblTHndl).optional = (unsigned char) ((e->type->optional) || (e->type->defaultVal != NULL)); } break; case BASICTYPE_SEQUENCEOF: tblT->typeId = TBL_SEQUENCEOF; tblT->content->choiceId = TBLTYPECONTENT_ELMTS; tblT->content->a.elmts = AsnListNew (sizeof (void*)); tblTHndl = AsnListAppend (tblT->content->a.elmts); *tblTHndl = GenTblTypesRec (tbl, m, tblMod, td, tblTd, t->basicType->a.sequenceOf); /* if (t->subtypes) tblT->constraint = GenTblValueRange(tbl, m, tblMod,t->subtypes,1); */ break; case BASICTYPE_SETOF: tblT->typeId = TBL_SETOF; tblT->content->choiceId = TBLTYPECONTENT_ELMTS; tblT->content->a.elmts = AsnListNew (sizeof (void*)); tblTHndl = AsnListAppend (tblT->content->a.elmts); *tblTHndl = GenTblTypesRec (tbl, m, tblMod, td, tblTd, t->basicType->a.setOf); /* if (t->subtypes) tblT->constraint = GenTblValueRange(tbl, m, tblMod,t->subtypes,1); */ break; case BASICTYPE_CHOICE: tblT->typeId = TBL_CHOICE; tblT->content->choiceId = TBLTYPECONTENT_ELMTS; tblT->content->a.elmts = AsnListNew (sizeof (void*)); FOR_EACH_LIST_ELMT (e, t->basicType->a.set) { tblTHndl = AsnListAppend (tblT->content->a.elmts); *tblTHndl = GenTblTypesRec (tbl, m, tblMod, td, tblTd, e->type); if (*tblTHndl == NULL) break; if (e->fieldName != NULL) { (**tblTHndl).fieldName.octetLen = strlen (e->fieldName); (**tblTHndl).fieldName.octs = Malloc ((**tblTHndl).fieldName.octetLen + 1); strcpy ((**tblTHndl).fieldName.octs, e->fieldName); tblStringsTotalG++; tblStringLenTotalG += (**tblTHndl).fieldName.octetLen; } (**tblTHndl).optional = (unsigned char) ((e->type->optional) || (e->type->defaultVal != NULL)); } break; case BASICTYPE_LOCALTYPEREF: case BASICTYPE_IMPORTTYPEREF: tblT->typeId = TBL_TYPEREF; tblT->content->choiceId = TBLTYPECONTENT_TYPEREF; tblT->content->a.typeRef = MT (TBLTypeRef); tblT->content->a.typeRef->implicit = t->implicit; tblT->content->a.typeRef->typeDef = t->basicType->a.localTypeRef->link->tmpRefCount; break; default: if (!abortTblTypeDefG) /* only print first time */ { fprintf (errFileG, "WARNING: Type definition \"%s\" will not be included in the type table because it contains a weird type.\n", td->definedName); } abortTblTypeDefG = TRUE; Free (tblT->content); Free (tblT); tblT = NULL; break; } /* handle constraints */ if (t->subtypes) { switch (GetTblBasicType(t->basicType)) { case BASICTYPE_INTEGER: /* tblT->constraint = GenTblValueRange(tbl,m,tblMod,t->subtypes,0); */ break; case BASICTYPE_OCTETSTRING: case BASICTYPE_SEQUENCEOF: /* tblT->constraint = GenTblValueRange(tbl,m,tblMod,t->subtypes,1); */ break; default: break; } } /* copy the tags */ if ((tblT != NULL) && ((t->tags != NULL) && (!LIST_EMPTY (t->tags)))) { tblT->tagList = AsnListNew (sizeof (void*)); FOR_EACH_LIST_ELMT (tag, t->tags) { tblTagsTotalG++; tblTagHndl = AsnListAppend (tblT->tagList); *tblTagHndl = MT (TBLTag); switch (tag->tclass) { case UNIV: (**tblTagHndl).tclass = UNIVERSAL; break; case APPL: (**tblTagHndl).tclass = APPLICATION; break; case CNTX: (**tblTagHndl).tclass = CONTEXT; break; case PRIV: (**tblTagHndl).tclass = PRIVATE; break; } (**tblTagHndl).code = tag->code; } } return tblT; } /* GenTblTypesRec */ esnacc-ng-1.8.1/compiler/core/gfsi.c000066400000000000000000000115771302010526100172160ustar00rootroot00000000000000#include #include #include #include #if defined(WIN32) || defined(WIN16) #pragma warning(disable: 4115) #include #include #include #include #include #else #include #include #include #include #endif #ifndef WIN32 static char *striEnd(const char *string1, const char *string2); #endif typedef void * GFSI_HANDLE; /* Generic File System Interface (GFSI) */ // GFSI_GetFirstFile: // PURPOSE: Returns first file in a path // char *GFSI_GetFirstFile(GFSI_HANDLE *gfsi_handle, const char *path, const char *extension) { char *fn = NULL; #ifdef WIN32 char real_path[256]; WIN32_FIND_DATA findData; *gfsi_handle = NULL; if (extension == NULL) sprintf(real_path,"%s\\*.*",path); else sprintf(real_path,"%s\\*.%s", path, extension); do { if (fn == NULL) *gfsi_handle = (GFSI_HANDLE) FindFirstFile(real_path, &findData); else FindNextFile((HANDLE) *gfsi_handle, &findData); if (*gfsi_handle != NULL && (int) *gfsi_handle != -1) { if(fn != NULL) free(fn); fn = strdup(findData.cFileName); } } while ((gfsi_handle != INVALID_HANDLE_VALUE) && (findData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)); #else struct dirent *dirEntry = NULL; *gfsi_handle = NULL; *gfsi_handle = (GFSI_HANDLE) opendir(path); if (*gfsi_handle != NULL) { if (extension != NULL) { while ((dirEntry = readdir( (DIR *) *gfsi_handle)) != NULL) { fn = striEnd(dirEntry->d_name, extension); if (fn != NULL) { fn = strdup(dirEntry->d_name); break; } } } else { while ((dirEntry = readdir( (DIR *) *gfsi_handle)) != NULL) { fn = dirEntry->d_name; if ((fn != NULL) && (strcmp(fn,".") != 0) && (strcmp(fn, "..") != 0)) { fn = strdup(dirEntry->d_name); break; } } } } #endif return fn; } // END OF FUNCTION GFSI_GetFirstFile // GFSI_GetNextFile: // PURPOSE: Returns next file in a path // char *GFSI_GetNextFile( GFSI_HANDLE *gfsi_handle, const char *extension) { char *fn = NULL; #ifdef WIN32 WIN32_FIND_DATA findData; char bDone = FALSE; extension = extension; // NOTE: We ignore the extension paramater for the WIN32 Case do { if (FindNextFile((HANDLE) *gfsi_handle, &findData)) { if (findData.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY) fn = strdup(findData.cFileName); } else { bDone = TRUE; } } while (!bDone && (fn == NULL)); #else struct dirent *dirEntry = NULL; if (extension != NULL) { while ((dirEntry = readdir( (DIR *) *gfsi_handle)) != NULL) { fn = striEnd(dirEntry->d_name, extension); if (fn != NULL) { fn = strdup(dirEntry->d_name); break; } } } else { if ((dirEntry = readdir( (DIR *) *gfsi_handle)) != NULL) { fn = strdup(dirEntry->d_name); } } #endif return fn; } // END OF FUNCTION GFSI_GetNextFile // GFSI_Close: // void GFSI_Close( GFSI_HANDLE *gfsi_handle ) { #ifdef WIN32 FindClose((HANDLE) *gfsi_handle); #else if (*gfsi_handle != NULL) { closedir((DIR *) *gfsi_handle); } #endif } // END OF FUNCTION GFSI_Close long findFileSize(char *fileName) { struct stat buf; int result; /* Get data associated with "stat.c": */ result = stat(fileName, &buf); /* Check if statistics are valid: */ if (result != 0) return 0; else return(buf.st_size); } #ifndef WIN32 static char *striEnd(const char *string1, const char *string2) { /* The striEnd function performs a case-insensitive comparison of the two strings in reverse (starting from the ends). The function returns a pointer to the occurrence of string2 within string1, only if it occurs at the end of string1. This function returns NULL if string2 does not occur at the end of string1 or if string1 or string2 is of 0 length. For example: string1 = "The quick brown fox jumped over the lazy dog" string2 = "Lazy Dog" result = "lazy dog" (in string1) */ long len1, len2, x; char c1, c2; if ((string1 == NULL) || (string2 == NULL)) return NULL; len1 = strlen(string1); len2 = strlen(string2); if ((len1 == 0) || (len2 == 0) || (len2 > len1)) return NULL; x = 1; do { c1 = string1[len1 - x]; if ((c1 >= 'A') && (c1 <= 'Z')) c1 += 'a' - 'A'; c2 = string2[len2 - x]; if ((c2 >= 'A') && (c2 <= 'Z')) c2 += 'a' - 'A'; } while ((c1 == c2) && (len2 > x++)); if (c1 == c2) return (char *)&string1[len1 - len2]; else return NULL; } /* end of striEnd() */ #endif // EOF acl_FileFuncs.cpp esnacc-ng-1.8.1/compiler/core/lex-asn1.l000066400000000000000000000534231302010526100177230ustar00rootroot00000000000000/* compiler/core/lex-asn1.l */ /* AUTHOR: Mike Sample */ /* DATE: 91/92 */ /* Copyright (C) 1991, 1992 Michael Sample */ /* and the University of British Columbia */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* these comments must only be a single line each - lex blows it otherwise */ /* due to this claim, the rcs log is at the end of this file. */ /* $Header: /baseline/SNACC/compiler/core/lex-asn1.l,v 1.14 2004/03/25 19:20:16 gronej Exp $ */ /* This lex spec should compile under either lex or flex. */ /* There arGe three modes to the lexical analyzer, INITIAL, MACRO_DEF, */ /* and BRACE_BAL. INITIAL is the normal mode. MACRO_DEF is used by */ /* a lexical tie-in from the yacc code to eat a MACRO DEFINTION as a */ /* single blk of text. BRACE_BAL is used to by a lexical tie-in for */ /* eating values inside { }'s. */ /* if your ASN.1 source file has control characters that cause */ /* snacc to choke, use a program like 'tr' to condition them first. */ %{ #include "config.h" #include #include #include "asn-incl.h" #include "asn1module.h" #include "exports.h" #include "y.tab.h" /* defines the returned token values */ #include "lex-stuff.h" unsigned long int myLineNoG = 0; %} %s COMMENT MACRO_DEF BRACE_BAL SNACC_ATTRIBS %option noyywrap WHITESPC [ \t\n\r] %% "[C]" return BOXC_SYM; "[S]" return BOXS_SYM; {WHITESPC}+ { COUNT_NEWLINES (myLineNoG, yytext);} "..." return ELLIPSIS_SYM; "." return DOT_SYM; "," return COMMA_SYM; "{" return LEFTBRACE_SYM; "}" return RIGHTBRACE_SYM; "(" return LEFTPAREN_SYM; ")" return RIGHTPAREN_SYM; "[" return LEFTBRACKET_SYM; "]" return RIGHTBRACKET_SYM; "<" return LESSTHAN_SYM; "-" return MINUS_SYM; "::=" return GETS_SYM; "|" return BAR_SYM; ";" return SEMI_COLON_SYM; ":" return COLON_SYM; TAGS return TAGS_SYM; BOOLEAN return BOOLEAN_SYM; INTEGER return INTEGER_SYM; BIT return BIT_SYM; STRING return STRING_SYM; OCTET return OCTET_SYM; CONTAINING return CONTAINING_SYM; ENCODED return ENCODED_SYM; NULL return NULL_SYM; SEQUENCE return SEQUENCE_SYM; OF return OF_SYM; SET return SET_SYM; IMPLICIT return IMPLICIT_SYM; CHOICE return CHOICE_SYM; ANY return ANY_SYM; OBJECT{WHITESPC}*IDENTIFIER { COUNT_NEWLINES (myLineNoG, yytext); return OBJECT_IDENTIFIER_SYM;} RELATIVE-OID { COUNT_NEWLINES (myLineNoG, yytext); return RELATIVE_OID_SYM;} OPTIONAL return OPTIONAL_SYM; DEFAULT return DEFAULT_SYM; COMPONENTS return COMPONENTS_SYM; UNIVERSAL return UNIVERSAL_SYM; APPLICATION return APPLICATION_SYM; PRIVATE return PRIVATE_SYM; TRUE return TRUE_SYM; FALSE return FALSE_SYM; BEGIN return BEGIN_SYM; END return END_SYM; DEFINITIONS return DEFINITIONS_SYM; EXPLICIT return EXPLICIT_SYM; ENUMERATED return ENUMERATED_SYM; EXPORTS return EXPORTS_SYM; EXTERNAL return EXTERNAL_SYM; IMPORTS return IMPORTS_SYM; REAL return REAL_SYM; INCLUDES return INCLUDES_SYM; MIN return MIN_SYM; MAX return MAX_SYM; SIZE return SIZE_SYM; FROM return FROM_SYM; WITH return WITH_SYM; COMPONENT return COMPONENT_SYM; PRESENT return PRESENT_SYM; ABSENT return ABSENT_SYM; DEFINED return DEFINED_SYM; BY return BY_SYM; PLUS-INFINITY return PLUS_INFINITY_SYM; MINUS-INFINITY return MINUS_INFINITY_SYM; AUTOMATIC return AUTOMATIC_SYM; NumericString return NUMERICSTRING_SYM; PrintableString return PRINTABLESTRING_SYM; IA5String return IA5STRING_SYM; BMPString return BMPSTRING_SYM; UniversalString return UNIVERSALSTRING_SYM; UTF8String return UTF8STRING_SYM; TeletexString return TELETEXSTRING_SYM; T61String return T61STRING_SYM; VideotexString return VIDEOTEXSTRING_SYM; GraphicString return GRAPHICSTRING_SYM; ISO646String return ISO646STRING_SYM; VisibleString return VISIBLESTRING_SYM; GeneralString return GENERALSTRING_SYM; GeneralizedTime return GENERALIZEDTIME_SYM; UTCTime return UTCTIME_SYM; ObjectDescriptor return OBJECTDESCRIPTOR_SYM; (.|\n) { int i; char *buf; int bufSize; int inComment; int inStr; unsigned int c, c1, c2; /* * matches any first char, then * copies everything until an uncommented, * unquoted END. This Lex state is started * from the yacc src (lexical tie in) * from the MACRO_DEF production. * * if you don't like realloc and don't care about * macro defs just have this return a constant string * like "BEGIN END" after eating the definition */ unput (yytext[0]); bufSize = 1024; buf = Malloc (1024); i = 0; /* put BEGIN str at beginning */ buf[i++] = 'B'; buf[i++] = 'E'; buf[i++] = 'G'; buf[i++] = 'I'; buf[i++] = 'N'; buf[i++] = '\n'; inStr = FALSE; inComment = FALSE; for ( ; ; i++) { c = input(); if (i >= (bufSize - 4)) { bufSize += 512; buf = (char*) Realloc (buf, bufSize); } buf[i] = (char)c; if ((inComment) && (c == '\n')) inComment = FALSE; else if (!(inStr) && (c == '-')) { c = input(); if (c == '-') { buf[++i] = (char)c; inComment = !inComment; } else unput (c); } else if (inComment) continue; else if (c == '"') inStr = !inStr; else if (inStr) continue; else if (c == 'E') { c1 = input(); c2 = input(); if ((c1 == 'N') && (c2 == 'D')) { buf[++i] = 'N'; buf[++i] = 'D'; buf[++i] = '\0'; yylval.charPtr = buf; COUNT_NEWLINES (myLineNoG, buf); myLineNoG -=1; /* take off 1 added after "BEGIN" */ return MACRODEFBODY_SYM; } else { unput (c2); unput (c1); } } } /* not reached */ } [A-Z](-[A-Z0-9]|[A-Z0-9])*{WHITESPC}*MACRO { int i; /* copy and return the Macro's name only */ /* doesn't handle comments between macro name and MACRO sym */ for (i = 0; (yytext[i] != ' ') && (yytext[i] != '\t') && (yytext[i] != '\n') && (yytext[i] != '\r'); i++); yylval.charPtr = Malloc (i+1); strncpy (yylval.charPtr, yytext, i); yylval.charPtr[i] = '\0'; return NAMEDMACRO_SYM; } OPERATION return OPERATION_SYM; ARGUMENT return ARGUMENT_SYM; RESULT return RESULT_SYM; ERRORS return ERRORS_SYM; LINKED return LINKED_SYM; ERROR return ERROR_SYM; PARAMETER return PARAMETER_SYM; BIND return BIND_SYM; BIND-ERROR return BINDERROR_SYM; UNBIND return UNBIND_SYM; UNBIND-ERROR return UNBINDERROR_SYM; APPLICATION-CONTEXT return AC_SYM; APPLICATION-SERVICE-ELEMENTS return ASES_SYM; REMOTE return REMOTE_SYM; INITIATOR return INITIATOR_SYM; RESPONDER return RESPONDER_SYM; ABSTRACT{WHITESPC}*SYNTAXES { COUNT_NEWLINES (myLineNoG, yytext); return ABSTRACTSYNTAXES_SYM;} APPLICATION-SERVICE-ELEMENT return ASE_SYM; OPERATIONS return OPERATIONS_SYM; CONSUMER{WHITESPC}*INVOKES { COUNT_NEWLINES (myLineNoG, yytext); return CONSUMERINVOKES_SYM;} SUPPLIER{WHITESPC}*INVOKES { COUNT_NEWLINES (myLineNoG, yytext); return SUPPLIERINVOKES_SYM;} EXTENSION-ATTRIBUTE return EXTENSIONATTRIBUTE_SYM; EXTENSIONS return EXTENSIONS_SYM; CHOSEN return CHOSEN_SYM; EXTENSION return EXTENSION_SYM; CRITICAL return CRITICAL_SYM; FOR return FOR_SYM; SUBMISSION return SUBMISSION_SYM; DELIVERY return DELIVERY_SYM; TRANSFER return TRANSFER_SYM; OBJECT return OBJECT_SYM; PORTS return PORTS_SYM; PORT return PORT_SYM; ABSTRACT{WHITESPC}*OPERATIONS { COUNT_NEWLINES (myLineNoG, yytext); return ABSTRACTOPS_SYM;} REFINE return REFINE_SYM; AS return AS_SYM; RECURRING return RECURRING_SYM; VISIBLE return VISIBLE_SYM; PAIRED return PAIRED_SYM; ABSTRACT-BIND return ABSTRACTBIND_SYM; TO return TO_SYM; ABSTRACT-UNBIND return ABSTRACTUNBIND_SYM; ABSTRACT-ERROR return ABSTRACTERROR_SYM; ABSTRACT-OPERATION return ABSTRACTOPERATION_SYM; TOKEN return TOKEN_SYM; TOKEN-DATA return TOKENDATA_SYM; SECURITY-CATEGORY return SECURITYCATEGORY_SYM; ALGORITHM return ALGORITHM_SYM; ENCRYPTED return ENCRYPTED_SYM; SIGNED return SIGNED_SYM; SIGNATURE return SIGNATURE_SYM; PROTECTED return PROTECTED_SYM; OBJECT-TYPE return OBJECTTYPE_SYM; SYNTAX return SYNTAX_SYM; ACCESS return ACCESS_SYM; STATUS return STATUS_SYM; DESCRIPTION return DESCRIPTION_SYM; REFERENCE return REFERENCE_SYM; INDEX return INDEX_SYM; DEFVAL return DEFVAL_SYM; (.|\n) { int i; char *buf; int bufSize; int inComment; int inStr; int braceDepth; char c; /* * matches any first char, then * copies everything until an ending "}" * Assumes that initially parsed a "{" * and puts one at beg. of returned string */ unput (yytext[0]); bufSize = 256; buf = Malloc (256); i = 0; /* put openning brace at beginning */ buf[i++] = '{'; buf[i++] = ' '; inStr = FALSE; inComment = FALSE; braceDepth = 1; for ( ; ; i++) { c = (char)input(); if (i >= (bufSize - 2)) { bufSize += 256; buf = (char*) Realloc (buf, bufSize); } buf[i] = c; if ((inComment) && (c == '\n')) inComment = FALSE; else if (!(inStr) && (c == '-')) { c = (char)input(); if (c == '-') { buf[++i] = c; inComment = !inComment; } else unput (c); } else if (inComment) continue; else if (c == '"') inStr = !inStr; else if (inStr) continue; else if (c == '{') braceDepth++; else if (c == '}') { braceDepth--; if (braceDepth == 0) { buf[++i] = '\0'; yylval.charPtr = buf; COUNT_NEWLINES (myLineNoG, buf); return BRACEBAL_SYM; } } } /* not reached */ } \'[0-1 \t\r\v\f\n]*\'B { COUNT_NEWLINES (myLineNoG, yytext); yylval.charPtr = (char*)Malloc (yyleng); strncpy (yylval.charPtr, yytext+1, yyleng -1); /* strip "'"s */ yylval.charPtr[yyleng-2] = '\0'; return BSTRING_SYM;} \'[0-9A-Fa-f \r\t\v\f\n]*\'H { COUNT_NEWLINES (myLineNoG, yytext); yylval.charPtr = (char*)Malloc (yyleng); strncpy (yylval.charPtr, yytext+1, yyleng -1); /* strip "'"s */ yylval.charPtr[yyleng-2] = '\0'; return HSTRING_SYM;} \"([^\"]|"\"\"")*\" { COUNT_NEWLINES (myLineNoG, yytext); yylval.charPtr = (char*)Malloc (yyleng); strncpy (yylval.charPtr, yytext+1, yyleng -1); /* strip '"'s */ yylval.charPtr[yyleng-2] = '\0'; /* 2 quotes == quote in a quote */ return CSTRING_SYM;} [A-Z][a-zA-Z0-9]*([-][a-zA-Z0-9]+)* { yylval.charPtr = (char*)Malloc (yyleng+1); strcpy (yylval.charPtr, yytext); yylval.charPtr[yyleng] = '\0'; return UCASEFIRST_IDENT_SYM;} [a-z][a-zA-Z0-9]*([-][a-zA-Z0-9]+)* { yylval.charPtr = (char*)Malloc (yyleng+1); strcpy (yylval.charPtr, yytext); yylval.charPtr[yyleng] = '\0'; return LCASEFIRST_IDENT_SYM;} [1-9][0-9]* { /*first digit cannot be zero on multi-digit #'s*/ errno = 0; { unsigned long ul = (unsigned long) strtol(yytext,NULL,10); if (!errno && ul>(unsigned long)0xFFFFFFFF) { errno = ERANGE; } if (!errno) { yylval.uintVal = (unsigned int) ul; return NUMBER_SYM; } } yylval.charPtr = (char*)Malloc (yyleng+1); strcpy (yylval.charPtr, yytext); yylval.charPtr[yyleng] = '\0'; return NUMBER_ERANGE;} 0 { /*allow zero as first digit on single digit #'s*/ yylval.uintVal = 0; return NUMBER_SYM;} "--" BEGIN(COMMENT); "--snacc" BEGIN(SNACC_ATTRIBS); /* Bob's fix "--snacc namespace"(-[^-\n]|[^\-\n])*("--"|\n) { char *ptr1, *ptr2; printf("RWC --snacc namespace found\n"); COUNT_NEWLINES (myLineNoG, yytext); yylval.charPtr = (char*)Malloc (yyleng-4); ptr1 = strchr(yytext+7+10, '"'); ptr2 = strchr(ptr1+1, '"'); if (ptr1 && ptr2) { ptr1++; strncpy (yylval.charPtr, ptr1, ptr2-ptr1); modulePtrG->namespaceToUse = strdup(yylval.charPtr); } return ATTRIB_NAMESPACE_SYM; } */ /* OLD SNACC compiler directive parser "--snacc"(-[^-\n]|[^\-\n])*("--"|\n) { * this must be before the normal comment eater so that snacc attribs * are not treated as normal comments * * eat comments, update line no * int len; COUNT_NEWLINES (myLineNoG, yytext); yylval.charPtr = (char*)Malloc (yyleng-4); * skip first "--snacc" in copy to ret val * strcpy (yylval.charPtr, yytext + 7); len = strlen (yylval.charPtr); * strip off newline or -- terminator for comment * if (yylval.charPtr[len-1] == '\n') yylval.charPtr[len-1] = '\0'; else yylval.charPtr[len-2] = '\0'; return SNACC_ATTRIBUTES; } "--"(-[^\-\n]|[^\-\n])*("--"|\n|"-\n") { * eat comments, update line no * COUNT_NEWLINES (myLineNoG, yytext);} */ (-[^\-\n]|[^\-\n])*("--"|\n|"-\n") { /* eat comments, update line no */ COUNT_NEWLINES (myLineNoG, yytext); BEGIN(INITIAL); } { /* Begin SNACC_ATTRIBS start condition */ asn1TypeId return ATTRIB_ASN1_TYPE_ID; cTypeId return ATTRIB_C_TYPE_ID; cTypeName return ATTRIB_C_TYPE_NAME_SYM; cFieldName return ATTRIB_C_FIELD_NAME_SYM; isPdu return ATTRIB_IS_PDU_SYM; isPtr return ATTRIB_IS_PTR_SYM; isPtrForTypeDef return ATTRIB_IS_PTR_TYPEDEF_SYM; isPtrForTypeRef return ATTRIB_IS_PTR_TYPE_REF_SYM; isPtrInChoice return ATTRIB_IS_PTR_IN_CHOICE_SYM; isPtrForOpt return ATTRIB_IS_PTR_FOR_OPT_SYM; optTestRoutineName return ATTRIB_OPT_TEST_ROUTINE_SYM; defaultFieldName return ATTRIB_DEFAULT_FIELD_SYM; printRoutineName return ATTRIB_PRINT_ROUTINE_SYM; encodeRoutineName return ATTRIB_ENCODE_ROUTINE_SYM; decodeRoutineName return ATTRIB_DECODE_ROUTINE_SYM; freeRoutineName return ATTRIB_FREE_ROUTINE_SYM; isEncDec return ATTRIB_IS_ENC_DEC_SYM; genTypeDef return ATTRIB_GEN_TYPEDEF_SYM; genPrintRoutine return ATTRIB_GEN_PRINT_ROUTINE_SYM; genEncodeRoutine return ATTRIB_GEN_ENCODE_ROUTINE_SYM; genDecodeRoutine return ATTRIB_GEN_DECODE_ROUTINE_SYM; genFreeRoutine return ATTRIB_GEN_FREE_ROUTINE_SYM; choiceIdSymbol return ATTRIB_CHOICE_ID_SYMBOL_SYM; choiceIdValue return ATTRIB_CHOICE_ID_VALUE_SYM; choiceIdEnumName return ATTRIB_CHOICE_ID_ENUM_NAME_SYM; choiceIdEnumFieldName return ATTRIB_CHOICE_ID_ENUM_FIELD_NAME_SYM; isBigInt return ATTRIB_IS_BIG_INT_SYM; namespace return ATTRIB_NAMESPACE_SYM; \"TRUE\" return TRUE_SYM; \"FALSE\" return FALSE_SYM; \"C_CHOICE\" return C_CHOICE_SYM; \"C_LIST\" return C_LIST_SYM; \"C_ANYDEFINEDBY\" return C_ANYDEFBY_SYM; \"C_ANY\" return C_ANY_SYM; \"C_LIB\" return C_LIB_SYM; \"C_STRUCT\" return C_STRUCT_SYM; \"C_TYPEDEF\" return C_TYPEDEF_SYM; \"C_TYPEREF\" return C_TYPEREF_SYM; \"C_NO_TYPE\" return C_NO_TYPE_SYM; \"UNKNOWN\" return UNKNOWN_SYM; \"BOOLEAN\" return BOOLEAN_SYM; \"INTEGER\" return INTEGER_SYM; \"BITSTRING\" return BITSTRING_SYM; \"OCTETSTRING\" return OCTETSTRING_SYM; \"NULL\" return NULL_SYM; \"OID\" return OBJECT_IDENTIFIER_SYM; \"RELATIVE-OID\" return RELATIVE_OID_SYM; \"REAL\" return REAL_SYM; \"ENUMERATED\" return ENUMERATED_SYM; \"SEQUENCEOF\" return SEQUENCE_OF_SYM; \"SEQUENCE\" return SEQUENCE_SYM; \"SETOF\" return SET_OF_SYM; \"SET\" return SET_SYM; \"CHOICE\" return CHOICE_SYM; \"ANYDEFINEDBY\" return ANY_DEFINED_BY_SYM; \"ANY\" return ANY_SYM; \"LOCALTYPEREF\" return LOCAL_TYPE_REF_SYM; \"IMPORTYPEREF\" return IMPORT_TYPE_REF_SYM; \"NumericString\" return NUMERICSTRING_SYM; \"PrintableString\" return PRINTABLESTRING_SYM; \"IA5String\" return IA5STRING_SYM; \"BMPString\" return BMPSTRING_SYM; \"UniversalString\" return UNIVERSALSTRING_SYM; \"UTF8String\" return UTF8STRING_SYM; \"TeletexString\" return TELETEXSTRING_SYM; \"(0|[1-9][0-9]*)\" { yylval.uintVal = atoi(yytext + 1); return NUMBER_SYM; } \"[^\"\n]*\" { yylval.charPtr = (char*)Malloc (yyleng - 1); strncpy (yylval.charPtr, yytext + 1, yyleng - 2); yylval.charPtr[yyleng - 2] = '\0'; return CSTRING_SYM; } [ \t]* /* Skip white space */ "--" { BEGIN(INITIAL); } "\n" { ++myLineNoG; BEGIN(INITIAL); } . return *yytext; /* Any other character is just returned */ } /* end of SNACC_ATTRIBS start condition */ %% /* * these "LexBegin..." routines are used by yacc for (ack!) * lexical tie ins */ int LexBeginMacroDefContext() { BEGIN (MACRO_DEF); return 0; } int LexBeginBraceBalContext() { BEGIN (BRACE_BAL); return 0; } int LexBeginInitialContext() { BEGIN (INITIAL); return 0; } /* * $Log: lex-asn1.l,v $ * Revision 1.14 2004/03/25 19:20:16 gronej * fixed some linux warnings * * Revision 1.13 2004/01/29 21:21:45 gronej * Took all Init() calls out of Clear() functions in generated code * * Revision 1.12 2004/01/14 19:07:52 gronej * Updated Compiler to accept and process relative-oid's * * Revision 1.11 2003/12/17 19:05:04 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.10.2.4 2003/07/29 14:43:02 nicholar * Fixed handling of --snacc compiler directives * * Revision 1.10.2.3 2003/07/28 11:11:23 colestor * Changes to complete handing of the "--snacc namespace" compiler directive. * Also, updates to handle ASN.1 constant integer tag designations for C++/C. * * Revision 1.10.2.2 2003/07/14 21:07:44 nicholar * Changed how parser handles --snacc directives. Added namespace option. * * Revision 1.10.2.1 2003/07/07 20:55:07 nicholar * no message * * Revision 1.7 2003/04/21 13:04:19 leonberp * Fixed typo changed GraphicsString to GraphicString * * Revision 1.6 2002/10/24 15:13:57 leonberp * fixing OCTET STRING CONTAINING * * Revision 1.5 2002/10/24 14:04:22 leonberp * fixing support for OCTET STRING CONTAINING * * Revision 1.4 2002/10/23 20:03:04 leonberp * updated lexer and parser and handle OCTET STRING CONTAINING * * Revision 1.3 2002/05/15 17:00:59 leonberp * added support for new basicTypes to compiler * * Revision 1.2 2000/10/24 14:54:52 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:36:00 leonberp * First CVS Version of SNACC. * * Revision 1.5 1997/08/28 09:46:41 wan * Reworked number range checking, only gives warning now. * * Revision 1.4 1997/06/19 09:17:17 wan * Added isPdu flag to tables. Added value range checks during parsing. * * Revision 1.3 1995/07/25 19:41:30 rj * changed `_' to `-' in file names. * * Revision 1.2 1994/09/01 00:37:12 rj * snacc_config.h removed. * * for a list of changes relative to the 1.1 distribution, please refer to the ChangeLog. */ esnacc-ng-1.8.1/compiler/core/lex-stuff.h000066400000000000000000000040371302010526100202010ustar00rootroot00000000000000/* * compiler/core/lex_stuff.h * * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/core/lex-stuff.h,v 1.3 2002/03/19 22:33:45 rwc Exp $ * $Log: lex-stuff.h,v $ * Revision 1.3 2002/03/19 22:33:45 rwc * Updates to the DER encoding of SET OFs. They now include all tag/length bytes, no * longer skipping them as before (in a mis-interpretation of the specs). Also updated * the test routine to test this feature (modified an existing data array). Tested! * * Revision 1.1.1.1 2000/08/21 20:36:00 leonberp * First CVS Version of SNACC. * * Revision 1.4 1995/07/25 19:41:31 rj * changed `_' to `-' in file names. * * Revision 1.3 1994/10/08 03:48:45 rj * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long. * * Revision 1.2 1994/09/01 01:16:07 rj * decide upon type of yytext thru cxx macro provided by autoconf. * * Revision 1.1 1994/08/28 09:49:13 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ extern unsigned long myLineNoG; #if defined(YYTEXT_POINTER) || defined(WIN32) extern char *yytext; #else extern char yytext[]; #endif extern FILE *yyin; int LexBeginInitialContext(); int LexBeginMacroDefContext(); int LexBeginBraceBalContext(); int LexBeginCommentContext(); #define COUNT_NEWLINES( cumulativeTotal, nullTermStr)\ {\ int cnlStrIndex;\ for (cnlStrIndex = 0; nullTermStr[cnlStrIndex] != '\0'; cnlStrIndex++)\ if (nullTermStr[cnlStrIndex] == '\n')\ cumulativeTotal++;\ } esnacc-ng-1.8.1/compiler/core/lib-types.c000066400000000000000000000167121302010526100201720ustar00rootroot00000000000000/* * compiler/core/lib_types.c - tag form/code and any refs info * * * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/core/lib-types.c,v 1.7 2004/01/14 19:07:52 gronej Exp $ * $Log: lib-types.c,v $ * Revision 1.7 2004/01/14 19:07:52 gronej * Updated Compiler to accept and process relative-oid's * * Revision 1.6 2003/07/07 14:50:13 nicholar * Eliminated headers and cleaned up include references * * Revision 1.5 2002/10/28 19:57:03 leonberp * Added BITSTRING CONTAINING support and fixed CONTAINED ANY DEFINED BY * * Revision 1.4 2002/10/24 21:07:22 leonberp * latest fixing for OCTET CONTAINING * * Revision 1.3 2002/05/15 17:00:59 leonberp * added support for new basicTypes to compiler * * Revision 1.2 2002/05/15 14:53:12 leonberp * added support for new basicTypes to compiler * * Revision 1.1.1.1 2000/08/21 20:36:00 leonberp * First CVS Version of SNACC. * * Revision 1.3 1995/07/25 19:41:33 rj * changed `_' to `-' in file names. * * Revision 1.2 1994/09/01 00:37:51 rj * snacc_config.h removed. * * Revision 1.1 1994/08/28 09:49:14 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #define NO_EXTN_LIBTYPE #include "asn-incl.h" #include "asn1module.h" /* for BASICTYPE_... choice ids */ #include "lib-types.h" /* * Warning: this table must be in order of ascending * BASICTYPE ids such that * libTypesG[BASICTYPE_X].typeId == BASICTYPE_X * is alwas true */ /* BER Types */ LibType libBERTypesG[ BASICTYPE_RELATIVE_OID + 1] = { { BASICTYPE_UNKNOWN, NO_TAG_CODE, NULL_FORM, NULL }, { BASICTYPE_BOOLEAN, BOOLEAN_TAG_CODE, PRIM, NULL }, { BASICTYPE_INTEGER, INTEGER_TAG_CODE, PRIM, NULL }, { BASICTYPE_BITSTRING, BITSTRING_TAG_CODE, ANY_FORM, NULL }, { BASICTYPE_OCTETSTRING, OCTETSTRING_TAG_CODE, ANY_FORM, NULL }, { BASICTYPE_NULL, NULLTYPE_TAG_CODE, PRIM, NULL }, { BASICTYPE_OID, OID_TAG_CODE, PRIM, NULL }, { BASICTYPE_REAL, REAL_TAG_CODE, PRIM, NULL }, { BASICTYPE_ENUMERATED, ENUM_TAG_CODE, PRIM, NULL }, { BASICTYPE_SEQUENCE, SEQ_TAG_CODE, CONS, NULL }, { BASICTYPE_SEQUENCEOF, SEQ_TAG_CODE, CONS, NULL }, { BASICTYPE_SET, SET_TAG_CODE, CONS, NULL }, { BASICTYPE_SETOF, SET_TAG_CODE, CONS, NULL }, { BASICTYPE_CHOICE, NO_TAG_CODE, CONS, NULL }, { BASICTYPE_SELECTION, NO_TAG_CODE, NULL_FORM, NULL }, { BASICTYPE_COMPONENTSOF, NO_TAG_CODE, CONS, NULL }, { BASICTYPE_ANY, NO_TAG_CODE, CONS, NULL }, { BASICTYPE_ANYDEFINEDBY, NO_TAG_CODE, CONS, NULL }, { BASICTYPE_LOCALTYPEREF, NO_TAG_CODE, NULL_FORM, NULL }, { BASICTYPE_IMPORTTYPEREF, NO_TAG_CODE, NULL_FORM, NULL }, { BASICTYPE_MACROTYPE, NO_TAG_CODE, NULL_FORM, NULL }, { BASICTYPE_MACRODEF, NO_TAG_CODE, NULL_FORM, NULL }, { BASICTYPE_NUMERIC_STR, NUMERICSTRING_TAG_CODE, ANY_FORM, NULL }, { BASICTYPE_PRINTABLE_STR, PRINTABLESTRING_TAG_CODE, ANY_FORM, NULL }, { BASICTYPE_UNIVERSAL_STR, UNIVERSALSTRING_TAG_CODE, ANY_FORM, NULL }, { BASICTYPE_IA5_STR, IA5STRING_TAG_CODE, ANY_FORM, NULL }, { BASICTYPE_BMP_STR, BMPSTRING_TAG_CODE, ANY_FORM, NULL }, { BASICTYPE_UTF8_STR, UTF8STRING_TAG_CODE, ANY_FORM, NULL }, { BASICTYPE_UTCTIME, UTCTIME_TAG_CODE, ANY_FORM, NULL }, { BASICTYPE_GENERALIZEDTIME, GENERALIZEDTIME_TAG_CODE, ANY_FORM, NULL }, { BASICTYPE_GRAPHIC_STR, GRAPHICSTRING_TAG_CODE, ANY_FORM, NULL }, { BASICTYPE_VISIBLE_STR, VISIBLESTRING_TAG_CODE, ANY_FORM, NULL }, { BASICTYPE_GENERAL_STR, GENERALSTRING_TAG_CODE, ANY_FORM, NULL }, { BASICTYPE_OBJECTDESCRIPTOR, OD_TAG_CODE, ANY_FORM, NULL}, { BASICTYPE_VIDEOTEX_STR, VIDEOTEXSTRING_TAG_CODE, ANY_FORM, NULL }, { BASICTYPE_T61_STR, TELETEXSTRING_TAG_CODE, ANY_FORM, NULL }, { BASICTYPE_EXTERNAL, EXTERNAL_TAG_CODE, CONS, NULL }, { BASICTYPE_OCTETCONTAINING, OCTETSTRING_TAG_CODE, PRIM, NULL }, { BASICTYPE_BITCONTAINING, BITSTRING_TAG_CODE, PRIM, NULL }, { BASICTYPE_RELATIVE_OID, RELATIVE_OID_TAG_CODE, PRIM, NULL } }; /* DER Types */ LibType libDERTypesG[ BASICTYPE_RELATIVE_OID + 1] = { { BASICTYPE_UNKNOWN, NO_TAG_CODE, NULL_FORM, NULL }, { BASICTYPE_BOOLEAN, BOOLEAN_TAG_CODE, PRIM, NULL }, { BASICTYPE_INTEGER, INTEGER_TAG_CODE, PRIM, NULL }, { BASICTYPE_BITSTRING, BITSTRING_TAG_CODE, PRIM, NULL }, { BASICTYPE_OCTETSTRING, OCTETSTRING_TAG_CODE, PRIM, NULL }, { BASICTYPE_NULL, NULLTYPE_TAG_CODE, PRIM, NULL }, { BASICTYPE_OID, OID_TAG_CODE, PRIM, NULL }, { BASICTYPE_REAL, REAL_TAG_CODE, PRIM, NULL }, { BASICTYPE_ENUMERATED, ENUM_TAG_CODE, PRIM, NULL }, { BASICTYPE_SEQUENCE, SEQ_TAG_CODE, CONS, NULL }, { BASICTYPE_SEQUENCEOF, SEQ_TAG_CODE, CONS, NULL }, { BASICTYPE_SET, SET_TAG_CODE, CONS, NULL }, { BASICTYPE_SETOF, SET_TAG_CODE, CONS, NULL }, { BASICTYPE_CHOICE, NO_TAG_CODE, CONS, NULL }, { BASICTYPE_SELECTION, NO_TAG_CODE, NULL_FORM, NULL }, { BASICTYPE_COMPONENTSOF, NO_TAG_CODE, CONS, NULL }, { BASICTYPE_ANY, NO_TAG_CODE, CONS, NULL }, { BASICTYPE_ANYDEFINEDBY, NO_TAG_CODE, CONS, NULL }, { BASICTYPE_LOCALTYPEREF, NO_TAG_CODE, NULL_FORM, NULL }, { BASICTYPE_IMPORTTYPEREF, NO_TAG_CODE, NULL_FORM, NULL }, { BASICTYPE_MACROTYPE, NO_TAG_CODE, NULL_FORM, NULL }, { BASICTYPE_MACRODEF, NO_TAG_CODE, NULL_FORM, NULL }, { BASICTYPE_NUMERIC_STR, NUMERICSTRING_TAG_CODE, ANY_FORM, NULL }, { BASICTYPE_PRINTABLE_STR, PRINTABLESTRING_TAG_CODE, ANY_FORM, NULL }, { BASICTYPE_UNIVERSAL_STR, UNIVERSALSTRING_TAG_CODE, ANY_FORM, NULL }, { BASICTYPE_IA5_STR, IA5STRING_TAG_CODE, ANY_FORM, NULL }, { BASICTYPE_BMP_STR, BMPSTRING_TAG_CODE, ANY_FORM, NULL }, { BASICTYPE_UTF8_STR, UTF8STRING_TAG_CODE, ANY_FORM, NULL }, { BASICTYPE_UTCTIME, UTCTIME_TAG_CODE, ANY_FORM, NULL }, { BASICTYPE_GENERALIZEDTIME, GENERALIZEDTIME_TAG_CODE, ANY_FORM, NULL }, { BASICTYPE_GRAPHIC_STR, GRAPHICSTRING_TAG_CODE, ANY_FORM, NULL }, { BASICTYPE_VISIBLE_STR, VISIBLESTRING_TAG_CODE, ANY_FORM, NULL }, { BASICTYPE_GENERAL_STR, GENERALSTRING_TAG_CODE, ANY_FORM, NULL }, { BASICTYPE_OBJECTDESCRIPTOR, OD_TAG_CODE, ANY_FORM, NULL}, { BASICTYPE_VIDEOTEX_STR, VIDEOTEXSTRING_TAG_CODE, ANY_FORM, NULL }, { BASICTYPE_T61_STR, TELETEXSTRING_TAG_CODE, ANY_FORM, NULL }, { BASICTYPE_EXTERNAL, EXTERNAL_TAG_CODE, CONS, NULL }, { BASICTYPE_OCTETCONTAINING, OCTETSTRING_TAG_CODE, PRIM, NULL }, { BASICTYPE_BITCONTAINING, OCTETSTRING_TAG_CODE, PRIM, NULL }, { BASICTYPE_RELATIVE_OID, RELATIVE_OID_TAG_CODE, PRIM, NULL } }; /* Default is BER */ LibType *libTypesG = libBERTypesG; esnacc-ng-1.8.1/compiler/core/lib-types.h000066400000000000000000000045431302010526100201760ustar00rootroot00000000000000/* * compiler/core/lib_types.h * * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/core/lib-types.h,v 1.3 2001/07/12 19:34:30 leonberp Exp $ * $Log: lib-types.h,v $ * Revision 1.3 2001/07/12 19:34:30 leonberp * Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. * * Revision 1.2 2000/10/24 14:54:52 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:36:00 leonberp * First CVS Version of SNACC. * * Revision 1.3 1995/07/25 19:41:34 rj * changed `_' to `-' in file names. * * Revision 1.2 1994/10/08 03:48:46 rj * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long. * * Revision 1.1 1994/08/28 09:49:15 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #ifndef _LibTypeInclude #define _LibTypeInclude typedef struct LibType { enum BasicTypeChoiceId typeId; BER_UNIV_CODE univTagCode; BER_FORM tagForm; AnyRefList *anyRefs; /* these may be filled in do_macros.c*/ } LibType; #ifndef NO_EXTN_LIBTYPE extern LibType* libTypesG; extern LibType libBERTypesG[]; extern LibType libDERTypesG[]; #endif #define LIBTYPE_GET_UNIV_TAG_CODE( tId) (libTypesG[tId].univTagCode) #define LIBTYPE_GET_TAG_FORM( tId) (libTypesG[tId].tagForm) #define LIBTYPE_GET_ANY_REFS( tId) (libTypesG[tId].anyRefs) #define LIBTYPE_GET_ANY_REFS_HNDL( tId) (&libTypesG[tId].anyRefs) #define LIBTYPE_GET_ANY_REFS( tId) (libTypesG[tId].anyRefs) #define SET_BER_LIBTYPE() (libTypesG = libBERTypesG) #define SET_DER_LIBTYPE() (libTypesG = libDERTypesG) #endif esnacc-ng-1.8.1/compiler/core/link-types.c000066400000000000000000001565031302010526100203640ustar00rootroot00000000000000/* * compiler/core/link_types.c * * Links type references. Also increments 'refCount' in a TypeDef * * Does type checking when linking SELECTION and COMPONENTS OF types * * MS * 91/09/04 * Completely Rewritten for new ModuleList data structure (ASN.1 based) * * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/core/link-types.c,v 1.21 2004/04/06 15:13:41 gronej Exp $ * $Log: link-types.c,v $ * Revision 1.21 2004/04/06 15:13:41 gronej * *** empty log message *** * * Revision 1.20 2004/03/25 19:20:17 gronej * fixed some linux warnings * * Revision 1.19 2004/02/06 21:21:32 nicholar * Replaced List with std::list * Numerous changes/fixes to constraints code * * Revision 1.18 2004/01/29 21:21:45 gronej * Took all Init() calls out of Clear() functions in generated code * * Revision 1.17 2004/01/14 19:07:52 gronej * Updated Compiler to accept and process relative-oid's * * Revision 1.16 2003/07/28 11:11:23 colestor * Changes to complete handing of the "--snacc namespace" compiler directive. * Also, updates to handle ASN.1 constant integer tag designations for C++/C. * * Revision 1.15 2003/07/14 21:07:44 nicholar * Changed how parser handles --snacc directives. Added namespace option. * * Revision 1.14 2003/07/07 14:50:13 nicholar * Eliminated headers and cleaned up include references * * Revision 1.13 2003/04/29 21:08:36 leonberp * integerated Deepak's changes for IOB support * * Revision 1.12 2003/01/06 16:16:31 leonberp * added GeneralString * * Revision 1.11 2002/11/01 17:16:39 mcphersc * added import used * * Revision 1.10 2002/10/28 19:57:03 leonberp * Added BITSTRING CONTAINING support and fixed CONTAINED ANY DEFINED BY * * Revision 1.9 2002/10/24 21:07:22 leonberp * latest fixing for OCTET CONTAINING * * Revision 1.8 2002/09/16 16:50:04 mcphersc * iFixed warnings * CV: -rnings * --------------------------------------------------------------------- * * Revision 1.7 2002/09/04 18:23:07 vracarl * got rid of c++ comments * * Revision 1.6 2002/05/15 17:00:59 leonberp * added support for new basicTypes to compiler * * Revision 1.5 2002/05/15 14:53:12 leonberp * added support for new basicTypes to compiler * * Revision 1.4 2002/05/10 16:39:40 leonberp * latest changes for release 2.2 * includes integrating asn-useful into C & C++ runtime library, the compiler changes that go along with that, SnaccException changes for C++ runtime and compiler * * Revision 1.3 2001/05/11 16:32:34 rwc * Update to remove need for "-u"; code core dumped if "-u" was not present * on the command line due to newly added logic handling the new String * handling ASN.1 classes (e.g. PrintableString). * * Revision 1.2 2000/10/24 14:54:52 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:36:00 leonberp * First CVS Version of SNACC. * * Revision 1.3 1995/07/25 19:41:36 rj * changed `_' to `-' in file names. * * Revision 1.2 1994/09/01 00:38:30 rj * snacc_config.h removed. * * Revision 1.1 1994/08/28 09:49:17 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include #include #include "asn-incl.h" #include "asn1module.h" #include "snacc-util.h" /* non-exported prototypes */ void TypeLinkImportLists PROTO ((ModuleList *m)); void TypeLinkTypeDef PROTO ((ModuleList *m, Module *currMod, TypeDef *head)); void TypeLinkElmtTypes PROTO ((ModuleList *m, Module *currMod, TypeDef *head, NamedTypeList *e)); void TypeLinkElmtType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, NamedType *n)); void TypeLinkType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *currType)); void TypeLinkBasicType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *type, BasicType *bt)); void TypeLinkSubtypes PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *currType, Subtype *s)); void TypeLinkSubtypeValue PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *currType, SubtypeValue *s)); void TypeLinkNamedElmts PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, ValueDefList *v)); // Deepak: 04/Mar/2003 void TypeLinkObjectAssignmentField PROTO ((ModuleList *m, Module *currMod, ObjectAssignment *head, ObjectAssignmentField *field)); void TypeLinkObjectAssignments PROTO ((ModuleList *m, Module *currMod, ObjectAssignment *head)); void TypeLinkObjectSetAssignments PROTO ((ModuleList *m, Module *currMod, ObjectSetAssignment *head)); void TypeLinkWithSyntaxes PROTO ((ModuleList *m, Module *currMod, TypeDef *head, ObjectClassDef *ocd)); //////////////////// void TypeLinkValueDef PROTO ((ModuleList *m, Module *currMod, ValueDef *v)); void TypeLinkValue PROTO ((ModuleList *m, Module *currMod, ValueDef *head, Type *valuesType, Value *v)); void TypeLinkRosOperationMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, RosOperationMacroType *op)); void TypeLinkRosErrorMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, RosErrorMacroType *err)); void TypeLinkRosBindMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, RosBindMacroType *bind)); void TypeLinkRosAseMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, RosAseMacroType *ase)); void TypeLinkRosAcMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, RosAcMacroType *ac)); void TypeLinkMtsasExtensionsMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, MtsasExtensionsMacroType *exts)); void TypeLinkMtsasExtensionMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, MtsasExtensionMacroType *ext)); void TypeLinkMtsasExtensionAttributeMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, MtsasExtensionAttributeMacroType *ext)); void TypeLinkMtsasTokenMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, MtsasTokenMacroType *tok)); void TypeLinkMtsasTokenDataMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, MtsasTokenDataMacroType *tok)); void TypeLinkMtsasSecurityCategoryMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, MtsasSecurityCategoryMacroType *sec)); void TypeLinkAsnObjectMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, AsnObjectMacroType *obj)); void TypeLinkAsnPortMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, AsnPortMacroType *p)); void TypeLinkAsnAbstractBindMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, AsnAbstractBindMacroType *bind)); void TypeLinkSnmpObjectTypeMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, SnmpObjectTypeMacroType *ot)); /* end of prototypes */ static char *asn1SrcFileNameG; /* * returns 0 if no link error occured, * otherwise returns a value < 0. * Processing should not continue if an error is returned */ int LinkTypeRefs PARAMS ((m), ModuleList *m) { Module *currMod; TypeDef *td; ValueDef *vd; ObjectAssignment *oa; ObjectSetAssignment *osa; int linkErr = 0; /* * link imported types/values to their definition if * the defining module is in the modulelist */ TypeLinkImportLists (m); /* * go through types, values & macros of each module */ FOR_EACH_LIST_ELMT (currMod, m) { asn1SrcFileNameG = currMod->asn1SrcFileName; /* * go through each type in typeList and link as nec */ FOR_EACH_LIST_ELMT (td, currMod->typeDefs) // Deepak: all typedefs are processed here { TypeLinkTypeDef (m, currMod, td); // Deepak: all the major types e.g. sequence, objectclass } // are linked here, subtypes in further functions. /* * go through each value in valueList and link as nec */ FOR_EACH_LIST_ELMT (vd, currMod->valueDefs) // Deepak: all valuedefs are processed here { TypeLinkValueDef (m, currMod, vd); } /* Deepak: 04/Mar/2003 * go through each field in objectAssignments and link as nec */ FOR_EACH_LIST_ELMT (oa, currMod->objAssignments) { TypeLinkObjectAssignments (m, currMod, oa); // Deepak: 04/Mar/2003 } /* Deepak: 04/Mar/2003 * go through each object in objectSetAssignments and link as nec */ FOR_EACH_LIST_ELMT (osa, currMod->objSetAssignments) { TypeLinkObjectSetAssignments (m, currMod, osa); } if (currMod->status != MOD_ERROR) currMod->status = MOD_OK; else linkErr = -1; } return linkErr; } /* LinkRefs */ /* * goes through import lists of each module making sure each * imported type is in the referenced module. Will flag * errors if the imported type cannot be found or is not * exported by the referenced module. */ void TypeLinkImportLists PARAMS ((m), ModuleList *m) { Module *currMod; TypeDef *t; /* ValueDef *v; */ ImportModule *currImpList; ImportElmt *currImpElmt; Module *impRefMod; /* Link each modules imports */ FOR_EACH_LIST_ELMT (currMod, m) { /* * Link each import list in the currMod. * (there is an import list for every module * imported from by this module */ FOR_EACH_LIST_ELMT (currImpList, currMod->imports) { /* lookup ref'd module by it's name and oid (if any) */ impRefMod = LookupModule (m, currImpList->modId->name, currImpList->modId->oid); if (impRefMod == NULL) { /* * The needed module is not available. * Let user know and set fatal error */ currMod->status = MOD_ERROR; PrintErrLoc (currMod->asn1SrcFileName, (long)currImpList->lineNo); fprintf (errFileG, "ERROR - cannot locate IMPORT module \"%s\", ", currImpList->modId->name); fprintf (errFileG, "so the following types/values are missing:\n"); FOR_EACH_LIST_ELMT (currImpElmt, currImpList->importElmts) { fprintf (errFileG, " "); /* indent */ if (currImpElmt->privateScope) fprintf (errFileG, "%s.", currImpList->modId->name); fprintf (errFileG, "%s\n", currImpElmt->name); } fprintf (errFileG, "\n"); /* * go onto next import list in this module * to report more errors if any */ continue; } /* * go through each import elements and look for the * the referenced type in the ref'd module */ FOR_EACH_LIST_ELMT (currImpElmt, currImpList->importElmts) { /* * only do types (types have uppercase first letter) */ if (!isupper (currImpElmt->name[0])) continue; /* look for the type in the ref'd module */ t = LookupType (impRefMod->typeDefs, currImpElmt->name); if (t != NULL) { if (!t->exported) { currMod->status = MOD_ERROR; PrintErrLoc (currMod->asn1SrcFileName, (long)currImpElmt->lineNo); fprintf (errFileG, "ERROR - \"%s\" module imports \"%s\", which is not exported from module \"%s\".\n", currMod->modId->name, currImpElmt->name, impRefMod->modId->name); } /* set as ref'd if imported by someone */ t->importRefCount++; currImpElmt->resolvedRef = (ImportElmtChoice*)Malloc (sizeof (ImportElmtChoice)); currImpElmt->resolvedRef->choiceId = IMPORTELMTCHOICE_TYPE; currImpElmt->resolvedRef->a.type = t; currMod->ImportUsed = TRUE; } else /* type not found in ref'd module */ { currMod->status = MOD_ERROR; PrintErrLoc (currMod->asn1SrcFileName, (long)currImpElmt->lineNo); fprintf (errFileG, "ERROR - \"%s\" is imported from module \"%s\" by module \"%s\", but is not defined in the referenced module\n", currImpElmt->name, impRefMod->modId->name, currMod->modId->name); } } } } } /* TypeLinkImportLists */ void // Deepak: 04/Mar/2003 TypeLinkObjectAssignments PARAMS ((m, currMod, oa), ModuleList *m _AND_ Module *currMod _AND_ ObjectAssignment *oa) { ObjectAssignmentField *oaf; TypeDef *tmpTypeDef; NamedType* nt; if (oa == NULL) return; // chk here objClassName CLASS exists or not. tmpTypeDef = LookupType (currMod->typeDefs, oa->objectClassName); if(tmpTypeDef) // CLASS is defined { tmpTypeDef->localRefCount++; // CLASS is referenced here } else // CLASS is not defined { currMod->status = MOD_ERROR; PrintErrLoc (currMod->asn1SrcFileName, (long)oa->lineNo); fprintf (errFileG, "ERROR - CLASS \"%s\" is referenced but not defined.\n", oa->objectClassName); } FOR_EACH_LIST_ELMT (oaf, oa->objectAssignmentField) { if(tmpTypeDef->type->basicType->a.objectclass->withsyntax) { // if WITH SYNTAX is used WithSyntax *ws; char bError; bError = FALSE; oa->bWithSyntaxPresent = 1; // Deepak: ????? Remove if not used further. ws = (WithSyntax*)LookupObjectClassFieldTypeWithSyntax(tmpTypeDef->type->basicType->a.objectclass->withsyntax, oaf->objectFieldName, &bError); if(ws) { if(bError) // typeName present, but With Syntax construct is not used { currMod->status = MOD_ERROR; PrintErrLoc (currMod->asn1SrcFileName, (long)oaf->lineNo); fprintf (errFileG, "ERROR - type \"%s\" must be used in place of \"%s\" in CLASS %s.\n", ws->definedName, oaf->objectFieldName, oa->objectClassName); } else // typeName is present, process it { oaf->objectFieldNameWS = oaf->objectFieldName; // WITH SYNTAX NAME oaf->objectFieldName = ws->typeName; // ORIGINAL NAME oaf->bOptional = ws->bOptional; } // Check whether it is Unknown Type or not nt = LookupObjectClassFieldType(tmpTypeDef->type->basicType->a.objectclass->classdef, oaf->objectFieldName); if(nt && nt->type->basicType->choiceId == 0) oaf->bUnknownType = 1; } else // typeName is not present et al { currMod->status = MOD_ERROR; PrintErrLoc (currMod->asn1SrcFileName, (long)oaf->lineNo); fprintf (errFileG, "ERROR - type \"%s\" is referenced but not defined in CLASS %s.\n", oaf->objectFieldName, oa->objectClassName); } } else // if WITH SYNTAX is not used { oa->bWithSyntaxPresent = 0; // Deepak: ????? nt = LookupObjectClassFieldType(tmpTypeDef->type->basicType->a.objectclass->classdef, oaf->objectFieldName); if(nt) { if(nt->type->basicType->choiceId == 0) oaf->bUnknownType = 1; } else // CLASS.&identifier is not defined { currMod->status = MOD_ERROR; PrintErrLoc (currMod->asn1SrcFileName, (long)oaf->lineNo); fprintf (errFileG, "ERROR - type \"%s\" is referenced but not defined in CLASS %s.\n", oaf->objectFieldName, oa->objectClassName); } } TypeLinkObjectAssignmentField(m, currMod, oa, oaf); } /* For all oaf's that are in classdef but not in objectAssignment, mark their bPresent = 0 and also add those in the oaf's list. For all others, which are already present, mark bPresent = 1 This whole gamut is done just to write ".m.Present = 0;" in init_Module_nameObjects(...). Deepak: 22/Mar/2003 */ FOR_EACH_LIST_ELMT (nt, tmpTypeDef->type->basicType->a.objectclass->classdef) { int bFound = 0; FOR_EACH_LIST_ELMT (oaf, oa->objectAssignmentField) { if(strcmp(nt->fieldName, oaf->objectFieldName) == 0) { oaf->bPresent = 1; bFound = 1; break; } } if(!bFound) { ObjectAssignmentField *t; t = MT (ObjectAssignmentField); t->objectFieldName = nt->fieldName; t->bOptional = nt->type->optional; t->typeOrValue = NULL; APPEND (t, oa->objectAssignmentField); } } } /* LinkTypeDef */ void // Deepak: 04/Mar/2003 TypeLinkObjectAssignmentField PARAMS ((m, currMod, head, field), ModuleList *m _AND_ Module *currMod _AND_ ObjectAssignment *head _AND_ ObjectAssignmentField *field) { TypeOrValue *tOrV; if (field == NULL) return; tOrV = field->typeOrValue; if (tOrV->choiceId == TYPEORVALUE_TYPE) TypeLinkType (m, currMod, NULL, tOrV->a.type); else TypeLinkValue (m, currMod, NULL, NULL, tOrV->a.value); head = head; // avoids warning } void // Deepak: 04/Mar/2003 TypeLinkObjectSetAssignments PARAMS ((m, currMod, head), ModuleList *m _AND_ Module *currMod _AND_ ObjectSetAssignment *head) { TypeOrValue *tOrV; TypeDef *tmpTypeDef; ObjectAssignment *oa; if (head == NULL) return; // chk here objClassName CLASS exists or not. tmpTypeDef = LookupType (currMod->typeDefs, head->objectClassName); if(tmpTypeDef) // CLASS is defined { tmpTypeDef->localRefCount++; // CLASS is referenced here head->objectClassDefLink = tmpTypeDef->type->basicType->a.objectclass; // Deepak: 26/Mar/2003 } else // CLASS is not defined { currMod->status = MOD_ERROR; PrintErrLoc (currMod->asn1SrcFileName, (long)head->lineNo); fprintf (errFileG, "ERROR - CLASS \"%s\" is referenced but not defined.\n", head->objectClassName); } // then chk each object exists or not. FOR_EACH_LIST_ELMT (tOrV, head->objectNameList) { oa = LookupObjectClassObjectAssignment(currMod->objAssignments, tOrV->a.value->basicValue->a.namedValue->fieldName); tOrV->a.value->basicValue->a.objAssignment = oa; tOrV->a.value->basicValue->a.localValueRef->module = currMod; } //TypeLinkObjectAssignmentField (m, currMod, head, head->type); m = m; // avoids warning } /* LinkTypeDef */ /* * given a type def, it goes through the entire typedef * (aggregate parts if any) and links refs */ void TypeLinkTypeDef PARAMS ((m, currMod, head), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head) { if (head == NULL) return; TypeLinkType (m, currMod, head, head->type); } /* LinkTypeDef */ /* * given a type t, this routine goes through the components of * the type and links any type references */ void TypeLinkType PARAMS ((m, currMod, head, t), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *t) { if (t == NULL) return; /* like main type information */ TypeLinkBasicType (m, currMod, head, t, t->basicType); // Deepak: main job is done here... /* link any type references in the subtypes (if any)*/ TypeLinkSubtypes (m, currMod, head, t, t->subtypes); // Deepak: e.g. NumericString(SIZE(15)) has a subtype SIZE /* like type refs in the default value (if any) */ if (t->defaultVal != NULL) TypeLinkValue (m, currMod, NULL, t, t->defaultVal->value); } /* TypeLinkType */ /* * given a sequence of NamedTypes (components of a SET, SEQ or * CHOICE etc), this links any type refs in each one. */ void TypeLinkElmtTypes PARAMS ((m, currMod, head, e), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ NamedTypeList *e) { NamedType *n; FOR_EACH_LIST_ELMT (n, e) // Process All the elements in the sequence etc. { TypeLinkElmtType (m, currMod, head, n); } } /* TypeLinkElmtTypes */ void TypeLinkElmtType PARAMS ((m, currMod, head, n), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ NamedType *n) { if (n != NULL) TypeLinkType (m, currMod, head, n->type); } /* * given a BasicType, this links any type refs that are * part of it. */ void TypeLinkBasicType PARAMS ((m, currMod, head, type, bt), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *type _AND_ BasicType *bt) { TypeDef *tmpTypeDef; /*TypeDefList *tmpTypeDefs; */ Type *tmpType; /*Module *tmpMod; */ NamedType *tmpElmtType; ImportElmt *impElmt; ImportModule *impMod; /*int implicitRef; */ if (bt == NULL) return; switch (bt->choiceId) { case BASICTYPE_SEQUENCET: // Deepak: added on 29/Nov/2002 case BASICTYPE_SEQUENCE: case BASICTYPE_SET: case BASICTYPE_CHOICE: // Deepak: process the elements in sequence etc here. TypeLinkElmtTypes (m, currMod, head, bt->a.set); // Deepak: bt->a.set is of NamedTypeList* break; case BASICTYPE_BITCONTAINING: case BASICTYPE_OCTETCONTAINING: TypeLinkType (m, currMod, head, bt->a.stringContaining); break; case BASICTYPE_SEQUENCEOF: case BASICTYPE_SETOF: TypeLinkType (m, currMod, head, bt->a.setOf); break; case BASICTYPE_SELECTION: TypeLinkType (m, currMod, head, bt->a.selection->typeRef); /* * check that elmt type is CHOICE * and set up link (if resolved) */ tmpType = bt->a.selection->typeRef; if ((tmpType->basicType->choiceId == BASICTYPE_IMPORTTYPEREF) || (tmpType->basicType->choiceId == BASICTYPE_LOCALTYPEREF)) { tmpTypeDef = tmpType->basicType->a.importTypeRef->link; if (tmpTypeDef == NULL) /* unlinked import or local type */ { currMod->status = MOD_ERROR; return; } } else { PrintErrLoc (currMod->asn1SrcFileName, (long)type->lineNo); fprintf (errFileG, "ERROR - selection type defines type instead of referencing CHOICE field.\n"); currMod->status = MOD_ERROR; return; } /* * selections types must reference choice types */ tmpType = ParanoidGetType (tmpTypeDef->type); if (tmpType->basicType->choiceId != BASICTYPE_CHOICE) { PrintErrLoc (currMod->asn1SrcFileName, (long)type->lineNo); fprintf (errFileG, "ERROR - SELECTION types must reference a CHOICE type\n"); currMod->status = MOD_ERROR; return; } /* * find field ref'd by selection */ tmpElmtType = LookupFieldInType (tmpTypeDef->type, bt->a.selection->fieldName); if (tmpElmtType == NULL) { PrintErrLoc (currMod->asn1SrcFileName, (long)type->lineNo); fprintf (errFileG, "ERROR - selection type's reference field name \"%s\" is not in CHOICE \"%s\".\n", bt->a.selection->fieldName, tmpTypeDef->definedName); currMod->status = MOD_ERROR; return; } bt->a.selection->link = tmpElmtType; break; case BASICTYPE_COMPONENTSOF: TypeLinkType (m, currMod, head, bt->a.componentsOf); /* error checks done in normalize.c */ break; case BASICTYPE_ANYDEFINEDBY: /* * set the link to the defining field if not already linked */ if (bt->a.anyDefinedBy->link == NULL) { /* * get set or seq that holds this any def'd by */ tmpType = GetParentS (head->type, type); if (tmpType == NULL) { PrintErrLoc (currMod->asn1SrcFileName, (long)type->lineNo); fprintf (errFileG, " ERROR - could not find parent type for linking ANY DEFINED BY\n"); } /* * find "defining" field */ tmpElmtType = LookupFieldInType (tmpType, bt->a.anyDefinedBy->fieldName); if (tmpElmtType == NULL) { currMod->status = MOD_ERROR; PrintErrLoc (currMod->asn1SrcFileName, (long)type->lineNo); fprintf (errFileG, " ERROR - could not find identifier field \"%s\" in type \"%s\" for linking ANY DEFINED BY\n", bt->a.anyDefinedBy->fieldName, head->definedName); } bt->a.anyDefinedBy->link = tmpElmtType; } break; case BASICTYPE_OBJECTCLASSFIELDTYPE: // Deepak: added on 04/Feb/2003 { char* name; name = strchr(bt->a.localTypeRef->typeName, '.'); if(name) { NamedType *namedType; int pos = name - bt->a.localTypeRef->typeName; // Deepak: changed from malloc to Malloc //char* name2 = Malloc(sizeof(bt->a.localTypeRef->typeName + 1)); char* name2 = Malloc(strlen(bt->a.localTypeRef->typeName) + 1); strcpy(name2, bt->a.localTypeRef->typeName); name2[pos] = '\0'; // Name of CLASS tmpTypeDef = LookupType (currMod->typeDefs, name2); if(tmpTypeDef) // CLASS is defined { tmpTypeDef->localRefCount++; // CLASS is referenced here namedType = LookupObjectClassFieldType(tmpTypeDef->type->basicType->a.objectclass->classdef, &name[1]); if(namedType) // CLASS.&identifier is defined { TypeLinkBasicType (m, currMod, head, type, namedType->type->basicType); // Link the basic type & forget about the ObjectClassFieldType (choiceId:37) // only except when choice id == 0 // Deepak: 31/Mar/2003 if(namedType->type->basicType->choiceId) { type->basicType = namedType->type->basicType; type->tags = namedType->type->tags; // Deepak: 31/Mar/2003 } type->typeName = &name[1]; // Deepak: 26/Mar/2003 // Check for the TableConstraints are valid or not? // Deepak: 11/Mar/2003 if(type->tableConstraint) { ObjectSetAssignment *osa; osa = LookupObjectClassObjectSetAssignment (currMod->objSetAssignments, type->tableConstraint->objSetAssignment->objectSetName); if(osa) { head->bHasTableConstraint = TRUE; type->tableConstraint->objSetAssignment = osa; // Deepak: 26/Mar/2003 } else { currMod->status = MOD_ERROR; PrintErrLoc (currMod->asn1SrcFileName, (long)type->lineNo); fprintf (errFileG, "ERROR - TableConstraint \"%s\" is referenced but not defined.\n", type->tableConstraint->objSetAssignment->objectSetName); } ///////////////////////////////////////////////////////////////////////////// // Also to be checked the validity of AtNotations here ????? // LookupAtNotationsType (type->basicType->a.set, type->tableConstraint->atNotations); // A new func has to be written for this. ///////////////////////////////////////////////////////////////////////////// } } else // CLASS.&identifier is not defined { currMod->status = MOD_ERROR; PrintErrLoc (currMod->asn1SrcFileName, (long)type->lineNo); fprintf (errFileG, "ERROR - type \"%s\" is referenced but not defined in CLASS %s.\n", &name[1], name2); } } else // CLASS is not defined { currMod->status = MOD_ERROR; PrintErrLoc (currMod->asn1SrcFileName, (long)type->lineNo); fprintf (errFileG, "ERROR - CLASS \"%s\" is referenced but not defined.\n", name2); } } } break; case BASICTYPE_LOCALTYPEREF: /* * Remember: the parser sets any typeref it encounters * to LOCALTYPE_REF, so some Localtyperefs may be import * type refs. */ /* * First, look in this module's type defs and create a * resolvedLocalTypeRef if it's there. */ if ((tmpTypeDef = LookupType (currMod->typeDefs, bt->a.localTypeRef->typeName)) != NULL) { /* * locally defined type */ tmpTypeDef->localRefCount++; bt->a.localTypeRef->link = tmpTypeDef; bt->a.localTypeRef->module = currMod; break; /* finished here */ } // ~~~~~~~~~~~~ This else is for variableTypeValueFieldSpec ~~~~~~~~~~~~~~ else if(head && ((head->type->basicType->choiceId == BASICTYPE_OBJECTCLASS) // Deepak: 10/Feb/2003 /*|| (type->basicType->choiceId == BASICTYPE_OBJECTCLASSFIELDTYPE)*/ )) // Deepak: 24/Apr/2003 { //if(bt->a.localTypeRef->typeName[0] == '&') // i.e. variable type field { NamedType* namedType = NULL; namedType = LookupObjectClassFieldType(head->type->basicType->a.objectclass->classdef, bt->a.localTypeRef->typeName); if(namedType) { if(namedType->type->basicType->choiceId == BASICTYPE_UNKNOWN) { TypeLinkBasicType (m, currMod, head, type, namedType->type->basicType); type->basicType = namedType->type->basicType; } else { currMod->status = MOD_ERROR; PrintErrLoc (currMod->asn1SrcFileName, (long)type->lineNo); fprintf (errFileG, "ERROR - \"%s\" must be a type field. \n", bt->a.localTypeRef->typeName); } } else { currMod->status = MOD_ERROR; PrintErrLoc (currMod->asn1SrcFileName, (long)type->lineNo); fprintf (errFileG, "ERROR - \"%s\" is not a field of the CLASS \"%s\" \n", bt->a.localTypeRef->typeName, head->definedName); } break; } } else if(type->basicType->choiceId == BASICTYPE_OBJECTCLASSFIELDTYPE) { } else /* not locally defined type */ bt->choiceId = BASICTYPE_IMPORTTYPEREF; /* !!!!!! fall through !!!!!!!! */ case BASICTYPE_IMPORTTYPEREF: /* This handles "modname.type" type refs. */ if (bt->a.importTypeRef->moduleName != NULL) { /* * Lookup the import list maintained in this module * from the named module. (the parser generates * an import list from Foo module for "Foo.Bar" style * import refs) */ impMod = LookupImportModule (currMod, bt->a.importTypeRef->moduleName); if (impMod == NULL) /* whoa, compiler error */ { currMod->status = MOD_ERROR; fprintf (errFileG, "Compiler Error: \"%s.%s\" typeref - no import list defined from module \"%s\"\n", bt->a.importTypeRef->moduleName, bt->a.importTypeRef->typeName, bt->a.importTypeRef->moduleName); return; } impElmt = LookupImportElmtInImportElmtList (impMod->importElmts, bt->a.importTypeRef->typeName); if (impElmt == NULL) /* whoa, compiler error again */ { currMod->status = MOD_ERROR; fprintf (errFileG, "Compiler Error: \"%s.%s\" typeref - no import element defined for type \"%s\"\n", bt->a.importTypeRef->moduleName, bt->a.importTypeRef->typeName, bt->a.importTypeRef->typeName); return; } /* * should already be resolved unless could not find * the import for some reason */ if (impElmt->resolvedRef != NULL) { if (impElmt->resolvedRef->choiceId != IMPORTELMTCHOICE_TYPE) fprintf (errFileG, "Linker Warning: import TYPE ref \"%s\" resolves with an imported VALUE\n", impElmt->name); bt->a.importTypeRef->link = impElmt->resolvedRef->a.type; bt->a.importTypeRef->link->importRefCount++; bt->a.importTypeRef->module = impMod->moduleRef; } else { /* print loc of refs to unresolved imports */ PrintErrLoc (currMod->asn1SrcFileName, (long)type->lineNo); fprintf (errFileG, "reference to unresolved imported type \"%s\"\n", impElmt->name); } } else /* not a "modname.type" type ref */ { impElmt = LookupImportElmtInModule (currMod, bt->a.importTypeRef->typeName, &impMod); /* * privateScope one's should only resolve with one's * non-null module names (see last if) (mod.type form) */ if ((impElmt != NULL) && (!impElmt->privateScope)) { /* * should already be resolved unless could not find * the import for some reason */ if (impElmt->resolvedRef != NULL) { if (impElmt->resolvedRef->choiceId != IMPORTELMTCHOICE_TYPE) fprintf (errFileG, "Linker Warning: import TYPE ref \"%s\" resolves with an imported VALUE\n", impElmt->name); bt->a.importTypeRef->link = impElmt->resolvedRef->a.type; bt->a.importTypeRef->link->importRefCount++; bt->a.importTypeRef->module = impMod->moduleRef; } else { /* print loc of refs to unresolved imports */ PrintErrLoc (currMod->asn1SrcFileName, (long)type->lineNo); fprintf (errFileG, "reference to unresolved imported type \"%s\"\n", impElmt->name); } } else /* impElmt == NULL */ { /* * Type not defined locally, imported or * in useful types module. */ currMod->status = MOD_ERROR; PrintErrLoc (currMod->asn1SrcFileName, (long)type->lineNo); fprintf (errFileG, "ERROR - type \"%s\" is referenced but not defined or imported.\n", bt->a.importTypeRef->typeName); } } break; /* * these types may optionally have named elmts */ case BASICTYPE_INTEGER: case BASICTYPE_BITSTRING: case BASICTYPE_ENUMERATED: TypeLinkNamedElmts (m, currMod, head, type, bt->a.integer); break; /* * these types have no extra info and cause no linking action */ case BASICTYPE_UNKNOWN: case BASICTYPE_BOOLEAN: case BASICTYPE_OCTETSTRING: case BASICTYPE_NULL: case BASICTYPE_OID: case BASICTYPE_RELATIVE_OID: case BASICTYPE_REAL: case BASICTYPE_ANY: case BASICTYPE_EXTERNAL: case BASICTYPE_MACRODEF: case BASICTYPE_EXTENSION: break; /* Pierce 4-29-2002 Added as native types. no linking necessary */ case BASICTYPE_NUMERIC_STR: case BASICTYPE_PRINTABLE_STR: case BASICTYPE_GENERAL_STR: case BASICTYPE_IA5_STR: case BASICTYPE_BMP_STR: case BASICTYPE_UNIVERSAL_STR: case BASICTYPE_UTF8_STR: case BASICTYPE_T61_STR: case BASICTYPE_VISIBLE_STR: case BASICTYPE_GRAPHIC_STR: case BASICTYPE_GENERALIZEDTIME: case BASICTYPE_UTCTIME: case BASICTYPE_VIDEOTEX_STR: break; case BASICTYPE_MACROTYPE: switch (bt->a.macroType->choiceId) { case MACROTYPE_ROSOPERATION: case MACROTYPE_ASNABSTRACTOPERATION: TypeLinkRosOperationMacroType (m, currMod, head, type, bt, bt->a.macroType->a.rosOperation); break; case MACROTYPE_ROSERROR: case MACROTYPE_ASNABSTRACTERROR: TypeLinkRosErrorMacroType (m, currMod, head, type, bt, bt->a.macroType->a.rosError); break; case MACROTYPE_ROSBIND: case MACROTYPE_ROSUNBIND: TypeLinkRosBindMacroType (m, currMod, head, type, bt, bt->a.macroType->a.rosBind); break; case MACROTYPE_ROSASE: TypeLinkRosAseMacroType (m, currMod, head, type, bt, bt->a.macroType->a.rosAse); break; case MACROTYPE_MTSASEXTENSIONS: TypeLinkMtsasExtensionsMacroType (m, currMod, head, type, bt, bt->a.macroType->a.mtsasExtensions); break; case MACROTYPE_MTSASEXTENSION: TypeLinkMtsasExtensionMacroType (m, currMod, head, type, bt, bt->a.macroType->a.mtsasExtension); break; case MACROTYPE_MTSASEXTENSIONATTRIBUTE: TypeLinkMtsasExtensionAttributeMacroType (m, currMod, head, type, bt, bt->a.macroType->a.mtsasExtensionAttribute); break; case MACROTYPE_MTSASTOKEN: TypeLinkMtsasTokenMacroType (m, currMod, head, type, bt, bt->a.macroType->a.mtsasToken); break; case MACROTYPE_MTSASTOKENDATA: TypeLinkMtsasTokenDataMacroType (m, currMod, head, type, bt, bt->a.macroType->a.mtsasTokenData); break; case MACROTYPE_MTSASSECURITYCATEGORY: TypeLinkMtsasSecurityCategoryMacroType (m, currMod, head, type, bt, bt->a.macroType->a.mtsasSecurityCategory); break; case MACROTYPE_ASNOBJECT: TypeLinkAsnObjectMacroType (m, currMod, head, type, bt, bt->a.macroType->a.asnObject); break; case MACROTYPE_ASNPORT: TypeLinkAsnPortMacroType (m, currMod, head, type, bt, bt->a.macroType->a.asnPort); break; case MACROTYPE_ASNABSTRACTBIND: case MACROTYPE_ASNABSTRACTUNBIND: TypeLinkAsnAbstractBindMacroType (m, currMod, head, type, bt, bt->a.macroType->a.asnAbstractBind); break; case MACROTYPE_AFALGORITHM: case MACROTYPE_AFENCRYPTED: case MACROTYPE_AFPROTECTED: case MACROTYPE_AFSIGNATURE: case MACROTYPE_AFSIGNED: TypeLinkType (m, currMod, head, bt->a.macroType->a.afAlgorithm); break; case MACROTYPE_SNMPOBJECTTYPE: TypeLinkSnmpObjectTypeMacroType (m, currMod, head, type, bt, bt->a.macroType->a.snmpObjectType); break; default: fprintf (errFileG, "TypeLinkBasicType: ERROR - unknown macro type id!\n"); } break; case BASICTYPE_OBJECTCLASS: // Deepak: 28/Jan/2003 { // Deepak: process the elements in objectclass here. TypeLinkElmtTypes (m, currMod, head, bt->a.objectclass->classdef); if(bt->a.objectclass->withsyntax) TypeLinkWithSyntaxes (m, currMod, head, bt->a.objectclass); } break; default: fprintf (errFileG, "TypeLinkBasicType: ERROR - unknown basic type id!\n"); } } /* LinkBasicType */ /* Deepak: 05/Mar/2003 * given a ObjectClassDef, this Checks any with syntax refs that are * part of it. */ void TypeLinkWithSyntaxes PARAMS ((m, currMod, head, ocd), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ ObjectClassDef *ocd) { WithSyntax* ws; NamedType *nt; if (ocd == NULL) return; FOR_EACH_LIST_ELMT (ws, ocd->withsyntax) { nt = LookupObjectClassFieldType(ocd->classdef, ws->typeName); if(nt == NULL) { currMod->status = MOD_ERROR; PrintErrLoc (currMod->asn1SrcFileName, (long)ws->lineNo); fprintf (errFileG, "ERROR - type \"%s\" is referenced but not defined in CLASS %s.\n", ws->typeName, head->definedName); } else { // WS is Present // Now, Perform Optionality Test // Here check if the type is having default value or not? int bTempTypeOptional = nt->type->optional; if(nt->type->defaultVal) bTempTypeOptional = 1; // Assume that the parameter is optional if the default value is not NULL if (bTempTypeOptional != ws->bOptional) { currMod->status = MOD_ERROR; PrintErrLoc (currMod->asn1SrcFileName, (long)ws->lineNo); if(ws->bOptional) { fprintf (errFileG, "ERROR - type \"[%s]\" in CLASS \"%s\" should be defined as \"%s\"\n", ws->definedName, head->definedName, ws->definedName); } else { fprintf (errFileG, "ERROR - type \"%s\" in CLASS \"%s\" should be defined as \"[%s]\"\n", ws->definedName, head->definedName, ws->definedName); } } } } m=m; // avoids warning } /* TypeLinkWithSyntaxes */ /* Deepak: 05/Mar/2003 */ /*void TypeLinkWithSyntax PARAMS ((m, currMod, head, classdef, ws), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ NamedTypeList* classdef _AND_ WithSyntax* ws) { NamedType *nt; if (ws == NULL) return; FOR_EACH_LIST_ELMT (nt, classdef) { //////// } }*/ /* TypeLinkWithSyntax */ /////////////////////////////////////////////////////////////////////////////// /* * resolve any type/value refs in the subtypes (if any) */ void TypeLinkSubtypes PARAMS ((m, currMod, head, currType, s), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *currType _AND_ Subtype *s) { Subtype *sElmt; if (s == NULL) return; switch (s->choiceId) { case SUBTYPE_SINGLE: TypeLinkSubtypeValue(m, currMod, head, currType, s->a.single); break; case SUBTYPE_AND: case SUBTYPE_OR: FOR_EACH_LIST_ELMT (sElmt, s->a.and) TypeLinkSubtypes(m, currMod, head, currType, sElmt); break; case SUBTYPE_NOT: TypeLinkSubtypes(m, currMod, head, currType, s->a.not); default: fprintf (errFileG, "TypeLinkSubtypes: ERROR - unknown Subtype id\n"); break; } } /* TypeLinkSubtypes */ /* * link any type referenced in the value parts of subtypes */ void TypeLinkSubtypeValue PARAMS ((m, currMod, head, currType, s), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *currType _AND_ SubtypeValue *s) { Constraint *constraint; if (s == NULL) return; switch (s->choiceId) { case SUBTYPEVALUE_SINGLEVALUE: TypeLinkValue (m, currMod, NULL, currType, s->a.singleValue); break; case SUBTYPEVALUE_CONTAINED: TypeLinkType (m, currMod, head, s->a.contained); break; case SUBTYPEVALUE_VALUERANGE: TypeLinkValue (m, currMod, NULL, currType, s->a.valueRange->lowerEndValue->endValue); TypeLinkValue (m, currMod, NULL, currType, s->a.valueRange->upperEndValue->endValue); break; case SUBTYPEVALUE_PERMITTEDALPHABET: TypeLinkSubtypes (m, currMod, head, currType, s->a.permittedAlphabet); break; case SUBTYPEVALUE_SIZECONSTRAINT: TypeLinkSubtypes (m, currMod, head, currType, s->a.sizeConstraint); break; case SUBTYPEVALUE_INNERSUBTYPE: FOR_EACH_LIST_ELMT (constraint, s->a.innerSubtype->constraints) { TypeLinkSubtypes (m, currMod, head, currType, constraint->valueConstraints); } break; default: fprintf (errFileG, "TypeLinkSubtype: ERROR - unknown subtype choiceId\n"); } } /* TypeLinkSubtype */ /* * go through named elements of INTEGER/ENUMERATED/BOOLEAN * and link any type refs in the values */ void TypeLinkNamedElmts PARAMS ((m, currMod, head, t, v), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *t _AND_ ValueDefList *v) { ValueDef *vd; FOR_EACH_LIST_ELMT (vd, v) { TypeLinkValue (m, currMod, vd, vd->value->type, vd->value); } t = t; /* AVOIDS compiler warning.*/ head = head; } /* TypeLinkNamedElmts */ /* * only use this for 'real' value defs * ie those in the value def list - not ones for namedElmts * since infinitite recursion can result from the * attempt to link the values type which will try to link * this value again. */ void TypeLinkValueDef PARAMS ((m, currMod, v), ModuleList *m _AND_ Module *currMod _AND_ ValueDef *v) { if (v == NULL) return; TypeLinkType (m, currMod, NULL, v->value->type); // Deepak: chk the type of the value defined here. if ((v->value->valueType == BASICTYPE_UNKNOWN) && (v->value->type != NULL)) v->value->valueType = v->value->type->basicType->choiceId; } /* TypeLinkValueDef */ /* * link any type refs associated with the given value. * also sets the values type field with the given * 'valuesType' Type. */ void TypeLinkValue PARAMS ((m, currMod, head, valuesType, v), ModuleList *m _AND_ Module *currMod _AND_ ValueDef *head _AND_ Type *valuesType _AND_ Value *v) { if (v == NULL) return; v->type = valuesType; /* TypeLinkType (m, currMod, NULL, v->typeRef); */ if ((v->valueType == BASICTYPE_UNKNOWN) && (valuesType != NULL)) v->valueType = valuesType->basicType->choiceId; head = head; /* AVOIDS compiler warning.*/ currMod = currMod; m = m; } /* TypeLinkValue */ /* * link any type refs in this macro's parsed data struct */ void TypeLinkRosOperationMacroType PARAMS ((m, currMod, head, t, bt, op), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ RosOperationMacroType *op) { TypeOrValue *tOrV; if (op->arguments != NULL) TypeLinkType (m, currMod, head, op->arguments->type); if (op->result != NULL) TypeLinkType (m, currMod, head, op->result->type); /* * go through errors (if any) and link types/values */ FOR_EACH_LIST_ELMT (tOrV, op->errors) { if (tOrV->choiceId == TYPEORVALUE_TYPE) TypeLinkType (m, currMod, head, tOrV->a.type); else TypeLinkValue (m, currMod, NULL, t, tOrV->a.value); } /* * go through linked operations (if any) and * link types/values */ FOR_EACH_LIST_ELMT (tOrV, op->linkedOps) { if (tOrV->choiceId == TYPEORVALUE_TYPE) TypeLinkType (m, currMod, head, tOrV->a.type); else TypeLinkValue (m, currMod, NULL, t, tOrV->a.value); } bt = bt; /*AVOIDS Compiler warning.*/ } /* TypeLinkRosOperationMacroType */ /* * link any type refs in this macro's parsed data struct */ void TypeLinkRosErrorMacroType PARAMS ((m, currMod, head, t, bt, err), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ RosErrorMacroType *err) { if ((err != NULL) && (err->parameter != NULL)) { TypeLinkType (m, currMod, head, err->parameter->type); } bt = bt; /*AVOIDS Compiler warning.*/ t = t; } /* TypeLinkRosErrorMacroType */ /* * link any type refs in this macro's parsed data struct */ void TypeLinkRosBindMacroType PARAMS ((m, currMod, head, t, bt, bind), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ RosBindMacroType *bind) { if (bind != NULL) { TypeLinkElmtType (m, currMod, head, bind->argument); TypeLinkElmtType (m, currMod, head, bind->result); TypeLinkElmtType (m, currMod, head, bind->error); } bt = bt; /*AVOIDS Compiler warning.*/ t = t; } /* TypeLinkRosBindMacroType */ /* * link any type refs in this macro's parsed data struct */ void TypeLinkRosAseMacroType PARAMS ((m, currMod, head, t, bt, ase), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ RosAseMacroType *ase) { Value *v; FOR_EACH_LIST_ELMT (v, ase->operations) TypeLinkValue (m, currMod, NULL, t, v); FOR_EACH_LIST_ELMT (v, ase->consumerInvokes) TypeLinkValue (m, currMod, NULL, t, v); FOR_EACH_LIST_ELMT (v, ase->supplierInvokes) TypeLinkValue (m, currMod, NULL, t, v); bt = bt; /*AVOIDS Compiler warning.*/ head = head; } /* TypeLinkRosAseMacroType */ /* * link any type refs in this macro's parsed data struct */ void TypeLinkRosAcMacroType PARAMS ((m, currMod, head, t, bt, ac), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ RosAcMacroType *ac) { Value *v; /*OID *oid; */ FOR_EACH_LIST_ELMT (v, ac->nonRoElements) TypeLinkValue (m, currMod, NULL, t, v); TypeLinkType (m, currMod, head, ac->bindMacroType); TypeLinkType (m, currMod, head, ac->unbindMacroType); FOR_EACH_LIST_ELMT (v, ac->operationsOf) TypeLinkValue (m, currMod, NULL, t, v); FOR_EACH_LIST_ELMT (v, ac->initiatorConsumerOf) TypeLinkValue (m, currMod, NULL, t, v); FOR_EACH_LIST_ELMT (v, ac->responderConsumerOf) TypeLinkValue (m, currMod, NULL, t, v); bt = bt; /*AVOIDS Compiler warning.*/ head = head; } /* TypeLinkRosAcMacroType */ /* * link any type refs in this macro's parsed data struct */ void TypeLinkMtsasExtensionsMacroType PARAMS ((m, currMod, head, t, bt, exts), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ MtsasExtensionsMacroType *exts) { Value *v; FOR_EACH_LIST_ELMT (v, exts->extensions) TypeLinkValue (m, currMod, NULL, t, v); bt= bt; /*AVOIDS Compiler warning.*/ head = head; } /* TypeLinkMtsasExtensionsMacroType */ /* * link any type refs in this macro's parsed data struct */ void TypeLinkMtsasExtensionMacroType PARAMS ((m, currMod, head, t, bt, ext), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ MtsasExtensionMacroType *ext) { TypeLinkElmtType (m, currMod, head, ext->elmtType); TypeLinkValue (m, currMod, NULL, t, ext->defaultValue); bt = bt; /*AVOIDS Compiler warning.*/ } /* TypeLinkMtsasExtensionMacroType */ /* * link any type refs in this macro's parsed data struct */ void TypeLinkMtsasExtensionAttributeMacroType PARAMS ((m, currMod, head, t, bt, ext), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ MtsasExtensionAttributeMacroType *ext) { if (ext != NULL) TypeLinkType (m, currMod, head, ext->type); bt = bt; /*AVOIDS Compiler warning.*/ t = t; } /* TypeLinkMtsasExtensionAttributeMacroType */ /* * link any type refs in this macro's parsed data struct */ void TypeLinkMtsasTokenMacroType PARAMS ((m, currMod, head, t, bt, tok), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ MtsasTokenMacroType *tok) { if (tok != NULL) TypeLinkType (m, currMod, head, tok->type); bt = bt ; /*AVOIDS Compiler warning.*/ t = t; } /* TypeLinkMtsasTokenMacroType */ /* * link any type refs in this macro's parsed data struct */ void TypeLinkMtsasTokenDataMacroType PARAMS ((m, currMod, head, t, bt, tok), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ MtsasTokenDataMacroType *tok) { if (tok != NULL) TypeLinkType (m, currMod, head, tok->type); bt = bt; /*AVOIDS Compiler warning.*/ t = t; } /* TypeLinkMtsasTokenDataMacroType */ /* * link any type refs in this macro's parsed data struct */ void TypeLinkMtsasSecurityCategoryMacroType PARAMS ((m, currMod, head, t, bt, sec), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ MtsasSecurityCategoryMacroType *sec) { if (sec != NULL) TypeLinkType (m, currMod, head, sec->type); bt = bt; /*AVOIDS Compiler warning.*/ t = t; } /* TypeLinkMtsasSecurityCategoryMacroType */ /* * link any type refs in this macro's parsed data struct */ void TypeLinkAsnObjectMacroType PARAMS ((m, currMod, head, t, bt, obj), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ AsnObjectMacroType *obj) { AsnPort *ap; FOR_EACH_LIST_ELMT (ap, obj->ports) TypeLinkValue (m, currMod, NULL, t, ap->portValue); bt = bt; /*AVOIDS Compiler warning.*/ head = head; } /* TypeLinkAsnObjectMacroType */ /* * link any type refs in this macro's parsed data struct */ void TypeLinkAsnPortMacroType PARAMS ((m, currMod, head, t, bt, p), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ AsnPortMacroType *p) { TypeOrValue *tOrV; FOR_EACH_LIST_ELMT (tOrV, p->abstractOps) { if (tOrV->choiceId == TYPEORVALUE_TYPE) TypeLinkType (m, currMod, head, tOrV->a.type); else TypeLinkValue (m, currMod, NULL, t, tOrV->a.value); } FOR_EACH_LIST_ELMT (tOrV, p->supplierInvokes) { if (tOrV->choiceId == TYPEORVALUE_TYPE) TypeLinkType (m, currMod, head, tOrV->a.type); else TypeLinkValue (m, currMod, NULL, t, tOrV->a.value); } FOR_EACH_LIST_ELMT (tOrV, p->consumerInvokes) { if (tOrV->choiceId == TYPEORVALUE_TYPE) TypeLinkType (m, currMod, head, tOrV->a.type); else TypeLinkValue (m, currMod, NULL, t, tOrV->a.value); } bt = bt; /*AVOIDS Compiler warning.*/ } /* TypeLinkAsnPortMacroType */ /* * link any type refs in this macro's parsed data struct */ void TypeLinkAsnAbstractBindMacroType PARAMS ((m, currMod, head, t, bt, bind), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ AsnAbstractBindMacroType *bind) { AsnPort *ap; FOR_EACH_LIST_ELMT (ap, bind->ports) TypeLinkValue (m, currMod, NULL, t, ap->portValue); bt = bt; /*AVOIDS Compiler warning.*/ head = head; } /* TypeLinkAsnBindMacroType */ /* * link any type refs in this macro's parsed data struct */ void TypeLinkSnmpObjectTypeMacroType PARAMS ((m, currMod, head, t, bt, ot), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ SnmpObjectTypeMacroType *ot) { TypeOrValue *tOrV; TypeLinkType (m, currMod, head, ot->syntax); TypeLinkValue (m, currMod, NULL, t, ot->description); TypeLinkValue (m, currMod, NULL, t, ot->reference); TypeLinkValue (m, currMod, NULL, t, ot->defVal); FOR_EACH_LIST_ELMT (tOrV, ot->index) { if (tOrV->choiceId == TYPEORVALUE_TYPE) TypeLinkType (m, currMod, head, tOrV->a.type); else TypeLinkValue (m, currMod, NULL, t, tOrV->a.value); } bt = bt; /*AVOIDS Compiler warning.*/ } /* TypeLinkSnmpObjectTypeMacroType */ esnacc-ng-1.8.1/compiler/core/link-values.c000066400000000000000000001130301302010526100205030ustar00rootroot00000000000000/* * compiler/core/link.c * * first links value refs in the import list then * links value references in value defs and types' default values * * * Mike Sample * 91/09/04 * Completely Rewritten for new ModuleList data structure (ASN.1 based) * * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/core/link-values.c,v 1.14 2004/04/06 15:13:41 gronej Exp $ * $Log: link-values.c,v $ * Revision 1.14 2004/04/06 15:13:41 gronej * *** empty log message *** * * Revision 1.13 2004/01/29 21:21:45 gronej * Took all Init() calls out of Clear() functions in generated code * * Revision 1.12 2004/01/14 19:07:52 gronej * Updated Compiler to accept and process relative-oid's * * Revision 1.11 2003/07/14 21:07:44 nicholar * Changed how parser handles --snacc directives. Added namespace option. * * Revision 1.10 2003/07/07 14:50:13 nicholar * Eliminated headers and cleaned up include references * * Revision 1.9 2003/04/29 21:08:25 leonberp * integerated Deepak's changes for IOB support * * Revision 1.8 2002/11/01 17:16:21 mcphersc * added import used * * Revision 1.7 2002/10/28 19:57:03 leonberp * Added BITSTRING CONTAINING support and fixed CONTAINED ANY DEFINED BY * * Revision 1.6 2002/10/24 21:07:22 leonberp * latest fixing for OCTET CONTAINING * * Revision 1.5 2002/09/16 16:50:08 mcphersc * Fixed warnings * * Revision 1.4 2002/09/04 18:23:06 vracarl * got rid of c++ comments * * Revision 1.3 2002/05/15 17:00:59 leonberp * added support for new basicTypes to compiler * * Revision 1.2 2000/10/24 14:54:53 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:36:00 leonberp * First CVS Version of SNACC. * * Revision 1.3 1995/07/25 19:41:38 rj * changed `_' to `-' in file names. * * Revision 1.2 1994/09/01 00:38:43 rj * snacc_config.h removed. * * Revision 1.1 1994/08/28 09:49:19 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include #include "asn-incl.h" #include "asn1module.h" #include "snacc-util.h" /* non-exported fcn prototypes */ void ValueLinkImportLists PROTO ((ModuleList *m)); void ValueLinkTypeDef PROTO ((ModuleList *m, Module *currMod, TypeDef *head)); void ValueLinkElmtTypes PROTO ((ModuleList *m, Module *currMod, TypeDef *head, NamedTypeList *e)); void ValueLinkElmtType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, NamedType *n)); void ValueLinkTag PROTO ((ModuleList *m, Module *currMod, Type *t, Tag *tag)); void ValueLinkType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *currType)); void ValueLinkBasicType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *type, BasicType *bt)); void ValueLinkSubtypes PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *currType, Subtype *s)); void ValueLinkSubtypeValue PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *currType, SubtypeValue *s)); void ValueLinkNamedElmts PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, ValueDefList *v)); void ValueLinkValueDef PROTO ((ModuleList *m, Module *currMod, ValueDef *v)); void ValueLinkValue PROTO ((ModuleList *m, Module *currMod, ValueDef *head, Type *valuesType, Value *v)); void ValueLinkBasicValue PROTO ((ModuleList *m, Module *currMod, ValueDef *head, Type *valuesType, Value *v, BasicValue *bv)); void ValueLinkOid PROTO ((ModuleList *m, Module *currMod, ValueDef *head, Value *v, OID *oid)); void ValueLinkRosOperationMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, RosOperationMacroType *op)); void ValueLinkRosErrorMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, RosErrorMacroType *err)); void ValueLinkRosBindMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, RosBindMacroType *bind)); void ValueLinkRosAseMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, RosAseMacroType *ase)); void ValueLinkRosAcMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, RosAcMacroType *ac)); void ValueLinkMtsasExtensionsMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, MtsasExtensionsMacroType *exts)); void ValueLinkMtsasExtensionMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, MtsasExtensionMacroType *ext)); void ValueLinkMtsasExtensionAttributeMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, MtsasExtensionAttributeMacroType *ext)); void ValueLinkMtsasTokenMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, MtsasTokenMacroType *tok)); void ValueLinkMtsasTokenDataMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, MtsasTokenDataMacroType *tok)); void ValueLinkMtsasSecurityCategoryMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, MtsasSecurityCategoryMacroType *sec)); void ValueLinkAsnObjectMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, AsnObjectMacroType *obj)); void ValueLinkAsnPortMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, AsnPortMacroType *p)); void ValueLinkAsnAbstractBindMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, AsnAbstractBindMacroType *bind)); void ValueLinkSnmpObjectTypeMacroType PROTO ((ModuleList *m, Module *currMod, TypeDef *head, Type *t, BasicType *bt, SnmpObjectTypeMacroType *ot)); /* end of prototypes */ static char *asn1SrcFileNameG; static int linkOidCallDepthG = 0; /* big hack!! */ /* * returns 0 if no link error occured * otherwise returns a value < 0. * processing should not continue is an error is returned */ int LinkValueRefs PARAMS ((m), ModuleList *m) { Module *currMod; TypeDef *td; ValueDef *vd; int linkErr = 0; /* * link imported types/values to there definition if * the defining module is in the modulelist */ ValueLinkImportLists (m); /* * go through types, values & macros of each parsed module */ FOR_EACH_LIST_ELMT (currMod, m) { asn1SrcFileNameG = currMod->asn1SrcFileName; /* * link this modules object identifier value */ ValueLinkOid (m, currMod, NULL, NULL, currMod->modId->oid); /* * go through each type in typeList and link as nec */ FOR_EACH_LIST_ELMT (td, currMod->typeDefs) { ValueLinkTypeDef (m, currMod, td); } /* * go through each value in valueList and link as nec */ FOR_EACH_LIST_ELMT (vd, currMod->valueDefs) { ValueLinkValueDef (m, currMod, vd); } if (currMod->status != MOD_ERROR) { currMod->ImportUsed = TRUE; currMod->status = MOD_OK; } else linkErr = -1; } return linkErr; } /* ValueLinkRefs */ /* * go through each modules import lists and link * any values as nec. values'symbols start with a * lowercase letter */ void ValueLinkImportLists PARAMS ((m), ModuleList *m) { Module *currMod; ValueDef *v; ImportModule *currImpList; ImportElmt *currImpElmt; Module *impRefMod; /* link imports of each module in the list */ FOR_EACH_LIST_ELMT (currMod, m) { /* for each import list in the current module */ FOR_EACH_LIST_ELMT (currImpList, currMod->imports) { /* see if the referenced module is in the list */ impRefMod = LookupModule (m, currImpList->modId->name, currImpList->modId->oid); if (impRefMod == NULL) { /* the type linker will have reported this error */ continue; } /* * link each value referencing import elmt in * the current import list */ FOR_EACH_LIST_ELMT (currImpElmt, currImpList->importElmts) { /* * only link values (all vals have lowercase first letter) */ if (!islower (currImpElmt->name[0])) continue; v = LookupValue (impRefMod->valueDefs, currImpElmt->name); if (v != NULL) { if (!v->exported) { currMod->status = MOD_ERROR; PrintErrLoc (currMod->asn1SrcFileName, (long)currImpElmt->lineNo); fprintf (errFileG, "ERROR - \"%s\" module imports value \"%s\", which is not exported from module \"%s\".\n", currMod->modId->name, currImpElmt->name, impRefMod->modId->name); } /* resolve value */ currImpElmt->resolvedRef = (ImportElmtChoice*)Malloc (sizeof (ImportElmtChoice)); currImpElmt->resolvedRef->choiceId = IMPORTELMTCHOICE_VALUE; currImpElmt->resolvedRef->a.value = v; } else /* value not found in ref'd module */ { currMod->status = MOD_ERROR; PrintErrLoc (currMod->asn1SrcFileName, (long)currImpElmt->lineNo); fprintf (errFileG, "ERROR - \"%s\" is imported from module \"%s\" by module \"%s\", but is not defined in the referenced module\n", currImpElmt->name, impRefMod->modId->name, currMod->modId->name); } } } } } /* ValueLinkImportLists */ void ValueLinkTypeDef PARAMS ((m, currMod, head), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head) { if (head == NULL) return; ValueLinkType (m, currMod, head, head->type); } /* ValueLinkTypeDef */ void ValueLinkType PARAMS ((m, currMod, head, t), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *t) { Tag *tag; if (t == NULL) return; // Link any values that appear in the tags FOR_EACH_LIST_ELMT (tag, t->tags) { ValueLinkTag (m, currMod, t, tag); } ValueLinkBasicType (m, currMod, head, t, t->basicType); ValueLinkSubtypes (m, currMod, head, t, t->subtypes); if (t->defaultVal != NULL) ValueLinkValue (m, currMod, NULL, t, t->defaultVal->value); } /* ValueLinkType */ void ValueLinkTag PARAMS ((m, currMod, head, tag), ModuleList *m _AND_ Module *currMod _AND_ Type *t _AND_ Tag *tag) { if (tag->valueRef == NULL) return; ValueLinkValue (m, currMod, NULL, t, tag->valueRef); } /* ValueLinkTag */ void ValueLinkElmtTypes PARAMS ((m, currMod, head, e), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ NamedTypeList *e) { NamedType *n; FOR_EACH_LIST_ELMT (n, e) { ValueLinkElmtType (m, currMod, head, n); } } /* ValueLinkElmtTypes */ void ValueLinkElmtType PARAMS ((m, currMod, head, n), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ NamedType *n) { if (n != NULL) ValueLinkType (m, currMod, head, n->type); } void ValueLinkBasicType PARAMS ((m, currMod, head, type, bt), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *type _AND_ BasicType *bt) { if (bt == NULL) return; switch (bt->choiceId) { case BASICTYPE_SEQUENCET: // Deepak: added on 29/Nov/2002 case BASICTYPE_SEQUENCE: case BASICTYPE_SET: case BASICTYPE_CHOICE: // Deepak: process the elements in sequence etc here. ValueLinkElmtTypes (m, currMod, head, bt->a.set); break; case BASICTYPE_SEQUENCEOF: case BASICTYPE_SETOF: ValueLinkType (m, currMod, head, bt->a.setOf); break; case BASICTYPE_OBJECTCLASS: // Deepak: added on 31/03/2003 ValueLinkElmtTypes (m, currMod, head, bt->a.objectclass->classdef); break; case BASICTYPE_SELECTION: case BASICTYPE_COMPONENTSOF: case BASICTYPE_ANYDEFINEDBY: case BASICTYPE_LOCALTYPEREF: case BASICTYPE_IMPORTTYPEREF: case BASICTYPE_OBJECTCLASSFIELDTYPE: // Deepak: added on 05/Feb/2003 break; /* * these types may optionally have named elmts */ case BASICTYPE_INTEGER: case BASICTYPE_BITSTRING: case BASICTYPE_ENUMERATED: ValueLinkNamedElmts (m, currMod, head, type, bt->a.integer); break; /* * these types have no extra info and cause no linking action */ case BASICTYPE_UNKNOWN: case BASICTYPE_BOOLEAN: case BASICTYPE_OCTETSTRING: case BASICTYPE_NULL: case BASICTYPE_OID: case BASICTYPE_RELATIVE_OID: case BASICTYPE_REAL: case BASICTYPE_EXTERNAL: case BASICTYPE_ANY: case BASICTYPE_MACRODEF: case BASICTYPE_NUMERIC_STR: case BASICTYPE_PRINTABLE_STR: case BASICTYPE_VISIBLE_STR: case BASICTYPE_GRAPHIC_STR: case BASICTYPE_VIDEOTEX_STR: case BASICTYPE_GENERAL_STR: case BASICTYPE_IA5_STR: case BASICTYPE_BMP_STR: case BASICTYPE_UNIVERSAL_STR: case BASICTYPE_UTF8_STR: case BASICTYPE_T61_STR: case BASICTYPE_GENERALIZEDTIME: case BASICTYPE_UTCTIME: case BASICTYPE_OBJECTDESCRIPTOR: case BASICTYPE_OCTETCONTAINING: case BASICTYPE_BITCONTAINING: case BASICTYPE_EXTENSION: break; /* * these have no more info - only the choiceId is used */ case BASICTYPE_MACROTYPE: switch (bt->a.macroType->choiceId) { case MACROTYPE_ROSOPERATION: case MACROTYPE_ASNABSTRACTOPERATION: ValueLinkRosOperationMacroType (m, currMod, head, type, bt, bt->a.macroType->a.rosOperation); break; case MACROTYPE_ROSERROR: case MACROTYPE_ASNABSTRACTERROR: ValueLinkRosErrorMacroType (m, currMod, head, type, bt, bt->a.macroType->a.rosError); break; case MACROTYPE_ROSBIND: case MACROTYPE_ROSUNBIND: ValueLinkRosBindMacroType (m, currMod, head, type, bt, bt->a.macroType->a.rosBind); break; case MACROTYPE_ROSASE: ValueLinkRosAseMacroType (m, currMod, head, type, bt, bt->a.macroType->a.rosAse); break; case MACROTYPE_MTSASEXTENSIONS: ValueLinkMtsasExtensionsMacroType (m, currMod, head, type, bt, bt->a.macroType->a.mtsasExtensions); break; case MACROTYPE_MTSASEXTENSION: ValueLinkMtsasExtensionMacroType (m, currMod, head, type, bt, bt->a.macroType->a.mtsasExtension); break; case MACROTYPE_MTSASEXTENSIONATTRIBUTE: ValueLinkMtsasExtensionAttributeMacroType (m, currMod, head, type, bt, bt->a.macroType->a.mtsasExtensionAttribute); break; case MACROTYPE_MTSASTOKEN: ValueLinkMtsasTokenMacroType (m, currMod, head, type, bt, bt->a.macroType->a.mtsasToken); break; case MACROTYPE_MTSASTOKENDATA: ValueLinkMtsasTokenDataMacroType (m, currMod, head, type, bt, bt->a.macroType->a.mtsasTokenData); break; case MACROTYPE_MTSASSECURITYCATEGORY: ValueLinkMtsasSecurityCategoryMacroType (m, currMod, head, type, bt, bt->a.macroType->a.mtsasSecurityCategory); break; case MACROTYPE_ASNOBJECT: ValueLinkAsnObjectMacroType (m, currMod, head, type, bt, bt->a.macroType->a.asnObject); break; case MACROTYPE_ASNPORT: ValueLinkAsnPortMacroType (m, currMod, head, type, bt, bt->a.macroType->a.asnPort); break; case MACROTYPE_ASNABSTRACTBIND: case MACROTYPE_ASNABSTRACTUNBIND: ValueLinkAsnAbstractBindMacroType (m, currMod, head, type, bt, bt->a.macroType->a.asnAbstractBind); break; case MACROTYPE_AFALGORITHM: case MACROTYPE_AFENCRYPTED: case MACROTYPE_AFPROTECTED: case MACROTYPE_AFSIGNATURE: case MACROTYPE_AFSIGNED: ValueLinkType (m, currMod, head, bt->a.macroType->a.afAlgorithm); break; case MACROTYPE_SNMPOBJECTTYPE: ValueLinkSnmpObjectTypeMacroType (m, currMod, head, type, bt, bt->a.macroType->a.snmpObjectType); break; default: fprintf (errFileG, "ValueLinkBasicType: ERROR - unknown macro type id!\n"); break; } break; default: fprintf (errFileG, "ValueLinkBasicType: ERROR - unknown basic type id!\n"); } } /* ValueLinkBasicType */ /* * resolve any type/value refs in the subtypes (if any) */ void ValueLinkSubtypes PARAMS ((m, currMod, head, currType, s), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *currType _AND_ Subtype *s) { Subtype *sElmt; if (s == NULL) return; switch (s->choiceId) { case SUBTYPE_SINGLE: ValueLinkSubtypeValue (m, currMod, head, currType, s->a.single); break; case SUBTYPE_AND: case SUBTYPE_OR: case SUBTYPE_NOT: FOR_EACH_LIST_ELMT (sElmt, s->a.and) { ValueLinkSubtypes (m, currMod, head, currType, sElmt); } break; default: fprintf (errFileG, "ValueLinkSubtypes: ERROR - unknown Subtype id\n"); break; } } /* ValueLinkSubtypes */ void ValueLinkSubtypeValue PARAMS ((m, currMod, head, currType, s), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *currType _AND_ SubtypeValue *s) { Constraint *constraint; if (s == NULL) return; switch (s->choiceId) { case SUBTYPEVALUE_SINGLEVALUE: ValueLinkValue (m, currMod, NULL, currType, s->a.singleValue); break; case SUBTYPEVALUE_CONTAINED: ValueLinkType (m, currMod, head, s->a.contained); break; case SUBTYPEVALUE_VALUERANGE: ValueLinkValue (m, currMod, NULL, currType, s->a.valueRange->lowerEndValue->endValue); ValueLinkValue (m, currMod, NULL, currType, s->a.valueRange->upperEndValue->endValue); break; case SUBTYPEVALUE_PERMITTEDALPHABET: ValueLinkSubtypes (m, currMod, head, currType, s->a.permittedAlphabet); break; case SUBTYPEVALUE_SIZECONSTRAINT: ValueLinkSubtypes (m, currMod, head, currType, s->a.sizeConstraint); break; case SUBTYPEVALUE_INNERSUBTYPE: FOR_EACH_LIST_ELMT (constraint, s->a.innerSubtype->constraints) { ValueLinkSubtypes (m, currMod, head, currType, constraint->valueConstraints); } break; default: fprintf (errFileG, "ValueLinkSubtype: ERROR - unknown subtype choiceId\n"); } } /* ValueLinkSubtype */ void ValueLinkNamedElmts PARAMS ((m, currMod, head, t, v), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *t _AND_ ValueDefList *v) { ValueDef *vd; FOR_EACH_LIST_ELMT (vd, v) { ValueLinkValue (m, currMod, vd, vd->value->type, vd->value); } t = t; /*AVOIDS Compiler warning.*/ head = head; } /* ValueLinkNamedElmts */ void ValueLinkValueDef PARAMS ((m, currMod, v), ModuleList *m _AND_ Module *currMod _AND_ ValueDef *v) { if (v == NULL) return; ValueLinkType (m, currMod, NULL, v->value->type); ValueLinkValue (m, currMod, v, v->value->type, v->value); } /* ValueLinkValueDef */ void ValueLinkValue PARAMS ((m, currMod, head, valuesType, v), ModuleList *m _AND_ Module *currMod _AND_ ValueDef *head _AND_ Type *valuesType _AND_ Value *v) { if (v == NULL) return; ValueLinkBasicValue (m, currMod, head, valuesType, v, v->basicValue); } /* ValueLinkValue */ void ValueLinkBasicValue PARAMS ((m, currMod, head, valuesType, v, bv), ModuleList *m _AND_ Module *currMod _AND_ ValueDef *head _AND_ Type *valuesType _AND_ Value *v _AND_ BasicValue *bv) { ValueDef *tmpValueDef; ImportElmt *impElmt; ImportModule *impMod; ValueDef *n; ValueDefList *namedElmtList; if (v == NULL) return; switch (bv->choiceId) { case BASICVALUE_UNKNOWN: case BASICVALUE_EMPTY: case BASICVALUE_INTEGER: case BASICVALUE_SPECIALINTEGER: case BASICVALUE_BOOLEAN: case BASICVALUE_REAL: case BASICVALUE_SPECIALREAL: case BASICVALUE_ASCIITEXT: case BASICVALUE_ASCIIHEX: case BASICVALUE_ASCIIBITSTRING: case BASICVALUE_BERVALUE: case BASICVALUE_PERVALUE: case BASICVALUE_NAMEDVALUE: case BASICVALUE_NULL: case BASICVALUE_VALUENOTATION: case BASICVALUE_OID: break; case BASICVALUE_LOCALVALUEREF: /* * parser sets all value refs to "Local" so must * check if local, then if import .... */ /* * first check in named elmts of the given type */ namedElmtList = GetAllNamedElmts (valuesType); if (namedElmtList != NULL) { n = LookupValue (namedElmtList, bv->a.localValueRef->valueName); if (n != NULL) { bv->a.localValueRef->link = n; bv->a.localValueRef->module = currMod; /* now free list structure (not data elmts) */ AsnListFree (namedElmtList); break; /* exit switch since done here. */ } } /* * second, look for values defined in this module */ tmpValueDef = LookupValue (currMod->valueDefs, bv->a.localValueRef->valueName); if (tmpValueDef != NULL) { bv->a.localValueRef->link = tmpValueDef; break; /* exit switch since done here. */ } else bv->choiceId = BASICVALUE_IMPORTVALUEREF; /*!!!!!!!!!! fall through from else clause */ case BASICVALUE_IMPORTVALUEREF: /* This handles "modname.value" value refs. */ if (bv->a.importValueRef->moduleName != NULL) { /* * Lookup the import list maintained in this module * from the named module. (the parser generates * an import list from Foo module for "Foo.Bar" style * import refs) */ impMod = LookupImportModule (currMod, bv->a.importValueRef->moduleName); if (impMod == NULL) /* whoa, compiler error */ { currMod->status = MOD_ERROR; fprintf (errFileG, "Compiler Error: \"%s.%s\" valueref - no import list defined from module \"%s\".\n", bv->a.importValueRef->moduleName, bv->a.importValueRef->valueName, bv->a.importValueRef->moduleName); return; } impElmt = LookupImportElmtInImportElmtList (impMod->importElmts, bv->a.importValueRef->valueName); if (impElmt == NULL) /* whoa, compiler error again */ { currMod->status = MOD_ERROR; fprintf (errFileG, "Compiler Error: \"%s.%s\" valueref - no import element defined for value \"%s\".\n", bv->a.importValueRef->moduleName, bv->a.importValueRef->valueName, bv->a.importValueRef->valueName); } else if (impElmt->resolvedRef != NULL) { if (impElmt->resolvedRef->choiceId != IMPORTELMTCHOICE_VALUE) { fprintf (errFileG, "Linker Warning: import VALUE ref \"%s\" resolves with an imported TYPE\n", impElmt->name); } bv->a.importValueRef->link = impElmt->resolvedRef->a.value; bv->a.importValueRef->module = impMod->moduleRef; } else { PrintErrLoc (currMod->asn1SrcFileName, (long)v->lineNo); fprintf (errFileG, "reference to unresolved imported value \"%s\"\n", impElmt->name); } } else { impElmt = LookupImportElmtInModule (currMod, bv->a.importValueRef->valueName, &impMod); if ((impElmt != NULL) && (!impElmt->privateScope)) { /* * if import elmt is resolved then * set up link */ if (impElmt->resolvedRef != NULL) { if (impElmt->resolvedRef->choiceId != IMPORTELMTCHOICE_VALUE) { fprintf (errFileG, "Linker Warning: import VALUE ref \"%s\" resolves with an imported TYPE\n", impElmt->name); } bv->a.importValueRef->link = impElmt->resolvedRef->a.value; bv->a.importValueRef->module = impMod->moduleRef; } else { PrintErrLoc (currMod->asn1SrcFileName, (long)v->lineNo); fprintf (errFileG, "reference to unresolved imported value \"%s\"\n", impElmt->name); } } else { /* * value not defined locally, nor imported nor * defined in useful types module */ currMod->status = MOD_ERROR; PrintErrLoc (currMod->asn1SrcFileName, (long)v->lineNo); fprintf (errFileG, "ERROR - value \"%s\" is referenced but not defined or imported.\n", bv->a.importValueRef->valueName); } } break; case BASICVALUE_LINKEDOID: ValueLinkOid (m, currMod, head, v, bv->a.linkedOid); break; default: fprintf (errFileG, "ValueLinkBasicValue: ERROR - unknown value type\n"); } } /* ValueLinkBasicValue */ /* * link the value refs from an object identifier * * * eg * for { ccitt foo (1) bar bell (bunt) 2 } the format is * * ccitt * arcnum is set to number from oid table (oid.c) * foo (1) * - arc num is set to 1 * - sets up a new value def foo defined as 1 * - makes oid valueref a value ref to foo (doesn't link it tho) * bar * - makes oid valueref a value ref to bar (doesn't link it tho) * bell (bunt) * - sets up a new value def bell defined as a val ref to bunt * - makes oid valueref a value ref to bell (doesn't link it tho) * 2 * -arc num is set to 2 * */ void ValueLinkOid PARAMS ((m, currMod, head, v, oid), ModuleList *m _AND_ Module *currMod _AND_ ValueDef *head _AND_ Value *v _AND_ OID *oid) { /* * WARNING: for cyclic oid value definintions like. * foo OID ::= { bar 1 3 } * bar OID ::= { foo 1 3 } * infinite recursion is prevented by * a hack (linkOidCallDepth) */ if (linkOidCallDepthG > 100) { currMod->status = MOD_ERROR; PrintErrLoc (currMod->asn1SrcFileName, (long)v->lineNo); fprintf (errFileG, "ERROR - OBJECT IDENTIFIER value \"%s\" appears to be defined recursively\n", head->definedName); linkOidCallDepthG = 0; return; } else linkOidCallDepthG++; for (; oid != NULL; oid = oid->next) { if (oid->valueRef != NULL) { ValueLinkValue (m, currMod, head, NULL, oid->valueRef); if ((oid->valueRef->basicValue->choiceId != BASICVALUE_LOCALVALUEREF) && (oid->valueRef->basicValue->choiceId != BASICVALUE_IMPORTVALUEREF)) { fprintf (errFileG, "Internal error: Oid valueref is not a ref\n"); break; /* exit for */ } /* * leave simplification (replacement of value refs with values) * of oid values to normalize.c */ } } linkOidCallDepthG--; } /* ValueLinkOid */ void ValueLinkRosOperationMacroType PARAMS ((m, currMod, head, t, bt, op), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ RosOperationMacroType *op) { TypeOrValue *tOrV; if (op->arguments != NULL) ValueLinkType (m, currMod, head, op->arguments->type); if (op->result != NULL) ValueLinkType (m, currMod, head, op->result->type); /* * go through errors (if any) and link types/values */ FOR_EACH_LIST_ELMT (tOrV, op->errors) { if (tOrV->choiceId == TYPEORVALUE_TYPE) ValueLinkType (m, currMod, head, tOrV->a.type); else ValueLinkValue (m, currMod, NULL, t, tOrV->a.value); } /* * go through linked operations (if any) and * link types/values */ FOR_EACH_LIST_ELMT (tOrV, op->linkedOps) { if (tOrV->choiceId == TYPEORVALUE_TYPE) ValueLinkType (m, currMod, head, tOrV->a.type); else ValueLinkValue (m, currMod, NULL, t, tOrV->a.value); } bt = bt; /*AVOIDS Compiler warning.*/ t = t; } /* ValueLinkRosOperationMacroType */ void ValueLinkRosErrorMacroType PARAMS ((m, currMod, head, t, bt, err), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ RosErrorMacroType *err) { if ((err != NULL) && (err->parameter != NULL)) { ValueLinkType (m, currMod, head, err->parameter->type); } bt = bt; /*AVOIDS Compiler warning.*/ t = t; } /* ValueLinkRosErrorMacroType */ void ValueLinkRosBindMacroType PARAMS ((m, currMod, head, t, bt, bind), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ RosBindMacroType *bind) { if (bind != NULL) { ValueLinkElmtType (m, currMod, head, bind->argument); ValueLinkElmtType (m, currMod, head, bind->result); ValueLinkElmtType (m, currMod, head, bind->error); } bt = bt; /*AVOIDS Compiler warning.*/ t = t; } /* ValueLinkRosBindMacroType */ void ValueLinkRosAseMacroType PARAMS ((m, currMod, head, t, bt, ase), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ RosAseMacroType *ase) { Value *v; FOR_EACH_LIST_ELMT (v, ase->operations) ValueLinkValue (m, currMod, NULL, t, v); FOR_EACH_LIST_ELMT (v, ase->consumerInvokes) ValueLinkValue (m, currMod, NULL, t, v); FOR_EACH_LIST_ELMT (v, ase->supplierInvokes) ValueLinkValue (m, currMod, NULL, t, v); bt = bt; /*AVOIDS Compiler warning.*/ head = head; } /* ValueLinkRosAseMacroType */ void ValueLinkRosAcMacroType PARAMS ((m, currMod, head, t, bt, ac), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ RosAcMacroType *ac) { Value *v; OID *oid; FOR_EACH_LIST_ELMT (v, ac->nonRoElements) ValueLinkValue (m, currMod, NULL, t, v); ValueLinkType (m, currMod, head, ac->bindMacroType); ValueLinkType (m, currMod, head, ac->unbindMacroType); FOR_EACH_LIST_ELMT (v, ac->operationsOf) ValueLinkValue (m, currMod, NULL, t, v); FOR_EACH_LIST_ELMT (v, ac->initiatorConsumerOf) ValueLinkValue (m, currMod, NULL, t, v); FOR_EACH_LIST_ELMT (v, ac->responderConsumerOf) ValueLinkValue (m, currMod, NULL, t, v); FOR_EACH_LIST_ELMT (oid, ac->abstractSyntaxes) ValueLinkOid (m, currMod, NULL, NULL, oid); bt = bt; /*AVOIDS Compiler warning.*/ } /* ValueLinkRosAcMacroType */ void ValueLinkMtsasExtensionsMacroType PARAMS ((m, currMod, head, t, bt, exts), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ MtsasExtensionsMacroType *exts) { Value *v; FOR_EACH_LIST_ELMT (v, exts->extensions) ValueLinkValue (m, currMod, NULL, t, v); bt = bt; /*AVOIDS Compiler warning.*/ head = head; } /* ValueLinkMtsasExtensionsMacroType */ void ValueLinkMtsasExtensionMacroType PARAMS ((m, currMod, head, t, bt, ext), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ MtsasExtensionMacroType *ext) { ValueLinkElmtType (m, currMod, head, ext->elmtType); ValueLinkValue (m, currMod, NULL, t, ext->defaultValue); bt = bt; /*AVOIDS Compiler warning.*/ } /* ValueLinkMtsasExtensionMacroType */ void ValueLinkMtsasExtensionAttributeMacroType PARAMS ((m, currMod, head, t,bt, ext), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ MtsasExtensionAttributeMacroType *ext) { if (ext != NULL) ValueLinkType (m, currMod, head, ext->type); bt = bt; /*AVOIDS Compiler warning.*/ t = t; } /* ValueLinkMtsasExtensionAttributeMacroType */ void ValueLinkMtsasTokenMacroType PARAMS ((m, currMod, head, t, bt, tok), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ MtsasTokenMacroType *tok) { if (tok != NULL) ValueLinkType (m, currMod, head, tok->type); bt = bt; /*AVOIDS Compiler warning.*/ t = t; } /* ValueLinkMtsasTokenMacroType */ void ValueLinkMtsasTokenDataMacroType PARAMS ((m, currMod, head, t, bt, tok), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ MtsasTokenDataMacroType *tok) { if (tok != NULL) ValueLinkType (m, currMod, head, tok->type); bt = bt; /*AVOIDS Compiler warning.*/ t = t; } /* ValueLinkMtsasTokenDataMacroType */ void ValueLinkMtsasSecurityCategoryMacroType PARAMS ((m, currMod, head, t, bt, sec), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ MtsasSecurityCategoryMacroType *sec) { if (sec != NULL) ValueLinkType (m, currMod, head, sec->type); bt =bt; /*AVOIDS Compiler warning.*/ t = t; } /* ValueLinkMtsasSecurityCategoryMacroType */ void ValueLinkAsnObjectMacroType PARAMS ((m, currMod, head, t, bt, obj), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ AsnObjectMacroType *obj) { AsnPort *ap; FOR_EACH_LIST_ELMT (ap, obj->ports) ValueLinkValue (m, currMod, NULL, t, ap->portValue); bt = bt; /*AVOIDS Compiler warning.*/ head = head; } /* ValueLinkAsnObjectMacroType */ void ValueLinkAsnPortMacroType PARAMS ((m, currMod, head, t, bt, p), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ AsnPortMacroType *p) { TypeOrValue *tOrV; FOR_EACH_LIST_ELMT (tOrV, p->abstractOps) { if (tOrV->choiceId == TYPEORVALUE_TYPE) ValueLinkType (m, currMod, head, tOrV->a.type); else ValueLinkValue (m, currMod, NULL, t, tOrV->a.value); } FOR_EACH_LIST_ELMT (tOrV, p->supplierInvokes) { if (tOrV->choiceId == TYPEORVALUE_TYPE) ValueLinkType (m, currMod, head, tOrV->a.type); else ValueLinkValue (m, currMod, NULL, t, tOrV->a.value); } FOR_EACH_LIST_ELMT (tOrV, p->consumerInvokes) { if (tOrV->choiceId == TYPEORVALUE_TYPE) ValueLinkType (m, currMod, head, tOrV->a.type); else ValueLinkValue (m, currMod, NULL, t, tOrV->a.value); } bt = bt; /*AVOIDS Compiler warning.*/ } /* ValueLinkAsnPortMacroType */ void ValueLinkAsnAbstractBindMacroType PARAMS ((m, currMod, head, t, bt, bind), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ AsnAbstractBindMacroType *bind) { AsnPort *ap; FOR_EACH_LIST_ELMT (ap, bind->ports) ValueLinkValue (m, currMod, NULL, t, ap->portValue); bt = bt; /*AVOIDS Compiler warning.*/ head = head; } /* ValueLinkAsnBindMacroType */ void ValueLinkSnmpObjectTypeMacroType PARAMS ((m, currMod, head, t, bt, ot), ModuleList *m _AND_ Module *currMod _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ SnmpObjectTypeMacroType *ot) { TypeOrValue *tOrV; ValueLinkType (m, currMod, head, ot->syntax); ValueLinkValue (m, currMod, NULL, t, ot->description); ValueLinkValue (m, currMod, NULL, t, ot->reference); ValueLinkValue (m, currMod, NULL, t, ot->defVal); FOR_EACH_LIST_ELMT (tOrV, ot->index) { if (tOrV->choiceId == TYPEORVALUE_TYPE) ValueLinkType (m, currMod, head, tOrV->a.type); else ValueLinkValue (m, currMod, NULL, t, tOrV->a.value); } bt = bt; /*AVOIDS Compiler warning.*/ } /* ValueLinkSnmpObjectTypeMacroType */ esnacc-ng-1.8.1/compiler/core/meta.c000066400000000000000000000027221302010526100172040ustar00rootroot00000000000000/* * file: compiler/core/meta.c * * Copyright ¨ 1994 1995 Robert Joop * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program and the associated libraries are distributed in the hope * that they will be useful, but WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License and GNU Library General * Public License for more details. * * $Header: /baseline/SNACC/compiler/core/meta.c,v 1.1.1.1 2000/08/21 20:36:00 leonberp Exp $ * $Log: meta.c,v $ * Revision 1.1.1.1 2000/08/21 20:36:00 leonberp * First CVS Version of SNACC. * * Revision 1.2 1995/08/17 15:00:11 rj * the PDU flag belongs to the metacode, not only to the tcl interface. (type and variable named adjusted) * * Revision 1.1 1995/07/27 10:54:11 rj * new file * */ #include #include "snacc.h" #include "meta.h" #if META int isMetaPDU PARAMS ((module, type, pdus), const char *module _AND_ const char *type _AND_ MetaPDU *pdus) { MetaPDU *pdu; for (pdu=pdus; pdu; pdu=pdu->next) if (!strcmp (pdu->module, module) && !strcmp (pdu->type, type)) { pdu->used = TRUE; return TRUE; } return FALSE; } #endif /* META */ esnacc-ng-1.8.1/compiler/core/meta.h000066400000000000000000000034131302010526100172070ustar00rootroot00000000000000/* * file: compiler/core/meta.h * * Copyright ¨ 1994 1995 Robert Joop * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program and the associated libraries are distributed in the hope * that they will be useful, but WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License and GNU Library General * Public License for more details. * * $Header: /baseline/SNACC/compiler/core/meta.h,v 1.2 2001/07/12 19:34:31 leonberp Exp $ * $Log: meta.h,v $ * Revision 1.2 2001/07/12 19:34:31 leonberp * Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. * * Revision 1.1.1.1 2000/08/21 20:36:00 leonberp * First CVS Version of SNACC. * * Revision 1.4 1995/09/07 19:14:26 rj * enum MetaNameStyle introduced. * * Revision 1.3 1995/08/17 15:00:12 rj * the PDU flag belongs to the metacode, not only to the tcl interface. (type and variable named adjusted) * * Revision 1.1 1995/07/27 10:54:11 rj * new file */ #if META typedef enum { META_off = 0, /* metacode generation disabled */ META_asn1_names, /* names as defined in .asn1 file */ META_backend_names, /* names as being used by the backend code */ } MetaNameStyle; typedef struct { const char *srcfn; FILE *srcfp; } Meta; typedef struct MetaPDU { const char *module, *type; int used; struct MetaPDU *next; } MetaPDU; extern int isMetaPDU PROTO ((const char *module, const char *type, MetaPDU *pdus)); #endif /* META */ esnacc-ng-1.8.1/compiler/core/normalize.c000066400000000000000000001046011302010526100202550ustar00rootroot00000000000000/* * compiler/core/normalize.c * * 1. swap COMPONENTS OF for actual types * - do this since save lots of special case handling in * code generation * * 2. change SEQUENCE OF/SET OF (type def (not ref)) * to SEQUENCE OF/SEQ OF (type ref) * and add type def for orig. * - do this since OF type are AsnList * * 3. change CHOICE defs within other constructed types * into CHOICE refs * - makes code production easier. can be changed * with some work * * 4. change SEQUENCE/SET defs within other constructed types * into SEQUENCE/SET refs * - makes code production easier. can be changed * with some work (allocation in decode is wrong * - isPtr set incorrectly) * * 5. change SELECTION types to the actual field from the choice * * 6. convert Linked oid's with value refs into a ENC_OID's * so values can be easily defined in C/C++. MS 92/03/01 * * 7. if IMPLICIT-TAGS is specified, mark type references * as implicit, if the ref'd type is not CHOICE or ANY. * (Extra tags on primitives (ie not references) are already * removed in the parsing step (asn1.yacc)). * * 8. SET OF/SEQ OF defs nested in other SETs/SEQ/CHOICEs/SET OF/SEQ OF * types are moved to separate type defs - added 08/92 to support * C++ lists more easily. * * 9. INTEGERs with named elmts and ENUM defs nested in other * SETs/SEQ/CHOICEs/SET OF/SEQ OF types are moved to separate type * defs - added 08/92 to support C++ class hierarchy better. * * ******** 10 is no longer done - in fact it was stupid for ****** * ******** ANY DEFINED BY types MS 09/92 ****** * 10. Move ANY and ANY DEFINED BY type defs nested in SET/SEQ/CHOICE/SET OF * /SEQ OF to a separate definition - this should make fixing the * produced code simpler. * * Mike Sample * 91/12/12 * * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/core/normalize.c,v 1.11 2004/04/06 15:13:41 gronej Exp $ * $Log: normalize.c,v $ * Revision 1.11 2004/04/06 15:13:41 gronej * *** empty log message *** * * Revision 1.10 2004/03/25 19:20:17 gronej * fixed some linux warnings * * Revision 1.9 2003/07/07 14:50:13 nicholar * Eliminated headers and cleaned up include references * * Revision 1.8 2003/04/29 21:08:05 leonberp * integerated Deepak's changes for IOB support * * Revision 1.7 2002/10/21 17:15:19 mcphersc * fixed long int * * Revision 1.6 2002/09/16 16:50:13 mcphersc * Fixed warnings * * Revision 1.5 2002/09/04 18:23:06 vracarl * got rid of c++ comments * * Revision 1.4 2002/07/02 16:58:27 leonberp * removed #ifdef'd code (old string fudge). * * Revision 1.3 2002/05/10 16:39:40 leonberp * latest changes for release 2.2 * includes integrating asn-useful into C & C++ runtime library, the compiler changes that go along with that, SnaccException changes for C++ runtime and compiler * * Revision 1.2 2000/10/24 14:54:53 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:36:00 leonberp * First CVS Version of SNACC. * * Revision 1.3 1995/07/25 19:41:40 rj * changed `_' to `-' in file names. * * Revision 1.2 1994/09/01 00:40:56 rj * snacc_config.h removed. * * Revision 1.1 1994/08/28 09:49:23 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include #include "asn-incl.h" #include "asn1module.h" #include "lib-types.h" #include "snacc-util.h" #define LIST_ELMT_SUFFIX "ListElmt" #define CHOICE_SUFFIX "Choice" #define SET_SUFFIX "Set" #define SEQ_SUFFIX "Seq" #define OBJECTCLASS_SUFFIX "Class" // Deepak: 12/Mar/2003 #define SETOF_SUFFIX "SetOf" #define SEQOF_SUFFIX "SeqOf" #define INT_SUFFIX "Int" #define ENUM_SUFFIX "Enum" #define BITS_SUFFIX "Bits" #define ANY_SUFFIX "Any" void AppendDigit PROTO ((char *str, int digit)); int CountTags PROTO ((Type *t)); long oidRecursionCountG = 0; void NormalizeTypeDef PROTO ((Module *m, TypeDef *td)); void NormalizeType PROTO ((Module *m, TypeDef *td, Type *parent, NamedTypeList *e, Type *t)); void NormalizeElmtTypes PROTO ((Module *m, TypeDef *td, Type *parent, NamedTypeList *e)); void NormalizeBasicType PROTO ((Module *m, TypeDef *td, Type *parent, NamedTypeList *e, Type *type, BasicType *bt)); void NormalizeValue PROTO ((Module *m, ValueDef *vd, Value *v, int quiet)); TypeDef *AddListElmtTypeDef PROTO ((Module *m, TypeDef *td, Type *t, BasicType *bt)); TypeDef *AddConsTypeDef PROTO ((Module *m, TypeDef *td, Type *t, BasicType *bt, char *suffix)); TypeDef* AddConsObjectAssignment PROTO ((Module *m, ObjectAssignment *oa, Type *t, BasicType *bt, char *suffix)); void NormalizeValueDef PROTO ((Module *m, ValueDef *vd)); int FlattenLinkedOid PROTO ((OID *o, char *asn1FileName, AsnInt lineNo, int quiet)); // Deepak: 14/Mar/2003 void NormalizeObjectAssignment PROTO ((Module *m, ObjectAssignment *oa)); // Deepak: 15/Mar/2003 void NormalizeObjectAssignmentFields PROTO ((Module *m, ObjectAssignment *oa, ObjectAssignmentField *oafList)); // Deepak: 15/Mar/2003 void NormalizeObjectAssignmentFieldBasicType PROTO ((Module *m, ObjectAssignment *oa, ObjectAssignmentField *oafList, TypeOrValue* tOrV)); /* * looks through the given module and performs the operations * mentioned above */ void NormalizeModule PARAMS ((m), Module *m) { TypeDef *td; ValueDef *vd; ObjectAssignment *oa; /* * go through each type in typeList */ FOR_EACH_LIST_ELMT (td, m->typeDefs) { NormalizeTypeDef (m, td); } /* * go through each value for types? */ FOR_EACH_LIST_ELMT (vd, m->valueDefs) { NormalizeValueDef (m, vd); } /* // Deepak: 14/Mar/2003 * go through each value for ObjectAssignments */ FOR_EACH_LIST_ELMT (oa, m->objAssignments) { NormalizeObjectAssignment (m, oa); } } /* NormalizeModule */ void NormalizeObjectAssignment PARAMS ((m, oa), // Deepak: 14/Mar/2003 Module *m _AND_ ObjectAssignment *oa) { ObjectAssignmentField *oaf; if (oa == NULL) return; FOR_EACH_LIST_ELMT (oaf, oa->objectAssignmentField) { if (oaf->bPresent && oaf->typeOrValue->choiceId == 0) // type { NormalizeObjectAssignmentFields(m, oa, oaf); } else { // value // don't precess values here. } } /* FOR_EACH_LIST_ELMT (oaf, oa->objectAssignmentField) { if (oaf->typeOrValue->choiceId == 0) // type { switch(oaf->typeOrValue->a.type->basicType->choiceId) //if(oaf->typeOrValue->a.type != type) { case BASICTYPE_SEQUENCE: newDef = AddConsObjectAssignment (m, oa, oaf->typeOrValue->a.type, oaf->typeOrValue->a.type->basicType, SEQ_SUFFIX); NormalizeType (m, newDef, NULL, NULL, newDef->type); break; } } else { // value // don't precess values here. } } */ } /* NormalizeObjectAssignment */ void NormalizeObjectAssignmentFields PARAMS ((m, oa, oaf), // Deepak: 15/Mar/2003 Module *m _AND_ ObjectAssignment *oa _AND_ ObjectAssignmentField *oaf) { // FOR_EACH_LIST_ELMT (oaf, oafList) { NormalizeObjectAssignmentFieldBasicType(m, oa, oaf, oaf->typeOrValue); } } /* NormalizeObjectAssignmentFields */ //////////////// BEWARE: PRONE TO ERRORS ////////////// // Deepak: ????? void NormalizeObjectAssignmentFieldBasicType PARAMS ((m, oa, oaf, tOrV), // Deepak: 15/Mar/2003 Module *m _AND_ ObjectAssignment *oa _AND_ ObjectAssignmentField *oaf _AND_ TypeOrValue* tOrV) { TypeDef *newDef; switch(tOrV->a.type->basicType->choiceId) //if(oaf->typeOrValue->a.type != type) { case BASICTYPE_SEQUENCE: newDef = AddConsObjectAssignment (m, oa, tOrV->a.type, tOrV->a.type->basicType, SEQ_SUFFIX); NormalizeType (m, newDef, NULL, NULL, newDef->type); break; case BASICTYPE_CHOICE: newDef = AddConsObjectAssignment (m, oa, tOrV->a.type, tOrV->a.type->basicType, CHOICE_SUFFIX); NormalizeType (m, newDef, NULL, NULL, newDef->type); break; case BASICTYPE_SETOF: newDef = AddConsObjectAssignment (m, oa, tOrV->a.type, tOrV->a.type->basicType, SETOF_SUFFIX); NormalizeType (m, newDef, NULL, NULL, newDef->type); break; case BASICTYPE_SEQUENCEOF: newDef = AddConsObjectAssignment (m, oa, tOrV->a.type, tOrV->a.type->basicType, SEQOF_SUFFIX); NormalizeType (m, newDef, NULL, NULL, newDef->type); break; case BASICTYPE_SET: newDef = AddConsObjectAssignment (m, oa, tOrV->a.type, tOrV->a.type->basicType, SET_SUFFIX); NormalizeType (m, newDef, NULL, NULL, newDef->type); break; case BASICTYPE_INTEGER: newDef = AddConsObjectAssignment (m, oa, tOrV->a.type, tOrV->a.type->basicType, INT_SUFFIX); break; case BASICTYPE_ENUMERATED: newDef = AddConsObjectAssignment (m, oa, tOrV->a.type, tOrV->a.type->basicType, ENUM_SUFFIX); break; case BASICTYPE_BITSTRING: newDef = AddConsObjectAssignment (m, oa, tOrV->a.type, tOrV->a.type->basicType, BITS_SUFFIX); break; default: break; } oaf = oaf; // avoids warning } /* NormalizeObjectAssignmentFieldBasicType */ void NormalizeTypeDef PARAMS ((m, td), Module *m _AND_ TypeDef *td) { if (td == NULL) return; NormalizeType (m, td, NULL, NULL, td->type); } /* NormalizeTypeDef */ void NormalizeType PARAMS ((m, td, parent, e, t), Module *m _AND_ TypeDef *td _AND_ Type *parent _AND_ NamedTypeList *e _AND_ Type *t) { Tag *lastTag; if (t == NULL) return; NormalizeBasicType (m, td, parent, e, t, t->basicType); /* * make type refs implicit if IMPLICIT-TAGS specified and * ref'd type is OK for implicit tagging. * Tag removal work is done in parsing (yacc). */ if ((m->tagDefault == IMPLICIT_TAGS)) { if ((t->tags != NULL) && (!LIST_EMPTY (t->tags))) lastTag = (Tag*)LAST_LIST_ELMT (t->tags); else lastTag = NULL; /* * only mark as implicit if * 1. This type has a tag in it's taglist * 2. This type is a reference to another type * 3. the referenced type is not an untagged CHOICE, ANY or * ANY DEFINED BY (just need to check that it has * tags since all other types have tags) */ if (((lastTag != NULL) && !(lastTag->explicit)) && ((t->basicType->choiceId == BASICTYPE_LOCALTYPEREF) || (t->basicType->choiceId == BASICTYPE_IMPORTTYPEREF) ) && (CountTags (t->basicType->a.localTypeRef->link->type) != 0)) { t->implicit = TRUE; } } } /* NormalizeType */ void NormalizeElmtTypes PARAMS ((m, td, parent, e), Module *m _AND_ TypeDef *td _AND_ Type *parent _AND_ NamedTypeList *e) { NamedType *nt; FOR_EACH_LIST_ELMT (nt, e) { NormalizeType (m, td, parent, e, nt->type); } } /* NormalizeElmtTypes */ /* * this is where most of the action happens * assumes that "e"'s curr ptr is namedtype that holds "type" */ void NormalizeBasicType PARAMS ((m, td, parent, e, type, bt), Module *m _AND_ TypeDef *td _AND_ Type *parent _AND_ NamedTypeList *e _AND_ Type *type _AND_ BasicType *bt) { int i, numElmtsAdded; NamedType **newElmtHndl; NamedType *nt; NamedTypeList *elmts; Type *compType; Type *parentType; TypeDef *newDef; BasicType *tmpBasicType; TagList *tags; Tag *tag; Tag **tagHndl; if (bt == NULL) return; switch (bt->choiceId) { case BASICTYPE_COMPONENTSOF: /* * copy elmts of COMPONENTS OF type into this type */ if (parent == NULL) { PrintErrLoc (m->asn1SrcFileName, (long)type->lineNo); fprintf (errFileG, "ERROR - COMPONENTS OF must be a SET or SEQUENCE element\n"); m->status = MOD_ERROR; return; } compType = ParanoidGetType (bt->a.componentsOf); parentType = ParanoidGetType (parent); /* COMPONENTS OF must be nested in a SET or SEQUENCE type */ if ((parentType->basicType->choiceId != BASICTYPE_SET) && (parentType->basicType->choiceId != BASICTYPE_SEQUENCE)) { PrintErrLoc (m->asn1SrcFileName, (long)type->lineNo); fprintf (errFileG, "ERROR - COMPONENTS OF must be a SET or SEQUENCE element\n"); m->status = MOD_ERROR; return; } /* COMPONENTS OF in a SET must ref a SET and vice versa for SEQ */ if (((parentType->basicType->choiceId == BASICTYPE_SET) && (compType->basicType->choiceId != BASICTYPE_SET)) || ((parentType->basicType->choiceId == BASICTYPE_SEQUENCE) && (compType->basicType->choiceId != BASICTYPE_SEQUENCE))) { PrintErrLoc (m->asn1SrcFileName, (long)type->lineNo); fprintf (errFileG, "ERROR - COMPONENTS OF in a SET must reference a SET type and COMPONENTS OF in SEQUENCE must reference a SEQUENCE type\n"); type->basicType = compType->basicType; m->status = MOD_ERROR; return; } /* * replace "COMPONENTS OF" with elmts from ref'd set */ elmts = compType->basicType->a.set; if (elmts == NULL) break; /* * add new list elmts that point to elmts * of type ref'd by COMPONENTS OF */ FOR_EACH_LIST_ELMT (nt, elmts) { newElmtHndl = (NamedType**)AsnListAdd (e); *newElmtHndl = nt; } /* * Set e list's curr ptr to first of of the * newly added components. * Do this so NormalizeElmtTypes will do the * newly added ones as well */ numElmtsAdded = AsnListCount (elmts); for (i = 0; i < numElmtsAdded; i++) AsnListPrev (e); /* remove the componets of ref since elmts copied in */ AsnListRemove (e); break; case BASICTYPE_SELECTION: /* * first normalize the CHOICE that is selected from * - this will be done twice to the CHOICE but nothing * bad should happen. The main reason for 'normalizing' * the CHOICE first is to strip tags from the choice elmts * if IMPLICIT-TAGS is set. * NOTE: this call assumes that import/local type refs * both use the 'TypeRef' struct and that a selection references * a CHOICE by name (not definition) */ NormalizeType (m, type->basicType->a.selection->typeRef->basicType->a.localTypeRef->link, NULL, NULL, type->basicType->a.selection->typeRef->basicType->a.localTypeRef->link->type); /* * use SELECTION field name if this is an elmt type with no * field name. */ if ((e != NULL) && (((NamedType*) e->curr->data)->fieldName == NULL)) ((NamedType*) e->curr->data)->fieldName = type->basicType->a.selection->link->fieldName; /* * replace SELECTION type with refd type. * must append the named CHOICE field's tags to * any existing tags on this SELECTION type. */ tmpBasicType = type->basicType->a.selection->link->type->basicType; tags = type->basicType->a.selection->link->type->tags; FOR_EACH_LIST_ELMT (tag, tags) { if (!(((m->tagDefault == IMPLICIT_TAGS) || (type->implicit)) && (tag == (Tag*)FIRST_LIST_ELMT (tags)))) { tagHndl = (Tag**) AsnListAppend (type->tags); *tagHndl = tag; } type->implicit = FALSE; } if (type->basicType->a.selection->link->type->implicit) type->implicit = TRUE; Free (type->basicType->a.selection->fieldName); Free (type->basicType->a.selection->typeRef->basicType); Free (type->basicType->a.selection->typeRef); type->basicType = tmpBasicType; break; case BASICTYPE_SEQUENCEOF: case BASICTYPE_SETOF: /* convert def inside other type into a ref */ if (td->type != type) { if (bt->choiceId == BASICTYPE_SETOF) newDef = AddConsTypeDef (m, td, type, bt, SETOF_SUFFIX); else newDef = AddConsTypeDef (m, td, type, bt, SEQOF_SUFFIX); NormalizeType (m, newDef, NULL, NULL, newDef->type); } else NormalizeType (m, td, type, NULL, type->basicType->a.setOf); break; /* NOT NEEDED ANY MORE * convert typdef after SET OF/SEQ OF to type REFS switch (bt->a.setOf->basicType->choiceId) { case BASICTYPE_SEQUENCE: case BASICTYPE_SET: case BASICTYPE_CHOICE: case BASICTYPE_SEQUENCEOF: case BASICTYPE_SETOF: case BASICTYPE_COMPONENTSOF: newDef = AddListElmtTypeDef (m, td, type, bt); NormalizeType (m, newDef, NULL, NULL, newDef->type); break; default: NormalizeType (m, td, NULL, NULL, bt->a.setOf); break; } */ break; case BASICTYPE_CHOICE: /* * change CHOICE defs embedded in other types * into type refs */ if (td->type != type) { newDef = AddConsTypeDef (m, td, type, bt, CHOICE_SUFFIX); NormalizeType (m, newDef, NULL, NULL, newDef->type); } else NormalizeElmtTypes (m, td, type, bt->a.set); break; case BASICTYPE_SEQUENCE: /* * change SEQ defs embedded in other types * into type refs */ if (td->type != type) { newDef = AddConsTypeDef (m, td, type, bt, SEQ_SUFFIX); NormalizeType (m, newDef, NULL, NULL, newDef->type); } else NormalizeElmtTypes (m, td, type, bt->a.sequence); break; case BASICTYPE_OBJECTCLASS: // Deepak: 12/Mar/2003 /* * change SEQ defs embedded in other types * into type refs ??? */ if (td->type != type) { newDef = AddConsTypeDef (m, td, type, bt, OBJECTCLASS_SUFFIX); NormalizeType (m, newDef, NULL, NULL, newDef->type); } else NormalizeElmtTypes (m, td, type, bt->a.objectclass->classdef); break; case BASICTYPE_SET: /* * change SET defs embedded in other types * into type refs */ if (td->type != type) { newDef = AddConsTypeDef (m, td, type, bt, SET_SUFFIX); NormalizeType (m, newDef, NULL, NULL, newDef->type); } else NormalizeElmtTypes (m, td, type, bt->a.set); break; case BASICTYPE_INTEGER: /* if they have named elements convert this def into a ref */ if ((td->type != type) && (bt->a.integer != NULL) && (!LIST_EMPTY (bt->a.integer))) { newDef = AddConsTypeDef (m, td, type, bt, INT_SUFFIX); } break; case BASICTYPE_ENUMERATED: /* if they have named elements convert this def into a ref */ if ((td->type != type) && (bt->a.enumerated != NULL) && (!LIST_EMPTY (bt->a.enumerated))) { newDef = AddConsTypeDef (m, td, type, bt, ENUM_SUFFIX); } break; case BASICTYPE_BITSTRING: /* if they have named elements convert this def into a ref */ if ((td->type != type) && (bt->a.bitString != NULL) && (!LIST_EMPTY (bt->a.bitString))) { newDef = AddConsTypeDef (m, td, type, bt, BITS_SUFFIX); } break; /* REN -- 1/12/98 -- m->hasAnys should not be set here since it will be set in the module where the ANYs are actually defined (with the OBJECT-TYPE macro). case BASICTYPE_ANY: case BASICTYPE_ANYDEFINEDBY: m->hasAnys = TRUE; end REN */ /* NO LONGER DONE * change ANY defs embedded in other types * into type refs if (td->type != type) newDef = AddConsTypeDef (m, td, type, bt, ANY_SUFFIX); */ break; default: /* the rest are not processed */ break; } } /* NormalizeBasicType */ /* * given a set of/seq of type t within typedef td, change the * set of /seq of elmt type def into a type ref and * add a type def for the elmt at the top level. */ TypeDef* AddListElmtTypeDef PARAMS ((m, td, t, bt), Module *m _AND_ TypeDef *td _AND_ Type *t _AND_ BasicType *bt) { TypeDef *newDef; TypeDef **typeDefHndl; int end; int digit; /* * make new type def */ newDef = (TypeDef*)Malloc (sizeof (TypeDef)); newDef->exported = FALSE; newDef->type = bt->a.setOf; /* * make name for new type * Foo ::= SET OF SEQUENCE {...} * --> * FooListElmt ::= SEQUENCE {...} * Foo ::= SET OF FooListElmt */ newDef->definedName = Malloc (strlen (td->definedName) + strlen (LIST_ELMT_SUFFIX) + 4); strcpy (newDef->definedName, td->definedName); strcat (newDef->definedName, LIST_ELMT_SUFFIX); end = strlen (newDef->definedName); digit = 1; while (LookupType (m->typeDefs, newDef->definedName) != NULL) { newDef->definedName[end] = '\0'; AppendDigit (newDef->definedName, digit++); } /* * now put new type at head of list */ typeDefHndl = (TypeDef**)AsnListPrepend (m->typeDefs); *typeDefHndl = newDef; /* * replace SET OF/SEQ OF body with type ref */ bt->a.setOf = (Type*)Malloc (sizeof (Type)); bt->a.setOf->optional = FALSE; bt->a.setOf->implicit = FALSE; bt->a.setOf->lineNo = t->lineNo; bt->a.setOf->basicType = (BasicType*)Malloc (sizeof (BasicType)); bt->a.setOf->basicType->choiceId = BASICTYPE_LOCALTYPEREF; bt->a.setOf->basicType->a.localTypeRef = (TypeRef*)Malloc (sizeof (TypeRef)); bt->a.setOf->basicType->a.localTypeRef->link = newDef; bt->a.setOf->basicType->a.localTypeRef->typeName = newDef->definedName; bt->a.setOf->basicType->a.localTypeRef->moduleName = NULL; return newDef; } /* AddListElmtTypeDefs */ /* * given a CHOICE/SET/SEQ/etc type t within typedef td, make t into a ref * to a new top level typdef of the CHOICE/SET/SEQ */ TypeDef* AddConsTypeDef PARAMS ((m, td, t, bt, suffix), Module *m _AND_ TypeDef *td _AND_ Type *t _AND_ BasicType *bt _AND_ char *suffix) { TypeDef *newDef; TypeDef **typeDefHndl; Tag **tmpPtr; Tag *lastTag; int end; int digit; /* * make new type def */ newDef = (TypeDef*)Malloc (sizeof (TypeDef)); newDef->exported = FALSE; newDef->recursive = FALSE; newDef->localRefCount = 1; newDef->type = (Type*)Malloc (sizeof (Type)); newDef->type->optional = FALSE; newDef->type->lineNo = t->lineNo; newDef->type->basicType = bt; /* * make name for new choice/SET/SEQ * Foo ::= SEQUENCE { .., bar CHOICE { ...}, ..} * --> * FooChoice ::= CHOICE { ...} * Foo ::= SEQUENCE { .., bar FooChoice, .. } */ newDef->definedName = Malloc (strlen (td->definedName) + strlen (suffix) + 4); strcpy (newDef->definedName, td->definedName); strcat (newDef->definedName, suffix); end = strlen (newDef->definedName); digit = 1; /* keep name unique */ while (LookupType (m->typeDefs, newDef->definedName) != NULL) { newDef->definedName[end] = '\0'; AppendDigit (newDef->definedName, digit++); } /* * now put new type at head of list */ typeDefHndl = (TypeDef**)AsnListPrepend (m->typeDefs); *typeDefHndl = newDef; /* * what to do with tags? Use default universal type on * newly defined type and adjust (new) reference's tags * appropriately * * NOTE: may be simpler just to move all the tags to the * new def. */ newDef->type->tags = (TagList*)AsnListNew (sizeof (void*)); if (LIBTYPE_GET_UNIV_TAG_CODE ((newDef->type->basicType->choiceId)) != NO_TAG_CODE) { tmpPtr = (Tag**)AsnListAppend (newDef->type->tags); *tmpPtr = (Tag*)Malloc (sizeof (Tag)); (*tmpPtr)->tclass = UNIV; (*tmpPtr)->code = LIBTYPE_GET_UNIV_TAG_CODE ((newDef->type->basicType->choiceId)); /* adjust tags of new ref to new def */ if ((t->tags != NULL) && (!LIST_EMPTY (t->tags))) { lastTag = (Tag*)LAST_LIST_ELMT (t->tags); if ((lastTag->tclass == UNIV) && (lastTag->code == LIBTYPE_GET_UNIV_TAG_CODE ((newDef->type->basicType->choiceId)))) { /* zap it since same as default universal tag */ SET_CURR_LIST_NODE (t->tags, LAST_LIST_NODE (t->tags)); AsnListRemove (t->tags); t->implicit = FALSE; } else { t->implicit = TRUE; /* this will probably already be true */ } } } /* * replace embeded CHOICE/SET/SEQ def with ref to newly defined type */ t->basicType = (BasicType*)Malloc (sizeof (BasicType)); t->basicType->choiceId = BASICTYPE_LOCALTYPEREF; t->basicType->a.localTypeRef = (TypeRef*)Malloc (sizeof (TypeRef)); t->basicType->a.localTypeRef->link = newDef; t->basicType->a.localTypeRef->typeName = newDef->definedName; t->basicType->a.localTypeRef->moduleName = NULL; return newDef; } /* AddConsTypeDef */ /* * given a CHOICE/SET/SEQ/etc type t within ObjectAssignment oa, make t into a ref * to a new top level typdef of the CHOICE/SET/SEQ */ TypeDef* // Deepak: 14/Mar/2003 AddConsObjectAssignment PARAMS ((m, oa, t, bt, suffix), Module *m _AND_ ObjectAssignment *oa _AND_ Type *t _AND_ BasicType *bt _AND_ char *suffix) { TypeDef *newDef; TypeDef **typeDefHndl; // Tag **tmpPtr; // Tag *lastTag; int end; int digit; /* * make new type def */ newDef = (TypeDef*)Malloc (sizeof (TypeDef)); newDef->exported = FALSE; newDef->recursive = FALSE; newDef->localRefCount = 1; newDef->type = (Type*)Malloc (sizeof (Type)); newDef->type->optional = FALSE; newDef->type->lineNo = t->lineNo; newDef->type->basicType = bt; /* * make name for new choice/SET/SEQ * Foo ::= SEQUENCE { .., bar CHOICE { ...}, ..} * --> * FooChoice ::= CHOICE { ...} * Foo ::= SEQUENCE { .., bar FooChoice, .. } */ newDef->definedName = Malloc (strlen (oa->objectName) + strlen (suffix) + 4); strcpy (newDef->definedName, oa->objectName); strcat (newDef->definedName, suffix); end = strlen (newDef->definedName); digit = 1; /* keep name unique */ while (LookupType (m->typeDefs, newDef->definedName) != NULL) { newDef->definedName[end] = '\0'; AppendDigit (newDef->definedName, digit++); } /* * now put new type at head of list */ typeDefHndl = (TypeDef**)AsnListPrepend (m->typeDefs); *typeDefHndl = newDef; /* * what to do with tags? Use default universal type on * newly defined type and adjust (new) reference's tags * appropriately * * NOTE: may be simpler just to move all the tags to the * new def. */ ////// could not understand it, so leave it now. Deepak: ????? ///// /* newDef->type->tags = (TagList*)AsnListNew (sizeof (void*)); if (LIBTYPE_GET_UNIV_TAG_CODE ((newDef->type->basicType->choiceId)) != NO_TAG_CODE) { tmpPtr = (Tag**)AsnListAppend (newDef->type->tags); *tmpPtr = (Tag*)Malloc (sizeof (Tag)); (*tmpPtr)->tclass = UNIV; (*tmpPtr)->code = LIBTYPE_GET_UNIV_TAG_CODE ((newDef->type->basicType->choiceId)); // adjust tags of new ref to new def // if ((t->tags != NULL) && (!LIST_EMPTY (t->tags))) { lastTag = (Tag*)LAST_LIST_ELMT (t->tags); if ((lastTag->tclass == UNIV) && (lastTag->code == LIBTYPE_GET_UNIV_TAG_CODE ((newDef->type->basicType->choiceId)))) { // zap it since same as default universal tag // SET_CURR_LIST_NODE (t->tags, LAST_LIST_NODE (t->tags)); AsnListRemove (t->tags); t->implicit = FALSE; } else { t->implicit = TRUE; // this will probably already be true // } } } */ /* * replace embeded CHOICE/SET/SEQ def with ref to newly defined type */ t->basicType = (BasicType*)Malloc (sizeof (BasicType)); t->basicType->choiceId = BASICTYPE_LOCALTYPEREF; t->basicType->a.localTypeRef = (TypeRef*)Malloc (sizeof (TypeRef)); t->basicType->a.localTypeRef->link = newDef; t->basicType->a.localTypeRef->typeName = newDef->definedName; t->basicType->a.localTypeRef->moduleName = NULL; return newDef; } /* AddConsObjectAssignment */ void NormalizeValueDef PARAMS ((m, vd), Module *m _AND_ ValueDef *vd) { NormalizeValue (m, vd, vd->value, FALSE); } void NormalizeValue PARAMS ((m, vd, v, quiet), Module *m _AND_ ValueDef *vd _AND_ Value *v _AND_ int quiet) { AsnOid *eoid; OID *o; OID *tmp; int eLen; /* * convert linked oids into ENC_OID's */ if (v->basicValue->choiceId == BASICVALUE_LINKEDOID) { if (!FlattenLinkedOid (v->basicValue->a.linkedOid, m->asn1SrcFileName, v->lineNo, quiet)) return; eLen = EncodedOidLen (v->basicValue->a.linkedOid); if (eLen == 0) { return; } eoid = MT (AsnOid); eoid->octetLen = eLen; eoid->octs = (char*)Malloc (eLen); BuildEncodedOid (v->basicValue->a.linkedOid, eoid); /* free linked oid */ for (o = v->basicValue->a.linkedOid; o != NULL; ) { tmp = o->next; Free (o); o = tmp; } v->basicValue->choiceId = BASICVALUE_OID; v->basicValue->a.oid = eoid; } vd = vd; /* AVOIDS warning. */ } /* * replaces value refs with the value's number if poss * returns TRUE if successfully done. * returns FALSE if a value ref could not be traced * (false should not happen if the value link succeeded) * "quiet" parameter allows err msg to be turned off * which prevents cascading errors by other oid's that * reference a bad oid. */ int FlattenLinkedOid PARAMS ((o, asn1FileName, lineNo, quiet), OID *o _AND_ char *asn1FileName _AND_ AsnInt lineNo _AND_ int quiet) { OID *firstElmt; OID *refdOid; OID *tmpOid; OID **nextOid; Value *val; Value *valRef; if (oidRecursionCountG > 100) { PrintErrLoc (asn1FileName, (long)lineNo); fprintf (errFileG, "ERROR - recursive OBJECT IDENTIFIER value.\n"); return FALSE; } firstElmt = o; for (; o != NULL; o = o->next) { valRef = o->valueRef; if ((valRef == NULL) || (o->arcNum != NULL_OID_ARCNUM)) continue; /* no linking nec for this one */ val = GetValue (o->valueRef); /* * if the very first component is an oid val ref * then insert that value */ if ((o == firstElmt) && (val->basicValue->choiceId == BASICVALUE_OID)) { UnbuildEncodedOid (val->basicValue->a.oid, &refdOid); for (tmpOid = refdOid; tmpOid->next != NULL; tmpOid = tmpOid->next) ; tmpOid->next = o->next; memcpy (firstElmt, refdOid, sizeof (OID)); Free (refdOid); /* free first component of OID since copied */ } else if ((o == firstElmt) && (val->basicValue->choiceId == BASICVALUE_LINKEDOID)) { oidRecursionCountG++; if (!FlattenLinkedOid (val->basicValue->a.linkedOid, asn1FileName, lineNo, TRUE)) { oidRecursionCountG--; return FALSE; } oidRecursionCountG--; nextOid = &refdOid; for (tmpOid = val->basicValue->a.linkedOid; tmpOid != NULL; tmpOid = tmpOid->next) { *nextOid = (OID*)Malloc (sizeof (OID)); (*nextOid)->arcNum = tmpOid->arcNum; nextOid = &(*nextOid)->next; } (*nextOid) = o->next; memcpy (firstElmt, refdOid, sizeof (OID)); Free (refdOid); /* since copied into firstElmt */ } else if ((val->basicValue->choiceId == BASICVALUE_INTEGER)) { o->arcNum = val->basicValue->a.integer; if ((o->arcNum < 0) && !quiet) { PrintErrLoc (asn1FileName, (long)lineNo); fprintf (errFileG, "ERROR - OBJECT IDENTIFIER arc values cannot be negative.\n"); } } else /* bad arc value type */ { if (!quiet) { PrintErrLoc (asn1FileName, (long)lineNo); fprintf (errFileG, "ERROR - type mismatch for an arc value. Values ref'd from an OBJECT IDENTIFIER value must be either an OBJECT IDENTIFIER (first oid elmt only) or INTEGER value (this may be reported twice!)\n"); } return FALSE; } /* free mem assoc with value ref */ Free (valRef->basicValue->a.localValueRef->valueName); Free (valRef->basicValue->a.localValueRef); Free (valRef->basicValue); Free (valRef); o->valueRef = NULL; } return TRUE; } /* FlattenLinkedOid */ esnacc-ng-1.8.1/compiler/core/oid.c000066400000000000000000000160711302010526100170330ustar00rootroot00000000000000/* * compiler/core/oid.c - routines for: * converting an arc number list to an ENC_OID * converting an ENC_OID to an arc number list * arcName mapping routine * * does not handle OID's with unresolved valueRefs instead of arcNums * * MS 91 * * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/core/oid.c,v 1.7 2004/03/25 19:20:17 gronej Exp $ * $Log: oid.c,v $ * Revision 1.7 2004/03/25 19:20:17 gronej * fixed some linux warnings * * Revision 1.6 2003/07/07 14:50:14 nicholar * Eliminated headers and cleaned up include references * * Revision 1.5 2002/10/21 17:15:19 mcphersc * fixed long int * * Revision 1.4 2002/09/16 16:50:17 mcphersc * Fixed warnings * * Revision 1.3 2002/02/26 14:39:56 nicholar * Added itu-t and joint-iso-itu-t arcs to OID arc name table. * * Revision 1.2 2000/10/24 14:54:53 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:36:01 leonberp * First CVS Version of SNACC. * * Revision 1.3 1995/07/25 19:41:41 rj * changed `_' to `-' in file names. * * Revision 1.2 1994/09/01 00:41:33 rj * snacc_config.h removed; oid.h includet. * * Revision 1.1 1994/08/28 09:49:26 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include #include "asn-incl.h" typedef struct ArcNameMapElmt { char *arcName; int arcNum; } ArcNameMapElmt; /* * these are the CCITT and ISO pre-defined arc names for the * OBJECT IDENTIFIER tree. * Ref: CCITT X.208 1988 - Annexes B C and D * * NOTE: the last entry must have a NULL string and a * -1 arcnumber to indicate the end of the array. */ ArcNameMapElmt oidArcNameMapG[14] = { {"itu-t", 0}, {"iso", 1}, {"joint-iso-itu-t", 2}, {"standard", 0}, {"registration-authority", 1}, {"member-body", 2}, {"identified-organization", 3}, {"recommendation", 0}, {"question", 1}, {"administration", 2}, {"network-operator", 3}, {"ccitt", 0}, /* synonym for itu-t */ {"joint-iso-ccitt", 2}, /* synonym for joint-iso-itu-t */ {NULL,-1} }; /* * returns the arcnum (>0) of the given name if it * is a defined oid arc name like "iso" or "ccitt" * returns -1 if the name was not found * * name must be null terminated. */ int OidArcNameToNum PARAMS ((name), char *name) { int i; for (i= 0; oidArcNameMapG[i].arcName != NULL; i++) { if (strcmp (name, oidArcNameMapG[i].arcName) == 0) return oidArcNameMapG[i].arcNum; } return -1; } /* OidArcNameToNum */ /* * Takes and OBJECT IDENTIFER in the linked format * (produced by parser) and returns the number of octets * that are needed to hold the encoded version of that * OBJECT IDENTIFIER. */ unsigned long EncodedOidLen PARAMS ((oid), OID *oid) { unsigned long totalLen; unsigned long headArcNum; unsigned long tmpArcNum; OID *tmpOid; /* * oid must have at least 2 elmts */ if (oid->next == NULL) return 0; headArcNum = (oid->arcNum * 40) + oid->next->arcNum; /* * figure out total encoded length of oid */ tmpArcNum = headArcNum; for (totalLen = 1; (tmpArcNum >>= 7) != 0; totalLen++) ; for (tmpOid = oid->next->next; tmpOid != NULL; tmpOid = tmpOid->next) { totalLen++; tmpArcNum = tmpOid->arcNum; for (; (tmpArcNum >>= 7) != 0; totalLen++) ; } return totalLen; } /* EncodedOidLen */ /* * Given an oid arc number list and a pre-allocated ENC_OID * (use EncodedOidLen to figure out byte length needed) * fills the ENC_OID with a BER encoded version * of the oid. */ void BuildEncodedOid PARAMS ((oid, result), OID *oid _AND_ AsnOid *result) { unsigned long len; unsigned long headArcNum; unsigned long tmpArcNum; char *buf; int i; OID *tmpOid; buf = result->octs; /* * oid must have at least 2 elmts */ if (oid->next == NULL) return; /* * munge together first two arcNum * note first arcnum must be <= 2 * and second must be < 39 if first = 0 or 1 * see (X.209) for ref to this stupidity */ headArcNum = (oid->arcNum * 40) + oid->next->arcNum; tmpArcNum = headArcNum; /* * calc # bytes needed for head arc num */ for (len = 0; (tmpArcNum >>= 7) != 0; len++) ; /* * write more signifcant bytes (if any) of head arc num * with 'more' bit set */ for (i=0; i < (int)len; i++) *(buf++) = (char)(0x80 | (headArcNum >> ((len-i)*7))); /* * write least significant byte of head arc num */ *(buf++) = (char)(0x7f & headArcNum); /* * write following arc nums, if any */ for (tmpOid = oid->next->next; tmpOid != NULL; tmpOid = tmpOid->next) { /* * figure out encoded length -1 of this arcNum */ tmpArcNum = tmpOid->arcNum; for (len = 0; (tmpArcNum >>= 7) != 0; len++) ; /* * write more signifcant bytes (if any) * with 'more' bit set */ for (i=0; i < (int)len; i++) *(buf++) = (char)(0x80 | (tmpOid->arcNum >> ((len-i)*7))); /* * write least significant byte */ *(buf++) = (char)(0x7f & tmpOid->arcNum); } } /* BuildEncodedOid */ /* * Given an ENC_OID, this routine converts it into a * linked oid (OID). */ void UnbuildEncodedOid PARAMS ((eoid, result), AsnOid *eoid _AND_ OID **result) { OID **nextOid; OID *headOid; int arcNum; int i; int firstArcNum; int secondArcNum; for (arcNum = 0, i=0; (i < (int)(eoid->octetLen)) && (eoid->octs[i] & 0x80);i++) arcNum = (arcNum << 7) + (eoid->octs[i] & 0x7f); arcNum = (arcNum << 7) + (eoid->octs[i] & 0x7f); i++; firstArcNum = arcNum / 40; if (firstArcNum > 2) firstArcNum = 2; secondArcNum = arcNum - (firstArcNum * 40); headOid = (OID*)Malloc (sizeof (OID)); headOid->arcNum = firstArcNum; headOid->next = (OID*)Malloc (sizeof (OID)); headOid->next->arcNum = secondArcNum; nextOid = &headOid->next->next; for ( ; i < (int)(eoid->octetLen); ) { for (arcNum = 0; (i < (int)(eoid->octetLen)) && (eoid->octs[i] & 0x80);i++) arcNum = (arcNum << 7) + (eoid->octs[i] & 0x7f); arcNum = (arcNum << 7) + (eoid->octs[i] & 0x7f); i++; *nextOid = (OID*)Malloc (sizeof (OID)); (*nextOid)->arcNum = arcNum; nextOid = &(*nextOid)->next; } *result = headOid; } /* UnbuildEncodedOid */ esnacc-ng-1.8.1/compiler/core/print.c000066400000000000000000002142311302010526100174120ustar00rootroot00000000000000/* * compiler/core/print.c * * These routines are for printing the information from a Module * Data strucuture in ASN.1 form. * * Useful for debugging the parser and seeing changes caused by * normalization and sorting. * * Mike Sample * Feb 28/91 * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/core/print.c,v 1.8 2004/01/14 19:07:53 gronej Exp $ * $Log: print.c,v $ * Revision 1.8 2004/01/14 19:07:53 gronej * Updated Compiler to accept and process relative-oid's * * Revision 1.7 2003/07/14 21:07:44 nicholar * Changed how parser handles --snacc directives. Added namespace option. * * Revision 1.6 2003/07/07 14:50:14 nicholar * Eliminated headers and cleaned up include references * * Revision 1.5 2003/04/29 21:07:32 leonberp * integerated Deepak's changes for IOB support * * Revision 1.4 2002/09/16 16:50:20 mcphersc * Fixed warnings * * Revision 1.3 2002/09/04 18:31:39 vracarl * got rid of c++ comments * * Revision 1.2 2000/10/24 14:54:54 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:36:01 leonberp * First CVS Version of SNACC. * * Revision 1.6 1997/02/28 13:39:55 wan * Modifications collected for new version 1.3: Bug fixes, tk4.2. * * Revision 1.5 1995/08/17 14:58:57 rj * minor typographic change * * Revision 1.4 1995/07/25 19:41:42 rj * changed `_' to `-' in file names. * * Revision 1.3 1994/10/08 03:48:53 rj * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long. * * Revision 1.2 1994/09/01 00:42:16 rj * snacc_config.h removed. * * Revision 1.1 1994/08/28 09:49:32 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include "asn-incl.h" #include "asn1module.h" #include "lib-types.h" #include "print.h" #include #include #include extern FILE* errFileG; // Defined in snacc.c static int indentCountG; static int indentG = 0; static int indentStepG = 4; #define INDENT(f, i)\ for (indentCountG = 0; indentCountG < (i); indentCountG++)\ fputc (' ', (f))\ /* * Prints the given Module *, mod, to the given FILE *f in * ASN.1 format */ void PrintModule PARAMS ((f, mod), FILE *f _AND_ Module *mod) { if (mod->status == MOD_ERROR) { fprintf(f, "WARNING: this module contains errors\n"); fprintf(f,"(probably some type/value is referenced but is not defined or imported)\n"); fprintf(f,"The prog. may croak, cross your fingers!\n"); } fprintf(f, "%s ",mod->modId->name); PrintOid(f, mod->modId->oid); fprintf(f, "\nDEFINITIONS "); if (mod->tagDefault == EXPLICIT_TAGS) fprintf(f, "EXPLICIT TAGS"); else if (mod->tagDefault == IMPLICIT_TAGS) fprintf(f, "IMPLICIT TAGS"); else if (mod->tagDefault == AUTOMATIC_TAGS) fprintf(f, "AUTOMATIC TAGS"); else fprintf(f, "\n\n -- compiler error unknown tag default"); fprintf(f, " ::=\nBEGIN\n\n"); PrintExports (f, mod); PrintImportLists (f, mod->imports); PrintTypeDefs (f, mod->typeDefs); PrintValueDefs (f, mod->valueDefs); fprintf (f, "END\n"); } /* PrintModule */ void PrintExports PARAMS ((f, m), FILE *f _AND_ Module *m) { TypeDef *td; ValueDef *vd; int first; if (m->exportStatus == EXPORTS_ALL) { fprintf (f, "\n\n-- exports everything\n\n"); } else if (m->exportStatus == EXPORTS_NOTHING) { fprintf (f, "\n\nEXPORTS -- exports nothing\n\n"); } else { fprintf (f, "\n\nEXPORTS\n"); first = 1; FOR_EACH_LIST_ELMT (td, m->typeDefs) if (td->exported) { if (!first) fprintf (f,", "); fprintf (f, "%s", td->definedName); first = 0; } FOR_EACH_LIST_ELMT (vd, m->valueDefs) if (vd->exported) { if (!first) fprintf (f,", "); fprintf (f, "%s", vd->definedName); first = 0; } fprintf (f, "\n;\n\n"); } } /* PrintExports */ void PrintOid PARAMS ((f, oid), FILE *f _AND_ OID *oid) { if (oid == NULL) return; fprintf (f, "{ "); for (; oid != NULL; oid = oid->next) { /* * value ref to an integer or if first elmt in * oid can ref other oid value * { id-asdc } */ if (oid->valueRef != NULL) PrintValue (f, NULL, NULL, oid->valueRef); /* * just "arcNum" format * { 2 } */ else if (oid->arcNum != NULL_OID_ARCNUM) fprintf (f, "%d", (int)oid->arcNum); fprintf (f, " "); } fprintf (f, "}"); } /* PrintOid */ void PrintImportElmt PARAMS ((f, impElmt), FILE *f _AND_ ImportElmt *impElmt) { fprintf (f, "%s",impElmt->name); } /* PrintImportElmt */ void PrintImportElmts PARAMS ((f, impElmtList), FILE *f _AND_ ImportElmtList *impElmtList) { ImportElmt *ie; ImportElmt *last; if ((impElmtList == NULL) || (LIST_EMPTY (impElmtList))) return; last = (ImportElmt*)LAST_LIST_ELMT (impElmtList); FOR_EACH_LIST_ELMT (ie, impElmtList) { PrintImportElmt (f, ie); if (ie != last) fprintf (f, ", "); } } /* PrintImportElmts */ void PrintImportLists PARAMS ((f, impLists), FILE *f _AND_ ImportModuleList *impLists) { ImportModule *impMod; if (impLists == NULL) { fprintf (f,"\n\n-- imports nothing\n\n"); return; } fprintf (f, "IMPORTS\n\n"); FOR_EACH_LIST_ELMT (impMod, impLists) { PrintImportElmts (f, impMod->importElmts); fprintf (f, "\n FROM %s ", impMod->modId->name); PrintOid (f, impMod->modId->oid); fprintf (f, "\n\n\n"); } fprintf (f, ";\n\n\n"); } /* PrintImportLists */ void PrintTypeDefs PARAMS ((f, typeDefs), FILE *f _AND_ TypeDefList *typeDefs) { TypeDef *td; FOR_EACH_LIST_ELMT (td, typeDefs) { if (td->type->basicType->choiceId == BASICTYPE_MACRODEF) PrintMacroDef (f, td); else { fprintf (f,"-- %s notes: ", td->definedName); if (td->recursive) fprintf (f,"recursive, "); else fprintf (f,"not recursive, "); if (td->exported) fprintf (f,"exported,\n"); else fprintf (f,"not exported,\n"); fprintf (f,"-- locally refd %d times, ", td->localRefCount); fprintf (f,"import refd %d times\n", td->importRefCount); fprintf (f, "%s ::= ", td->definedName); PrintType (f, td, td->type); } fprintf (f, "\n\n\n"); } } /* PrintTypeDefs */ void PrintType PARAMS ((f, head, t), FILE *f _AND_ TypeDef *head _AND_ Type *t) { Tag *tag; if (t == NULL) return; FOR_EACH_LIST_ELMT (tag, t->tags) { if (! ((tag->tclass == UNIV) && (tag->code == LIBTYPE_GET_UNIV_TAG_CODE (t->basicType->choiceId)))) { PrintTag (f, tag); fprintf (f, " "); } } /* * check type has been implicitly tagged */ if (t->implicit) fprintf (f, "IMPLICIT "); PrintBasicType (f, head, t, t->basicType); /* * sequences of and set of print subtypes a special way * so ignore them here */ if ((t->subtypes != NULL) && (t->basicType->choiceId != BASICTYPE_SETOF) && (t->basicType->choiceId != BASICTYPE_SEQUENCEOF)) { fprintf (f," "); PrintSubtype (f, head, t, t->subtypes); } if (t->defaultVal != NULL) { fprintf (f, " DEFAULT "); if (t->defaultVal->fieldName != NULL) fprintf (f, "%s ", t->defaultVal->fieldName); PrintValue (f, NULL, t, t->defaultVal->value); } else if (t->optional) fprintf (f, " OPTIONAL"); #ifdef DEBUG fprintf (f, " -- lineNo = %d --", t->lineNo); #endif } /* PrintType */ void PrintBasicType PARAMS ((f, head, t, bt), FILE *f _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt) { switch (bt->choiceId) { case BASICTYPE_SEQUENCE: fprintf (f, "SEQUENCE\n"); INDENT (f, indentG); fprintf (f,"{\n"); indentG += indentStepG; INDENT (f, indentG); PrintElmtTypes (f, head, t, bt->a.sequence); indentG -= indentStepG; fprintf (f, "\n"); INDENT (f, indentG); fprintf (f, "}"); break; case BASICTYPE_SET: fprintf (f, "SET\n"); INDENT (f, indentG); fprintf (f,"{\n"); indentG += indentStepG; INDENT (f, indentG); PrintElmtTypes (f, head, t, bt->a.set); indentG -= indentStepG; fprintf (f, "\n"); INDENT (f, indentG); fprintf (f, "}"); break; case BASICTYPE_CHOICE: fprintf (f, "CHOICE\n"); INDENT (f, indentG); fprintf (f,"{\n"); indentG += indentStepG; INDENT (f, indentG); PrintElmtTypes (f, head, t, bt->a.choice); indentG -= indentStepG; fprintf (f, "\n"); INDENT (f, indentG); fprintf (f, "}"); break; case BASICTYPE_SEQUENCEOF: fprintf (f, "SEQUENCE "); if (t->subtypes != NULL) { PrintSubtype (f, head, t, t->subtypes); fprintf (f," "); } fprintf (f, "OF "); PrintType (f, head, bt->a.sequenceOf); break; case BASICTYPE_SETOF: fprintf (f, "SET "); if (t->subtypes != NULL) { PrintSubtype (f, head, t, t->subtypes); fprintf (f," "); } fprintf (f, "OF "); PrintType (f, head, bt->a.setOf); break; case BASICTYPE_SELECTION: fprintf (f, "%s < ", bt->a.selection->fieldName); PrintType (f, head, bt->a.selection->typeRef); break; case BASICTYPE_COMPONENTSOF: fprintf (f, "COMPONENTS OF "); PrintType (f, NULL, bt->a.componentsOf); break; case BASICTYPE_ANYDEFINEDBY: fprintf (f, "ANY DEFINED BY %s", bt->a.anyDefinedBy->fieldName); break; case BASICTYPE_LOCALTYPEREF: fprintf (f, "%s", bt->a.localTypeRef->typeName); break; case BASICTYPE_IMPORTTYPEREF: /* attempt to keep special scoping, ie modname.type forms */ if (bt->a.importTypeRef->moduleName != NULL) fprintf (f,"%s.", bt->a.importTypeRef->moduleName); fprintf (f, "%s", bt->a.importTypeRef->typeName); break; case BASICTYPE_UNKNOWN: fprintf (f, "unknown type !?!"); break; case BASICTYPE_BOOLEAN: fprintf (f, "BOOLEAN"); break; case BASICTYPE_INTEGER: fprintf (f, "INTEGER"); if ((bt->a.integer != NULL) && !LIST_EMPTY (bt->a.integer)) { fprintf (f, "\n"); INDENT (f, indentG); fprintf (f, "{\n"); indentG += indentStepG; PrintNamedElmts (f, head, t, bt->a.integer); indentG -= indentStepG; fprintf (f, "\n"); INDENT (f, indentG); fprintf (f, "}"); } break; /* case BASICTYPE_BIGINT: fprintf (f, "INTEGER (isBigInt:TRUE)"); if ((bt->a.integer != NULL) && !LIST_EMPTY (bt->a.integer)) { fprintf (f, "\n"); INDENT (f, indentG); fprintf (f, "{\n"); indentG += indentStepG; PrintNamedElmts (f, head, t, bt->a.integer); indentG -= indentStepG; fprintf (f, "\n"); INDENT (f, indentG); fprintf (f, "}"); } break; */ case BASICTYPE_BITSTRING: fprintf (f, "BIT STRING"); if ((bt->a.bitString != NULL) && !LIST_EMPTY (bt->a.bitString)) { fprintf (f, "\n"); INDENT (f, indentG); fprintf (f, "{\n"); indentG += indentStepG; PrintNamedElmts (f, head, t, bt->a.bitString); indentG -= indentStepG; fprintf (f, "\n"); INDENT (f, indentG); fprintf (f, "}"); } break; case BASICTYPE_OCTETSTRING: fprintf (f, "OCTET STRING"); break; case BASICTYPE_NULL: fprintf (f, "NULL"); break; case BASICTYPE_OID: fprintf (f, "OBJECT IDENTIFIER"); break; case BASICTYPE_RELATIVE_OID: fprintf (f, "RELATIVE-OID"); break; case BASICTYPE_REAL: fprintf (f, "REAL"); break; case BASICTYPE_ENUMERATED: fprintf (f, "ENUMERATED"); if ((bt->a.enumerated != NULL) && !LIST_EMPTY (bt->a.enumerated)) { fprintf (f, "\n"); INDENT (f, indentG); fprintf (f, "{\n"); indentG += indentStepG; PrintNamedElmts (f, head, t, bt->a.enumerated); indentG -= indentStepG; fprintf (f, "\n"); INDENT (f, indentG); fprintf (f, "}"); } break; case BASICTYPE_NUMERIC_STR: fprintf(f, "NumericString"); break; case BASICTYPE_PRINTABLE_STR: fprintf(f, "PrintableString"); break; case BASICTYPE_IA5_STR: fprintf(f, "IA5String"); break; case BASICTYPE_BMP_STR: fprintf(f, "BMPString"); break; case BASICTYPE_UNIVERSAL_STR: fprintf(f, "UniversalString"); break; case BASICTYPE_UTF8_STR: fprintf(f, "UTF8String"); break; case BASICTYPE_T61_STR: fprintf(f, "TeletexString"); break; case BASICTYPE_ANY: fprintf (f, "ANY"); break; case BASICTYPE_MACROTYPE: switch (bt->a.macroType->choiceId) { case MACROTYPE_ROSOPERATION: case MACROTYPE_ASNABSTRACTOPERATION: PrintRosOperationMacroType (f, head, t, bt, bt->a.macroType->a.rosOperation); break; case MACROTYPE_ROSERROR: case MACROTYPE_ASNABSTRACTERROR: PrintRosErrorMacroType (f, head, t, bt, bt->a.macroType->a.rosError); break; case MACROTYPE_ROSBIND: case MACROTYPE_ROSUNBIND: PrintRosBindMacroType (f, head, t, bt, bt->a.macroType->a.rosBind); break; case MACROTYPE_ROSASE: PrintRosAseMacroType (f, head, t, bt, bt->a.macroType->a.rosAse); break; case MACROTYPE_MTSASEXTENSIONS: PrintMtsasExtensionsMacroType (f, head, t, bt, bt->a.macroType->a.mtsasExtensions); break; case MACROTYPE_MTSASEXTENSION: PrintMtsasExtensionMacroType (f, head, t, bt, bt->a.macroType->a.mtsasExtension); break; case MACROTYPE_MTSASEXTENSIONATTRIBUTE: PrintMtsasExtensionAttributeMacroType (f, head, t, bt, bt->a.macroType->a.mtsasExtensionAttribute); break; case MACROTYPE_MTSASTOKEN: PrintMtsasTokenMacroType (f, head, t, bt, bt->a.macroType->a.mtsasToken); break; case MACROTYPE_MTSASTOKENDATA: PrintMtsasTokenDataMacroType (f, head, t, bt, bt->a.macroType->a.mtsasTokenData); break; case MACROTYPE_MTSASSECURITYCATEGORY: PrintMtsasSecurityCategoryMacroType (f, head, t, bt, bt->a.macroType->a.mtsasSecurityCategory); break; case MACROTYPE_ASNOBJECT: PrintAsnObjectMacroType (f, head, t, bt, bt->a.macroType->a.asnObject); break; case MACROTYPE_ASNPORT: PrintAsnPortMacroType (f, head, t, bt, bt->a.macroType->a.asnPort); break; case MACROTYPE_ASNABSTRACTBIND: case MACROTYPE_ASNABSTRACTUNBIND: PrintAsnAbstractBindMacroType (f, head, t, bt, bt->a.macroType->a.asnAbstractBind); break; case MACROTYPE_AFALGORITHM: PrintAfAlgorithmMacroType (f, head, t, bt, bt->a.macroType->a.afAlgorithm); break; case MACROTYPE_AFENCRYPTED: PrintAfEncryptedMacroType (f, head, t, bt, bt->a.macroType->a.afEncrypted); break; case MACROTYPE_AFSIGNED: PrintAfSignedMacroType (f, head, t, bt, bt->a.macroType->a.afSigned); break; case MACROTYPE_AFSIGNATURE: PrintAfSignatureMacroType (f, head, t, bt, bt->a.macroType->a.afSignature); break; case MACROTYPE_AFPROTECTED: PrintAfProtectedMacroType (f, head, t, bt, bt->a.macroType->a.afProtected); break; case MACROTYPE_SNMPOBJECTTYPE: PrintSnmpObjectTypeMacroType (f, head, t, bt, bt->a.macroType->a.snmpObjectType); break; default: fprintf (f, "< unknown macro type id ?! >"); } /* end macro type switch */ break; /* * @MACRO@ add new macro printers above this point */ case BASICTYPE_MACRODEF: /* * printing this should be handled in PrintTypeDefs */ break; default: fprintf (f, "< unknown type id ?! >"); } } /* PrintBasicType */ void PrintElmtType PARAMS ((f, head, t, nt), FILE *f _AND_ TypeDef *head _AND_ Type *t _AND_ NamedType *nt) { if (nt->fieldName != NULL) fprintf (f, "%s ", nt->fieldName); PrintType (f, head, nt->type); t = t; /* AVOIDS warning. */ } /* PrintElmtType */ void PrintElmtTypes PARAMS ((f, head, t, e), FILE *f _AND_ TypeDef *head _AND_ Type *t _AND_ NamedTypeList *e) { NamedType *nt; NamedType *last; if ((e == NULL) || LIST_EMPTY (e)) return; last = (NamedType*)LAST_LIST_ELMT (e); FOR_EACH_LIST_ELMT (nt, e) { PrintElmtType (f, head, t, nt); if (nt != last) { fprintf (f, ",\n"); INDENT (f, indentG); } } } /* PrintElmtTypes */ void PrintValueDefs PARAMS ((f, vList), FILE *f _AND_ ValueDefList *vList) { ValueDef *v; FOR_EACH_LIST_ELMT (v, vList) { PrintValueDef (f, v); } } /* PrintValueDefs */ void PrintValueDef PARAMS ((f, v), FILE *f _AND_ ValueDef *v) { fprintf (f, "%s ", v->definedName); if (v->value->type != NULL) PrintType (f, NULL, v->value->type); else /* just go by valueType */ PrintTypeById (f, v->value->valueType); fprintf (f, " ::= "); indentG += indentStepG; PrintValue (f, v, v->value->type, v->value); fprintf (f, "\n\n"); indentG -= indentStepG; } /* PrintValueDef */ void PrintValue PARAMS ((f, head, valuesType, v), FILE *f _AND_ ValueDef *head _AND_ Type *valuesType _AND_ Value *v) { if (v == NULL) return; PrintBasicValue (f, head, valuesType, v, v->basicValue); } /* PrintValue */ void PrintBasicValue PARAMS ((f, head, valuesType, v, bv), FILE *f _AND_ ValueDef *head _AND_ Type *valuesType _AND_ Value *v _AND_ BasicValue *bv) { if (v == NULL) return; switch (bv->choiceId) { case BASICVALUE_UNKNOWN: fprintf (f, ""); break; case BASICVALUE_EMPTY: fprintf (f,"{ }"); break; case BASICVALUE_INTEGER: fprintf (f, "%d", bv->a.integer); break; case BASICVALUE_SPECIALINTEGER: if (bv->a.specialInteger == MAX_INT) fprintf (f, "MAX"); else fprintf (f, "MIN"); break; case BASICVALUE_BOOLEAN: if (bv->a.boolean) fprintf (f,"TRUE"); else fprintf (f,"FALSE"); break; case BASICVALUE_REAL: fprintf (f, "%f", bv->a.real); break; case BASICVALUE_SPECIALREAL: if (bv->a.specialReal == PLUS_INFINITY_REAL) fprintf (f, "PLUS INFINITY"); else fprintf (f, "MINUS INFINITY"); break; case BASICVALUE_ASCIITEXT: fprintf (f, "\"%s\"", bv->a.asciiText->octs); break; case BASICVALUE_ASCIIHEX: fprintf (f, "\"%s\"", bv->a.asciiHex->octs); break; case BASICVALUE_ASCIIBITSTRING: fprintf (f, "\"%s\"", bv->a.asciiBitString->octs); break; case BASICVALUE_OID: PrintEncodedOid (f, bv->a.oid); break; case BASICVALUE_LINKEDOID: PrintOid (f, bv->a.linkedOid); break; case BASICVALUE_BERVALUE: fprintf (f,"a.namedValue); indentG -= indentStepG; fprintf (f,"\n"); INDENT (f, indentG); fprintf (f,"}"); break; case BASICVALUE_NULL: fprintf (f,"NULL"); break; case BASICVALUE_LOCALVALUEREF: fprintf (f, "%s", bv->a.localValueRef->valueName); break; case BASICVALUE_IMPORTVALUEREF: fprintf (f, "%s", bv->a.importValueRef->valueName); break; case BASICVALUE_VALUENOTATION: fprintf (f, "-- snacc warning: can't parse this value yet --"); fprintf (f, "%s", bv->a.valueNotation->octs); break; default: fprintf (errFileG, "PrintBasicValue: ERROR - unknown value type\n"); } valuesType = valuesType; /* AVOIDS warning. */ } /* PrintBasicValue */ void PrintElmtValue PARAMS ((f, head, v, nv), FILE *f _AND_ ValueDef *head _AND_ Value *v _AND_ NamedValue *nv) { if (nv->fieldName != NULL) fprintf (f, "%s ", nv->fieldName); PrintValue (f, NULL, NULL, nv->value); v = v; head = head; /* AVOIDS warning. */ } /* PrintElmtValue */ void PrintElmtValues PARAMS ((f, head, v, e), FILE *f _AND_ ValueDef *head _AND_ Value *v _AND_ NamedValueList *e) { NamedValue *nv; NamedValue *last; if ((e == NULL) || LIST_EMPTY (e)) return; last = (NamedValue*)LAST_LIST_ELMT (e); FOR_EACH_LIST_ELMT (nv, e) { PrintElmtValue (f, head, v, nv); if (nv != last) { fprintf (f, ",\n"); INDENT (f, indentG); } } } /* PrintElmtValues */ void PrintTypeById PARAMS ((f, typeId), FILE *f _AND_ int typeId) { switch (typeId) { case BASICTYPE_UNKNOWN: fprintf (f, "UNKNOWN"); break; case BASICTYPE_BOOLEAN: fprintf (f, "BOOLEAN"); break; case BASICTYPE_INTEGER: fprintf (f, "INTEGER"); break; case BASICTYPE_BITSTRING: fprintf (f, "BIT STRING"); break; case BASICTYPE_OCTETSTRING: fprintf (f, "OCTET STRING"); break; case BASICTYPE_NULL: fprintf (f, "NULL"); break; case BASICTYPE_SEQUENCE: fprintf (f, "SEQUENCE"); break; case BASICTYPE_SEQUENCEOF: fprintf (f, "SEQUENCE OF"); break; case BASICTYPE_SET: fprintf (f, "SET"); break; case BASICTYPE_SETOF: fprintf (f, "SET OF"); break; case BASICTYPE_CHOICE: fprintf (f, "CHOICE"); break; case BASICTYPE_SELECTION: fprintf (f, "SELECTION"); break; case BASICTYPE_ANY: fprintf (f, "ANY"); break; case BASICTYPE_ANYDEFINEDBY: fprintf (f, "ANY DEFINED BY"); break; case BASICTYPE_OID: fprintf (f, "OBJECT IDENTIFIER"); break; case BASICTYPE_RELATIVE_OID: fprintf (f, "RELATIVE-OID"); break; case BASICTYPE_ENUMERATED: fprintf (f, "ENUMERATED"); break; case BASICTYPE_REAL: fprintf (f, "REAL"); break; case BASICTYPE_COMPONENTSOF: fprintf (f, "COMPONENTS OF"); break; case BASICTYPE_NUMERIC_STR: fprintf(f, "NumericString"); break; case BASICTYPE_PRINTABLE_STR: fprintf(f, "PrintableString"); break; case BASICTYPE_IA5_STR: fprintf(f, "IA5String"); break; case BASICTYPE_BMP_STR: fprintf(f, "BMPString"); break; case BASICTYPE_UNIVERSAL_STR: fprintf(f, "UniversalString"); break; case BASICTYPE_UTF8_STR: fprintf(f, "UTF8String"); break; case BASICTYPE_T61_STR: fprintf(f, "TeletexString"); break; default: fprintf (f, "ERROR - %d is an unknown type id\n", typeId); } } /* PrintTypeById */ void PrintTag PARAMS ((f, tag), FILE *f _AND_ Tag *tag) { if (tag->tclass == UNIV) { fprintf (f, "[UNIVERSAL %d]", tag->code); } else if (tag->tclass == APPL) { fprintf (f, "[APPLICATION %d]", tag->code); } else if (tag->tclass == PRIV) { fprintf (f, "[PRIVATE %d]", tag->code); } else if (tag->tclass == CNTX) { fprintf (f, "[%d]", tag->code); } if (tag->explicit) fprintf (f, " EXPLICIT"); } /* PrintTag */ void PrintSubtype PARAMS ((f, head, t, s), FILE *f _AND_ TypeDef *head _AND_ Type *t _AND_ Subtype *s) { Subtype *tmpS; Subtype *last=NULL; if (s == NULL) return; /* fprintf (f, "("); */ switch (s->choiceId) { case SUBTYPE_SINGLE: PrintSubtypeValue (f, head, t, s->a.single); break; case SUBTYPE_AND: FOR_EACH_LIST_ELMT (tmpS, s->a.and) { fprintf (f, "("); PrintSubtype (f, head, t, tmpS); fprintf (f, ")"); } break; case SUBTYPE_OR: if ((s->a.or != NULL) && !LIST_EMPTY (s->a.or)) last = (Subtype*)LAST_LIST_ELMT (s->a.or); FOR_EACH_LIST_ELMT (tmpS, s->a.or) { fprintf (f, "("); PrintSubtype (f, head, t, tmpS); fprintf (f, ")"); if (tmpS != last) fprintf (f, " | "); } break; case SUBTYPE_NOT: fprintf (f, "NOT ("); PrintSubtype (f, head, t, s->a.not); fprintf (f, ")"); break; default: fprintf (errFileG, "PrintSubtype: ERROR - unknown Subtypes choiceId\n"); break; } /* fprintf (f, ")"); */ } /* PrintSubtype */ void PrintSubtypeValue PARAMS ((f, head, t, s), FILE *f _AND_ TypeDef *head _AND_ Type *t _AND_ SubtypeValue *s) { if (s == NULL) return; switch (s->choiceId) { case SUBTYPEVALUE_SINGLEVALUE: PrintValue (f, NULL, NULL, s->a.singleValue); break; case SUBTYPEVALUE_CONTAINED: fprintf (f, "a.valueRange->lowerEndValue->endValue); if (!s->a.valueRange->lowerEndValue->valueInclusive) fprintf (f, " >"); fprintf (f,".."); if (!s->a.valueRange->upperEndValue->valueInclusive) fprintf (f, "< "); PrintValue (f, NULL, NULL, s->a.valueRange->upperEndValue->endValue); break; case SUBTYPEVALUE_PERMITTEDALPHABET: fprintf (f,"FROM "); PrintSubtype (f, head, t, s->a.permittedAlphabet); break; case SUBTYPEVALUE_SIZECONSTRAINT: fprintf (f,"SIZE "); PrintSubtype (f, head, t, s->a.sizeConstraint); break; case SUBTYPEVALUE_INNERSUBTYPE: PrintInnerSubtype (f, head, t, s->a.innerSubtype); break; default: fprintf (errFileG, "PrintSubtype: ERROR - unknown Subtype choiceId\n"); break; } } /* PrintSubtype */ void PrintInnerSubtype PARAMS ((f, head, t, i), FILE *f _AND_ TypeDef *head _AND_ Type *t _AND_ InnerSubtype *i) { Constraint *constraint; if (i->constraintType == SINGLE_CT) { fprintf (f,"WITH COMPONENT "); constraint = *(Constraint**)AsnListFirst (i->constraints); PrintSubtype (f, head, t, constraint->valueConstraints); } else { fprintf (f, "WITH COMPONENTS\n"); INDENT (f, indentG); fprintf (f, "{\n"); indentG += indentStepG; if (i->constraintType == PARTIAL_CT) { INDENT (f, indentG); fprintf (f, "...,\n"); } PrintMultipleTypeConstraints (f, head, t, i->constraints); indentG -= indentStepG; fprintf (f, "\n"); INDENT (f, indentG); fprintf (f, "}"); } } /* PrintInnerSubtype */ void PrintMultipleTypeConstraints PARAMS ((f, head, t, cList), FILE *f _AND_ TypeDef *head _AND_ Type *t _AND_ ConstraintList *cList) { Constraint *c; Constraint *last; if ((cList == NULL) || LIST_EMPTY (cList)) return; last = (Constraint*)LAST_LIST_ELMT (cList); FOR_EACH_LIST_ELMT (c, cList) { if (c->fieldRef != NULL) { INDENT (f, indentG); fprintf (f, "%s ", c->fieldRef); } PrintSubtype (f, head, t, c->valueConstraints); if (c->presenceConstraint == ABSENT_CT) fprintf (f, " ABSENT"); if (c->presenceConstraint == PRESENT_CT) fprintf (f, " PRESENT"); if (c->presenceConstraint == OPTIONAL_CT) fprintf (f, " OPTIONAL"); if (c != last) fprintf (f, ",\n"); } } /* PrintMultipleTypeConstraints */ void PrintNamedElmts PARAMS ((f, head, t, n), FILE *f _AND_ TypeDef *head _AND_ Type *t _AND_ ValueDefList *n) { ValueDef *vd; ValueDef *last; if ((n == NULL) || LIST_EMPTY (n)) return; last = (ValueDef*)LAST_LIST_ELMT (n); FOR_EACH_LIST_ELMT (vd, n) { INDENT (f, indentG); fprintf (f, "%s (", vd->definedName); PrintValue (f, NULL, NULL, vd->value); fprintf (f,")"); if (vd != last) fprintf (f,",\n"); } t = t; head = head; /* AVOIDS warning. */ } /* PrintNamedElmts */ void PrintRosOperationMacroType PARAMS ((f, head, t, bt, op), FILE *f _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ RosOperationMacroType *op) { TypeOrValue *tOrV; TypeOrValue *last; if (bt->a.macroType->choiceId == MACROTYPE_ROSOPERATION) fprintf (f, "OPERATION"); else fprintf (f, "ABSTRACT-OPERATION"); indentG += indentStepG; if (op->arguments != NULL) { fprintf (f,"\n"); INDENT (f, indentG); fprintf (f, "ARGUMENT\n"); indentG += indentStepG; INDENT (f, indentG); if (op->arguments->fieldName != NULL) fprintf (f, "%s ", op->arguments->fieldName); PrintType (f, head, op->arguments->type); indentG -= indentStepG; } if (op->result != NULL) { fprintf (f,"\n"); INDENT (f, indentG); fprintf (f, "RESULT\n"); indentG += indentStepG; INDENT (f, indentG); if (op->arguments && op->arguments->fieldName) fprintf (f, "%s ", op->arguments->fieldName); PrintType (f, head, op->result->type); indentG -= indentStepG; } //if ((op->errors == NULL) || (!LIST_EMPTY (op->errors))) if ((op->errors != NULL) /*|| (!LIST_EMPTY (op->errors))*/) { fprintf (f,"\n"); INDENT (f, indentG); fprintf (f, "ERRORS\n"); INDENT (f, indentG); fprintf (f,"{\n"); indentG += indentStepG; last = (TypeOrValue*)LAST_LIST_ELMT (op->errors); FOR_EACH_LIST_ELMT (tOrV, op->errors) { INDENT (f, indentG); if (tOrV->choiceId == TYPEORVALUE_TYPE) PrintType (f, head, tOrV->a.type); else PrintValue (f, NULL, t, tOrV->a.value); if (tOrV != last) fprintf (f, ",\n"); } indentG -= indentStepG; fprintf (f,"\n"); INDENT (f, indentG); fprintf (f, "}"); } if ((op->linkedOps != NULL) && (!LIST_EMPTY (op->linkedOps))) { fprintf (f,"\n"); INDENT (f, indentG); fprintf (f, "LINKED\n"); INDENT (f, indentG); fprintf (f,"{\n"); indentG += indentStepG; last = (TypeOrValue*)LAST_LIST_ELMT (op->linkedOps); FOR_EACH_LIST_ELMT (tOrV, op->linkedOps) { INDENT (f, indentG); if (tOrV->choiceId == TYPEORVALUE_TYPE) PrintType (f, head, tOrV->a.type); else PrintValue (f, NULL, t, tOrV->a.value); if (tOrV != last) fprintf (f, ",\n"); } indentG -= indentStepG; fprintf (f,"\n"); INDENT (f, indentG); fprintf (f, " }"); } indentG -= indentStepG; } /* PrintRosOperationMacroType */ void PrintRosErrorMacroType PARAMS ((f, head, t, bt, err), FILE *f _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ RosErrorMacroType *err) { if (bt->a.macroType->choiceId == MACROTYPE_ROSERROR) fprintf (f,"ERROR\n"); else fprintf (f,"ABSTRACT-ERROR\n"); indentG += indentStepG; if (err->parameter != NULL) { INDENT (f, indentG); fprintf (f,"PARAMETER "); indentG += indentStepG; PrintElmtType (f, head, t, err->parameter); indentG -= indentStepG; } indentG -= indentStepG; } /* PrintRosErrorMacroType */ void PrintRosBindMacroType PARAMS ((f, head, t, bt, bind), FILE *f _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ RosBindMacroType *bind) { if (bt->a.macroType->choiceId == MACROTYPE_ROSBIND) fprintf (f,"BIND"); else fprintf (f,"UNBIND"); indentG += indentStepG; if (bind->argument != NULL) { fprintf (f, "\n"); INDENT (f, indentG); fprintf (f,"ARGUMENT\n"); indentG += indentStepG; INDENT (f, indentG); PrintElmtType (f, head, t, bind->argument); indentG -= indentStepG; } if (bind->result != NULL) { fprintf (f, "\n"); INDENT (f, indentG); fprintf (f,"RESULT\n"); indentG += indentStepG; INDENT (f, indentG); PrintElmtType (f, head, t, bind->result); indentG -= indentStepG; } if (bind->error != NULL) { fprintf (f, "\n"); INDENT (f, indentG); if (bt->a.macroType->choiceId == MACROTYPE_ROSBIND) fprintf (f,"BIND-ERROR\n"); else fprintf (f,"UNBIND-ERROR\n"); indentG += indentStepG; INDENT (f, indentG); PrintElmtType (f, head, t, bind->error); indentG -= indentStepG; } indentG -= indentStepG; } /* PrintRosBindMacroType */ void PrintRosAseMacroType PARAMS ((f, head, t, bt, ase), FILE *f _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ RosAseMacroType *ase) { Value *v; Value *last; fprintf (f, "APPLICATION-SERVICE-ELEMENT"); indentG += indentStepG; if ((ase->operations != NULL)&& (!LIST_EMPTY (ase->operations))) { fprintf (f,"\n"); INDENT (f, indentG); fprintf (f,"OPERATIONS\n"); INDENT (f, indentG); fprintf (f, "{\n"); indentG += indentStepG; last = (Value*)LAST_LIST_ELMT (ase->operations); FOR_EACH_LIST_ELMT (v, ase->operations) { INDENT (f, indentG); PrintValue (f, NULL, t, v); if (v != last) fprintf (f, ",\n"); } fprintf (f, "\n"); indentG -= indentStepG; INDENT (f, indentG); fprintf (f, "}"); } else /* either suuplier invokes or consumer invokes will be valid */ { if ((ase->consumerInvokes != NULL) && (!LIST_EMPTY (ase->consumerInvokes))) { fprintf (f,"\n"); INDENT (f, indentG); fprintf (f,"CONSUMER INVOKES\n"); INDENT (f, indentG); fprintf (f, "{\n"); indentG += indentStepG; last = (Value*) LAST_LIST_ELMT (ase->consumerInvokes); FOR_EACH_LIST_ELMT (v, ase->consumerInvokes) { INDENT (f, indentG); PrintValue (f, NULL, t, v); if (v != last) fprintf (f, ",\n"); } fprintf (f, "\n"); indentG -= indentStepG; INDENT (f, indentG); fprintf (f, "}"); } if ((ase->operations != NULL) && (!LIST_EMPTY (ase->operations))) { fprintf (f,"\n"); INDENT (f, indentG); fprintf (f,"SUPPLIER INVOKES\n"); INDENT (f, indentG); fprintf (f, "{\n"); indentG += indentStepG; last = (Value*)LAST_LIST_ELMT (ase->supplierInvokes); FOR_EACH_LIST_ELMT (v, ase->supplierInvokes) { INDENT (f, indentG); PrintValue (f, NULL, t, v); if (v != last) fprintf (f, ",\n"); } fprintf (f, "\n"); indentG -= indentStepG; INDENT (f, indentG); fprintf (f, "}"); } } indentG -= indentStepG; bt = bt; head = head; /* AVOIDS warning. */ } /* PrintRosAseMacrType */ void PrintRosAcMacroType PARAMS ((f, head, t, bt, ac), FILE *f _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ RosAcMacroType *ac) { Value *v; Value *last=NULL; OID *oid; OID *lastOid=NULL; fprintf (f, "APPLICATION-CONTEXT"); indentG += indentStepG; /* * print non Ros Elements */ fprintf (f,"\n"); INDENT (f, indentG); fprintf (f,"APPLICATION-SERVICE-ELEMENTS\n"); INDENT (f, indentG); fprintf (f, "{\n"); indentG += indentStepG; if ((ac->nonRoElements == NULL) && (!LIST_EMPTY (ac->nonRoElements))) last = (Value*)LAST_LIST_ELMT (ac->nonRoElements); FOR_EACH_LIST_ELMT (v, ac->nonRoElements) { INDENT (f, indentG); PrintValue (f, NULL, t, v); if (v != last) fprintf (f, ",\n"); } fprintf (f, "}\n"); /* * Print Bind Type */ INDENT (f, indentG); fprintf (f,"BIND\n"); INDENT (f, indentG); PrintType (f, head, ac->bindMacroType); fprintf (f, "\n"); /* * Print unbind Type */ INDENT (f, indentG); fprintf (f,"UNBIND\n"); INDENT (f, indentG); PrintType (f, head, ac->unbindMacroType); if (ac->remoteOperations != NULL) { fprintf (f, "\n"); INDENT (f, indentG); fprintf (f,"REMOTE OPERATIONS { "); PrintValue (f, NULL, t, ac->remoteOperations); fprintf (f, " }"); if ((ac->operationsOf != NULL) && (!LIST_EMPTY (ac->operationsOf))) { fprintf (f, "\n"); INDENT (f, indentG); fprintf (f,"OPERATIONS OF\n"); INDENT (f, indentG); fprintf (f, "{\n"); indentG += indentStepG; last = (Value*)LAST_LIST_ELMT (ac->operationsOf); FOR_EACH_LIST_ELMT (v, ac->operationsOf) { INDENT (f, indentG); PrintValue (f, NULL, t, v); if (v != last) fprintf (f, ",\n"); } fprintf (f, "\n"); indentG -= indentStepG; INDENT (f, indentG); fprintf (f, "}"); } if ((ac->initiatorConsumerOf != NULL) && (!LIST_EMPTY (ac->initiatorConsumerOf))) { fprintf (f, "\n"); INDENT (f, indentG); fprintf (f,"INITIATOR CONSUMER OF\n"); INDENT (f, indentG); fprintf (f, "{\n"); indentG += indentStepG; last = (Value*)LAST_LIST_ELMT (ac->initiatorConsumerOf); FOR_EACH_LIST_ELMT (v, ac->initiatorConsumerOf) { INDENT (f, indentG); PrintValue (f, NULL, t, v); if (v != last) fprintf (f, ",\n"); } fprintf (f, "\n"); indentG -= indentStepG; INDENT (f, indentG); fprintf (f, "}"); } if ((ac->responderConsumerOf != NULL) && (!LIST_EMPTY (ac->responderConsumerOf))) { fprintf (f, "\n"); INDENT (f, indentG); fprintf (f,"RESPONDER CONSUMER OF\n"); INDENT (f, indentG); fprintf (f, "{\n"); indentG += indentStepG; last = (Value*)LAST_LIST_ELMT (ac->responderConsumerOf); FOR_EACH_LIST_ELMT (v, ac->responderConsumerOf) { INDENT (f, indentG); PrintValue (f, NULL, t, v); if (v != last) fprintf (f, ",\n"); } fprintf (f, "\n"); indentG -= indentStepG; INDENT (f, indentG); fprintf (f, "}"); } } fprintf (f,"\n"); INDENT (f, indentG); fprintf (f,"ABSTRACT SYNTAXES\n"); INDENT (f, indentG); fprintf (f, "{\n"); if ((ac->abstractSyntaxes != NULL) && (!LIST_EMPTY (ac->abstractSyntaxes))) lastOid = (OID*)LAST_LIST_ELMT (ac->abstractSyntaxes); FOR_EACH_LIST_ELMT (oid, ac->abstractSyntaxes) { INDENT (f, indentG); PrintOid (f, oid); if (oid != lastOid) fprintf (f, ",\n"); } fprintf (f, "\n"); indentG -= indentStepG; INDENT (f, indentG); fprintf (f, "}"); indentG -= indentStepG; bt = bt; /* AVOIDS warning. */ } /* PrintRosAcMacroType */ void PrintMtsasExtensionsMacroType PARAMS ((f, head, t, bt, exts), FILE *f _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ MtsasExtensionsMacroType *exts) { Value *v; Value *last=NULL; fprintf (f, "EXTENSIONS CHOSEN FROM"); INDENT (f, indentG); fprintf (f, "{\n"); indentG += indentStepG; if ((exts->extensions == NULL) && (!LIST_EMPTY (exts->extensions))) last = (Value*)LAST_LIST_ELMT (exts->extensions); FOR_EACH_LIST_ELMT (v, exts->extensions) { INDENT (f, indentG); PrintValue (f, NULL, t, v); if (v != last) fprintf (f, ",\n"); } fprintf (f, "\n"); indentG -= indentStepG; INDENT (f, indentG); fprintf (f, "}"); bt = bt; head = head; /* AVOIDS warning. */ } /* PrintMtsasExtensionsMacroType */ void PrintMtsasExtensionMacroType PARAMS ((f, head, t, bt, ext), FILE *f _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ MtsasExtensionMacroType *ext) { fprintf (f, "EXTENSION"); indentG += indentStepG; if (ext->elmtType != NULL) { fprintf (f, "\n"); INDENT (f, indentG); PrintElmtType (f, head, t, ext->elmtType); if (ext->defaultValue != NULL) { fprintf (f, " DEFAULT "); PrintValue (f, NULL, t, ext->defaultValue); } } if ((ext->criticalForSubmission != NULL) || (ext->criticalForTransfer != NULL) || (ext->criticalForDelivery != NULL)) { fprintf (f,"\n"); INDENT (f, indentG); fprintf (f, "CRITICAL FOR "); if (ext->criticalForSubmission != NULL) { fprintf (f, "SUBMISSION"); if ((ext->criticalForTransfer != NULL) || (ext->criticalForDelivery != NULL)) fprintf (f,", "); } if (ext->criticalForTransfer != NULL) { fprintf (f, "TRANSFER, "); if (ext->criticalForDelivery != NULL) fprintf (f,", "); } if (ext->criticalForDelivery != NULL) fprintf (f, "DELIVERY"); } indentG -= indentStepG; bt = bt; /* AVOIDS warning. */ } /* PrintMtsasExtensionMacroType */ void PrintMtsasExtensionAttributeMacroType PARAMS ((f, head, t, bt, ext), FILE *f _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ MtsasExtensionAttributeMacroType *ext) { fprintf (f, "EXTENSION-ATTRIBUTE"); if (ext->type != NULL) { fprintf (f, "\n"); indentG += indentStepG; INDENT (f, indentG); PrintType (f, head, ext->type); indentG -= indentStepG; } bt = bt; t = t; /* AVOIDS warning. */ } /* PrintMtsasExtensionAttributeMacroType */ void PrintMtsasTokenMacroType PARAMS ((f, head, t, bt, tok), FILE *f _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ MtsasTokenMacroType *tok) { fprintf (f, "TOKEN"); if (tok->type != NULL) { fprintf (f, "\n"); indentG += indentStepG; INDENT (f, indentG); PrintType (f, head, tok->type); indentG -= indentStepG; } bt = bt; t = t; /* AVOIDS warning. */ } /* PrintMtsasTokenMacro */ void PrintMtsasTokenDataMacroType PARAMS ((f, head, t, bt, tok), FILE *f _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ MtsasTokenDataMacroType *tok) { fprintf (f, "TOKEN-DATA"); if (tok->type != NULL) { fprintf (f, "\n"); indentG += indentStepG; INDENT (f, indentG); PrintType (f, head, tok->type); indentG -= indentStepG; } bt = bt; t = t; /* AVOIDS warning. */ } /* PrintMtsasTokenDataMacro */ void PrintMtsasSecurityCategoryMacroType PARAMS ((f, head, t, bt, sec), FILE *f _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ MtsasSecurityCategoryMacroType *sec) { fprintf (f, "SECURITY-CATEGORY"); if (sec->type != NULL) { fprintf (f, "\n"); indentG += indentStepG; INDENT (f, indentG); PrintType (f, head, sec->type); indentG -= indentStepG; } bt = bt; t = t; /* AVOIDS warning. */ } /* PrintMtsasSecurityCategoryMacroType */ void PrintAsnObjectMacroType PARAMS ((f, head, t, bt, obj), FILE *f _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ AsnObjectMacroType *obj) { AsnPort *ap; AsnPort *last; fprintf (f, "OBJECT"); indentG += indentStepG; if ((obj->ports != NULL) && !LIST_EMPTY (obj->ports)) { fprintf (f,"\n"); INDENT (f, indentG); fprintf (f, "PORTS\n"); INDENT (f, indentG); fprintf (f, "{\n"); indentG += indentStepG; last = (AsnPort*)LAST_LIST_ELMT (obj->ports); FOR_EACH_LIST_ELMT (ap, obj->ports) { INDENT (f, indentG); PrintValue (f, NULL, t, ap->portValue); if (ap->portType == CONSUMER_PORT) fprintf (f, " [C]"); else if (ap->portType == SUPPLIER_PORT) fprintf (f, " [S]"); if (ap != last) fprintf (f, ",\n"); } fprintf (f, "\n"); indentG -= indentStepG; INDENT (f, indentG); fprintf (f, "}"); } indentG -= indentStepG; bt = bt; head = head; /* AVOIDS warning. */ } /* PrintAsnObjectMacroType */ void PrintAsnPortMacroType PARAMS ((f, head, t, bt, p), FILE *f _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ AsnPortMacroType *p) { TypeOrValue *tOrV; TypeOrValue *last; fprintf (f, "PORT"); indentG += indentStepG; if ((p->abstractOps != NULL) && (!LIST_EMPTY (p->abstractOps))) { fprintf (f,"\n"); INDENT (f, indentG); fprintf (f, "ABSTRACT OPERATIONS\n"); INDENT (f, indentG); fprintf (f, "{\n"); indentG += indentStepG; last = (TypeOrValue*)LAST_LIST_ELMT (p->abstractOps); FOR_EACH_LIST_ELMT (tOrV, p->abstractOps) { INDENT (f, indentG); if (tOrV->choiceId == TYPEORVALUE_TYPE) PrintType (f, head, tOrV->a.type); else PrintValue (f, NULL, t, tOrV->a.value); if (tOrV != last) fprintf (f, ",\n"); } fprintf (f, "\n"); indentG -= indentStepG; INDENT (f, indentG); fprintf (f, "}"); } if ((p->consumerInvokes != NULL) && (!LIST_EMPTY (p->consumerInvokes))) { fprintf (f,"\n"); INDENT (f, indentG); fprintf (f, "CONSUMER INVOKES\n"); INDENT (f, indentG); fprintf (f, "{\n"); indentG += indentStepG; last = (TypeOrValue*)LAST_LIST_ELMT (p->consumerInvokes); FOR_EACH_LIST_ELMT (tOrV, p->consumerInvokes) { INDENT (f, indentG); if (tOrV->choiceId == TYPEORVALUE_TYPE) PrintType (f, head, tOrV->a.type); else PrintValue (f, NULL, t, tOrV->a.value); if (tOrV != last) fprintf (f, ",\n"); } fprintf (f, "\n"); indentG -= indentStepG; INDENT (f, indentG); fprintf (f, "}"); } if ((p->supplierInvokes != NULL) && (!LIST_EMPTY (p->supplierInvokes))) { fprintf (f,"\n"); INDENT (f, indentG); fprintf (f, "SUPPLIER INVOKES\n"); INDENT (f, indentG); fprintf (f, "{\n"); indentG += indentStepG; last = (TypeOrValue*)LAST_LIST_ELMT (p->supplierInvokes); FOR_EACH_LIST_ELMT (tOrV, p->supplierInvokes) { INDENT (f, indentG); if (tOrV->choiceId == TYPEORVALUE_TYPE) PrintType (f, head, tOrV->a.type); else PrintValue (f, NULL, t, tOrV->a.value); if (tOrV != last) fprintf (f, ",\n"); } fprintf (f, "\n"); indentG -= indentStepG; INDENT (f, indentG); fprintf (f, "}"); } indentG -= indentStepG; bt = bt; /* AVOIDS warning. */ } /* PrintAsnPortMacroType */ void PrintAsnAbstractBindMacroType PARAMS ((f, head, t, bt, bind), FILE *f _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ AsnAbstractBindMacroType *bind) { AsnPort *ap; AsnPort *last; if (bt->a.macroType->choiceId == MACROTYPE_ASNABSTRACTBIND) fprintf (f, "ABSTRACT-BIND"); else fprintf (f, "ABSTRACT-UNBIND"); indentG += indentStepG; if ((bind->ports != NULL) && (!LIST_EMPTY (bind->ports))) { fprintf (f,"\n"); INDENT (f, indentG); if (bt->a.macroType->choiceId == MACROTYPE_ASNABSTRACTBIND) fprintf (f, "TO\n"); else fprintf (f, "FROM\n"); INDENT (f, indentG); fprintf (f, "{\n"); indentG += indentStepG; last = (AsnPort*)LAST_LIST_ELMT (bind->ports); FOR_EACH_LIST_ELMT (ap, bind->ports) { INDENT (f, indentG); PrintValue (f, NULL, t, ap->portValue); if (ap->portType == CONSUMER_PORT) fprintf (f, " [C]"); else if (ap->portType == SUPPLIER_PORT) fprintf (f, " [S]"); if (ap != last) fprintf (f, ",\n"); } fprintf (f, "\n"); indentG -= indentStepG; INDENT (f, indentG); fprintf (f, "}"); } if (bind->type != NULL) { fprintf (f,"\n"); INDENT (f, indentG); PrintType (f, head, bind->type); } indentG -= indentStepG; } /* PrintAsnAbstractBindMacroType */ void PrintAfAlgorithmMacroType PARAMS ((f, head, t, bt, alg), FILE *f _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ Type *alg) { indentG += indentStepG; fprintf (f, "ALGORITHM PARAMETER "); PrintType (f, head, alg); indentG -= indentStepG; bt = bt; t = t; /* AVOIDS warning. */ } /* PrintAfAlgorithmMacroType */ void PrintAfEncryptedMacroType PARAMS ((f, head, t, bt, encrypt), FILE *f _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ Type *encrypt) { indentG += indentStepG; fprintf (f, "ENCRYPTED "); PrintType (f, head, encrypt); indentG -= indentStepG; bt = bt; t = t; /* AVOIDS warning. */ } /* PrintAfEncryptedMacroType */ void PrintAfSignedMacroType PARAMS ((f, head, t, bt, sign), FILE *f _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ Type *sign) { indentG += indentStepG; fprintf (f, "SIGNED "); PrintType (f, head, sign); indentG -= indentStepG; bt = bt; t = t; /* AVOIDS warning. */ } /* PrintAfSignedMacroType */ void PrintAfSignatureMacroType PARAMS ((f, head, t, bt, sig), FILE *f _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ Type *sig) { indentG += indentStepG; fprintf (f, "SIGNATURE "); PrintType (f, head, sig); indentG -= indentStepG; bt = bt; t = t; /* AVOIDS warning. */ } /* PrintAfSignatureMacroType */ void PrintAfProtectedMacroType PARAMS ((f, head, t, bt, p), FILE *f _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ Type *p) { indentG += indentStepG; fprintf (f, "PROTECTED "); PrintType (f, head, p); indentG -= indentStepG; bt = bt; t = t; /* AVOIDS warning. */ } /* PrintAfMacroType */ void PrintSnmpObjectTypeMacroType PARAMS ((f, head, t, bt, ot), FILE *f _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt _AND_ SnmpObjectTypeMacroType *ot) { TypeOrValue *tOrV; TypeOrValue *last; fprintf (f, "OBJECT-TYPE\n"); indentG += indentStepG; INDENT (f,indentG); fprintf (f,"SYNTAX "); indentG += indentStepG; PrintType (f, head, ot->syntax); indentG -= indentStepG; fprintf (f,"\n"); INDENT (f,indentG); fprintf (f,"ACCESS "); switch (ot->access) { case SNMP_READ_ONLY: fprintf (f,"read-only"); break; case SNMP_READ_WRITE: fprintf (f,"read-write"); break; case SNMP_WRITE_ONLY: fprintf (f,"write-only"); break; case SNMP_NOT_ACCESSIBLE: fprintf (f,"not-accessible"); break; default: fprintf (f," < ?? unknown access type ?? >"); } fprintf (f,"\n"); INDENT (f, indentG); fprintf (f,"STATUS "); switch (ot->status) { case SNMP_MANDATORY: fprintf (f,"mandatory"); break; case SNMP_OPTIONAL: fprintf (f,"optional"); break; case SNMP_OBSOLETE: fprintf (f,"obsolete"); break; case SNMP_DEPRECATED: fprintf (f,"deprecated"); break; default: fprintf (f," < ?? unknown status type ?? >"); } if (ot->description != NULL) { fprintf (f,"\n"); INDENT (f, indentG); fprintf (f,"DESCRIPTION\n"); indentG += indentStepG; INDENT (f, indentG); PrintValue (f, NULL, t, ot->description); indentG -= indentStepG; } if (ot->reference != NULL) { fprintf (f,"\n"); INDENT (f, indentG); fprintf (f,"REFERENCE\n"); indentG += indentStepG; INDENT (f, indentG); PrintValue (f, NULL, t, ot->reference); indentG -= indentStepG; } if (ot->index != NULL) { fprintf (f,"\n"); INDENT (f, indentG); fprintf (f,"INDEX\n"); indentG += indentStepG; INDENT (f, indentG); last = (TypeOrValue*)LAST_LIST_ELMT (ot->index); FOR_EACH_LIST_ELMT (tOrV, ot->index) { INDENT (f, indentG); if (tOrV->choiceId == TYPEORVALUE_TYPE) PrintType (f, head, tOrV->a.type); else PrintValue (f, NULL, t, tOrV->a.value); if (tOrV != last) fprintf (f, ",\n"); } indentG -= indentStepG; } if (ot->defVal != NULL) { fprintf (f,"\n"); INDENT (f, indentG); fprintf (f,"DEFVAL\n"); indentG += indentStepG; INDENT (f, indentG); PrintValue (f, NULL, t, ot->defVal); indentG -= indentStepG; } fprintf (f,"\n"); indentG -= indentStepG; bt = bt; /* AVOIDS warning. */ } /* PrintSnmpObjectTypeMacroType */ /* * @MACRO@ add new macro print routines above this point */ void PrintMacroDef PARAMS ((f, head), FILE *f _AND_ TypeDef *head) { char *s; fprintf (f,"\n-- Note: snacc does not use macro defs to extend the compiler."); fprintf (f,"\n-- All macros that are understood have been hand coded."); fprintf (f,"\n-- The macro def body is kept as a string only.\n\n"); s = head->type->basicType->a.macroDef; fprintf (f, "%s MACRO ::=\n", head->definedName); fprintf (f, "%s", s); } /* PrintMacroDef */ void PrintEncodedOid PARAMS ((f, eoid), FILE *f _AND_ AsnOid *eoid) { int i; int arcNum; int firstArcNum; int secondArcNum; if (eoid == NULL) return; fprintf (f, "{ "); for (arcNum = 0, i=0; (i < (int)(eoid->octetLen)) && (eoid->octs[i] & 0x80);i++) arcNum = (arcNum << 7) + (eoid->octs[i] & 0x7f); arcNum = (arcNum << 7) + (eoid->octs[i] & 0x7f); i++; firstArcNum = arcNum / 40; if (firstArcNum > 2) firstArcNum = 2; secondArcNum = arcNum - (firstArcNum * 40); fprintf (f, "%d ", firstArcNum); fprintf (f, "%d ", secondArcNum); for (; i < (int)(eoid->octetLen); ) { for (arcNum = 0; (i < (int)(eoid->octetLen)) && (eoid->octs[i] & 0x80);i++) arcNum = (arcNum << 7) + (eoid->octs[i] & 0x7f); arcNum = (arcNum << 7) + (eoid->octs[i] & 0x7f); i++; fprintf (f, "%d ", arcNum); } fprintf (f, "}"); } /* PrintEncodedOid */ /* * this just prints a short form of the given type. It * does not print the components of a constructed type * such as a SEQUENCE * This is used by the header file generators to annotate * the C/C++ types */ void SpecialPrintBasicType PARAMS ((f, head, t, bt), FILE *f _AND_ TypeDef *head _AND_ Type *t _AND_ BasicType *bt) { switch (bt->choiceId) { case BASICTYPE_OBJECTCLASSFIELDTYPE: fprintf (f, "ObjectClassFieldType: TypeField"); break; case BASICTYPE_SEQUENCE: fprintf (f, "SEQUENCE"); break; case BASICTYPE_SEQUENCET: // Deepak: 30/Nov/2002 fprintf (f, "SEQUENCET"); break; case BASICTYPE_SET: fprintf (f, "SET"); break; case BASICTYPE_CHOICE: fprintf (f, "CHOICE"); break; case BASICTYPE_OBJECTCLASS: // Deepak: 11/Mar/2003 fprintf (f, "CLASS"); break; case BASICTYPE_SEQUENCEOF: fprintf (f, "SEQUENCE "); if (t->subtypes != NULL) { PrintSubtype (f, head, t, t->subtypes); fprintf (f," "); } fprintf (f, "OF "); SpecialPrintType (f, head, t->basicType->a.sequenceOf); break; case BASICTYPE_SETOF: fprintf (f, "SET "); if (t->subtypes != NULL) { PrintSubtype (f, head, t, t->subtypes); fprintf (f," "); } fprintf (f, "OF "); SpecialPrintType (f, head, t->basicType->a.sequenceOf); break; case BASICTYPE_SELECTION: fprintf (f, "%s < ", bt->a.selection->fieldName); PrintType (f, head, bt->a.selection->typeRef); break; case BASICTYPE_COMPONENTSOF: fprintf (f, "COMPONENTS OF "); PrintType (f, NULL, bt->a.componentsOf); break; case BASICTYPE_ANYDEFINEDBY: fprintf (f, "ANY DEFINED BY %s", bt->a.anyDefinedBy->fieldName); break; case BASICTYPE_LOCALTYPEREF: fprintf (f, "%s", bt->a.localTypeRef->typeName); break; case BASICTYPE_IMPORTTYPEREF: fprintf (f, "%s", bt->a.importTypeRef->typeName); break; case BASICTYPE_UNKNOWN: fprintf (f, "unknown type !?!"); break; case BASICTYPE_BOOLEAN: fprintf (f, "BOOLEAN"); break; case BASICTYPE_INTEGER: fprintf (f, "INTEGER"); if ((bt->a.integer != NULL) && !LIST_EMPTY (bt->a.integer)) SpecialPrintNamedElmts (f, head, t); break; /* case BASICTYPE_BIGINT: fprintf (f, "INTEGER (isBigInt:TRUE)"); if ((bt->a.integer != NULL) && !LIST_EMPTY (bt->a.integer)) SpecialPrintNamedElmts (f, head, t); break; */ case BASICTYPE_BITSTRING: fprintf (f, "BIT STRING"); if ((bt->a.bitString != NULL) && !LIST_EMPTY (bt->a.bitString)) SpecialPrintNamedElmts (f, head, t); break; case BASICTYPE_OCTETSTRING: fprintf (f, "OCTET STRING"); break; case BASICTYPE_NULL: fprintf (f, "NULL"); break; case BASICTYPE_OID: fprintf (f, "OBJECT IDENTIFIER"); break; case BASICTYPE_RELATIVE_OID: fprintf (f, "RELATIVE-OID"); break; case BASICTYPE_REAL: fprintf (f, "REAL"); break; case BASICTYPE_ENUMERATED: fprintf (f, "ENUMERATED"); if ((bt->a.enumerated != NULL) && !LIST_EMPTY (bt->a.enumerated)) SpecialPrintNamedElmts (f, head, t); break; case BASICTYPE_NUMERIC_STR: fprintf(f, "NumericString"); break; case BASICTYPE_PRINTABLE_STR: fprintf(f, "PrintableString"); break; case BASICTYPE_IA5_STR: fprintf(f, "IA5String"); break; case BASICTYPE_BMP_STR: fprintf(f, "BMPString"); break; case BASICTYPE_UNIVERSAL_STR: fprintf(f, "UniversalString"); break; case BASICTYPE_UTF8_STR: fprintf(f, "UTF8String"); break; case BASICTYPE_T61_STR: fprintf(f, "TeletexString"); break; case BASICTYPE_ANY: fprintf (f, "ANY"); break; case BASICTYPE_MACROTYPE: switch (bt->a.macroType->choiceId) { case MACROTYPE_ROSOPERATION: case MACROTYPE_ASNABSTRACTOPERATION: PrintRosOperationMacroType (f, head, t, bt, bt->a.macroType->a.rosOperation); break; case MACROTYPE_ROSERROR: case MACROTYPE_ASNABSTRACTERROR: PrintRosErrorMacroType (f, head, t, bt, bt->a.macroType->a.rosError); break; case MACROTYPE_ROSBIND: case MACROTYPE_ROSUNBIND: PrintRosBindMacroType (f, head, t, bt, bt->a.macroType->a.rosBind); break; case MACROTYPE_ROSASE: PrintRosAseMacroType (f, head, t, bt, bt->a.macroType->a.rosAse); break; case MACROTYPE_MTSASEXTENSIONS: PrintMtsasExtensionsMacroType (f, head, t, bt, bt->a.macroType->a.mtsasExtensions); break; case MACROTYPE_MTSASEXTENSION: PrintMtsasExtensionMacroType (f, head, t, bt, bt->a.macroType->a.mtsasExtension); break; case MACROTYPE_MTSASEXTENSIONATTRIBUTE: PrintMtsasExtensionAttributeMacroType (f, head, t, bt, bt->a.macroType->a.mtsasExtensionAttribute); break; case MACROTYPE_MTSASTOKEN: PrintMtsasTokenMacroType (f, head, t, bt, bt->a.macroType->a.mtsasToken); break; case MACROTYPE_MTSASTOKENDATA: PrintMtsasTokenDataMacroType (f, head, t, bt, bt->a.macroType->a.mtsasTokenData); break; case MACROTYPE_MTSASSECURITYCATEGORY: PrintMtsasSecurityCategoryMacroType (f, head, t, bt, bt->a.macroType->a.mtsasSecurityCategory); break; case MACROTYPE_ASNOBJECT: PrintAsnObjectMacroType (f, head, t, bt, bt->a.macroType->a.asnObject); break; case MACROTYPE_ASNPORT: PrintAsnPortMacroType (f, head, t, bt, bt->a.macroType->a.asnPort); break; case MACROTYPE_ASNABSTRACTBIND: case MACROTYPE_ASNABSTRACTUNBIND: PrintAsnAbstractBindMacroType (f, head, t, bt, bt->a.macroType->a.asnAbstractBind); break; case MACROTYPE_AFALGORITHM: PrintAfAlgorithmMacroType (f, head, t, bt, bt->a.macroType->a.afAlgorithm); break; case MACROTYPE_AFENCRYPTED: PrintAfEncryptedMacroType (f, head, t, bt, bt->a.macroType->a.afEncrypted); break; case MACROTYPE_AFSIGNED: PrintAfSignedMacroType (f, head, t, bt, bt->a.macroType->a.afSigned); break; case MACROTYPE_AFSIGNATURE: PrintAfSignatureMacroType (f, head, t, bt, bt->a.macroType->a.afSignature); break; case MACROTYPE_AFPROTECTED: PrintAfProtectedMacroType (f, head, t, bt, bt->a.macroType->a.afProtected); break; case MACROTYPE_SNMPOBJECTTYPE: PrintSnmpObjectTypeMacroType (f, head, t, bt, bt->a.macroType->a.snmpObjectType); break; default: fprintf (f, "< unknown macro type id ?! >"); } /* end macro type switch */ break; /* * @MACRO@ add new macro printers above this point */ case BASICTYPE_MACRODEF: /* * printing this should be handled in PrintTypeDefs */ break; default: fprintf (f, "< unknown type id ?! >"); } } /* SpecialPrintBasicType */ /* * this just prints a short form of the given type. It * does not print the components of a constructed type * such as a SEQUENCE * This is used by the header file generators to annotate * the C types */ void SpecialPrintType PARAMS ((f, head, t), FILE *f _AND_ TypeDef *head _AND_ Type *t) { Tag *tag; if (t == NULL) return; FOR_EACH_LIST_ELMT (tag, t->tags) { if (!(tag->tclass == UNIV && tag->code == LIBTYPE_GET_UNIV_TAG_CODE (t->basicType->choiceId))) { PrintTag (f, tag); fprintf (f, " "); } } /* * check type has been implicitly tagged */ if (t->implicit) fprintf (f, "IMPLICIT "); SpecialPrintBasicType (f, head, t, t->basicType); /* * sequences of and set of print subtypes a special way * so ignore them here */ if ((t->subtypes != NULL) && (t->basicType->choiceId != BASICTYPE_SETOF) && (t->basicType->choiceId != BASICTYPE_SEQUENCEOF)) { fprintf (f," "); PrintSubtype (f, head, t, t->subtypes); } if (t->defaultVal != NULL) { fprintf (f, " DEFAULT "); if (t->defaultVal->fieldName != NULL) fprintf (f, "%s ", t->defaultVal->fieldName); PrintValue (f, NULL, t, t->defaultVal->value); } else if (t->optional) fprintf (f, " OPTIONAL"); #ifdef DEBUG fprintf (f, " -- lineNo = %d", t->lineNo); fprintf (f, " --"); #endif } /* SpecialPrintType */ /* * This is used by the header file generators to annotate * the C/C++ types. This version prints the C version of the * enum/bits elmt names to make sure the programmer can use * the correct defines/enum constants. * NOTE: this can only be called after the CTRI infor is filled in * so the C/C++ names can be accessed */ void SpecialPrintNamedElmts PARAMS ((f, head, t), FILE *f _AND_ TypeDef *head _AND_ Type *t) { CNamedElmt *last; CNamedElmt *cne; CNamedElmts *n = NULL; if (t->cTypeRefInfo != NULL) n = t->cTypeRefInfo->cNamedElmts; if ((n == NULL) && (t->cxxTypeRefInfo != NULL)) n = t->cxxTypeRefInfo->namedElmts; if ((n == NULL) || LIST_EMPTY (n)) return; fprintf (f," { "); last = (CNamedElmt*)LAST_LIST_ELMT (n); FOR_EACH_LIST_ELMT (cne, n) { fprintf (f, "%s (%d)", cne->name, cne->value); if (cne != last) fprintf (f,", "); } fprintf (f," } "); head = head; /* AVOIDS warning. */ } /* SpecialPrintNamedElmts */ #ifndef WIN32 static int _vscprintf (const char * format, va_list pargs) { int retval; va_list argcopy; va_copy(argcopy, pargs); retval = vsnprintf(NULL, 0, format, pargs); va_end(argcopy); return retval; } #endif #ifdef WIN32 static int snacc_vsnprintf(char *dest, size_t destsz, const char *format, va_list args) { int needed = _vscprintf(format, args); if (dest && destsz) { vsnprintf(dest, destsz, format, args); dest[destsz-1] = '\0'; } return needed; } int snacc_snprintf(char *dst, size_t destsz, const char *format, ...) { int len; va_list args; va_start(args, format); len = snacc_vsnprintf(dst, destsz, format, args); va_end(args); return len; } #endif esnacc-ng-1.8.1/compiler/core/print.h000066400000000000000000000132031302010526100174130ustar00rootroot00000000000000/* * compiler/core/print.h * * These are the prototypes for the typetree printing * routines. Attempts to convert a typetree back into its original * ASN.1 def. * * Mike Sample * Mar 3/91 * * Rewritten 91/09/05 * * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/core/print.h,v 1.2 2001/07/12 19:34:33 leonberp Exp $ * $Log: print.h,v $ * Revision 1.2 2001/07/12 19:34:33 leonberp * Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. * * Revision 1.1.1.1 2000/08/21 20:36:01 leonberp * First CVS Version of SNACC. * * Revision 1.2 1994/10/08 03:48:56 rj * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long. * * Revision 1.1 1994/08/28 09:49:33 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ void PrintModule PROTO ((FILE *f, Module *mod)); void PrintExports PROTO ((FILE *f, Module *m)); void PrintOid PROTO ((FILE *f, OID *oid)); void PrintImportElmt PROTO ((FILE *f, ImportElmt *impElmt)); void PrintImportLists PROTO ((FILE *f, ImportModuleList *impLists)); void PrintTypeDefs PROTO ((FILE *f, TypeDefList *typeDefs)); void PrintType PROTO ((FILE *f, TypeDef *head, Type *t)); void PrintBasicType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt)); void PrintElmtType PROTO ((FILE *f, TypeDef *head, Type *t, NamedType *nt)); void PrintElmtTypes PROTO ((FILE *f, TypeDef *head, Type *t, NamedTypeList *e)); void PrintValueDefs PROTO ((FILE *f, ValueDefList *v)); void PrintValueDef PROTO ((FILE *f, ValueDef *v)); void PrintValue PROTO ((FILE *f, ValueDef *head, Type *valuesType, Value *v)); void PrintBasicValue PROTO ((FILE *f, ValueDef *head, Type *valuesType, Value *v, BasicValue *bv)); void PrintElmtValue PROTO ((FILE *f, ValueDef *head, Value *v, NamedValue *nv)); void PrintElmtValues PROTO ((FILE *f, ValueDef *head, Value *v, NamedValueList *e)); void PrintTag PROTO ((FILE *f, Tag *tag)); void PrintSubtype PROTO ((FILE *f, TypeDef *head, Type *t, Subtype *s)); void PrintSubtypeValue PROTO ((FILE *f, TypeDef *head, Type *t, SubtypeValue *s)); void PrintNamedElmts PROTO ((FILE *f, TypeDef *head, Type *t, ValueDefList *n)); void PrintInnerSubtype PROTO ((FILE *f, TypeDef *head, Type *t, InnerSubtype *i)); void PrintMultipleTypeConstraints PROTO ((FILE *f, TypeDef *head, Type *t, ConstraintList *c)); void PrintTypeById PROTO ((FILE *f, int typeId)); void PrintRosOperationMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, RosOperationMacroType *op)); void PrintRosErrorMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, RosErrorMacroType *err)); void PrintRosBindMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, RosBindMacroType *bind)); void PrintRosAseMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, RosAseMacroType *ase)); void PrintRosAcMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, RosAcMacroType *ac)); void PrintMtsasExtensionsMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, MtsasExtensionsMacroType *exts)); void PrintMtsasExtensionMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, MtsasExtensionMacroType *ext)); void PrintMtsasExtensionAttributeMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, MtsasExtensionAttributeMacroType *ext)); void PrintMtsasTokenMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, MtsasTokenMacroType *tok)); void PrintMtsasTokenDataMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, MtsasTokenDataMacroType *tok)); void PrintMtsasSecurityCategoryMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, MtsasSecurityCategoryMacroType *sec)); void PrintAsnObjectMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, AsnObjectMacroType *obj)); void PrintAsnPortMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, AsnPortMacroType *p)); void PrintAsnAbstractBindMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, AsnAbstractBindMacroType *bind)); void PrintAfAlgorithmMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, Type *alg)); void PrintAfEncryptedMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, Type *encrypt)); void PrintAfSignedMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, Type *sign)); void PrintAfSignatureMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, Type *sig)); void PrintAfProtectedMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, Type *p)); void PrintSnmpObjectTypeMacroType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt, SnmpObjectTypeMacroType *ot)); void PrintMacroDef PROTO ((FILE *f, TypeDef *head)); void PrintEncodedOid PROTO ((FILE *f, AsnOid *eoid)); void SpecialPrintType PROTO ((FILE *f, TypeDef *head, Type *t)); void SpecialPrintBasicType PROTO ((FILE *f, TypeDef *head, Type *t, BasicType *bt)); void SpecialPrintNamedElmts PROTO ((FILE *f, TypeDef *head, Type *t)); #ifdef WIN32 int snacc_snprintf(char *dst, size_t destsz, const char *format, ...); #else #define snacc_snprintf snprintf #endif esnacc-ng-1.8.1/compiler/core/recursive.c000066400000000000000000000152571302010526100202740ustar00rootroot00000000000000/* * compiler/core/recursive.c - finds and marks the recursive types in a module. * * ALSO: * prints msgs for infinitely recursive types (ie recursive component * is not OPTIONAL, nor a CHOICE elmt, nor a SET OF nor a SEQ OF elmt. * (OPTIONALs can be left out, CHOICE elements have alternatives (hopefully), * and SET OF and SEQUENCE OF values can have zero elements) * * prints msg for recursive types that hold no real information * Foo ::= SET OF Foo (sets of sets of .... of empty sets) * * finds bogus recursive types (hold no info) (same as above) * A ::= B * B ::= C * D ::= A * * MS 92 * * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/core/recursive.c,v 1.7 2004/04/06 15:13:41 gronej Exp $ * $Log: recursive.c,v $ * Revision 1.7 2004/04/06 15:13:41 gronej * *** empty log message *** * * Revision 1.6 2004/03/25 19:20:17 gronej * fixed some linux warnings * * Revision 1.5 2003/07/07 14:50:14 nicholar * Eliminated headers and cleaned up include references * * Revision 1.4 2002/09/16 16:50:23 mcphersc * Fixed warnings * * Revision 1.3 2002/09/04 18:31:39 vracarl * got rid of c++ comments * * Revision 1.2 2000/10/24 14:54:55 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:36:01 leonberp * First CVS Version of SNACC. * * Revision 1.3 1995/07/25 19:41:43 rj * changed `_' to `-' in file names. * * Revision 1.2 1994/09/01 00:43:10 rj * snacc_config.h removed; recursive.h includet. * * Revision 1.1 1994/08/28 09:49:35 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include "asn-incl.h" #include "asn1module.h" #include "snacc-util.h" void MkRecTypeDef PROTO ((Module *m, TypeDef *td)); void MkRecType PROTO ((Module *m, TypeDef *td,Type *t, int optional, int empty)); extern FILE* errFileG; // Defined in snacc.c void MarkRecursiveTypes PARAMS ((m), Module *m) { TypeDef *td; /* first set all typedef as un-visited */ FOR_EACH_LIST_ELMT (td, m->typeDefs) { td->visited = FALSE; td->tmpRefCount = 0; } FOR_EACH_LIST_ELMT (td, m->typeDefs) { MkRecTypeDef (m, td); } } /* MarkRecursiveTypes */ void MkRecTypeDef PARAMS ((m, td), Module *m _AND_ TypeDef *td) { MkRecType (m, td, td->type, 0, 1); } /* MkRecTypeDef */ /* * cruise through aggregate types and type refs looking for * a type ref to the original type def, td. If is a ref to * the td, then mark the td as recusive. * * the optional flag is set if the current type branch is * optional via an OPTIONAL SET/SEQ elmt, CHOICE elmt, SET OF elmt * or SEQ OF elmt. * * the empty flag is initially TRUE and remains true until a * non-type reference type is encountered */ void MkRecType PARAMS ((m, td, t, optional, empty), Module *m _AND_ TypeDef *td _AND_ Type *t _AND_ int optional _AND_ int empty) { int newOptional; NamedType *e; switch (t->basicType->choiceId) { case BASICTYPE_CHOICE: if (AsnListCount (t->basicType->a.choice) > 1) { empty = 0; optional = 1; } FOR_EACH_LIST_ELMT (e, t->basicType->a.choice) { MkRecType (m, td, e->type, optional, empty); } break; case BASICTYPE_SET: case BASICTYPE_SEQUENCE: empty = 0; FOR_EACH_LIST_ELMT (e, t->basicType->a.set) { newOptional = optional || (e->type->optional) || (e->type->defaultVal != NULL); MkRecType (m, td, e->type, newOptional, empty); } break; case BASICTYPE_SETOF: case BASICTYPE_SEQUENCEOF: empty = 0; /* since an empty set is actual data */ optional = 1; /* since SET OF and SEQ OF's can be empty */ MkRecType (m, td, t->basicType->a.setOf, optional, empty); break; case BASICTYPE_LOCALTYPEREF: case BASICTYPE_IMPORTTYPEREF: /* * check if ref to original type def & mark recursive if so. */ /* if ((strcmp (t->basicType->a.localTypeRef->typeName, td->definedName) == 0) && (t->basicType->a.localTypeRef->module == m)) easier to just check ptrs! */ if (t->basicType->a.localTypeRef->link == td) { td->recursive = 1; if (empty) { PrintErrLoc (m->asn1SrcFileName, (long)td->type->lineNo); fprintf (errFileG, "WARNING: Type \"%s\" appears to be infinitely recursive and can hold no values! (circular type references)\n", td->definedName); } else if (!optional) { PrintErrLoc (m->asn1SrcFileName, (long)t->lineNo); fprintf (errFileG, "WARNING: Type \"%s\" appears to be infinitely recursive! (infinitely sized values)\n", td->definedName); } } /* * else follow this type reference if we aren't in it already * (ie another recursive type in td) */ else if (t->basicType->a.localTypeRef->link->tmpRefCount == 0) { /* * mark this typedef as 'entered' to * detect when looping in a recusive type that is contained * in the original td (use tmpRefCount) */ t->basicType->a.localTypeRef->link->tmpRefCount = 1; newOptional = optional || (t->optional) || (t->defaultVal != NULL); MkRecType (m, td, t->basicType->a.localTypeRef->link->type, newOptional, empty); /* * un-mark this type since finished with it * for recursive ref's to td */ t->basicType->a.localTypeRef->link->tmpRefCount = 0; } break; default: break; /* * default: other types are not aggregate and * do not make recursive refs - they can be ignored */ } } /* MkRecType */ esnacc-ng-1.8.1/compiler/core/snacc-util.c000066400000000000000000001243701302010526100203240ustar00rootroot00000000000000/* * compiler/core/snacc_util.c * * utilities for dealing with the Module data structure * * AUTHOR: Mike Sample * DATE: 91/09/02 * * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/core/snacc-util.c,v 1.15 2004/04/06 15:13:41 gronej Exp $ * $Log: snacc-util.c,v $ * Revision 1.15 2004/04/06 15:13:41 gronej * *** empty log message *** * * Revision 1.14 2004/03/25 19:20:17 gronej * fixed some linux warnings * * Revision 1.13 2004/01/14 19:07:53 gronej * Updated Compiler to accept and process relative-oid's * * Revision 1.12 2003/07/28 11:11:24 colestor * Changes to complete handing of the "--snacc namespace" compiler directive. * Also, updates to handle ASN.1 constant integer tag designations for C++/C. * * Revision 1.11 2003/07/07 14:50:14 nicholar * Eliminated headers and cleaned up include references * * Revision 1.10 2003/04/29 21:07:14 leonberp * integerated Deepak's changes for IOB support * * Revision 1.9 2003/01/27 16:50:45 leonberp * added GetLastNamedNumberValue() * * Revision 1.8 2002/10/28 20:50:58 leonberp * Ok.. I think this is the final fix for OCTET/BIT STRING CONTAINING * * Revision 1.7 2002/10/24 21:07:22 leonberp * latest fixing for OCTET CONTAINING * * Revision 1.6 2002/10/21 17:15:19 mcphersc * fixed long int * * Revision 1.5 2002/09/16 16:50:27 mcphersc * Fixed warnings * * Revision 1.4 2002/09/04 18:31:39 vracarl * got rid of c++ comments * * Revision 1.3 2002/05/15 17:01:01 leonberp * added support for new basicTypes to compiler * * Revision 1.2 2000/10/24 14:54:55 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:36:01 leonberp * First CVS Version of SNACC. * * Revision 1.3 1995/07/25 19:41:44 rj * changed `_' to `-' in file names. * * Revision 1.2 1994/09/01 00:45:09 rj * snacc_config.h removed. * * Revision 1.1 1994/08/28 09:49:39 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include #include "asn-incl.h" #include "asn1module.h" #include "lib-types.h" #include "define.h" #include "snacc-util.h" extern FILE* errFileG; // Defined in snacc.c /* * Allocates and initializes a type and it's basicType info * used extensively by asn1.yacc * (was a macro) */ void SetupType PARAMS ((t, typeId, lineNum), Type **t _AND_ enum BasicTypeChoiceId typeId _AND_ unsigned long lineNum) { Tag **tmpPtr; (*t) = (Type*)Malloc (sizeof (Type)); (*t)->lineNo = lineNum; (*t)->basicType = (BasicType*)Malloc (sizeof (BasicType)); (*t)->basicType->choiceId = typeId; (*t)->tags = (TagList*)AsnListNew (sizeof (void*)); if (LIBTYPE_GET_UNIV_TAG_CODE ((typeId)) != NO_TAG_CODE) { tmpPtr = (Tag**)AsnListAppend ((AsnList*)(*t)->tags); *tmpPtr = (Tag*)Malloc (sizeof (Tag)); (*tmpPtr)->tclass = UNIV; (*tmpPtr)->code = LIBTYPE_GET_UNIV_TAG_CODE ((typeId)); } } /* SetupType */ /* * Allocates and initializes a type and it's basicType to MACROTYPE * and sets the MACROTYPE type to the given macrotype */ void SetupMacroType PARAMS ((t, macroTypeId, lineNum), Type **t _AND_ enum MacroTypeChoiceId macroTypeId _AND_ unsigned long lineNum) { (*t) = MT (Type); (*t)->lineNo = lineNum; (*t)->basicType = MT (BasicType); (*t)->basicType->choiceId = BASICTYPE_MACROTYPE; (*t)->tags = (TagList*)AsnListNew (sizeof (void*)); (*t)->basicType->a.macroType = MT (MacroType); (*t)->basicType->a.macroType->choiceId = macroTypeId; } /* SetupMacroType */ /* * similar to SetupType but for values instead */ void SetupValue PARAMS ((v, valId, lineNum), Value **v _AND_ enum BasicValueChoiceId valId _AND_ unsigned long lineNum) { *v = (Value*)Malloc (sizeof (Value)); (*v)->basicValue = (BasicValue*)Malloc (sizeof (BasicValue)); (*v)->basicValue->choiceId = valId; (*v)->lineNo = lineNum; } /* SetupValue */ /* * adds elmt with given name to module m's import list from * the module with name refdModuleName. If module m does not * have an import list from that module one is created. * The import element is given the private scope implied * by the ASN.1 modname.typ-or-val-name reference format * The passed in strings (name, refdModuleName) are copied. */ void AddPrivateImportElmt PARAMS ((m, name, refdModuleName, lineNo), Module *m _AND_ char *name _AND_ char *refdModuleName _AND_ long lineNo) { ImportElmt *newElmt; ImportElmt *ie; ImportModule *impMod; /* see if module m already imports something from "refdModule" */ if ((impMod = LookupImportModule (m, refdModuleName)) == NULL) { impMod = MT (ImportModule); impMod->modId = MT (ModuleId); impMod->modId->name = Malloc (strlen (refdModuleName)+1); strcpy (impMod->modId->name, refdModuleName); newElmt = MT (ImportElmt); newElmt->name = Malloc (strlen (name)+1); strcpy (newElmt->name, name); newElmt->privateScope = TRUE; APPEND (newElmt, impMod->importElmts); APPEND (impMod, m->imports); } else /* module "refdModule is already imported from */ { ie = LookupImportElmtInImportElmtList (impMod->importElmts, name); if (ie == NULL) { newElmt = MT (ImportElmt); newElmt->name = Malloc (strlen (name)+1); strcpy (newElmt->name, name); APPEND (newElmt, impMod->importElmts); } else if (!ie->privateScope) { PrintErrLoc (m->asn1SrcFileName, (long)lineNo); fprintf (errFileG, "WARNING - \"%s.%s\" type/value reference refers to a type/value already in the import list that does not have private scope.\n", refdModuleName, name); } } } /* AddPrivateImportElmt */ /* * looks for the named import type/value in all of the IMPORT lists of the * given module. * RETURNS a ptr to the import elmt if found, NULL if it was not found. * If the item was found (ptr returned) the foundImportModule addr * parameter will be set to the module's importModule that holds * the found elmt. * * returns NULL if the named import name was not found * */ ImportElmt* LookupImportElmtInModule PARAMS ((m, name, foundImportModule), Module *m _AND_ char *name _AND_ ImportModule **foundImportModule) { ImportModule *importMod; ImportElmt *importElmt; ImportElmt *retVal; void *tmp; if (m->imports == NULL) return NULL; tmp = (void*)CURR_LIST_NODE (m->imports); retVal = NULL; FOR_EACH_LIST_ELMT (importMod, m->imports) { importElmt = LookupImportElmtInImportElmtList (importMod->importElmts, name); if (importElmt != NULL) { *foundImportModule = importMod; retVal = importElmt; break; } } SET_CURR_LIST_NODE (m->imports, tmp); /* restore orig loc */ return retVal; } /* LookupImportElmtInModule */ /* * given a list of import elmts, returns ptr to the elmt with * the matching name. NULL if not found */ ImportElmt* LookupImportElmtInImportElmtList PARAMS ((impElmtList, name), ImportElmtList *impElmtList _AND_ char *name) { ImportElmt *impElmt; ImportElmt *retVal; void *tmp; if (impElmtList == NULL) return NULL; tmp = (void*) CURR_LIST_NODE (impElmtList); retVal = NULL; FOR_EACH_LIST_ELMT (impElmt, impElmtList) { if (strcmp (impElmt->name, name) == 0) { retVal = impElmt; break; } } SET_CURR_LIST_NODE (impElmtList, tmp); return retVal; } /* LookupImportElmtInImportElmtList */ /* * looks for an import list that imports from "importModuleName" * module in the given module. * * returns a ptr to the ImportList if found * returns NULL if not found */ ImportModule* LookupImportModule PARAMS ((m, importModuleName), Module *m _AND_ char *importModuleName) { ImportModule *importModule; ImportModule *retVal; void *tmp; if (m->imports == NULL) return NULL; tmp = (void*)CURR_LIST_NODE (m->imports); retVal = NULL; FOR_EACH_LIST_ELMT (importModule, m->imports) { if (strcmp (importModule->modId->name, importModuleName) == 0) { retVal= importModule; break; } } SET_CURR_LIST_NODE (m->imports, tmp); return retVal; } /* LookupImportModule */ /* * Looks for the type with name matching typeName (null terminated char*) * in the given the TypeDef list * * RETURNS: ptr to the TypeDef with the matching typeName (if any) * NULL if no match was made */ TypeDef* LookupType PARAMS ((typeDefList, typeName), TypeDefList *typeDefList _AND_ char *typeName) { TypeDef *td; TypeDef *retVal; void *tmp; if (typeDefList == NULL) return NULL; if (typeName == NULL) { #ifdef DEBUG fprintf (errFileG, "LookupType: warning - failure due to NULL key\n"); #endif return NULL; } tmp = (void*)CURR_LIST_NODE (typeDefList); /* remember curr list spot */ retVal = NULL; FOR_EACH_LIST_ELMT (td, typeDefList) { if (strcmp (typeName, td->definedName) == 0) { retVal = td; break; } } SET_CURR_LIST_NODE (typeDefList,tmp); /* restore curr location */ return retVal; } /* LookupType */ /* Deepak: 04/Feb/2003 * Looks for the type with name matching typeName (null terminated char*) * in the given NamedTypeList * * RETURNS: ptr to the NamedType with the matching typeName (if any) * NULL if no match was made */ NamedType* LookupObjectClassFieldType PARAMS ((namedTypeList, typeName), NamedTypeList *namedTypeList _AND_ char *typeName) { NamedType *nt; NamedType *retVal; void *tmp; if (namedTypeList == NULL) return NULL; if (typeName == NULL) { #ifdef DEBUG fprintf (errFileG, "LookupObjectClassFieldType: warning - failure due to NULL key\n"); #endif return NULL; } tmp = (void*)CURR_LIST_NODE (namedTypeList); /* remember curr list spot */ retVal = NULL; FOR_EACH_LIST_ELMT (nt, namedTypeList) { if (strcmp (typeName, nt->fieldName) == 0) { retVal = nt; break; } } SET_CURR_LIST_NODE (namedTypeList,tmp); /* restore curr location */ return retVal; } /* LookupObjectClassFieldType */ /* Deepak: 05/Mar/2003 * Looks for the type with name matching typeName according to With Syntax (null terminated char*) * in the given NamedTypeList * * RETURNS: ptr to the WithSyntax with the matching typeName (if any) * NULL if no match was made */ WithSyntax* LookupObjectClassFieldTypeWithSyntax PARAMS ((withSyntaxList, typeName, bError), WithSyntaxList *withSyntaxList _AND_ char *typeName _AND_ char* bError) { WithSyntax *ws; WithSyntax *retVal; void *tmp; if (withSyntaxList == NULL) return NULL; if (typeName == NULL) { #ifdef DEBUG fprintf (errFileG, "LookupObjectClassFieldType: warning - failure due to NULL key\n"); #endif return NULL; } tmp = (void*)CURR_LIST_NODE (withSyntaxList); /* remember curr list spot */ retVal = NULL; FOR_EACH_LIST_ELMT (ws, withSyntaxList) { if (strcmp (typeName, ws->definedName) == 0) { retVal = ws; *bError = FALSE; break; } else if (strcmp (typeName, ws->typeName) == 0) { retVal = ws; *bError = TRUE; break; } } SET_CURR_LIST_NODE (withSyntaxList,tmp); /* restore curr location */ return retVal; } /* LookupObjectClassFieldTypeWithSyntax */ /* Deepak: 05/Mar/2003 * Looks for the object with name matching objectName (null terminated char*) * in the given objAssignmentList * * RETURNS: ptr to the ObjectAssignment with the matching objectName (if any) * NULL if no match was made */ ObjectAssignment* LookupObjectClassObjectAssignment PARAMS ((objAssignmentList, objName), ObjectAssignmentList *objAssignmentList _AND_ char *objName) { ObjectAssignment *oa; ObjectAssignment *retVal; void *tmp; if (objAssignmentList == NULL) return NULL; if (objName == NULL) { #ifdef DEBUG fprintf (errFileG, "LookupObjectClassFieldType: warning - failure due to NULL key\n"); #endif return NULL; } tmp = (void*)CURR_LIST_NODE (objAssignmentList); /* remember curr list spot */ retVal = NULL; FOR_EACH_LIST_ELMT (oa, objAssignmentList) { if (strcmp (objName, oa->objectName) == 0) { retVal = oa; break; } } SET_CURR_LIST_NODE (objAssignmentList,tmp); /* restore curr location */ return retVal; } /* LookupObjectClassObjectAssignment */ /* Deepak: 11/Mar/2003 * Looks for the ObjectSet with name matching objectName (null terminated char*) * in the given objSetAssignmentList * * RETURNS: ptr to the ObjectSetAssignment with the matching objectName (if any) * NULL if no match was made */ ObjectSetAssignment* LookupObjectClassObjectSetAssignment PARAMS ((objSetAssignmentList, objSetName), ObjectSetAssignmentList *objSetAssignmentList _AND_ char *objSetName) { ObjectSetAssignment *osa; ObjectSetAssignment *retVal; void *tmp; if (objSetAssignmentList == NULL) return NULL; if (objSetName == NULL) { #ifdef DEBUG fprintf (errFileG, "LookupObjectClassFieldType: warning - failure due to NULL key\n"); #endif return NULL; } tmp = (void*)CURR_LIST_NODE (objSetAssignmentList); /* remember curr list spot */ retVal = NULL; FOR_EACH_LIST_ELMT (osa, objSetAssignmentList) { if (strcmp (objSetName, osa->objectSetName) == 0) { retVal = osa; break; } } SET_CURR_LIST_NODE (objSetAssignmentList,tmp); /* restore curr location */ return retVal; } /* LookupObjectClassObjectSetAssignment */ /* * Returns ptr to module that has matching name or OID * if oid is not null, lookup done only by oid * * returns NULL if no match was found */ Module* LookupModule PARAMS ((moduleList, modName, oid), ModuleList *moduleList _AND_ char *modName _AND_ OID *oid) { Module *currMod; Module *retVal; void *tmp; if ((moduleList == NULL) || ((modName == NULL) && (oid == NULL))) return NULL; tmp = (void*)CURR_LIST_NODE (moduleList); /* remember orig loc */ retVal = NULL; FOR_EACH_LIST_ELMT (currMod, moduleList) { /* * may fail due to unresolved int or oid value ref * so try name match anyway. * This is not standard (CCITT) if the oids were resolved * but different, in which case the match should * fail regardless of the name match. oh well, ts. */ if (CompareOids (oid, currMod->modId->oid)) { retVal = currMod; break; /* exit for loop */ } else if ((modName != NULL) && (strcmp (modName, currMod->modId->name) == 0)) { retVal = currMod; break; /* exit for loop */ } } SET_CURR_LIST_NODE (moduleList, tmp); return retVal; } /* LookupModule */ /* * Given a constructed type, it returns the component of that * type with the matching field name. Returns NULL if teh * given type does not have the named field or is not * a type that has fields. */ NamedType* LookupFieldInType PARAMS ((tRef, fieldName), Type *tRef _AND_ char *fieldName) { NamedType *e; NamedType *retVal; Type *t; void *tmp; t = ParanoidGetType (tRef); /* skip any references etc */ if ((t->basicType->choiceId != BASICTYPE_SET) && (t->basicType->choiceId != BASICTYPE_SEQUENCE) && (t->basicType->choiceId != BASICTYPE_CHOICE)) { #ifdef DEBUG fprintf (errFileG, "LookupFieldInType: ERROR - attempt to look for field in a non SET/SEQ/CHOICE type\n"); #endif return NULL; } /* return if null list */ if (t->basicType->a.set == NULL) return NULL; /* remember set's original curr elmt */ tmp = (void*)CURR_LIST_NODE (t->basicType->a.set); retVal = NULL; FOR_EACH_LIST_ELMT (e, t->basicType->a.set) { /* remember fieldname is optional so it can be null */ if ((e->fieldName != NULL) && (strcmp (e->fieldName, fieldName) == 0)) { retVal = e; break; /* exit for loop */ } } SET_CURR_LIST_NODE (t->basicType->a.set, tmp); return retVal; } /* LookupFieldInType */ /* * Goes through typerefs (if any) to get to actual * ASN1 type. Returns the found "defining" type. * May return the given type t, if it's not a typeref * or if it is an unlinked type ref */ Type* GetType PARAMS ((type), Type *type) { TypeDef *td; Type *t; t = type; if (t == NULL) return NULL; while (1) { switch (t->basicType->choiceId) { case BASICTYPE_LOCALTYPEREF: case BASICTYPE_IMPORTTYPEREF: td = t->basicType->a.localTypeRef->link; if (td == NULL) return type; else t = td->type; break; default: return t; } } } /* GetType */ /* * like GetType ie, skips type references to return the defining type. * This is a paranoid version - it checks for circular type errors. * eg: A ::= B * B ::= A * would make the normal GetType recurse forever (until no stk mem) */ Type* ParanoidGetType PARAMS ((type), Type *type) { TypeDef *td; Type *t; DefinedObj *l; t = type; if (t == NULL) return NULL; l = NewObjList(); while (1) { switch (t->basicType->choiceId) { case BASICTYPE_LOCALTYPEREF: case BASICTYPE_IMPORTTYPEREF: td = t->basicType->a.localTypeRef->link; if ((td == NULL) || (ObjIsDefined (l, td->type, ObjPtrCmp))) { return type; } else { t = td->type; DefineObj (&l, t); } break; default: FreeDefinedObjs (&l); return t; } } } /* ParnoidGetType */ /* * Goes through typerefs (if any) to get to actual * ASN1 basic type (eg int, bool, seq, seq of, set, * set of, choice, any, etc. * Returns the typeId of that type, otherwise -1. */ enum BasicTypeChoiceId GetBuiltinType PARAMS ((t), Type *t) { Type *definingType; definingType = GetType (t); if (definingType != NULL) return definingType->basicType->choiceId; else return -1; } /* GetBuiltinType */ /* Paranoid version of GetBuiltinType * goes through typerefs (if any) to get to actual * ASN1 basic type (eg int, bool, seq, seq of, set, * set of, choice, any, etc. * Returns the typeId of that type, otherwise -1. */ enum BasicTypeChoiceId ParanoidGetBuiltinType PARAMS ((t), Type *t) { Type *definingType; definingType = ParanoidGetType (t); if (definingType != NULL) return definingType->basicType->choiceId; else return -1; } /* GetBuiltinType */ /* * Goes through typerefs (if any) to get to * the namedElmts (if any) associated with the * given type (INTEGER, ENUMERATED, BITSTRING or * LOCAL/IMPORT REFS to these types). * Returns NULL if there are no associated Named Elmts */ NamedNumberList* GetNamedElmts PARAMS ((t), Type *t) { Type *definingType; if (t == NULL) return NULL; definingType = ParanoidGetType (t); if (definingType == NULL) return NULL; switch (definingType->basicType->choiceId) { case BASICTYPE_INTEGER: case BASICTYPE_ENUMERATED: case BASICTYPE_BITSTRING: return definingType->basicType->a.integer; /* * for non-named elmt types * just return NULL */ default: return NULL; } /* not reached */ } /* GetNamedElmts */ /* * [Same as GetNamedElmts except goes through CHOICEs as well & * REQUIRES you to deallocate the list (but not its members).] * This is nec. for CHOICEs that contain INTs etc. with named #'s] * This is used for value linking. * * Goes through typerefs (if any) to get to * the namedElmts (if any) associated with the * given type (INTEGER, ENUMERATED, BITSTRING or * LOCAL/IMPORT REFS to these types). Also returns * a named element list for CHOICE types that contain * named elemnts * Returns an empty list if there are no associated Named Elmts. * you are responsible for freeing this list. Do not free the list * elmts - they are part of the types. */ NamedNumberList* GetAllNamedElmts PARAMS ((t), Type *t) { Type *definingType; NamedType *nt; NamedNumberList *retVal; NamedNumberList *ntElmtList; ValueDef *nn; /* named number is a valuedef */ ValueDef **nnHndl; retVal = AsnListNew (sizeof (void*)); if (t == NULL) return retVal; definingType = ParanoidGetType (t); if (definingType == NULL) return retVal; switch (definingType->basicType->choiceId) { case BASICTYPE_INTEGER: case BASICTYPE_ENUMERATED: case BASICTYPE_BITSTRING: /* * add the named elmts (if any) to the new list */ FOR_EACH_LIST_ELMT (nn, definingType->basicType->a.integer) { nnHndl = (ValueDef**)AsnListAppend (retVal); *nnHndl = nn; } break; /* * for choices must group all named elmts from choice components * and return in a list. */ case BASICTYPE_CHOICE: FOR_EACH_LIST_ELMT (nt, definingType->basicType->a.choice) { ntElmtList = GetAllNamedElmts (nt->type); retVal = AsnListConcat (retVal, ntElmtList); Free (ntElmtList); /* zap now unused list head */ } break; default: break; } return retVal; } /* GetAllNamedElmts */ /* * Recursively does pseudo breadth first search from the given ancestor * looking for the given child node. Returns the direct parent Type * of the child if found, NULL otherwise. This routine does not follow * type references. */ Type* GetParentS PARAMS ((ancestor, child), Type *ancestor _AND_ Type *child) { NamedType *e; Type *parent; void *tmp; if ((ancestor->basicType->choiceId != BASICTYPE_SET) && (ancestor->basicType->choiceId != BASICTYPE_SEQUENCE) && (ancestor->basicType->choiceId != BASICTYPE_CHOICE) && (ancestor->basicType->choiceId != BASICTYPE_SETOF) && (ancestor->basicType->choiceId != BASICTYPE_SEQUENCEOF) && (ancestor->basicType->choiceId != BASICTYPE_OCTETCONTAINING) && (ancestor->basicType->choiceId != BASICTYPE_BITCONTAINING)) { return NULL; } if (ancestor->basicType->a.set == NULL) return NULL; if ((ancestor->basicType->choiceId == BASICTYPE_SETOF) || (ancestor->basicType->choiceId == BASICTYPE_SEQUENCEOF)) { if (child == ancestor->basicType->a.setOf) return ancestor; else return GetParentS (ancestor->basicType->a.setOf, child); } tmp = (void*)CURR_LIST_NODE (ancestor->basicType->a.set); /* * look through direct children of ancestor first */ FOR_EACH_LIST_ELMT (e, ancestor->basicType->a.set) { if ( ((e->type->basicType->choiceId == BASICTYPE_OCTETCONTAINING) || (e->type->basicType->choiceId == BASICTYPE_BITCONTAINING)) && (child == e->type->basicType->a.stringContaining) ) { SET_CURR_LIST_NODE (ancestor->basicType->a.set, tmp); return ancestor; } else if (child == e->type) { SET_CURR_LIST_NODE (ancestor->basicType->a.set, tmp); return ancestor; } } /* * look through grandchildren if not in children */ FOR_EACH_LIST_ELMT (e, ancestor->basicType->a.set) { if ((parent = GetParentS (e->type, child)) != NULL) { SET_CURR_LIST_NODE (ancestor->basicType->a.set, tmp); return parent; } } SET_CURR_LIST_NODE (ancestor->basicType->a.set, tmp); return NULL; } /* GetParent */ /* * Looks for the value with the given valueName (null term char*) in the * given list of ValueDefs * RETURNS: ptr to ValueDef with matching key (if any) * NULL if no match was made */ ValueDef* LookupValue PARAMS ((valueList, valueName), ValueDefList *valueList _AND_ char *valueName) { ValueDef *v; ValueDef *retVal; void *tmp; if (valueName == NULL) { #ifdef DEBUG fprintf (errFileG, "LookupType: warning - failure due to NULL key\n"); #endif return NULL; } if (valueList == NULL) return NULL; tmp = (void*)CURR_LIST_NODE (valueList); retVal = NULL; FOR_EACH_LIST_ELMT (v, valueList) { if (strcmp (valueName, v->definedName) == 0) { retVal = v; break; /* exit for loop */ } } SET_CURR_LIST_NODE (valueList, tmp); return retVal; } /* LookupValue */ BasicValue * GetLastNamedNumberValue PARAMS ((valueList), NamedNumberList *valueList) { ValueDef *v; BasicValue *retVal; void *tmp; if (valueList == NULL) return NULL; tmp = (void*)CURR_LIST_NODE (valueList); retVal = NULL; FOR_EACH_LIST_ELMT_RVS (v, valueList) { if (v->value->basicValue->choiceId == BASICVALUE_INTEGER) { retVal = v->value->basicValue; break; /* exit for loop */ } } SET_CURR_LIST_NODE (valueList, tmp); return retVal; } /* LookupValue */ /* * Goes through valuerefs (if any) to get to actual * ASN1 value. Analogous to GetType. */ Value* GetValue PARAMS ((v), Value *v) { ValueDef *vd; while (v != NULL) { switch (v->basicValue->choiceId) { case BASICVALUE_LOCALVALUEREF: case BASICVALUE_IMPORTVALUEREF: vd = v->basicValue->a.localValueRef->link; if (vd == NULL) v = NULL; else v = vd->value; break; default: return v; } } fprintf (errFileG, "GetValue: ERROR - cannot get value for unlinked local/import value refs\n"); return NULL; } /* GetValue */ /* * Returns TRUE if oid1 and oid2 are identical otherwise FALSE */ int CompareOids PARAMS ((oid1, oid2), OID *oid1 _AND_ OID *oid2) { if ((oid1 == NULL) && (oid2 == NULL)) return FALSE; for (; (oid1 != NULL) && (oid2 != NULL); oid1 = oid1->next, oid2 = oid2->next) { /* * fail if value refs have not been resolved or * no match between arcnums */ if ((oid1->arcNum == NULL_OID_ARCNUM) || (oid2->arcNum == NULL_OID_ARCNUM) || (oid1->arcNum != oid2->arcNum)) return FALSE; /* * could check ref'd values for same name * incase value ref has not been resolved * and put in arcNum */ } if ((oid1 == NULL) && (oid2 == NULL)) return TRUE; else return FALSE; } /* CompareOids */ /* * Returns TRUE if the given type is INTEGER, ENUMERATED or * BIT STRING and it has named elements * ie Foo ::= INTEGER { one (1), two (2) } would return TRUE */ int HasNamedElmts PARAMS ((t), Type *t) { return ((t->basicType->choiceId == BASICTYPE_INTEGER) || (t->basicType->choiceId == BASICTYPE_ENUMERATED) || (t->basicType->choiceId == BASICTYPE_BITSTRING)) && (t->basicType->a.integer != NULL) && !LIST_EMPTY (t->basicType->a.integer); } /* HasNamedElmts */ /* * Returns true if the given tag lists are the same * (assumes value refs have be resolved) */ int TagsAreIdentical PARAMS ((t1, t2), TagList *t1 _AND_ TagList *t2) { Tag *tag1; Tag *tag2; /* both lists are empty */ if (((t1 == NULL) || LIST_EMPTY (t1)) && ((t2 == NULL) || LIST_EMPTY (t2))) return TRUE; else if ((t1 == NULL) || (t2 == NULL)) return FALSE; else if (LIST_COUNT (t1) == LIST_COUNT (t2)) { SET_CURR_LIST_NODE (t2, FIRST_LIST_NODE (t2)); FOR_EACH_LIST_ELMT (tag1, t1) { tag2 = (Tag*) CURR_LIST_ELMT (t2); if ((tag1->tclass != tag2->tclass) || (tag1->code == tag2->code)) return FALSE; SET_CURR_LIST_NODE (t2, NEXT_LIST_NODE (t2)); } return TRUE; } else return FALSE; } /* TagsAreIdentical */ /* * Returns TRUE if the tag currently on the given type has the default * tag specified in the type tbl. otherwise returns FALSE. */ int HasDefaultTag PARAMS ((t), Type *t) { Tag *firstTag = NULL; int dfltCode; int dfltClass; dfltClass = UNIV; dfltCode = LIBTYPE_GET_UNIV_TAG_CODE (t->basicType->choiceId); if ((t->tags != NULL) && !LIST_EMPTY (t->tags)) firstTag = (Tag*)FIRST_LIST_ELMT (t->tags); return ((firstTag != NULL) && (LIST_COUNT (t->tags) == 1) && (firstTag->tclass == dfltClass) && (firstTag->code == dfltCode)) || ((firstTag == NULL) && (dfltCode == NO_TAG_CODE)); } /* HasDefaultTag */ /* * Returns TRUE if t is a primitive type or if it is * defined by a reference to a primitive type */ int IsPrimitiveByDefOrRef PARAMS ((t), Type *t) { Type *definingType; definingType = GetType (t); if (definingType == NULL) return FALSE; /* bad error handling */ return IsPrimitiveByDef (definingType); } /* IsPrimitiveByDefOrRef */ /* * Returns TRUE if the given type is a primitive type. Does NOT * follow type references - type refs are not considered primitive. * The following types are considered primitive: * BOOLEAN * INTEGER/BIG_INT * BITSTRING * OCTETSTRING * NULL * OID * REAL * ENUMERATED * NumericString, PrintableString, IA5String, BMPString, * UniversalString, UTF8String, and TeletexString (T61String) */ int IsPrimitiveByDef PARAMS ((t), Type *t) { switch (t->basicType->choiceId) { case BASICTYPE_LOCALTYPEREF: case BASICTYPE_IMPORTTYPEREF: case BASICTYPE_SEQUENCET: // Deepak: 29/Nov/2002 case BASICTYPE_OBJECTCLASS: // Deepak: 05/Feb/2003 case BASICTYPE_OBJECTCLASSFIELDTYPE: // Deepak: 05/Feb/2003 case BASICTYPE_SEQUENCE: case BASICTYPE_SET: case BASICTYPE_CHOICE: case BASICTYPE_SEQUENCEOF: case BASICTYPE_SETOF: case BASICTYPE_COMPONENTSOF: case BASICTYPE_ANYDEFINEDBY: case BASICTYPE_ANY: return FALSE; break; case BASICTYPE_SELECTION: if (t->basicType->a.selection->link != NULL) return IsPrimitiveByDef (t->basicType->a.selection->link->type); break; case BASICTYPE_BOOLEAN: case BASICTYPE_INTEGER: case BASICTYPE_BITSTRING: case BASICTYPE_OCTETSTRING: case BASICTYPE_NULL: case BASICTYPE_OID: case BASICTYPE_RELATIVE_OID: case BASICTYPE_REAL: case BASICTYPE_ENUMERATED: case BASICTYPE_NUMERIC_STR: case BASICTYPE_PRINTABLE_STR: case BASICTYPE_IA5_STR: case BASICTYPE_BMP_STR: case BASICTYPE_UNIVERSAL_STR: case BASICTYPE_UTF8_STR: case BASICTYPE_T61_STR: case BASICTYPE_GENERALIZEDTIME: case BASICTYPE_UTCTIME: case BASICTYPE_OBJECTDESCRIPTOR: case BASICTYPE_VISIBLE_STR: case BASICTYPE_GRAPHIC_STR: case BASICTYPE_VIDEOTEX_STR: case BASICTYPE_GENERAL_STR: return TRUE; break; case BASICTYPE_UNKNOWN: case BASICTYPE_MACROTYPE: case BASICTYPE_MACRODEF: case BASICTYPE_EXTERNAL: return FALSE; break; default: fprintf (errFileG, "IsPrimitiveByDef: ERROR - unknown type id ?!"); } return FALSE; } /* IsPrimitiveByDef */ /* * Returns TRUE if the given type is a local type reference or an * import type ref. * e.g. * * Gumby ::= P1.ORName --> isTypeRef returns TRUE P1.ORName * Bar ::= INTEGER --> isTypeRef returns FALSE for INTEGER * Foo ::= Bar --> isTypeRef returns TRUE for Bar */ int IsTypeRef PARAMS ((t), Type *t) { if ((t->basicType->choiceId == BASICTYPE_LOCALTYPEREF) || (t->basicType->choiceId == BASICTYPE_IMPORTTYPEREF)) return TRUE; else return FALSE; } /* IsTypeRef */ /* * Returns TRUE if the given type is defined * by a library type such as OCTET STRING. * Does NOT follow type refs - type refs return FALSE. * * NOTE - some possibly non-primitive types are defined by * library types (ANY, ANY DEFINED BY) * * types defined by type refs or structured defs * cause FALSE to be returned. i.e. * Foo ::= Bar -> FALSE for Bar * Bell ::= SEQUENCE { .. } -> False for SEQ... * * useful types are considered as type references and hence * return FALSE. */ int IsDefinedByLibraryType PARAMS ((t), Type *t) { int retVal; if (t == NULL) retVal = FALSE; else if (IsPrimitiveByDef (t)) retVal = TRUE; /* * check for non-primitive types that * are defined by a library type */ else switch (t->basicType->choiceId) { case BASICTYPE_ANYDEFINEDBY: case BASICTYPE_ANY: retVal = TRUE; break; default: retVal = FALSE; } return retVal; } /* IsDefinedByLibraryType*/ /* * Returns FALSE if type t is * a. a library type with default universal tags and no named elements * OR * b. a reference to a type with no extra tagging * * otherwise returns true, indicating that is is a new type derived * by tagging or adding named elmts to another type. * * eg INTEGER --> FALSE (same as lib type) * [APPLICATION 2] INTEGER --> TRUE (re-tagged lib type) * INTEGER { one (1), two (2) } --> TRUE (lib type with named elmts) * Bar2 --> FALSE (simple type ref) */ int IsNewType PARAMS ((t), Type *t) { /* * Type = [re-tagging] DefiningType [namedelmts] * identical: no retagging and no named elements */ if (IsDefinedByLibraryType (t) && HasDefaultTag (t) && ! HasNamedElmts (t)) return FALSE; else if (IsTypeRef (t) && ((t->tags == NULL) || (LIST_EMPTY (t->tags)))) return FALSE; else return TRUE; } /* IsNewType */ /* * Returns TRUE if elmts including curr list elmt * onward are all optional otherwise returns FALSE. * (note: this relies on the 'curr' ptr in the list) * if the list is null or the curr elmt is null * then returns TRUE */ int IsTailOptional PARAMS ((e), NamedTypeList *e) { NamedType *elmt; void *tmp; int retVal; if (e == NULL) return TRUE; tmp = (void*)CURR_LIST_NODE (e); if (tmp == NULL) return TRUE; retVal = TRUE; FOR_REST_LIST_ELMT (elmt, e) { if ((!elmt->type->optional) && (elmt->type->defaultVal == NULL) && (!elmt->type->extensionAddition)) { retVal = FALSE; break; } } SET_CURR_LIST_NODE (e, tmp); /* reset list to orig loc */ return retVal; } /* IsTailOptional */ /* * Returns TRUE if all elmts after but not including the curr list elmt * are optional otherwise returns FALSE. * (note: this relies on the 'curr' ptr in the list) * if the list is null or the curr elmt is null * then returns TRUE. if there are no elmts after the curr elmt * returns TRUE. */ int NextIsTailOptional PARAMS ((e), NamedTypeList *e) { NamedType *elmt; void *tmp; void *tmp2; int retVal; if ((e == NULL) || (LIST_EMPTY (e))) return TRUE; tmp = (void*)CURR_LIST_NODE (e); if (tmp == NULL) return TRUE; tmp2 = (void*)NEXT_LIST_NODE (e); if (tmp2 == NULL) return TRUE; SET_CURR_LIST_NODE (e, tmp2); retVal = TRUE; FOR_REST_LIST_ELMT (elmt, e) { if ((!elmt->type->optional) && (elmt->type->defaultVal == NULL) && (!elmt->type->extensionAddition)) { retVal = FALSE; break; } } SET_CURR_LIST_NODE (e, tmp); /* reset list to orig loc */ return retVal; } /* NextIsTailOptional */ /* * Returns TRUE if all elmts of the curr list are optional * or have default values. Useful with SET and SEQ elements. */ int AllElmtsOptional PARAMS ((e), NamedTypeList *e) { NamedType *elmt; void *tmp; int retVal; if ((e == NULL) || LIST_EMPTY (e)) return TRUE; tmp = (void*)CURR_LIST_NODE (e); SET_CURR_LIST_NODE (e, FIRST_LIST_NODE (e)); retVal = TRUE; FOR_REST_LIST_ELMT (elmt, e) { if ((!elmt->type->optional) && (elmt->type->defaultVal == NULL) && (!elmt->type->extensionAddition)) { retVal = FALSE; break; } } SET_CURR_LIST_NODE (e, tmp); /* reset list to orig loc */ return retVal; } /* AllElmtsOptional */ /* * Follows single levely of type ref or library type and returns a * handle to its AnyRefList. Typically used in do_macros.c to * add a hash key for the type that t is or refs. Need to get * to the type def of type t to give the AnyRefListHndl. */ AnyRefList** GetAnyRefListHndl PARAMS ((t), Type *t) { TypeDef *td; if (IsDefinedByLibraryType (t)) return LIBTYPE_GET_ANY_REFS_HNDL (t->basicType->choiceId); else { if (!IsTypeRef (t)) return NULL; else { td = t->basicType->a.localTypeRef->link; return &td->anyRefs; } } } /* GetAnyRefListHndl */ /* * Given a subtype list s (possibly empty *s == NULL) it tacks on * the newSubtype in a appropriate fashion, possible chaning *s. * Op can be SUBTYPE_AND or SUBTYPE_OR. * * e.g. Foo ::= INTEGER ((1..100) | 200) * * Add the subtypes by * AppendSubtype (&t->subtypes, (1..100), SUBTYPE_AND) * AppendSubtype (&t->subtypes, 200, SUBTYPE_OR) * * op is meaningless if s is empty */ void AppendSubtype PARAMS ((s, newSubtype, op), Subtype **s _AND_ Subtype *newSubtype _AND_ enum SubtypeChoiceId op) { void **tmpPtr; Subtype *sPtr; if (*s == NULL) *s = newSubtype; else if (op == SUBTYPE_AND) { if ((*s)->choiceId == SUBTYPE_AND) { tmpPtr = (void**)AsnListAppend ((*s)->a.and); *tmpPtr = (void*)newSubtype; } else { sPtr = (Subtype*)Malloc (sizeof (Subtype)); sPtr->choiceId = SUBTYPE_AND; sPtr->a.and = NEWLIST(); tmpPtr = (void**)AsnListAppend (sPtr->a.and); *tmpPtr = (void*)*s; tmpPtr = (void**)AsnListAppend (sPtr->a.and); *tmpPtr = (void*)newSubtype; *s = sPtr; } } else if (op == SUBTYPE_OR) { if ((*s)->choiceId == SUBTYPE_OR) { tmpPtr = (void**)AsnListAppend ((*s)->a.or); *tmpPtr = (void*)newSubtype; } else { sPtr = (Subtype*)Malloc (sizeof (Subtype)); sPtr->choiceId = SUBTYPE_OR; sPtr->a.or = NEWLIST(); tmpPtr = (void**)AsnListAppend (sPtr->a.or); *tmpPtr = (void*)*s; tmpPtr = (void**)AsnListAppend (sPtr->a.or); *tmpPtr = (void*)newSubtype; *s = sPtr; } } else /* NOT not supported here */ fprintf (errFileG, "AppendSubtype - unknown operation\n"); } /* AppendSubtype */ static int TagCodeFound(AsnList *tags, AsnInt startingTag) { Tag *tag; FOR_EACH_LIST_ELMT(tag, tags) { if (tag->code == startingTag) return 1; } return 0; } void AutomaticTagNamed PARAMS ((l, all), NamedTypeList *l) { AsnList *used_tag; NamedType *e; void *lcurr; AsnInt startingTag = 0; if (l == NULL) { fprintf(errFileG, "AutomaticTagNamed - NULL tag list.\n"); } /* Two passes */ used_tag = AsnListNew(sizeof(void*)); /* First pass, identify all the tags, and all the elements which need tags */ lcurr = l->curr; FOR_EACH_LIST_ELMT(e, l) { if (e->type->tags != NULL) { Tag *t; void *curr = e->type->tags->curr; FOR_EACH_LIST_ELMT(t, e->type->tags) { if (t->tclass == CNTX) { APPEND(t, used_tag); break; } } e->type->tags->curr = curr; } } FOR_EACH_LIST_ELMT(e, l) { int found = 0; Tag *t; FOR_EACH_LIST_ELMT(t, e->type->tags) { if (t->tclass == CNTX) { fprintf(errFileG, "CNTX tag exists\n"); found = 1; } } if (!found) { Tag *newTag = Malloc(sizeof(Tag)); newTag->tclass = CNTX; newTag->form = PRIM; newTag->valueRef = NULL; /* It seems strange to only use context tagging; however, after * some brief interop testing, that seems like the right thing to * do */ if (!(e->type->tags)) AsnListFree(e->type->tags); e->type->tags = AsnListNew(sizeof(void *)); while(TagCodeFound(used_tag, startingTag)) startingTag++; newTag->code = startingTag++; newTag->explicit = FALSE; PREPEND(newTag, e->type->tags); } } l->curr = lcurr; AsnListFree(used_tag); } esnacc-ng-1.8.1/compiler/core/snacc-util.h000066400000000000000000000132371302010526100203300ustar00rootroot00000000000000/* * compiler/core/snacc_util.h * * Copyright (C) 1992 Michael Sample and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/core/snacc-util.h,v 1.10 2004/03/31 20:03:20 leonberp Exp $ * $Log: snacc-util.h,v $ * Revision 1.10 2004/03/31 20:03:20 leonberp * resolved many gcc compile warnings * * Revision 1.9 2004/01/29 21:21:45 gronej * Took all Init() calls out of Clear() functions in generated code * * Revision 1.8 2003/07/28 11:11:24 colestor * Changes to complete handing of the "--snacc namespace" compiler directive. * Also, updates to handle ASN.1 constant integer tag designations for C++/C. * * Revision 1.7 2003/07/07 21:01:19 nicholar * no message * * Revision 1.6 2003/07/07 14:50:14 nicholar * Eliminated headers and cleaned up include references * * Revision 1.5 2003/04/29 21:07:03 leonberp * integerated Deepak's changes for IOB support * * Revision 1.4 2003/01/27 16:50:45 leonberp * added GetLastNamedNumberValue() * * Revision 1.3 2002/10/21 17:15:19 mcphersc * fixed long int * * Revision 1.2 2001/07/12 19:34:34 leonberp * Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. * * Revision 1.1.1.1 2000/08/21 20:36:02 leonberp * First CVS Version of SNACC. * * Revision 1.3 1995/07/25 19:41:46 rj * changed `_' to `-' in file names. * * Revision 1.2 1994/09/01 00:46:41 rj * snacc_config.h's 2nd last macro, PrintErrLoc(), got here. * * Revision 1.1 1994/08/28 09:49:41 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #define PrintErrLoc( fileName, lineNo)\ fprintf (errFileG, "%s(%ld) : ", fileName, (long int)(lineNo)) /* * macro to allocate room for str & null & put in give STR* */ #define SETUP_STR( strPtr, string)\ (strPtr)->str = Malloc (strlen (string) + 1);\ strcpy ((strPtr)->str, string);\ (strPtr)->len = strlen (string) + 1 /* * Create a new list type such that each elmt has space * to hold a pointer */ #define NEWLIST() AsnListNew (sizeof (void *)) /* * macro to append an element to the end of linked list * - helps on left recursion when order must be maintained * * be careful of calling context if list is null * that is, make sure the change to list is not lost. */ #define APPEND( elmt, list) \ {\ void **tmpPtr;\ if ((list) == NULL)\ (list) = NEWLIST();\ tmpPtr = (void **) AsnListAppend ((AsnList *)list);\ *tmpPtr = (void *) (elmt);\ } /* * like APPEND except puts elmt at head of list */ #define PREPEND( elmt, list) \ {\ void **tmpPtr;\ if ((list) == NULL)\ (list) = NEWLIST();\ tmpPtr = (void **)AsnListPrepend ((AsnList *)list);\ *tmpPtr = (void *) (elmt);\ } #define CONCAT( list1, list2)\ {\ AsnListConcat(list1, list2);\ } BasicValue * GetLastNamedNumberValue PROTO ((NamedNumberList *valueList)); void SetupType PROTO ((Type **t, enum BasicTypeChoiceId typeId, unsigned long lineNum)); void AutomaticTagNamed PROTO ((NamedTypeList *l)); void SetupMacroType PROTO ((Type **t, enum MacroTypeChoiceId macroTypeId, unsigned long lineNum)); void SetupValue PROTO ((Value **v, enum BasicValueChoiceId valId, unsigned long lineNum)); void AddPrivateImportElmt PROTO ((Module *m, char *name, char *refModuleName, long lineNo)); ImportElmt *LookupImportElmtInModule PROTO ((Module *m, char *name, ImportModule **importModule)); ImportElmt *LookupImportElmtInImportElmtList PROTO ((ImportElmtList *importElmtList, char *name)); ImportModule *LookupImportModule PROTO ((Module *m, char *importModuleName)); TypeDef *LookupType PROTO ((TypeDefList *t, char *typeName)); // Deepak: 04/Feb/2003 NamedType *LookupObjectClassFieldType PROTO ((NamedTypeList *n, char *typeName)); // Deepak: 05/Mar/2003 WithSyntax* LookupObjectClassFieldTypeWithSyntax PROTO ((WithSyntaxList *withSyntaxList, char *typeName, char* bError)); // Deepak: 05/Mar/2003 ObjectAssignment* LookupObjectClassObjectAssignment PROTO ((ObjectAssignmentList *objAssignmentList, char *objName)); // Deepak: 11/Mar/2003 ObjectSetAssignment* LookupObjectClassObjectSetAssignment PROTO ((ObjectSetAssignmentList *objSetAssignmentList, char *objSetName)); Module *LookupModule PROTO ((ModuleList *m, char *modName, OID *oid)); NamedType *LookupFieldInType PROTO ((Type *t, char *fieldName)); Type *GetType PROTO ((Type *t)); Type *ParanoidGetType PROTO ((Type *t)); enum BasicTypeChoiceId GetBuiltinType PROTO ((Type *t)); NamedNumberList *GetNamedElmts PROTO ((Type *t)); NamedNumberList *GetAllNamedElmts PROTO ((Type *t)); Type *GetParentS PROTO ((Type *ancestor, Type *child)); ValueDef *LookupValue PROTO ((ValueDefList *v, char *valueName)); Value *GetValue PROTO ((Value *v)); int CompareOids PROTO ((OID *oid1, OID *oid2)); int HasNamedElmts PROTO ((Type *t)); int TagsAreIdentical PROTO ((TagList *t1, TagList *t2)); int HasDefaultTag PROTO ((Type *t)); int IsPrimitiveByDefOrRef PROTO ((Type *t)); int IsPrimitiveByDef PROTO ((Type *t)); int IsDefinedByLibraryType PROTO ((Type *t)); int IsTypeRef PROTO ((Type *t)); int IsNewType PROTO ((Type *t)); int IsTailOptional PROTO ((NamedTypeList *e)); int NextIsTailOptional PROTO ((NamedTypeList *e)); int AllElmtsOptional PROTO ((NamedTypeList *e)); AnyRefList **GetAnyRefListHndl PROTO ((Type *t)); void AppendSubtype PROTO ((Subtype **s, Subtype *newSubtype, enum SubtypeChoiceId op)); extern FILE* errFileG; // Defined in snacc.c esnacc-ng-1.8.1/compiler/core/snacc.c000066400000000000000000001423371302010526100173540ustar00rootroot00000000000000/* * compiler/core/snacc.c---Compiles ASN.1 src files into an internal type tree. * Imported type/value references are resolved if possible. * Produces C or C++ encoder/decoder/print/free code and .h for * data struct and prototypes. * Generated C can be either ANSI or old style via macros. * Produces values for OBJECT IDENTIFIERs, INTEGERs and BOOLEANs * * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program and the associated libraries are distributed in the hope * that they will be useful, but WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License and GNU Library General * Public License for more details. * * $Header: /baseline/SNACC/compiler/core/snacc.c,v 1.54 2004/04/06 15:13:41 gronej Exp $ * */ #include int gNO_NAMESPACE=0; const char *gAlternateNamespaceString=0; /* DEFAULT no DLL Export of SNACC built classes. */ char *bVDAGlobalDLLExport=(char *)0; #ifdef WIN32 #pragma warning( disable : 4706 4115) /* IGNORE assign w/in conditional expression. */ #endif #ifdef WIN32 #include #define chdir _chdir #else #include #endif #include #if TIME_WITH_SYS_TIME # include # include #else # if HAVE_SYS_TIME_H # include # else # include # endif #endif #include #include #include #include "asn-incl.h" #if STDC_HEADERS || HAVE_STRING_H #include #else #include #endif #include "version.h" #include "mem.h" #include "asn1module.h" #include "exports.h" #include "enc-rules.h" #include "print.h" #include "define.h" #include "snacc-util.h" #include "str-util.h" #if META #include "meta.h" #endif #include "c-gen/rules.h" /* for c file generation */ #include "c-gen/type-info.h" #include "c++-gen/rules.h" /* for c++ file generation */ #if IDL #include "idl-gen/rules.h" /* for idl file generation */ #endif typedef struct SRC_FILE { char *fileName; short ImportFileFlag; struct SRC_FILE *next; } SRC_FILE; /* ******************* */ /* Function Prototypes */ /* ******************* */ /* Generic File System Interface (GFSI) */ typedef void * GFSI_HANDLE; char *GFSI_GetFirstFile(GFSI_HANDLE *gfsi_handle, const char *path, const char *extension); char *GFSI_GetNextFile( GFSI_HANDLE *gfsi_handle, const char *extension); void GFSI_Close( GFSI_HANDLE *gfsi_handle ); void ErrChkModule PROTO ((Module *m)); void FillCxxTypeInfo PROTO ((CxxRules *r, ModuleList *m)); void FillIDLTypeInfo PROTO ((IDLRules *r, ModuleList *modList)); void GenTypeTbls PROTO ((ModuleList *mods, char *fileName, int tableFileVersion)); int InitAsn1Parser PROTO ((Module *mod, char *fileName, FILE *fPtr)); int LinkTypeRefs PROTO ((ModuleList *m)); int LinkValueRefs PROTO ((ModuleList *m)); void MarkRecursiveTypes PROTO ((Module *m)); void NormalizeModule PROTO ((Module *m)); void NormalizeValue PROTO ((Module *m, ValueDef *vd, Value *v, int quiet)); int ParseValues PROTO ((ModuleList *mods, Module *m)); void PrintCCode PROTO ((FILE *src, FILE *hdr, ModuleList *mods, Module *m, CRules *r, long int longJmpVal, int printTypes, int printValues, int printEncoders, int printDecoders, int printPrinters, int printFree)); void PrintCxxCode (FILE *src, FILE *hdr, if_META (MetaNameStyle genMeta COMMA const Meta *meta COMMA MetaPDU *metapdus COMMA) ModuleList *mods, Module *m, CxxRules *r, long longJmpVal, int printTypes, int printValues, int printEncoders, int printDecoders, int printPrinters, int printFree, if_TCL (int printTcl COMMA) int novolatilefuncs); void PrintIDLCode PROTO ((FILE *idl, ModuleList *mods, Module *m, IDLRules *r, long int longJmpVal, int printValues)); void ProcessMacros PROTO ((Module *m)); void SortAllDependencies PROTO ((ModuleList *m)); int yyparse(); /* Internal routines */ static short Add2SrcList(SRC_FILE **FileList, const char *InputFile, short ImportFlag); static int GenCCode PROTO ((ModuleList *allMods, long longJmpVal, int genTypes, int genEncoders, int genDecoders, int genPrinters, int genValues, int genFree)); static void GenCxxCode PROTO ((ModuleList *allMods, long longJmpVal, int genTypes, int genEncoders, int genDecoders, int genPrinters, int genValues, int genFree, if_META (MetaNameStyle genMeta COMMA MetaPDU *meta_pdus COMMA) if_TCL (int genTcl COMMA) int novolatilefuncs)); static void GenIDLCode PROTO ((ModuleList *allMods, long longJmpVal, int genTypes, int genPrinters, int genValues, int genFree)); static int ModNamesUnique PROTO ((ModuleList *m)); static Module *ParseAsn1File PROTO ((char *fileName, short ImportFlag)); static short compareDupeFile(const char *fullpath, SRC_FILE *FileList); static char *sbasename(char *name); #if META static MetaPDU *parse_type_list PROTO (char *arg)); #endif /* META */ /* **************** */ /* Global Variables */ /* **************** */ extern int anyEnumValG; extern int smallErrG; /* can continue processing but don't produce code - see more errs */ /*RWC;extern int yydebug; / * set to 1 to enable debugging */ int maxFileNameLenG = -1; /* values > 2 are considered valid */ /* this is used in back_ends/c_gen/str_util.c */ static const char versionG[] = VERSION; static const char releasedateG[] = RELDATE; static const char bugreportaddressG[] = BUGREPADDR; FILE* errFileG = NULL; /* Pointer to file for reporting errors */ int genPERCode = FALSE; int isSyntax1997 = 1; /* Deepak: 24/Mar/2003 Syntax Checking for 1990/1997, defaults to 1997 */ int isTableConstraintAllowed = 1; /* Deepak: 25/Mar/2003 */ int isInWithSyntax = 0; /* Deepak: 26/Mar/2003 */ #ifdef WIN_SNACC /* Deepak: 14/Feb/2003 */ #define main Win_Snacc_Main #endif void Usage PARAMS ((prgName, fp), char *prgName _AND_ FILE *fp) { fprintf (fp, "\nUsage: %s ", prgName); fprintf (fp, "[-h] [-P] [-t] [-v] [-e] [-d] [-p] [-f] [-y] [-M] [-B] \n"); #if IDL fprintf (fp, " [-c | -C | -T | -idl ]\n"); #else fprintf (fp, " [-c | -C | -T
]\n"); #endif fprintf (fp, " [-I ]\n"); fprintf (fp, " [-mm] [-mf ]\n"); fprintf (fp, " [-l ]\n"); fprintf (fp, " [-VDAexport=DEFINE_NAME] to designate export of SNACC generated classes\n"); fprintf (fp, " [-E BER|DER select encoding rules to generate (C only)]\n"); fprintf (fp, " [-a ] select starting number for ANYs\n"); #if META fprintf (fp, " [-meta ] [-mA | -mC]\n"); #if TCL fprintf (fp, " [-tcl ]\n"); #endif #endif fprintf (fp, " \n\n"); fprintf (fp, " -c generate C encoders and decoders (default)\n"); fprintf (fp, " -C generate C++ encoders and decoders\n"); fprintf (fp, " -T write a type table file for the ASN.1 modules to file filename\n"); fprintf (fp, " -O writes the type table file in the original (<1.3b2) format\n"); fprintf (fp, " -B turns off generation of constrained PER classes\n"); #if IDL fprintf (fp, " -idl generate CORBA IDL\n"); #endif fprintf (fp, " -h prints this msg\n"); fprintf (fp, " -P print the parsed ASN.1 modules to stdout from their parse trees\n"); fprintf (fp, " (helpful debugging)\n"); fprintf (fp, " -t generate type definitions\n"); fprintf (fp, " -v generate value definitions (limited)\n"); fprintf (fp, " -e generate encode routines\n"); fprintf (fp, " -d generate decode routines\n"); fprintf (fp, " -p generate print routines\n"); fprintf (fp, " -f generate hierarchical free routines (C only)\n"); fprintf (fp, " Note: if none of -t -v -e -d -p -f are given, all are generated.\n"); fprintf (fp, " These do not affect type tables.\n"); fprintf (fp, " -y enable bison debugging\n"); fprintf (fp, " -M uses the 1990 Syntax, default is the 1997 Syntax\n"); fprintf (fp, " -mm mangle output file name into module name (by default, the output file\n"); fprintf (fp, " inherits the input file's name, with only the suffix replaced)\n"); fprintf (fp, " -mf num is maximum file name length for the generated source files\n"); fprintf (fp, " -mo store output in the directory specified by .\n"); fprintf (fp, " -l where to start error longjmp values decending from (obscure).\n"); fprintf (fp, " -L print syntax errors to the specified error log file\n"); fprintf (fp, " (default is stderr)\n"); #if META fprintf (fp, " -meta generate meta code that describes the generated types. Implies -C.\n"); fprintf (fp, " -mA metacode: use names as defined in the ASN.1 files.\n"); fprintf (fp, " -mC metacode: use names as used in the generated C++ files.\n"); #if TCL fprintf (fp, " -tcl generate code for a Tcl interpreter. Implies -meta.\n"); #endif fprintf (fp, " has the following syntax: .[,.[...]]\n"); fprintf (fp, " the types listed are the top level PDUs.\n"); #endif fprintf (fp, "\nUse `-' as the ASN.1 source file name to parse stdin.\n\n"); fprintf (fp, "This ASN.1 compiler produces C or C++ BER encoders and decoders or type tables.\n"); fprintf (fp, "\nVersion %s\n", versionG); fprintf (fp, "Release Date: %s\n", releasedateG); fprintf (fp, "Please see %s for new versions and where to send bug reports and comments.\n\n", bugreportaddressG); fprintf (fp, "Copyright (C) 1993 Michael Sample and UBC\n"); fprintf (fp, "Copyright (C) 1994, 1995 by Robert Joop and GMD FOKUS\n\n"); fprintf (fp, "Copyright (C) 2011-2016 by Aaron Conole\n\n"); fprintf (fp, "This program is free software; you can redistribute it and/or modify\n"); fprintf (fp, "it under the terms of the GNU General Public License as published by\n"); fprintf (fp, "the Free Software Foundation; either version 2 of the License, or\n"); fprintf (fp, "(at your option) any later version.\n\n"); fprintf (fp, "This program is distributed in the hope that it will be useful,\n"); fprintf (fp, "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"); fprintf (fp, "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"); fprintf (fp, "GNU General Public License for more details.\n\n"); fprintf (fp, "You should have received a copy of the GNU General Public License\n"); } /****************/ /* main routine */ /****************/ int main PARAMS ((argc, argv), int argc _AND_ char **argv) { int semErr; SRC_FILE *srcList = NULL, *tmpLst = NULL; char *file1, *file2; int numSrcFiles; ModuleList *allMods = NULL; Module *currMod; Module **tmpModHndl; int currArg; int printModuleFlag = FALSE; /* default: Don't print */ int genTypeTbls = 0; /* default: Don't gen tbls */ char *tblFileName=NULL; int encRulesSet = FALSE; int genTypeCode = FALSE; int genEncodeCode = FALSE; int genDecodeCode = FALSE; int genPrintCode = FALSE; int genValueCode = FALSE; int genFreeCode = FALSE; #if META MetaNameStyle genMetaCode = META_off; MetaPDU *meta_pdus = NULL; #if TCL int genTclCode = FALSE; #endif #endif int genCCode = FALSE; /* defaults to C if neither specified */ int genCxxCode = FALSE; int genIDLCode = FALSE; long longJmpVal = -100; int novolatilefuncs = FALSE; char* dirName; /* REN -- 6/2/03 -- added */ char* errFileName; /* REN -- 7/7/03 -- added */ if (argc <= 1) { Usage (argv[0], stderr); return 1; } errFileG = stderr; srcList = NULL; /* * parse cmd line args */ numSrcFiles = 0; for (currArg = 1; (currArg < argc); ) { if ((argv[currArg][0] == '-') && (argv[currArg][1] != '\0')) { switch (argv[currArg][1]) { case 'h': Usage (argv[0], stdout); return 0; break; case 'M': // Deepak: 24/Mar/2003 isSyntax1997 = 0; isTableConstraintAllowed = 0; currArg++; break; case 'a': /* AnyID start value */ if (argv[currArg][2] != '\0') /* no space after -a */ { anyEnumValG = atoi (&argv[currArg][2]); currArg++; } else { anyEnumValG = atoi (argv[currArg+1]); currArg += 2; } break; case 'I': if (argv[currArg][2] != '\0') dirName = &argv[currArg][2]; else dirName = argv[++currArg]; // Add or append the files if ((Add2SrcList(&srcList, dirName, TRUE)) == -1) { fprintf (stderr, "%s: ERROR---Unknown ASN Import Directory -I", dirName); Usage (argv[0], stderr); return 1; } currArg++; break; case 'P': printModuleFlag = TRUE; currArg++; break; case 'v': genValueCode = TRUE; currArg++; break; #if IDL case 'i': if (!strcmp (argv[currArg]+1, "idl")) { genIDLCode = TRUE; currArg++; } else goto error; break; #endif case 't': if (!strcmp (argv[currArg]+1, "tcl")) { #if TCL meta_pdus = parse_type_list (argv[++currArg]); genTclCode = TRUE; if (!genMetaCode) genMetaCode = META_backend_names; genCxxCode = TRUE; #else goto error; #endif } else genTypeCode = TRUE; currArg++; break; case 'e': genEncodeCode = TRUE; currArg++; break; case 'd': genDecodeCode = TRUE; currArg++; break; case 'p': genPrintCode = TRUE; currArg++; break; case 'f': genFreeCode = TRUE; currArg++; break; case 'C': /* produce C++ code */ genCxxCode = TRUE; currArg++; break; case 'b': /* produce per code */ genPERCode = TRUE; currArg++; break; case 'n': if (!strcmp (argv[currArg], "nons")) { currArg++; gNO_NAMESPACE=1; } else if(!strncmp(argv[currArg], "-ns", 3)) { gAlternateNamespaceString = &argv[currArg][4]; currArg+=2; } else if (!strcmp (argv[currArg]+1, "novolat")) { novolatilefuncs = TRUE; currArg++; } else goto error; break; case 'c': genCCode = TRUE; currArg++; break; case 'l': if (argv[currArg][2] != '\0') /* no space after -l */ { longJmpVal = atoi (&argv[currArg][2]); currArg++; } else { longJmpVal = atoi (argv[currArg+1]); currArg += 2; } break; case 'T': case 'O': genTypeTbls = argv[currArg][1]=='T'?2:1; if (argv[currArg][2] != '\0') /* no space after -T */ { tblFileName = &argv[currArg][2]; currArg++; } else { tblFileName = argv[currArg+1]; currArg += 2; } break; case 'E': if (currArg + 1 == argc) { fprintf (errFileG, "%s: ERROR---encoding rule missing after -E\n", argv[0]); Usage(argv[0], stdout); return 1; } /* Select encoding rules */ if (strcmp(argv[currArg+1], "BER") == 0) { AddEncRules(BER); encRulesSet = TRUE; currArg+=2; } else if (strcmp(argv[currArg+1], "DER") == 0) { AddEncRules(DER); encRulesSet = TRUE; currArg+=2; } else { fprintf (errFileG, "%s: ERROR---no such encoding rule \"%s\". Try BER or DER\n", argv[0], argv[currArg+1]); Usage(argv[0], stdout); return 1; } break; case 'V': if (!strncmp (argv[currArg]+1, "VDAexport", strlen("VDAexport"))) { if (strlen(argv[currArg]+1) > strlen("VDAexport")) bVDAGlobalDLLExport = strdup(argv[currArg]+1+ strlen("VDAexport")+1); //TRUE else // Default a definition for SFL. bVDAGlobalDLLExport = "VDASNACCDLL_API"; currArg++; break; } else currArg++; // IGNORE the "-V" option. break; case 'L': if (errFileG != NULL) { fprintf (stderr, "ERROR---Multiple occurrences of error log file option -L"); Usage (argv[0], stderr); return 1; } if (argv[currArg][2] != '\0') errFileName = &argv[currArg][2]; else errFileName = argv[++currArg]; /* Open the error log file */ errFileG = fopen(errFileName, "wt"); if (errFileG == NULL) { fprintf (stderr, "ERROR---Unable to open error log file: \'%s\'\n", errFileName); return 1; } currArg++; break; case 'y': /*RWC;yydebug = 1;*/ currArg++; break; case 'm': if (argv[currArg][2] == 'f') { if (argv[currArg][3] != '\0') /* no space after -mf */ { maxFileNameLenG = atoi (&argv[currArg][3]); currArg++; } else { maxFileNameLenG = atoi (argv[currArg+1]); currArg += 2; } break; } #if META else if (!strcmp (argv[currArg]+1, "meta")) { meta_pdus = parse_type_list (argv[++currArg]); if (!genMetaCode) genMetaCode = META_backend_names; genCxxCode = TRUE; currArg++; break; } else if (!strcmp (argv[currArg]+1, "mA")) { genMetaCode = META_asn1_names; genCxxCode = TRUE; currArg++; break; } else if (!strcmp (argv[currArg]+1, "mC")) { genMetaCode = META_backend_names; genCxxCode = TRUE; currArg++; break; } #endif else if (argv[currArg][2] == 'm') { keepbaseG = FALSE; currArg++; break; } else if (argv[currArg][2] == 'o') { const char *outDirectory = NULL; if (argv[currArg][3] != '\0') outDirectory = &argv[currArg][2]; else outDirectory = argv[++currArg]; if (outDirectory == NULL) { fprintf (stderr, "-mo Argument '' missing.\n"); return 1; } StoreOutputDirectory(outDirectory); currArg++; break; } error: default: fprintf (stderr, "%s: ERROR---unknown cmd line option `%s'\n\n", argv[0], argv[currArg]); Usage (argv[0], stderr); return 1; } } else /* asn1srcFileName */ { numSrcFiles++; file1 = sbasename(argv[currArg]); Add2SrcList(&srcList, argv[currArg], FALSE); currArg++; while (tmpLst != NULL) { if (tmpLst->fileName != NULL) { file2 = sbasename(tmpLst->fileName); if (strstr (file1, file2)) { free(tmpLst->fileName); tmpLst->fileName = NULL; } } tmpLst = tmpLst->next; } } } /* end of for loop */ if (numSrcFiles == 0) { fprintf (stderr, "%s: ERROR---no ASN.1 source files were specified\n", argv[0]); Usage (argv[0], stderr); return 1; } /* * set default options */ if (!(genTypeCode || genValueCode || genEncodeCode || genDecodeCode || genFreeCode || genPrintCode)) { genTypeCode = TRUE; genValueCode = TRUE; genEncodeCode = TRUE; genDecodeCode = TRUE; genFreeCode = TRUE; genPrintCode = TRUE; } else if (genCCode + genCxxCode + genTypeTbls + genIDLCode > 1) { fprintf (stderr, "%s: ERROR---Choose only one of the -c -C or -T options\n", argv[0]); Usage (argv[0], stderr); return 1; } if (!genCCode && !genCxxCode && !genTypeTbls && !genIDLCode) genCCode = TRUE; /* default to C if neither specified */ /* Set the encoding rules to BER if not set */ if (!encRulesSet) AddEncRules(BER); /* * STEP 1---parse each ASN.1 src file */ allMods = (ModuleList *)AsnListNew (sizeof (void*)); tmpLst = srcList; while (tmpLst != NULL) { // Only do if not NULL if (tmpLst->fileName) { currMod = ParseAsn1File (tmpLst->fileName, tmpLst->ImportFileFlag); if (currMod == NULL) { return 1; } /* * insert this module at the head of the list * of already parsed (if any) modules */ tmpModHndl = (Module **)AsnListAppend (allMods); *tmpModHndl = currMod; } tmpLst = tmpLst->next; } /* end per src file for loop */ /* * Check that the module names/oids are unique */ if (!ModNamesUnique (allMods)) { fprintf (errFileG, "\nConflicting module names, cannot proceed.\n"); return 1; } /* * STEP 2 * Now that all files have been parsed, * link local and locatable import type refs */ if (LinkTypeRefs (allMods) < 0) { fprintf (errFileG, "\nType linking errors---cannot proceed\n"); return 2; } /* * STEP 3 * Parse constructed values now that types are all parsed * and have been linked. Need type info to be able to * parse values easily (elimitate ambiguity). */ FOR_EACH_LIST_ELMT (currMod, allMods) { if (ParseValues (allMods, currMod) != 0) fprintf (errFileG, "WARNING: Value parsing error (s), attempting to continue\n"); } /* * STEP 4 * Value parsing may have defined some new values * so can link local and locatable import value refs now. */ if (LinkValueRefs (allMods) < 0) { fprintf (errFileG, "\nValue linking errors---cannot proceed\n"); return 4; } /* * STEP 5 * process macros * - adding type/value defs as nec * - mark type defs with ANY DEFINED BY id if nec * so they are put in the id to ANY type hash tbl. */ semErr = 0; FOR_EACH_LIST_ELMT (currMod, allMods) { // For Macors, New TypeDefs are added here, if required ProcessMacros (currMod); if (currMod->status == MOD_ERROR) semErr = 1; } if (semErr) return 5; /* * STEP 6 * convert silly type constructs into * a normal format, leaving behind pure type/value info * eg: expand COMPONENTS OF refs, SELECTION types. * boil down values into simplest rep. (eg OID -> ENC_OID) */ semErr = 0; FOR_EACH_LIST_ELMT (currMod, allMods) { // New TypeDefs are added here, if required NormalizeModule (currMod); if (currMod->status == MOD_ERROR) semErr = 1; } if (semErr) return 6; /* * STEP 7 * Mark recusive types. Currently the recursive information is * not used elsewhere. */ FOR_EACH_LIST_ELMT (currMod, allMods) { MarkRecursiveTypes (currMod); } /* * STEP 8 * Check for errors in the ASN.1 modules. * Check all modules and exit if errors were found */ semErr = 0; FOR_EACH_LIST_ELMT (currMod, allMods) { ErrChkModule (currMod); if (currMod->status == MOD_ERROR) semErr = 1; } if (semErr) return 8; /* * exit if any sundry errors occurred at any point. * smallErrG is set upon finding small errors that prevent code * production but should not affect the other processing/error * checking steps. This allows full display of errors. */ if (smallErrG) { /* * for debugging show "parsed" version of ASN.1 module if * the print flag is set. * Dumps each module to stdout. Printed from Module data struct * print here before exiting otherwise print after sorting */ if (printModuleFlag) { FOR_EACH_LIST_ELMT (currMod, allMods) { printf ("\n\n"); PrintModule (stdout, currMod); } } return 8; } /* * STEP 9 * Make C/C++ typenames/routine names for enc/decode. * Type/Value renaming will occur if name conflicts * arise between modules. * * NOTE: this is done before sorting the types because * the type sorting routine may use the 'isPtr' * information to help order knots of recursive types. */ if (genCCode) FillCTypeInfo (&cRulesG, allMods); else if (genCxxCode) FillCxxTypeInfo (&cxxRulesG, allMods); #if IDL else if (genIDLCode) FillIDLTypeInfo (&idlRulesG, allMods); #endif /* * STEP 10 * Sort each typedef list such that independent types are * before the types that depend on them * * modules remain in same order as given on command line * (cmd line file order should be * least dependent module-> most dependent module * so that include file order in generated src is correct) */ SortAllDependencies (allMods); /* * for debugging show "parsed" version of ASN.1 module. * dumps each module to stdout. Printed from Module data struct * Shows the results of normalization and sorting. */ if (printModuleFlag) { FOR_EACH_LIST_ELMT (currMod, allMods) { printf ("\n\n"); PrintModule (stdout, currMod); } } /* * Step 12 * Final Step: Code/Type Table generation */ if (genCCode) GenCCode (allMods, longJmpVal, genTypeCode, genValueCode, genEncodeCode, genDecodeCode, genPrintCode, genFreeCode); else if (genCxxCode) GenCxxCode (allMods, longJmpVal, genTypeCode, genValueCode, genEncodeCode, genDecodeCode, genPrintCode, genFreeCode, if_META (genMetaCode COMMA meta_pdus COMMA) if_TCL (genTclCode COMMA) novolatilefuncs); else if (genTypeTbls) GenTypeTbls (allMods, tblFileName, genTypeTbls); #if IDL else if (genIDLCode) GenIDLCode (allMods, longJmpVal, genTypeCode, genValueCode, genPrintCode, genFreeCode); #endif tmpLst = srcList; while(tmpLst) { SRC_FILE *tmp; free(tmpLst->fileName); tmp = tmpLst; tmpLst = tmpLst->next; free(tmp); } free(allMods); return 0; } /* end main */ #if META MetaPDU *parse_type_list PARAMS ((arg), char *arg) { MetaPDU *meta_pdus = NULL; char *module; for (module = strtok (arg, ".:"); module; module = strtok (NULL, ".:")) { MetaPDU *pdu = MT (MetaPDU); char *type = strtok (NULL, " /,;"); if (!type) { fprintf (errFileG, "usage: {-meta|-tcl} module.type[,module.type[...]]\n"); return (1); } pdu->module = module; pdu->type = type; pdu->used = FALSE; pdu->next = meta_pdus; meta_pdus = pdu; } return meta_pdus; } #endif /* META */ /* * Calls the yacc/lex parser given a the ASN.1 src file's filename. * Returns a Module *for the given ASN.1 module. If the filename is * "-" stdin is used. */ Module * ParseAsn1File PARAMS ((fileName, ImportFlag), char *fileName _AND_ short ImportFlag) { FILE *fPtr; Module *retVal; int parseResult; /* * Open input file for lexical analyzer/parser * Use stdin if the filename is "-" */ if (strcmp (fileName, "-") == 0) { if (keepbaseG) { fprintf (errFileG, "ERROR---asn1 src file `%s' cannot be processed without output filename mangling\n", fileName); return NULL; } else fPtr = stdin; } else { fPtr = fopen (fileName, "r"); if (fPtr == NULL) { perror ("fopen: "); fprintf (errFileG, "ERROR---asn1 src file `%s' cannot be opened for reading\n", fileName); return NULL; } } retVal = (Module *)Malloc (sizeof (Module)); /* * Init Parser by giving it a ptr to the Module data struct * to initialize/use, and the file name associtated with * the given FILE *, fPtr (for error reporting). * fPtr should be an opened FILE *to an ASN.1 source FILE */ InitAsn1Parser (retVal, fileName, fPtr); /* * parse the current asn1 src file into the * Module data struct */ parseResult = yyparse(); if (parseResult != 0 || retVal->status == MOD_ERROR) { /* parser will print exact err msg */ fprintf (errFileG, "\nParsing errors---cannot proceed\n"); return NULL; } if (fPtr != stdin) fclose (fPtr); retVal->ImportedFlag = (unsigned char)ImportFlag; return retVal; } /* ParseAsn1File */ /* * Given the list of parsed, linked, normalized, error-checked and sorted * modules, and some code generation flags, generates C code and * writes it to files derived from each modules name. Each module * gets 2 source files, one .h for data struct and prototypes, the other .c * for the enc/dec/print/free routine code. */ int GenCCode PARAMS ((allMods, longJmpVal, genTypes, genValues, genEncoders, genDecoders, genPrinters, genFree), ModuleList *allMods _AND_ long longJmpVal _AND_ int genTypes _AND_ int genValues _AND_ int genEncoders _AND_ int genDecoders _AND_ int genPrinters _AND_ int genFree) { Module *currMod; char *modBaseFileName; FILE *cHdrFilePtr = NULL; FILE *cSrcFilePtr = NULL; DefinedObj *fNames; int fNameConflict = FALSE; /* * Make names for each module's encoder/decoder src and hdr files * so import references can be made via include files. * If file names conflict, print error msg & exit. */ fNames = NewObjList(); FOR_EACH_LIST_ELMT (currMod, allMods) { modBaseFileName = MakeBaseFileName (keepbaseG ? currMod->asn1SrcFileName : currMod->modId->name); /* shorten module name if necessary (SYSV etc) */ currMod->cHdrFileName = MakeCHdrFileName (modBaseFileName); currMod->cSrcFileName = MakeCSrcFileName (modBaseFileName); if (ObjIsDefined (fNames, currMod->cHdrFileName, StrObjCmp) || ObjIsDefined (fNames, currMod->cSrcFileName, StrObjCmp)) { fprintf (errFileG, "Ack! ERROR---file name conflict for generated source files with names `%s' and `%s'.\n\n", currMod->cHdrFileName, currMod->cSrcFileName); fprintf (errFileG, "This usually means the max file name length is truncating the file names.\n"); fprintf (errFileG, "Try re-naming the modules with shorter names or increasing the argument to -mf option (if you are using it).\n"); fprintf (errFileG, "This error can also be caused by 2 modules with the same names but different OBJECT IDENTIFIERs."); fprintf (errFileG, " Try renaming the modules to correct this.\n"); fNameConflict = TRUE; } else { DefineObj (&fNames, currMod->cHdrFileName); DefineObj (&fNames, currMod->cSrcFileName); } Free (modBaseFileName); } if (fNameConflict) return (1); FreeDefinedObjs (&fNames); /* * make c files */ FOR_EACH_LIST_ELMT (currMod, allMods) { if (currMod->ImportedFlag == FALSE) { cHdrFilePtr = fopen (currMod->cHdrFileName, "w"); cSrcFilePtr = fopen (currMod->cSrcFileName, "w"); } if ((currMod->ImportedFlag == FALSE) && ((cSrcFilePtr == NULL) || (cHdrFilePtr == NULL))) perror ("fopen"); else { if (currMod->ImportedFlag == FALSE) { PrintCCode (cSrcFilePtr, cHdrFilePtr, allMods, currMod, &cRulesG, longJmpVal, genTypes, genValues, genEncoders, genDecoders, genPrinters, genFree); } } if (cSrcFilePtr) { fclose (cSrcFilePtr); cSrcFilePtr = NULL; } if (cHdrFilePtr) { fclose (cHdrFilePtr); cHdrFilePtr = NULL; } } return 0; } /* GenCCode */ /* * Given the list of parsed, linked, normalized, error-checked and sorted * modules, and some code generation flags, generates C++ code and * writes it to files derived from each modules name. Each module * gets 2 source files, one .h for data struct and prototypes, the other .C * for the enc/dec/print/free routine code. */ void GenCxxCode PARAMS ((allMods, longJmpVal, genTypes, genValues, genEncoders, genDecoders, genPrinters, genFree, if_META (genMeta COMMA meta_pdus COMMA) if_TCL (genTcl COMMA) novolatilefuncs), ModuleList *allMods _AND_ long longJmpVal _AND_ int genTypes _AND_ int genValues _AND_ int genEncoders _AND_ int genDecoders _AND_ int genPrinters _AND_ int genFree _AND_ if_META (MetaNameStyle genMeta _AND_) if_META (MetaPDU *meta_pdus _AND_) if_TCL (int genTcl _AND_) int novolatilefuncs) { Module *currMod; AsnListNode *saveMods; char *modBaseFileName; FILE *hdrFilePtr; FILE *srcFilePtr; DefinedObj *fNames; int fNameConflict = FALSE; #if META static const char metabasefn[] = "modules"; Meta meta; #if TCL const MetaPDU *pdu; #endif #endif /* * Make names for each module's encoder/decoder src and hdr files * so import references can be made via include files * check for truncation --> name conflicts & exit if nec */ fNames = NewObjList(); #if META if (genMeta) DefineObj (&fNames, meta.srcfn = MakeCxxSrcFileName (metabasefn)); #endif FOR_EACH_LIST_ELMT (currMod, allMods) { modBaseFileName = MakeBaseFileName (keepbaseG ? currMod->asn1SrcFileName : currMod->modId->name); /* shorten module name if necessary (SYSV etc) */ currMod->cxxHdrFileName = MakeCxxHdrFileName (modBaseFileName); currMod->cxxSrcFileName = MakeCxxSrcFileName (modBaseFileName); #if META { char *in, *out; out = currMod->cxxname = (char *)malloc (strlen (in = currMod->modId->name)+1); do *out++ = *in == '-' ? '_' : *in; while (*in++); } #endif if (ObjIsDefined (fNames, currMod->cxxHdrFileName, StrObjCmp) || ObjIsDefined (fNames, currMod->cxxSrcFileName, StrObjCmp)) { fprintf (errFileG, "Ack! ERROR---file name conflict for generated source files with names `%s' and `%s'.\n\n", currMod->cxxHdrFileName, currMod->cxxSrcFileName); fprintf (errFileG, "This usually means the max file name length is truncating the file names.\n"); fprintf (errFileG, "Try re-naming the modules with shorter names or increasing the argument to -mf option (if you are using it).\n"); fprintf (errFileG, "This error can also be caused by 2 modules have the same names but different OBJECT IDENTIFIERs."); fprintf (errFileG, " Try renaming the modules to correct this.\n"); fNameConflict = TRUE; } else { DefineObj (&fNames, currMod->cxxHdrFileName); DefineObj (&fNames, currMod->cxxSrcFileName); } Free (modBaseFileName); if (fNameConflict) return; FreeDefinedObjs (&fNames); /* * make C++ files */ #if META if (genMeta) { time_t now = time (NULL); if (!(meta.srcfp = fopen (meta.srcfn, "w"))) { perror ("fopen"); exit (1); } fprintf (meta.srcfp, "// NOTE: this is a machine generated file--editing not recommended\n"); fprintf (meta.srcfp, "//\n"); fprintf (meta.srcfp, "// modules.C - reference to all modules and their types\n"); fprintf (meta.srcfp, "//\n"); fprintf (meta.srcfp, "// This file was generated by snacc on %s", ctime (&now)); } #endif } FOR_EACH_LIST_ELMT (currMod, allMods) { if (currMod->ImportedFlag == FALSE) { /* * create and fill .h file for module's data structs */ hdrFilePtr = fopen (currMod->cxxHdrFileName, "wt"); srcFilePtr = fopen (currMod->cxxSrcFileName, "wt"); if ((hdrFilePtr == NULL) || (srcFilePtr == NULL)) { perror ("fopen"); } else { saveMods = allMods->curr; PrintCxxCode (srcFilePtr, hdrFilePtr, if_META (genMeta COMMA &meta COMMA meta_pdus COMMA) allMods, currMod, &cxxRulesG, longJmpVal, genTypes, genValues, genEncoders, genDecoders, genPrinters, genFree, if_TCL (genTcl COMMA) novolatilefuncs); allMods->curr = saveMods; fclose (hdrFilePtr); fclose (srcFilePtr); } #if META if (genMeta) { fprintf (meta.srcfp, "\n"); fprintf (meta.srcfp, "#ifndef META\n"); fprintf (meta.srcfp, "#define META 1\n"); fprintf (meta.srcfp, "#endif\n"); if (meta_pdus) { for (pdu=meta_pdus; pdu; pdu=pdu->next) if (!pdu->used) fprintf (errFileG, "warning: PDU %s.%s couldn't be found\n", pdu->module, pdu->type); } #if TCL fprintf (meta.srcfp, "#ifndef TCL\n"); fprintf (meta.srcfp, "#define TCL META\n"); fprintf (meta.srcfp, "#endif\n"); } #endif fprintf (meta.srcfp, "\n"); fprintf (meta.srcfp, "#include \"asn-incl.h\"\n"); FOR_EACH_LIST_ELMT (currMod, allMods) fprintf (meta.srcfp, "#include \"%s\"\n", currMod->cxxHdrFileName); fprintf (meta.srcfp, "\n"); fprintf (meta.srcfp, "#if META\n\n"); fprintf (meta.srcfp, "const AsnModuleDesc *asnModuleDescs[] =\n"); fprintf (meta.srcfp, "{\n"); FOR_EACH_LIST_ELMT (currMod, allMods) fprintf (meta.srcfp, " &%sModuleDesc,\n", currMod->cxxname); fprintf (meta.srcfp, " NULL\n"); fprintf (meta.srcfp, "};\n\n"); if (genTcl) { fprintf (meta.srcfp, "#if TCL\n\n"); fprintf (meta.srcfp, "// hack to avoid the neccessity to list -ltk -ltcl both before and after -lasn1tcl:\n"); fprintf (meta.srcfp, "static int (*dummy)(Tcl_Interp *) = Tcl_AppInit;\n\n"); fprintf (meta.srcfp, "#endif // TCL\n\n"); } fprintf (meta.srcfp, "#endif // META\n"); fclose (meta.srcfp); #endif } } } /* GenCxxCode */ #if IDL /* * Given the list of parsed, linked, normalized, error-checked and sorted * modules, and some code generation flags, generates C++ code and * writes it to files derived from each modules name. Each module * gets 2 source files, one .h for data struct and prototypes, the other .C * for the enc/dec/print/free routine code. */ void GenIDLCode PARAMS ((allMods, longJmpVal, genTypes, genValues, genPrinters, genFree), ModuleList *allMods _AND_ long longJmpVal _AND_ int genTypes _AND_ int genValues _AND_ int genPrinters _AND_ int genFree) { Module *currMod; char *modBaseFileName; FILE *idlFilePtr; DefinedObj *fNames; int fNameConflict = FALSE; /* * Make names for each module's encoder/decoder src and hdr files * so import references can be made via include files * check for truncation --> name conflicts & exit if nec */ fNames = NewObjList(); FOR_EACH_LIST_ELMT (currMod, allMods) { modBaseFileName = MakeBaseFileName (keepbaseG ? currMod->asn1SrcFileName : currMod->modId->name); /* shorten module name if necessary (SYSV etc) */ currMod->idlFileName = MakeIDLFileName (modBaseFileName); { char *in, *out; out = currMod->idlname = (char *)malloc (strlen (in = currMod->modId->name)+1); do *out++ = (char)(*in == '-' ? '_' : *in); while (*in++); } if (ObjIsDefined (fNames, currMod->idlFileName, StrObjCmp)) { fprintf (errFileG, "Ack! ERROR---file name conflict for generated source file with name `%s'.\n\n", currMod->idlFileName); fprintf (errFileG, "This usually means the max file name length is truncating the file names.\n"); fprintf (errFileG, "Try re-naming the modules with shorter names or increasing the argument to -mf option (if you are using it).\n"); fprintf (errFileG, "This error can also be caused by 2 modules have the same names but different OBJECT IDENTIFIERs."); fprintf (errFileG, " Try renaming the modules to correct this.\n"); fNameConflict = TRUE; } else { DefineObj (&fNames, currMod->idlFileName); } Free (modBaseFileName); } if (fNameConflict) return; FreeDefinedObjs (&fNames); /* * make C++ files */ FOR_EACH_LIST_ELMT (currMod, allMods) { /* * create and fill .h file for module's data structs */ idlFilePtr = fopen (currMod->idlFileName, "w"); if (idlFilePtr == NULL) perror ("fopen"); else { PrintIDLCode (idlFilePtr, allMods, currMod, &idlRulesG, longJmpVal, genValues); fclose (idlFilePtr); } } genFree = genFree; genPrinters = genPrinters; genTypes = genTypes; /* AVOIDS warnings. */ } /* GenIDLCode */ #endif /* IDL */ /* * returns 1 if the module names and oid's are unique. * otherwise returns 0 */ int ModNamesUnique PARAMS ((mods), ModuleList *mods) { DefinedObj *names; DefinedObj *oids; Module *m; int retVal = 1; names = NewObjList(); oids = NewObjList(); FOR_EACH_LIST_ELMT (m, mods) { m->ImportUsed = FALSE; if (((m->modId->oid != NULL) && ObjIsDefined (oids, m->modId->oid, OidObjCmp))) { /* oops, 2 modules have the same oid */ PrintErrLoc (m->asn1SrcFileName, (long)1); fprintf (errFileG, "ERROR---2 modules have the OBJECT IDENTIFIER `"); PrintOid (stdout, m->modId->oid); fprintf (errFileG, "'.\n"); retVal = 0; } /* name is only signficant if oid is empty */ else if ((m->modId->oid == NULL) && (ObjIsDefined (names, m->modId->name, StrObjCmp))) { /* oops, 2 modules have the same name */ PrintErrLoc (m->asn1SrcFileName, (long)1); fprintf (errFileG, "ERROR---2 modules have the name `%s'\n", m->modId->name); retVal = 0; } else { // Add in the Imported File DefineObj (&names, m->modId->name); if (m->modId->oid != NULL) DefineObj (&oids, m->modId->oid); } } FreeDefinedObjs (&names); FreeDefinedObjs (&oids); return retVal; } /* ModNamesUnique */ /* * FileList is the linked list of files * InputFile is used only for snacc command line files * ImportFlag is set to true signifies a Imported file if * false then the file is a command line file */ short Add2SrcList(SRC_FILE **FileList, const char *InputFile, short ImportFlag) { static const char* gAsnExt = "asn1"; GFSI_HANDLE gfsi_handle = NULL; char *fileName = NULL; char *fullPath; SRC_FILE *tmpList; SRC_FILE *prev; short err = -1; /* Find the last file in the list */ prev = *FileList; while ((prev != NULL) && (prev->next != NULL)) prev = prev->next; if (ImportFlag) { /* Loop through the files in the specified directory and process each file with the proper extension. */ fileName = GFSI_GetFirstFile(&gfsi_handle, InputFile, gAsnExt); while (fileName != NULL) { size_t fullPathLen = strlen(InputFile)+strlen(fileName)+2; /* Alloc 2 extra bytes below - 1 for null byte, and 1 for the / which needs to be inserted in the middle */ fullPath = (char *)calloc(fullPathLen, sizeof(char)); /* Build the full path to the file */ snacc_snprintf(fullPath, fullPathLen, "%s/%s", InputFile, fileName); /* Check if this file is already present */ err = compareDupeFile(fullPath, *FileList); if (err < 0) { fprintf (stderr, "W:Duplicate include import file reference" " %s, using first reference \n", fullPath); } else if (err == 0) { /* Add this file to the list */ tmpList = (SRC_FILE*)Malloc(sizeof(SRC_FILE)); if (prev == NULL) *FileList = tmpList; else prev->next = tmpList; prev = tmpList; tmpList->fileName = strdup(fullPath); tmpList->ImportFileFlag = ImportFlag; } fileName = GFSI_GetNextFile(&gfsi_handle, gAsnExt); err = 0; free(fullPath); fullPath = 0; } GFSI_Close(&gfsi_handle); free(fileName); } else { /* File name specified on command line */ err = 0; if (*FileList) { /* Check if this file is already present */ err = compareDupeFile(InputFile, *FileList); } if (err < 0) { fprintf(errFileG, "W: Duplicate file %s specified.\n", InputFile); err = 0; } else { /* Add to head of the list */ tmpList = (SRC_FILE*)Malloc(sizeof(SRC_FILE)); tmpList->ImportFileFlag = ImportFlag; tmpList->fileName = strdup(InputFile); tmpList->next = *FileList; *FileList = tmpList; } } return err; } char *sbasename (char *name) { char *base; #ifdef WIN32 /* Skip over the disk name in MSDOS pathnames. */ if (isalpha (name[0]) && name[1] == ':') name += 2; #endif for (base = name; *name; name++) { if ((name[0] == '/') || (name[0] == '\\')) { base = name + 1; } } return (char *) base; } short compareDupeFile(const char *fullpath, SRC_FILE *FileList) { SRC_FILE *tmplist = FileList; char* file1 = sbasename((char*)fullpath); char *file2; while (tmplist != NULL) { if (tmplist->fileName != NULL) { file2 = sbasename (tmplist->fileName); if (strstr (file1, file2) != NULL) { if (tmplist->ImportFileFlag) return -1; else return 1; } } tmplist = tmplist->next; } return 0; } esnacc-ng-1.8.1/compiler/core/tbl.c000066400000000000000000000215521302010526100170410ustar00rootroot00000000000000/* * tbl.c * * "TBL" ASN.1 module encode/decode/print/free C src. * * This file was generated by snacc on Tue Jul 17 12:14:00 2001 * * UBC snacc written by Mike Sample * * NOTE: This is a machine generated file - editing not recommended */ #include "asn-incl.h" #include "tbl.h" AsnLen BEncTBLTypeRefContent PARAMS ((b, v), GenBuf *b _AND_ TBLTypeRef *v) { AsnLen totalLen = 0; AsnLen itemLen; itemLen = BEncAsnBoolContent (b, (&v->implicit)); BEncDefLenTo127 (b, itemLen); itemLen++; itemLen += BEncTag1 (b, UNIV, PRIM, BOOLEAN_TAG_CODE); totalLen += itemLen; itemLen = BEncTBLTypeDefIdContent (b, (&v->typeDef)); BEncDefLenTo127 (b, itemLen); itemLen++; itemLen += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE); totalLen += itemLen; return totalLen; } /* BEncTBLTypeRefContent */ AsnLen BEncTBLTagContent PARAMS ((b, v), GenBuf *b _AND_ TBLTag *v) { AsnLen totalLen = 0; AsnLen itemLen; itemLen = BEncAsnIntContent (b, (&v->code)); BEncDefLenTo127 (b, itemLen); itemLen++; itemLen += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE); totalLen += itemLen; itemLen = BEncTBLTagClassContent (b, (&v->tclass)); BEncDefLenTo127 (b, itemLen); itemLen++; itemLen += BEncTag1 (b, UNIV, PRIM, ENUM_TAG_CODE); totalLen += itemLen; return totalLen; } /* BEncTBLTagContent */ AsnLen BEncTBLTypeSeqOfContent PARAMS ((b, v), GenBuf *b _AND_ TBLTypeSeqOf *v) { AsnLen itemLen; AsnLen listLen; void *component; listLen = 0; FOR_EACH_LIST_ELMT_RVS (component, v) { BEncEocIfNec (b); itemLen = BEncTBLTagContent (b, component); itemLen += BEncConsLen (b, itemLen); itemLen += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE); listLen += itemLen; } return listLen; } /* BEncTBLTypeSeqOfContent */ AsnLen BEncTBLTypeContentSeqOfContent PARAMS ((b, v), GenBuf *b _AND_ TBLTypeContentSeqOf *v) { AsnLen itemLen; AsnLen listLen; void *component; listLen = 0; FOR_EACH_LIST_ELMT_RVS (component, v) { BEncEocIfNec (b); itemLen = BEncTBLTypeContent (b, component); itemLen += BEncConsLen (b, itemLen); itemLen += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE); listLen += itemLen; } return listLen; } /* BEncTBLTypeContentSeqOfContent */ AsnLen BEncTBLTypeContent PARAMS ((b, v), GenBuf *b _AND_ TBLType *v) { AsnLen totalLen = 0; AsnLen itemLen; if (ASNOCTS_PRESENT ((&v->fieldName))) { itemLen = BEncPrintableStringContent (b, (&v->fieldName)); itemLen += BEncDefLen (b, itemLen); itemLen += BEncTag1 (b, CNTX, PRIM, OCTETSTRING_TAG_CODE); totalLen += itemLen; } BEncEocIfNec (b); itemLen = BEncTBLTypeContentContent (b, (v->content)); itemLen += BEncConsLen (b, itemLen); itemLen += BEncTag1 (b, CNTX, CONS, BITSTRING_TAG_CODE); totalLen += itemLen; if (NOT_NULL ((v->tagList))) { BEncEocIfNec (b); itemLen = BEncTBLTypeSeqOfContent (b, (v->tagList)); itemLen += BEncConsLen (b, itemLen); itemLen += BEncTag1 (b, CNTX, CONS, INTEGER_TAG_CODE); totalLen += itemLen; } itemLen = BEncAsnBoolContent (b, (&v->optional)); BEncDefLenTo127 (b, itemLen); itemLen++; itemLen += BEncTag1 (b, CNTX, PRIM, BOOLEAN_TAG_CODE); totalLen += itemLen; itemLen = BEncTBLTypeIdContent (b, (&v->typeId)); BEncDefLenTo127 (b, itemLen); itemLen++; itemLen += BEncTag1 (b, CNTX, PRIM, 0); totalLen += itemLen; return totalLen; } /* BEncTBLTypeContent */ AsnLen BEncTBLTypeContentContent PARAMS ((b, v), GenBuf *b _AND_ TBLTypeContent *v) { AsnLen totalLen = 0; AsnLen itemLen; switch (v->choiceId) { case TBLTYPECONTENT_PRIMTYPE: itemLen = BEncAsnNullContent (b, (&v->a.primType)); BEncDefLenTo127 (b, itemLen); itemLen++; itemLen += BEncTag1 (b, CNTX, PRIM, 0); totalLen += itemLen; break; case TBLTYPECONTENT_ELMTS: BEncEocIfNec (b); itemLen = BEncTBLTypeContentSeqOfContent (b, (v->a.elmts)); itemLen += BEncConsLen (b, itemLen); itemLen += BEncTag1 (b, CNTX, CONS, BOOLEAN_TAG_CODE); totalLen += itemLen; break; case TBLTYPECONTENT_TYPEREF: BEncEocIfNec (b); itemLen = BEncTBLTypeRefContent (b, (v->a.typeRef)); itemLen += BEncConsLen (b, itemLen); itemLen += BEncTag1 (b, CNTX, CONS, INTEGER_TAG_CODE); totalLen += itemLen; break; } return totalLen; } /* BEncTBLTypeContentContent */ AsnLen BEncTBLTypeDefContent PARAMS ((b, v), GenBuf *b _AND_ TBLTypeDef *v) { AsnLen totalLen = 0; AsnLen itemLen; BEncEocIfNec (b); itemLen = BEncTBLTypeContent (b, (v->type)); itemLen += BEncConsLen (b, itemLen); itemLen += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE); totalLen += itemLen; if (ASNOCTS_PRESENT ((&v->typeName))) { itemLen = BEncPrintableStringContent (b, (&v->typeName)); itemLen += BEncDefLen (b, itemLen); itemLen += BEncTag1 (b, UNIV, PRIM, PRINTABLESTRING_TAG_CODE); totalLen += itemLen; } itemLen = BEncTBLTypeDefIdContent (b, (&v->typeDefId)); BEncDefLenTo127 (b, itemLen); itemLen++; itemLen += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE); totalLen += itemLen; return totalLen; } /* BEncTBLTypeDefContent */ AsnLen BEncTBLModuleSeqOfContent PARAMS ((b, v), GenBuf *b _AND_ TBLModuleSeqOf *v) { AsnLen itemLen; AsnLen listLen; void *component; listLen = 0; FOR_EACH_LIST_ELMT_RVS (component, v) { BEncEocIfNec (b); itemLen = BEncTBLTypeDefContent (b, component); itemLen += BEncConsLen (b, itemLen); itemLen += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE); listLen += itemLen; } return listLen; } /* BEncTBLModuleSeqOfContent */ AsnLen BEncTBLModuleContent PARAMS ((b, v), GenBuf *b _AND_ TBLModule *v) { AsnLen totalLen = 0; AsnLen itemLen; BEncEocIfNec (b); itemLen = BEncTBLModuleSeqOfContent (b, (v->typeDefs)); itemLen += BEncConsLen (b, itemLen); itemLen += BEncTag1 (b, CNTX, CONS, BITSTRING_TAG_CODE); totalLen += itemLen; itemLen = BEncAsnBoolContent (b, (&v->isUseful)); BEncDefLenTo127 (b, itemLen); itemLen++; itemLen += BEncTag1 (b, CNTX, PRIM, INTEGER_TAG_CODE); totalLen += itemLen; if (ASNOID_PRESENT ((&v->id))) { itemLen = BEncAsnOidContent (b, (&v->id)); itemLen += BEncDefLen (b, itemLen); itemLen += BEncTag1 (b, CNTX, PRIM, BOOLEAN_TAG_CODE); totalLen += itemLen; } itemLen = BEncPrintableStringContent (b, (&v->name)); itemLen += BEncDefLen (b, itemLen); itemLen += BEncTag1 (b, CNTX, PRIM, 0); totalLen += itemLen; return totalLen; } /* BEncTBLModuleContent */ AsnLen BEncTBLSeqOfContent PARAMS ((b, v), GenBuf *b _AND_ TBLSeqOf *v) { AsnLen itemLen; AsnLen listLen; void *component; listLen = 0; FOR_EACH_LIST_ELMT_RVS (component, v) { BEncEocIfNec (b); itemLen = BEncTBLModuleContent (b, component); itemLen += BEncConsLen (b, itemLen); itemLen += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE); listLen += itemLen; } return listLen; } /* BEncTBLSeqOfContent */ AsnLen BEncTBL PARAMS ((b, v), GenBuf *b _AND_ TBL *v) { AsnLen l=0; BEncEocIfNec (b); l = BEncTBLContent (b, v); l += BEncConsLen (b, l); l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE); return l; } /* BEncTBL */ AsnLen BEncTBLContent PARAMS ((b, v), GenBuf *b _AND_ TBL *v) { AsnLen totalLen = 0; AsnLen itemLen; BEncEocIfNec (b); itemLen = BEncTBLSeqOfContent (b, (v->modules)); itemLen += BEncConsLen (b, itemLen); itemLen += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE); totalLen += itemLen; itemLen = BEncAsnIntContent (b, (&v->totalLenStrings)); BEncDefLenTo127 (b, itemLen); itemLen++; itemLen += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE); totalLen += itemLen; itemLen = BEncAsnIntContent (b, (&v->totalNumStrings)); BEncDefLenTo127 (b, itemLen); itemLen++; itemLen += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE); totalLen += itemLen; itemLen = BEncAsnIntContent (b, (&v->totalNumTags)); BEncDefLenTo127 (b, itemLen); itemLen++; itemLen += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE); totalLen += itemLen; itemLen = BEncAsnIntContent (b, (&v->totalNumTypes)); BEncDefLenTo127 (b, itemLen); itemLen++; itemLen += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE); totalLen += itemLen; itemLen = BEncAsnIntContent (b, (&v->totalNumTypeDefs)); BEncDefLenTo127 (b, itemLen); itemLen++; itemLen += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE); totalLen += itemLen; itemLen = BEncAsnIntContent (b, (&v->totalNumModules)); BEncDefLenTo127 (b, itemLen); itemLen++; itemLen += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE); totalLen += itemLen; return totalLen; } /* BEncTBLContent */ esnacc-ng-1.8.1/compiler/core/tbl.h000066400000000000000000000104341302010526100170430ustar00rootroot00000000000000/* * tbl.h * * "TBL" ASN.1 module C type definitions and prototypes * * This .h file was generated by snacc on Tue Jul 17 12:14:00 2001 * * UBC snacc written compiler by Mike Sample * * NOTE: This is a machine generated file--editing not recommended */ #ifndef _tbl_h_ #define _tbl_h_ typedef enum { TBL_BOOLEAN = 0, TBL_INTEGER = 1, TBL_BITSTRING = 2, TBL_OCTETSTRING = 3, TBL_NULL = 4, TBL_OID = 5, TBL_REAL = 6, TBL_ENUMERATED = 7, TBL_SEQUENCE = 8, TBL_SET = 9, TBL_SEQUENCEOF = 10, TBL_SETOF = 11, TBL_CHOICE = 12, TBL_TYPEREF = 13, TBL_RELATIVE_OID = 14 } TBLTypeId; /* ENUMERATED { TBL_BOOLEAN (0), TBL_INTEGER (1), TBL_BITSTRING (2), TBL_OCTETSTRING (3), TBL_NULL (4), TBL_OID (5), TBL_REAL (6), TBL_ENUMERATED (7), TBL_SEQUENCE (8), TBL_SET (9), TBL_SEQUENCEOF (10), TBL_SETOF (11), TBL_CHOICE (12), TBL_TYPEREF (13) } */ #define BEncTBLTypeIdContent BEncAsnEnumContent typedef AsnInt TBLTypeDefId; /* INTEGER */ #define BEncTBLTypeDefIdContent BEncAsnIntContent typedef enum { UNIVERSAL = 0, APPLICATION = 1, CONTEXT = 2, PRIVATE = 3 } TBLTagClass; /* ENUMERATED { UNIVERSAL (0), APPLICATION (1), CONTEXT (2), PRIVATE (3) } */ #define BEncTBLTagClassContent BEncAsnEnumContent typedef struct TBLTypeRef /* SEQUENCE */ { TBLTypeDefId typeDef; /* TBLTypeDefId */ AsnBool implicit; /* BOOLEAN */ } TBLTypeRef; AsnLen BEncTBLTypeRefContent PROTO ((GenBuf *b, TBLTypeRef *v)); typedef struct TBLTag /* SEQUENCE */ { TBLTagClass tclass; /* TBLTagClass */ AsnInt code; /* INTEGER (0..MAX) */ } TBLTag; AsnLen BEncTBLTagContent PROTO ((GenBuf *b, TBLTag *v)); typedef AsnList TBLTypeSeqOf; /* SEQUENCE OF TBLTag */ AsnLen BEncTBLTypeSeqOfContent PROTO ((GenBuf *b, TBLTypeSeqOf *v)); typedef AsnList TBLTypeContentSeqOf; /* SEQUENCE OF TBLType */ AsnLen BEncTBLTypeContentSeqOfContent PROTO ((GenBuf *b, TBLTypeContentSeqOf *v)); typedef struct TBLType /* SEQUENCE */ { TBLTypeId typeId; /* [0] IMPLICIT TBLTypeId */ AsnBool optional; /* [1] IMPLICIT BOOLEAN */ TBLTypeSeqOf* tagList; /* [2] IMPLICIT TBLTypeSeqOf OPTIONAL */ struct TBLTypeContent* content; /* [3] TBLTypeContent */ PrintableString fieldName; /* [4] IMPLICIT PrintableString OPTIONAL */ } TBLType; AsnLen BEncTBLTypeContent PROTO ((GenBuf *b, TBLType *v)); typedef struct TBLTypeContent /* CHOICE */ { enum TBLTypeContentChoiceId { TBLTYPECONTENT_PRIMTYPE, TBLTYPECONTENT_ELMTS, TBLTYPECONTENT_TYPEREF } choiceId; union TBLTypeContentChoiceUnion { AsnNull primType; /* [0] IMPLICIT NULL */ TBLTypeContentSeqOf* elmts; /* [1] IMPLICIT TBLTypeContentSeqOf */ struct TBLTypeRef* typeRef; /* [2] IMPLICIT TBLTypeRef */ } a; } TBLTypeContent; AsnLen BEncTBLTypeContentContent PROTO ((GenBuf *b, TBLTypeContent *v)); typedef struct TBLTypeDef /* SEQUENCE */ { TBLTypeDefId typeDefId; /* TBLTypeDefId */ PrintableString typeName; /* PrintableString OPTIONAL */ struct TBLType* type; /* TBLType */ } TBLTypeDef; AsnLen BEncTBLTypeDefContent PROTO ((GenBuf *b, TBLTypeDef *v)); typedef AsnList TBLModuleSeqOf; /* SEQUENCE OF TBLTypeDef */ AsnLen BEncTBLModuleSeqOfContent PROTO ((GenBuf *b, TBLModuleSeqOf *v)); typedef struct TBLModule /* SEQUENCE */ { PrintableString name; /* [0] IMPLICIT PrintableString */ AsnOid id; /* [1] IMPLICIT OBJECT IDENTIFIER OPTIONAL */ AsnBool isUseful; /* [2] IMPLICIT BOOLEAN */ TBLModuleSeqOf* typeDefs; /* [3] IMPLICIT TBLModuleSeqOf */ } TBLModule; AsnLen BEncTBLModuleContent PROTO ((GenBuf *b, TBLModule *v)); typedef AsnList TBLSeqOf; /* SEQUENCE OF TBLModule */ AsnLen BEncTBLSeqOfContent PROTO ((GenBuf *b, TBLSeqOf *v)); typedef struct TBL /* SEQUENCE */ { AsnInt totalNumModules; /* INTEGER */ AsnInt totalNumTypeDefs; /* INTEGER */ AsnInt totalNumTypes; /* INTEGER */ AsnInt totalNumTags; /* INTEGER */ AsnInt totalNumStrings; /* INTEGER */ AsnInt totalLenStrings; /* INTEGER */ TBLSeqOf* modules; /* TBLSeqOf */ } TBL; AsnLen BEncTBL PROTO ((GenBuf *b, TBL *v)); AsnLen BEncTBLContent PROTO ((GenBuf *b, TBL *v)); #endif /* conditional include of tbl.h */ esnacc-ng-1.8.1/compiler/core/val-parser.c000066400000000000000000000504551302010526100203400ustar00rootroot00000000000000/* * compiler/core/val_parser.c * given a string with txt ASN.1 value notation, the length of * the string and the ASN.1 type the value notion defines a value * for, return a Value that contains the internal version * * * currently limited to parsing OBJECT IDENTIFIERs. * should be easy to extend for other values as needed * * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/core/val-parser.c,v 1.10 2004/04/06 15:13:41 gronej Exp $ * $Log: val-parser.c,v $ * Revision 1.10 2004/04/06 15:13:41 gronej * *** empty log message *** * * Revision 1.9 2004/01/14 19:07:53 gronej * Updated Compiler to accept and process relative-oid's * * Revision 1.8 2003/07/14 21:07:44 nicholar * Changed how parser handles --snacc directives. Added namespace option. * * Revision 1.7 2003/07/07 14:50:14 nicholar * Eliminated headers and cleaned up include references * * Revision 1.6 2003/04/29 21:06:37 leonberp * integerated Deepak's changes for IOB support * * Revision 1.5 2002/09/16 18:01:16 mcphersc * fixed warning * * Revision 1.4 2002/09/16 16:50:33 mcphersc * Fixed warnings * * Revision 1.3 2002/09/04 18:31:38 vracarl * got rid of c++ comments * * Revision 1.2 2000/10/24 14:54:55 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:36:02 leonberp * First CVS Version of SNACC. * * Revision 1.4 1997/10/10 13:43:16 wan * Corrected bug in generic table decoder wrt. indefinite length elements * Corrected compiler access to freed memory (bug reported by Markku Savela) * Broke asnwish.c into two pieces so that one can build ones on wish * Added beredit tool (based on asnwish, allowes to edit BER messages) * * Revision 1.3 1995/07/25 19:41:46 rj * changed `_' to `-' in file names. * * Revision 1.2 1994/09/01 00:47:33 rj * snacc_config.h removed; val_parser.h includet. * * Revision 1.1 1994/08/28 09:49:44 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include #include /* for isalpha, isdigit etc macros */ #include "asn-incl.h" #include "asn1module.h" #include "snacc-util.h" int OidArcNameToNum PROTO ((char *name)); /* * a bunch of macros for 'standard' parse routines */ #define P_LOCALS\ char *startStr #define SAVE_POS()\ startStr = *vStr; #define RESTORE_POS()\ *vStr = startStr; #define AT_EOF()\ (*vStr == eof) #define FAIL()\ {\ if (*vStr > farthestPosG)\ farthestPosG = *vStr;\ RESTORE_POS();\ return FALSE;\ } #define SUCCEED()\ return TRUE; #define PRINT_VAL(vd)\ PrintValueDef (errFileG, vd); /* * globals */ static ValueDefList *newValsG; static int parseValuesErrG; static unsigned long valLineNoG; static char *farthestPosG; /* * prototypes for non-exported routines */ char *StripComments PROTO ((char *asn1Str, int len)); Value *ParseValue PROTO ((ModuleList *mods, Module *m, ValueDef *vd, Type *t, char *valueNotation, int len)); Value *ParseValueInternal PROTO ((ModuleList *mods, Module *m, ValueDef *vd, Type *t, char **valueNotation, char *eof)); int ParseOidValue PROTO ((ModuleList *mods, Module *m, ValueDef *vd, Type *t, char **valueNotation, char *eof, Value **result)); void SkipWht PROTO ((char **vStr, char *eof)); int ParseIdentifier PROTO ((char **valueNotation, char *eof, char **result)); int ParseNum PROTO ((char **valueNotation, char *eof, char **result)); void AddNewValueDef PROTO ((ValueDefList *vdl, char *name, Value *value)); /* * returns 0 if no parse errors occurred * otherwise returns non-zero */ int ParseValues PARAMS ((mods, m), ModuleList *mods _AND_ Module *m) { ValueDef *v; Value *pv; newValsG = AsnListNew (sizeof (void*)); FOR_EACH_LIST_ELMT (v, m->valueDefs) { if (v->value->basicValue->choiceId == BASICVALUE_VALUENOTATION) { valLineNoG = v->value->lineNo; pv = ParseValue (mods, m, v, v->value->type, v->value->basicValue->a.valueNotation->octs, v->value->basicValue->a.valueNotation->octetLen); /* replace value notation value with parsed version */ if (pv != NULL) { pv->lineNo = v->value->lineNo; pv->type = v->value->type; Free (v->value->basicValue->a.valueNotation->octs); Free (v->value->basicValue->a.valueNotation); Free (v->value->basicValue); Free (v->value); v->value = pv; } } } /* * should traverse type structures for default values etc * that need parsing */ /* add any new value defs */ m->valueDefs = AsnListConcat (m->valueDefs, newValsG); Free (newValsG); return parseValuesErrG; } /* ParseValues */ /* * returns the Value that resuls from parsing the given * value notation string */ Value* ParseValue PARAMS ((mods, m, vd, t, valueNotationStr, vnLen), ModuleList *mods _AND_ Module *m _AND_ ValueDef *vd _AND_ Type *t _AND_ char *valueNotationStr _AND_ int vnLen) { char *vStr; char *vStrOrig; int vStrLen; Value *retVal; /* make copy of value notation with ASN.1 comments zapped */ vStrOrig = vStr = StripComments (valueNotationStr, vnLen); vStrLen = strlen (vStr); retVal = ParseValueInternal (mods, m, vd, t, &vStr, (vStr + vStrLen)); /* use original since parsing has changed vStr */ // Deepak: changed from free to Free Free (vStrOrig); return retVal; } /* * vStr is a handle to a commentless ASN.1 value string, * eof is a char * to character after the last valid character * in vStr. vStr will be advanced to the current parse location. */ Value* ParseValueInternal PARAMS ((mods, m, vd, t, vStr, eof), ModuleList *mods _AND_ Module *m _AND_ ValueDef *vd _AND_ Type *t _AND_ char **vStr _AND_ char *eof) { Type *dT; Value *retVal; int parseResult = FALSE; dT = ParanoidGetType (t); /* skip type refs to get defining type */ if (dT == NULL) return NULL; retVal = NULL; switch (dT->basicType->choiceId) { case BASICTYPE_SEQUENCE: case BASICTYPE_SET: case BASICTYPE_CHOICE: case BASICTYPE_SEQUENCEOF: case BASICTYPE_SETOF: /* don't do constructed types yet */ break; case BASICTYPE_SELECTION: case BASICTYPE_COMPONENTSOF: case BASICTYPE_ANYDEFINEDBY: case BASICTYPE_UNKNOWN: case BASICTYPE_ANY: /* don't do weird types */ break; /* * The following simple types will need to be filled in * when the constructed types are parsed. * (ie ParseValueInternal becomes recursive) * (currenly all simple types not in {}'s are parsed * in the main yacc parser.) */ case BASICTYPE_BOOLEAN: break; case BASICTYPE_INTEGER: case BASICTYPE_ENUMERATED: break; case BASICTYPE_REAL: break; case BASICTYPE_BITSTRING: break; case BASICTYPE_NULL: break; case BASICTYPE_OCTETSTRING: break; /* assume all macro values in {}'s are OID values */ case BASICTYPE_OID: case BASICTYPE_RELATIVE_OID: case BASICTYPE_MACROTYPE: parseResult = ParseOidValue (mods, m, vd, t, vStr, eof, &retVal); if (!parseResult) { parseValuesErrG = 1; PrintErrLoc (m->asn1SrcFileName, valLineNoG); } break; default: break; } if (parseResult) return retVal; else return NULL; } /* ParseValueInternal */ /* * Strips ASN.1 comments from the given string. * returns a null terminated malloc'd copy without the comments */ char* StripComments PARAMS ((s, len), char *s _AND_ int len) { char *cpy; int sIndex, cpyIndex; cpy = (char*)Malloc (len +1); cpyIndex = 0; for (sIndex = 0; sIndex < len; ) { if ((s[sIndex] == '-') && ((sIndex+1) < len) && (s[sIndex+1]== '-')) { /* eat comment body */ for (sIndex += 2; sIndex < len; ) { if ((s[sIndex] == '-') && ((sIndex+1) < len) && (s[sIndex+1]== '-')) { sIndex += 2; break; /* exit for */ } else if (s[sIndex] == '\n') { sIndex++; break; /* exit for */ } else sIndex++; } } else /* not in or start of comment */ cpy[cpyIndex++] = s[sIndex++]; } cpy[cpyIndex] = '\0'; /* add NULL terminator */ return cpy; } /* StripComments */ /* * Returns TRUE if successfully parsed an OID * otherwise returns FALSE. Puts the resulting OID Value in * result if successful. * The result Value's type is BASICVALUE_LINKEDOID * * Pseudo reg expr of the expected oid format: * "{" * (oid_val_ref)? *(defined_oid_elmt_name | digit+ | int_or_enum_val_ref |name"(" digit")")* * "}" * * Does not attempt to link/lookup referenced values * * eg * for { ccitt foo (1) bar bell (bunt) 2 } * * ccitt * arcnum is set to number from oid table (oid.c) * foo (1) * - arcnum set to 1 * - sets up a new integer value def "foo" * defined as 1 *CHANGED -see changes* * - makes oid valueref a value ref to foo (doesn't link it tho) * bar * - makes oid valueref a value ref to bar (doesn't link it tho) * bell (bunt) * - sets up a new integer value def "bell" defined * as a val ref to "bunt" *CHANGED -see changes* * - makes oid valueref a value ref to bell (doesn't link it tho) * 2 * -arc num is set to 2 * * CHANGES: * 93/05/03 - named arcs such as foo (1) or bell (bunt) handling * changed. The names (foo and bell) are now ignored * and *do not* define new integer values. * The old way led to problems of defining some values * more than once. E.g. in X.500 the { .. ds (5) } * arc name is used everywhere - "ds INTEGER ::= 5" * was defined multiple times as a result. * Then the snacc error checker halted the compilation * since the integer value "ds" was mulitply defined. * */ int ParseOidValue PARAMS ((mods, m, vd, t, vStr, eof, result), ModuleList *mods _AND_ Module *m _AND_ ValueDef *vd _AND_ Type *t _AND_ char **vStr _AND_ char *eof _AND_ Value **result) { Value *newVal; Value *oidVal; OID *parsedOid; OID **nextOid; char *id; char *id2; char *id3; char *num; int arcNum; P_LOCALS; SAVE_POS(); if (AT_EOF()) { PrintErrLoc ((char*)m, (long)vd); fprintf (errFileG, "ERROR - expecting more data in OBJECT IDENTIFER value\n"); FAIL(); } SkipWht (vStr, eof); if (**vStr != '{') { PrintErrLoc ((char*)m, (long)vd); fprintf (errFileG, "ERROR - OBJECT IDENTIFER values must begin with an \"{\".\n"); FAIL(); } else (*vStr)++; /* skip opening { */ SkipWht (vStr, eof); parsedOid = NULL; nextOid = &parsedOid; while (**vStr != '}') { if (ParseIdentifier (vStr, eof, &id)) { /* * check for named number ident (num) or ident (valref) * make a new value def with the name ident if is name * and number form */ SkipWht (vStr, eof); if (**vStr == '(') { (*vStr)++; /* skip opening ( */ SkipWht (vStr, eof); arcNum = NULL_OID_ARCNUM; /* * ident (num)/ident (valref) yields a new value definition * ident. The oid then refences this new value def. */ /* * first case check if of form * { ... ident (valref) ... } */ if (ParseIdentifier (vStr, eof, &id2)) { id3 = NULL; /* check if modname.val format */ if (**vStr == '.') { (*vStr)++; if (!ParseIdentifier (vStr, eof, &id3)) { PrintErrLoc ((char*)m, (long)vd); fprintf (errFileG, "ERROR - missing a module name after the \"%s.\" value reference", id2); FAIL(); } } /* grab closing ) */ SkipWht (vStr, eof); if (**vStr == ')') (*vStr)++; else { PrintErrLoc ((char*)m, (long)vd); fprintf (errFileG, "ERROR - missing a closing \")\", after the \"%s\" value reference.\n", id2); FAIL(); } if (id3 != NULL) /* modname.val format */ { SetupValue (&newVal, BASICVALUE_IMPORTVALUEREF,valLineNoG); newVal->basicValue->a.importValueRef = (ValueRef*)Malloc (sizeof (ValueRef)); newVal->basicValue->a.importValueRef->valueName = id2; newVal->basicValue->a.importValueRef->moduleName = id3; AddPrivateImportElmt (m, id2, id3, valLineNoG); } else { SetupValue (&newVal, BASICVALUE_LOCALVALUEREF,valLineNoG); newVal->basicValue->a.localValueRef = (ValueRef*)Malloc (sizeof (ValueRef)); newVal->basicValue->a.localValueRef->valueName = id2; } } /* check this form { ... ident (2)...}*/ else if (ParseNum (vStr, eof, &num)) { /* grab closing ) */ SkipWht (vStr, eof); if (**vStr == ')') (*vStr)++; else { PrintErrLoc ((char*)m, (long)vd); fprintf (errFileG, "ERROR - missing a closing \")\" after the \"%s (%s\".\n", id2, num); Free (num); FAIL(); } arcNum = atoi (num); Free (num); newVal = NULL; } else /* neither an ident or num after the "(" */ { PrintErrLoc ((char*)m, (long)vd); fprintf (errFileG, "ERROR - expecting either a value reference or number after the \"(\".\n"); FAIL(); } *nextOid = (OID*) Malloc (sizeof (OID)); (*nextOid)->valueRef = newVal; (*nextOid)->arcNum = arcNum; nextOid = &(*nextOid)->next; } /* end of ident (num) and ident (ident) form */ else /* value ref: { ... ident .... } */ { *nextOid = (OID*) Malloc (sizeof (OID)); (*nextOid)->arcNum = NULL_OID_ARCNUM; /* * check if special defined oid elmt name * like joint-iso-ccitt, iso, standard etc. */ arcNum = OidArcNameToNum (id); if (arcNum != -1) { (*nextOid)->arcNum = arcNum; } else /* value reference */ { SetupValue (&newVal, BASICVALUE_LOCALVALUEREF,valLineNoG); newVal->basicValue->a.localValueRef = (ValueRef*)Malloc (sizeof (ValueRef)); newVal->basicValue->a.localValueRef->valueName = id; (*nextOid)->valueRef = newVal; } nextOid = &(*nextOid)->next; } } else if (ParseNum (vStr, eof, &num)) /* { .. 2 .. } */ { *nextOid = (OID*) Malloc (sizeof (OID)); (*nextOid)->arcNum = atoi (num); nextOid = &(*nextOid)->next; Free (num); } else { PrintErrLoc ((char*)m, (long)vd); fprintf (errFileG, "ERROR - bady formed arc number\n"); FAIL(); } SkipWht (vStr, eof); } (*vStr)++; /* move over closing } */ SetupValue (&oidVal, BASICVALUE_LINKEDOID, valLineNoG); oidVal->basicValue->a.linkedOid = parsedOid; *result = oidVal; SUCCEED(); t = t; vd = vd; mods = mods; /* AVOIDSwarnings. */ } void SkipWht PARAMS ((vStr, eof), char **vStr _AND_ char *eof) { while (!AT_EOF()) switch (**vStr) { case '\n': /* newline */ case '\f': /* form feed ?*/ case '\v': /* vertical tab ?*/ case '\r': valLineNoG++; /* carriage return */ case '\t': /* tab */ case ' ': /* space */ case '\007': /* bell? */ case '\b': /* back spc */ (*vStr)++; break; default: return; } } /* * advances the vStr over ASN.1 identifier, returns a copy * in result, and returns TRUE. otherwise returns FALSE * * ASN.1 identifier is: lowercase letter followed by a * string of letters (upper and lower case allowed), digtits, or single * hyphens. last char cannot be a hyphen. */ int ParseIdentifier PARAMS ((vStr, eof, result), char **vStr _AND_ char *eof _AND_ char **result) { char *start; int len; P_LOCALS; SAVE_POS(); if (AT_EOF()) FAIL(); start = *vStr; if (!islower (**vStr)) FAIL(); (*vStr)++; while (!AT_EOF()) { /* allow letters, digits and single hyphens */ if ((isalpha (**vStr)) || isdigit (**vStr) || ((**vStr == '-') && !(*(*vStr - 1) == '-'))) (*vStr)++; else break; /* exit for loop */ } /* don't allow hyphens on the end */ if (*(*vStr - 1) == '-') (*vStr)--; len = *vStr - start; *result = Malloc (len +1); strncpy (*result, start, len); (*result)[len] = '\0'; /* null terminate */ SUCCEED(); } /* ParseIdentifier */ /* * advances the vStr over ASN.1 number, returns a * null terminated ascii copy of the number * in result, and returns TRUE. otherwise returns FALSE */ int ParseNum PARAMS ((vStr, eof, result), char **vStr _AND_ char *eof _AND_ char **result) { P_LOCALS; char *start; int len; SAVE_POS(); if (AT_EOF()) FAIL(); start = *vStr; while (!AT_EOF()) { if (isdigit (**vStr)) (*vStr)++; else break; /* exit for loop */ } len = *vStr - start; if (len == 0) FAIL(); *result = Malloc (len +1); strncpy (*result, start, len); (*result)[len] = '\0'; /* null terminate */ SUCCEED(); } /* ParseNum */ /* * adds a new value def to the vdl. Used * when parsing oid's that defined arc values * eg { 1 2 foo (3) } --> defined foo INTEGER ::= 3 * (should be foo INTEGER (0..MAX) ::= 3) */ void AddNewValueDef PARAMS ((vdl, name, value), ValueDefList *vdl _AND_ char *name _AND_ Value *value) { ValueDef *vd; ValueDef **tmpVd; vd = (ValueDef*)Malloc (sizeof (ValueDef)); vd->definedName = name; vd->value = value; tmpVd = (ValueDef**)AsnListAppend (vdl); *tmpVd = vd; } /* AddNewValueDef */ esnacc-ng-1.8.1/compiler/core/y.tab.y000066400000000000000000002447141302010526100173320ustar00rootroot00000000000000/* * compiler/core/parse-asn1.y * yacc source for ASN.1 '88 Parser * * As interpreted from Appendix II of CCITT recomendation X.208 * * Parses ASN.1 into a monster data structure * * Some old versions of yacc will croak due the length * of some of the symbols (use -Nc10000 with other versions) * * Mike Sample * 90/05/03 * 91/09/02 Rewritten with "ASN.1" generated data struct * * Copyright (C) 1990, 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * $Header: /baseline/SNACC/compiler/core/parse-asn1.y,v 1.20 2004/03/31 20:03:20 leonberp Exp $ * */ %{ #include "snacc.h" #if STDC_HEADERS || HAVE_STRING_H #include #else #include #endif //#include #include "asn-incl.h" #include "mem.h" #include "asn1module.h" #include "lib-types.h" #include "snacc-util.h" #include "exports.h" #include "lex-stuff.h" static unsigned int enumCtr; int OidArcNameToNum PROTO ((char *name)); int yylex(); static void yyerror(char* s); extern FILE* errFileG; // Defined in snacc.c /* * smallErrG * used for small errors that should prevent code generation but not * prevent the later error checking passes */ int smallErrG = FALSE; #ifdef FLEX_IN_USE /* * firstTimeThroughG * used incase the asn1.lex was compiled with flex in which * case the lexical analyzer must be reset for every ASN.1 file * parsed, except the first */ static int firstTimeThroughG = TRUE; #endif /* * modulePtrG * used to hold the parsed value. The root of the parse tree. */ Module *modulePtrG; /* * oidElmtValDefsG * used to hold integer values that are defined as arc numbers * the modules object identifiers. * eg. FOO-MODULE { joint-iso-ccitt dod (2) foo (2) 3 2 } DEFINITIONS ::= * would put dod/2 and foo/2 in the oidElmtValDefsG list * Note: only some oid's (modules name/import list module names) * are parsed by the yacc code. The rest are parsed later * due to ambiguities that arise without type info. // REN -- 9/23/02 ValueDefList *oidElmtValDefsG = NULL; */ /* * ApplTag * used to hold APPLICATION tags that have been defined in * a module. This permits checking for the the error of * using the same APPLICATION tag in 1 module. The * ApplTags list (appTagsG) is emptied for each module. */ typedef struct ApplTag { unsigned long lineNo; unsigned long tagCode; struct ApplTag *next; } ApplTag; ApplTag *applTagsG = NULL; /* * Protos for ApplTag related stuff. These are defined at the * end of this file */ void PushApplTag PROTO ((unsigned long tagCode, unsigned long lineNo)); void FreeApplTags(); /* * used to set exports flag in Type/value defs * exportListG holds the explicitly exported elements. * see SetExports routine in export.c */ ExportElmt *exportListG = NULL; int exportsParsedG; /* * globals for the APPLICATION-CONTEXT macro productions */ static ValueList *rosAcSymmetricAsesG; static ValueList *rosAcResponderConsumerOfG; static ValueList *rosAcInitiatorConsumerOfG; /* * used with MTSAS Extension macro * set to NULL for the initial parse. */ static AsnBool *mtsasCriticalForSubmissionG = NULL; static AsnBool *mtsasCriticalForTransferG = NULL; static AsnBool *mtsasCriticalForDeliveryG = NULL; /* * Asn PORT macro globals */ static TypeOrValueList *asnConsumerG; static TypeOrValueList *asnSupplierG; /* * parseErrCountG * used to prevent too many cascade errors */ int parseErrCountG = 0; #define MAX_ERR 50 #define PARSE_ERROR()\ parseErrCountG++;\ modulePtrG->status = MOD_ERROR;\ if (parseErrCountG > MAX_ERR)\ {\ fprintf (errFileG, "Ackkkkk! too many errors - bye!\n");\ YYABORT;\ } %} /* * Union structure. A terminal or non-terminal can have * one of these type values. */ %union { int intVal; unsigned int uintVal; char *charPtr; Type *typePtr; NamedType *namedTypePtr; NamedTypeList *namedTypeListPtr; Value *valuePtr; NamedValue *namedValuePtr; SubtypeValue *subtypeValuePtr; Subtype *subtypePtr; ModuleId *moduleId; OID *oidPtr; OidList *oidListPtr; TypeDef *typeDefPtr; TypeDefList *typeDefListPtr; ValueDef *valueDefPtr; ValueDefList *valueDefListPtr; ExportElmt *exportList; ImportModule *importModulePtr; ImportModuleList *importModuleListPtr; ImportElmt *importElmtPtr; ImportElmtList *importElmtListPtr; Tag *tagPtr; TagList *tagListPtr; Constraint *constraintPtr; ConstraintList *constraintListPtr; InnerSubtype *innerSubtypePtr; ValueRangeEndpoint *valueRangeEndpointPtr; ValueList *valueListPtr; TypeOrValueList *typeOrValueListPtr; TypeOrValue *typeOrValuePtr; AsnPort *asnPortPtr; AsnPortList *asnPortListPtr; SnaccDirectiveList *directiveList; SnaccDirective *directivePtr; SnaccDirectiveEnum directiveEnum; enum BasicTypeChoiceId basicTypeChoiceIdEnum; CTypeId cTypeIdEnum; AsnBool boolVal; } /* * Terminals. Definitions can be found in input.lex. */ /* * these tokens (literals) have attributes (set in asn1.lex) */ %token BSTRING_SYM HSTRING_SYM CSTRING_SYM UCASEFIRST_IDENT_SYM LCASEFIRST_IDENT_SYM NAMEDMACRO_SYM MACRODEFBODY_SYM BRACEBAL_SYM NUMBER_ERANGE %token NUMBER_SYM %token SNACC_ATTRIBUTES /* * these tokens have no attributes */ %token COLON_SYM ELLIPSIS_SYM DOT_SYM COMMA_SYM LEFTBRACE_SYM RIGHTBRACE_SYM LEFTPAREN_SYM RIGHTPAREN_SYM LEFTBRACKET_SYM RIGHTBRACKET_SYM LESSTHAN_SYM MINUS_SYM GETS_SYM BAR_SYM TAGS_SYM BOOLEAN_SYM INTEGER_SYM BIT_SYM STRING_SYM OCTET_SYM CONTAINING_SYM ENCODED_SYM NULL_SYM SEQUENCE_SYM OF_SYM SET_SYM IMPLICIT_SYM CHOICE_SYM ANY_SYM OBJECT_IDENTIFIER_SYM RELATIVE_OID_SYM OPTIONAL_SYM DEFAULT_SYM COMPONENTS_SYM UNIVERSAL_SYM APPLICATION_SYM PRIVATE_SYM TRUE_SYM FALSE_SYM BEGIN_SYM END_SYM DEFINITIONS_SYM EXPLICIT_SYM ENUMERATED_SYM EXPORTS_SYM IMPORTS_SYM REAL_SYM INCLUDES_SYM MIN_SYM MAX_SYM SIZE_SYM FROM_SYM WITH_SYM COMPONENT_SYM PRESENT_SYM ABSENT_SYM DEFINED_SYM BY_SYM PLUS_INFINITY_SYM MINUS_INFINITY_SYM SEMI_COLON_SYM IA5STRING_SYM PRINTABLESTRING_SYM NUMERICSTRING_SYM TELETEXSTRING_SYM T61STRING_SYM VIDEOTEXSTRING_SYM VISIBLESTRING_SYM ISO646STRING_SYM GRAPHICSTRING_SYM GENERALSTRING_SYM BMPSTRING_SYM UNIVERSALSTRING_SYM UTF8STRING_SYM GENERALIZEDTIME_SYM UTCTIME_SYM EXTERNAL_SYM OBJECTDESCRIPTOR_SYM AUTOMATIC_SYM /* the following are used in macros */ OPERATION_SYM ARGUMENT_SYM RESULT_SYM ERRORS_SYM LINKED_SYM ERROR_SYM PARAMETER_SYM BIND_SYM BINDERROR_SYM UNBIND_SYM UNBINDERROR_SYM ASE_SYM OPERATIONS_SYM CONSUMERINVOKES_SYM SUPPLIERINVOKES_SYM AC_SYM ASES_SYM REMOTE_SYM INITIATOR_SYM RESPONDER_SYM ABSTRACTSYNTAXES_SYM CONSUMER_SYM EXTENSIONS_SYM CHOSEN_SYM EXTENSION_SYM CRITICAL_SYM FOR_SYM DELIVERY_SYM SUBMISSION_SYM TRANSFER_SYM EXTENSIONATTRIBUTE_SYM TOKEN_SYM TOKENDATA_SYM SECURITYCATEGORY_SYM OBJECT_SYM PORTS_SYM BOXC_SYM BOXS_SYM PORT_SYM ABSTRACTOPS_SYM REFINE_SYM AS_SYM RECURRING_SYM VISIBLE_SYM PAIRED_SYM ABSTRACTBIND_SYM ABSTRACTUNBIND_SYM TO_SYM ABSTRACTERROR_SYM ABSTRACTOPERATION_SYM ALGORITHM_SYM ENCRYPTED_SYM SIGNED_SYM SIGNATURE_SYM PROTECTED_SYM OBJECTTYPE_SYM SYNTAX_SYM ACCESS_SYM STATUS_SYM DESCRIPTION_SYM REFERENCE_SYM INDEX_SYM DEFVAL_SYM /* Compiler directive attributes */ %token ATTRIB_ASN1_TYPE_ID ATTRIB_C_TYPE_ID ATTRIB_C_TYPE_NAME_SYM ATTRIB_C_FIELD_NAME_SYM ATTRIB_IS_PDU_SYM ATTRIB_IS_PTR_SYM ATTRIB_IS_PTR_TYPEDEF_SYM ATTRIB_IS_PTR_TYPE_REF_SYM ATTRIB_IS_PTR_IN_CHOICE_SYM ATTRIB_IS_PTR_FOR_OPT_SYM ATTRIB_OPT_TEST_ROUTINE_SYM ATTRIB_DEFAULT_FIELD_SYM ATTRIB_PRINT_ROUTINE_SYM ATTRIB_ENCODE_ROUTINE_SYM ATTRIB_DECODE_ROUTINE_SYM ATTRIB_FREE_ROUTINE_SYM ATTRIB_IS_ENC_DEC_SYM ATTRIB_GEN_TYPEDEF_SYM ATTRIB_GEN_PRINT_ROUTINE_SYM ATTRIB_GEN_ENCODE_ROUTINE_SYM ATTRIB_GEN_DECODE_ROUTINE_SYM ATTRIB_GEN_FREE_ROUTINE_SYM ATTRIB_CHOICE_ID_SYMBOL_SYM ATTRIB_CHOICE_ID_VALUE_SYM ATTRIB_CHOICE_ID_ENUM_NAME_SYM ATTRIB_CHOICE_ID_ENUM_FIELD_NAME_SYM ATTRIB_IS_BIG_INT_SYM ATTRIB_NAMESPACE_SYM %token C_CHOICE_SYM C_LIST_SYM C_ANY_SYM C_ANYDEFBY_SYM C_LIB_SYM C_STRUCT_SYM C_TYPEDEF_SYM C_TYPEREF_SYM C_NO_TYPE_SYM %token UNKNOWN_SYM BITSTRING_SYM OCTETSTRING_SYM SEQUENCE_OF_SYM SET_OF_SYM ANY_DEFINED_BY_SYM LOCAL_TYPE_REF_SYM IMPORT_TYPE_REF_SYM /* * Type definitions of non-terminal symbols */ %type LineNo SetOpening SequenceOpening %type TagDefault %type SymbolList %type SymbolsFromModuleList %type SymbolsFromModule %type TypeAssignment %type ValueAssignment %type BinaryString HexString CharString %type number Class VersionNumber %type SignedNumber %type modulereference typereference identifier Symbol OptionalSnaccNamespace %type ExternalValueReference %type Value DefinedValue BuiltinValue BooleanValue NullValue SpecialRealValue %type NamedValue %type ModuleIdentifier %type ObjectIdentifierValue AssignedIdentifier ObjIdComponent NumberForm NameAndNumberForm ObjIdComponentList %type ExtensionDefault %type NameForm %type BuiltinType DefinedType Subtype BooleanType IntegerType BitStringType NullType SequenceType SequenceOfType SetType SetOfType ChoiceType SelectionType BitContainingType TaggedType AnyType ObjectIdentifierType CharStrType UsefulType EnumeratedType RealType Type ExternalTypeReference OctetContainingType ExternalType RelativeOIDType %type NamedType ElementType %type AlternativeTypes AlternativeTypeList ElementTypes ElementTypeList Extension ExtList ExtensionAdditions ExtensionAddition ExtensionAdditionList ChoiceExtension ExtAdditionAlternatives ExtAddList ExtAddAlternative AltList %type SubtypeValueSet SingleValue ContainedSubtype ValueRange PermittedAlphabet SizeConstraint InnerTypeConstraints ExtensibleSubtype %type SubtypeSpec SubtypeValueSetList %type NamedConstraint Constraint %type TypeConstraints %type FullSpecification PartialSpecification SingleTypeConstraint MultipleTypeConstraints %type LowerEndPoint UpperEndPoint %type LowerEndValue UpperEndValue %type PresenceConstraint %type ValueConstraint %type ExportSymbolList %type NamedNumber Enumeration %type NamedNumberList NamedBitList Enumerations %type Tag ClassNumber %type SnaccDirectives SnaccDirectiveList %type SnaccDirective %type SnaccDirectiveBoolType SnaccDirectiveStringType SnaccDirectiveIntegerType %type SnaccDirectiveAsnTypeValue %type SnaccDirectiveCTypeValue %type SnaccDirectiveBoolValue %type DefinedMacroName MacroReference %type DefinedMacroType %type PossiblyEmptyValueList ValueList %type PossiblyEmptyTypeOrValueList TypeOrValueList %type TypeOrValue %type RosOperationMacroType RosOperationMacroBody RosErrorMacroType RosBindMacroType RosUnbindMacroType RosAseMacroType RosAcMacroType %type RosOpArgument RosOpResult RosOpResultType %type RosOpErrors RosOpLinkedOps %type RosErrParameter %type RosBindArgument RosBindResult RosBindError RosUnbindError %type RosAseSymmetricAse RosAseConsumerInvokes RosAseSupplierInvokes RosAseOperationList %type RosAcNonRoElements %type RosAcRoElements %type OidList RosAcAbstractSyntaxes %type MtsasExtensionsMacroType MtsasExtensionMacroType MtsasExtensionAttributeMacroType MtsasTokenMacroType MtsasTokenDataMacroType MtsasSecurityCategoryMacroType %type MtsasExtDefaultVal %type AsnObjectMacroType AsnPortMacroType AsnRefineMacroType AsnAbstractBindMacroType AsnAbstractUnbindMacroType AsnAbstractOperationMacroType AsnAbstractErrorMacroType %type AsnPorts AsnPortList %type AsnPort %type AsnPortType %type AsnObject AsnObjectList AsnPortSpec AsnPortSpecList AsnObjectSpec AsnComponent AsnComponentList %type AsnOperations AsnConsumer AsnSupplier %type AsnAbstractBindPorts AsnAbstractUnbindPorts %type AfAlgorithmMacroType AfEncryptedMacroType AfSignedMacroType AfSignatureMacroType AfProtectedMacroType %type SnmpObjectTypeMacroType %type SnmpStatus SnmpAccess %type SnmpDescrPart SnmpReferPart SnmpDefValPart %type SnmpIndexPart %start ModuleDefinition %% /*-----------------------------------------------------------------------*/ /* Module def/import/export productions */ /*-----------------------------------------------------------------------*/ LineNo: { $$ = myLineNoG; } ; ModuleDefinition: ModuleIdentifier DEFINITIONS_SYM TagDefault { modulePtrG->tagDefault = $3; } ExtensionDefault GETS_SYM BEGIN_SYM OptionalSnaccNamespace ModuleBody END_SYM { modulePtrG->modId = $1; modulePtrG->namespaceToUse = $8; /* * Set exported flags in type/value defs as appropriate */ SetExports (modulePtrG, exportListG, exportsParsedG); /* clean up */ /* Free Application tag list */ FreeApplTags(); /* * Add values defined in any parsed object identifiers. * Only the Module name and some macro oids have been parsed, * the rest are just "{...}" strings at this point * (they will be parsed in later) // REN -- 9/23/02 modulePtrG->valueDefs = AsnListConcat (modulePtrG->valueDefs, oidElmtValDefsG); */ /* * free list head only // REN -- 9/23/02 Free (oidElmtValDefsG); */ } ; TagDefault: EXPLICIT_SYM TAGS_SYM { $$ = EXPLICIT_TAGS; } | IMPLICIT_SYM TAGS_SYM { $$ = IMPLICIT_TAGS; } | AUTOMATIC_SYM TAGS_SYM { $$ = AUTOMATIC_TAGS; fprintf(errFileG, "WARNING: AUTOMATIC tags are still experimental.\n"); } | empty { /* default is EXPLICIT TAGS */ $$ = EXPLICIT_TAGS; } ; ExtensionDefault: ELLIPSIS_SYM { $$ = TRUE; } |empty { $$ = FALSE; } ; ModuleIdentifier: modulereference AssignedIdentifier { $$ = MT (ModuleId); $$->name = $1; $$->oid = $2; } ; AssignedIdentifier: ObjectIdentifierValue | empty { $$ = NULL; } ; OptionalSnaccNamespace: ATTRIB_NAMESPACE_SYM ':' CSTRING_SYM { $$ = $3; } | empty { $$ = NULL; } ; ModuleBody: Exports Imports AssignmentList | empty ; Exports: EXPORTS_SYM SymbolsExported SEMI_COLON_SYM { /* * allows differentiation between "EXPORTS;" * (in which no exports allowed) * and when the EXPORTS symbol does not appear * (then all are exported) */ exportsParsedG = TRUE; } | EXPORTS_SYM error SEMI_COLON_SYM { PARSE_ERROR(); exportsParsedG = FALSE; exportListG = NULL; yyerrok; } | empty { exportsParsedG = FALSE; } ; SymbolsExported: ExportSymbolList { exportListG = $1; } | empty { exportListG = NULL; } ; ExportSymbolList: Symbol { $$ = MT (ExportElmt); $$->name = $1; $$->lineNo = myLineNoG; $$->next = NULL; } | ExportSymbolList COMMA_SYM LineNo Symbol { $$ = MT (ExportElmt); $$->name = $4; $$->next = $1; $$->lineNo = $3; } ; Imports: IMPORTS_SYM SymbolsImported SEMI_COLON_SYM | IMPORTS_SYM error SEMI_COLON_SYM { PARSE_ERROR(); yyerrok; } | empty ; SymbolsImported: SymbolsFromModuleList { modulePtrG->imports = $1; } | empty ; SymbolsFromModuleList: SymbolsFromModuleList SymbolsFromModule { APPEND ($2,$1); } | SymbolsFromModule { $$ = NEWLIST(); APPEND ($1, $$); } ; SymbolsFromModule: SymbolList FROM_SYM LineNo ModuleIdentifier { $$ = MT (ImportModule); $$->modId = $4; $$->lineNo = $3; $$->importElmts = $1; } ; SymbolList: SymbolList COMMA_SYM Symbol { ImportElmt *ie; ie = MT (ImportElmt); ie->name = $3; ie->lineNo = myLineNoG; APPEND (ie, $1); $$ = $1; } | Symbol { ImportElmt *ie; /* called for the first element only, so create list head */ $$ = NEWLIST(); ie = MT (ImportElmt); ie->name = $1; ie->lineNo = myLineNoG; APPEND (ie, $$); } ; Symbol: typereference | identifier | DefinedMacroName /* This solves macro "keyword" problem */ { /* * hack to make DefinedMacroNames "freeable" * like idents and typeref */ $$ = Malloc (strlen ($1)+1); strcpy ($$, $1); } ; AssignmentList: AssignmentList AssignmentOrError | AssignmentOrError ; AssignmentOrError: Assignment | Assignment SEMI_COLON_SYM | error SEMI_COLON_SYM { PARSE_ERROR(); yyerrok; } ; Assignment: TypeAssignment { /* * a macro may produce a null type */ if ($1 != NULL) { /* * add to head of type def list */ APPEND ($1, modulePtrG->typeDefs); } } | ValueAssignment { /* * a macro may produce a null value */ if ($1 != NULL) { /* * add to head of value def list */ APPEND ($1, modulePtrG->valueDefs); } } | NAMEDMACRO_SYM GETS_SYM BEGIN_SYM LineNo { LexBeginMacroDefContext(); } MACRODEFBODY_SYM { TypeDef *tmpTypeDef; /* * LEXICAL TIE IN!! * create macro type to eliminate import resolution * errors msgs from other modules importing the macro. * (hopefully) Only the import list will link with * these type defs. * keeps macro def around incase of future processing needs * * NOTE: MACRODEFBODY_SYM returns the macro def body with * with "BEGIN" at the begininning and "END" at the end */ /* * put lexical analyzer back in normal state */ /* BEGIN (INITIAL); */ LexBeginInitialContext(); tmpTypeDef = MT (TypeDef); SetupType (&tmpTypeDef->type, BASICTYPE_MACRODEF, $4); tmpTypeDef->definedName = $1; /* * keeps the macro def body * (all text between & including the BEGIN and END) * as a simple string - incase you want to fart around with * it. */ tmpTypeDef->type->basicType->a.macroDef = $6; /* * put in type list */ APPEND (tmpTypeDef, modulePtrG->typeDefs); } | NAMEDMACRO_SYM GETS_SYM MacroReference { TypeDef *tmpTypeDef; tmpTypeDef = MT (TypeDef); SetupType (&tmpTypeDef->type, BASICTYPE_MACRODEF, myLineNoG); tmpTypeDef->definedName = $1; tmpTypeDef->type->basicType->a.macroDef = $3; /* * put in type list */ APPEND (tmpTypeDef, modulePtrG->typeDefs); } | NAMEDMACRO_SYM GETS_SYM modulereference DOT_SYM MacroReference { TypeDef *tmpTypeDef; tmpTypeDef = MT (TypeDef); SetupType (&tmpTypeDef->type, BASICTYPE_MACRODEF, myLineNoG); tmpTypeDef->definedName = $1; tmpTypeDef->type->basicType->a.macroDef = (MyString) Malloc (strlen ($3) + strlen ($5) + 2); strcpy (tmpTypeDef->type->basicType->a.macroDef, $3); strcat (tmpTypeDef->type->basicType->a.macroDef, "."); strcat (tmpTypeDef->type->basicType->a.macroDef, $5); /* * put in type list */ APPEND (tmpTypeDef, modulePtrG->typeDefs); Free ($3); Free ($5); } ; MacroReference: typereference | DefinedMacroName ; /*-----------------------------------------------------------------------*/ /* Type Notation Productions */ /*-----------------------------------------------------------------------*/ TypeAssignment: typereference GETS_SYM SnaccDirectives LineNo Type SnaccDirectives { /* * a macro type may produce a null type */ if ($5 != NULL) { $$ = MT (TypeDef); $$->type = $5; $$->type->lineNo = $4; $$->type->attrList = $6; $$->definedName = $1; $$->attrList = $3; } else $$ = NULL; } ; ExternalTypeReference: modulereference DOT_SYM LineNo typereference { /* allocate a Type with basic type of ImportTypeRef */ SetupType (&$$, BASICTYPE_IMPORTTYPEREF, $3); $$->basicType->a.importTypeRef = MT (TypeRef); $$->basicType->a.importTypeRef->typeName = $4; $$->basicType->a.importTypeRef->moduleName = $1; /* add entry to this module's import list */ AddPrivateImportElmt (modulePtrG, $4, $1, $3); } ; DefinedType: /* could by CharacterString or Useful types too */ ExternalTypeReference { $$ = $1; } | typereference { SetupType (&$$, BASICTYPE_LOCALTYPEREF, myLineNoG); $$->basicType->a.localTypeRef = MT (TypeRef); $$->basicType->a.localTypeRef->typeName = $1; } ; Type: DefinedMacroType | BuiltinType | DefinedType | Subtype ; BuiltinType: BooleanType | IntegerType | BitContainingType | BitStringType | NullType | ExternalType | SequenceType | SequenceOfType | SetType | SetOfType | ChoiceType | SelectionType | TaggedType | AnyType | ObjectIdentifierType | EnumeratedType | RealType | OctetContainingType | OCTET_SYM STRING_SYM { SetupType (&$$, BASICTYPE_OCTETSTRING, myLineNoG); } | OCTET_SYM STRING_SYM SizeConstraint { SetupType (&$$, BASICTYPE_OCTETSTRING, myLineNoG); } | CharStrType | UsefulType | RelativeOIDType ; NamedType: identifier Type { $$ = MT (NamedType); $$->type = $2; $$->fieldName = $1; } | Type /* this handles selectionType as well */ { printf("Line %ld: Warning - 2002 ASN.1 syntax no longer supports un-named types!\n", myLineNoG); printf(" --Suggest using an identifier or may cause errors\n"); $$ = MT (NamedType); $$->type = $1; } ; BooleanType: BOOLEAN_SYM { SetupType (&$$, BASICTYPE_BOOLEAN, myLineNoG); } ; IntegerType: INTEGER_SYM { SetupType (&$$, BASICTYPE_INTEGER, myLineNoG); $$->basicType->a.integer = NEWLIST(); /* empty list */ } | INTEGER_SYM LEFTBRACE_SYM NamedNumberList RIGHTBRACE_SYM { SetupType (&$$, BASICTYPE_INTEGER, myLineNoG); $$->basicType->a.integer = $3; } ; Enumeration: identifier { $$ = MT(ValueDef); $$->definedName = $1; SetupValue (&$$->value, BASICVALUE_INTEGER, myLineNoG); $$->value->basicValue->a.integer = enumCtr++; } | NamedNumber { enumCtr = $1->value->basicValue->a.integer + 1; $$ = $1; } ; Enumerations: Enumeration { $$ = NEWLIST(); APPEND ($1, $$); } | Enumerations COMMA_SYM Enumeration { APPEND ($3, $1); $$ = $1; } | Enumerations COMMA_SYM ELLIPSIS_SYM { $$ = $1; } NamedNumberList: NamedNumber { $$ = NEWLIST(); APPEND ($1, $$); } | NamedNumberList COMMA_SYM NamedNumber { APPEND ($3,$1); $$ = $1; } ; NamedNumber: identifier LEFTPAREN_SYM SignedNumber RIGHTPAREN_SYM { $$ = MT (ValueDef); $$->definedName = $1; SetupValue (&$$->value, BASICVALUE_INTEGER, myLineNoG); $$->value->basicValue->a.integer = $3; } | identifier LEFTPAREN_SYM DefinedValue RIGHTPAREN_SYM { $$ = MT (ValueDef); $$->definedName = $1; $$->value = $3; } ; SignedNumber: NUMBER_SYM { $$=$1; } | NUMBER_ERANGE { } | MINUS_SYM NUMBER_SYM { $2=0-$2; $$=$2; } | MINUS_SYM NUMBER_ERANGE { } ; EnumeratedType: ENUMERATED_SYM LEFTBRACE_SYM Enumerations RIGHTBRACE_SYM { SetupType (&$$, BASICTYPE_ENUMERATED, myLineNoG); $$->basicType->a.enumerated = $3; enumCtr = 0; } ; RealType: REAL_SYM { SetupType (&$$, BASICTYPE_REAL, myLineNoG); } ; BitStringType: BIT_SYM STRING_SYM { SetupType (&$$, BASICTYPE_BITSTRING, myLineNoG); $$->basicType->a.bitString = NEWLIST(); /* empty list */ } | BIT_SYM STRING_SYM SizeConstraint { SetupType (&$$, BASICTYPE_BITSTRING, myLineNoG); $$->basicType->a.bitString = NEWLIST(); /* empty list */ } | BIT_SYM STRING_SYM LEFTBRACE_SYM NamedBitList RIGHTBRACE_SYM { SetupType (&$$, BASICTYPE_BITSTRING, myLineNoG); $$->basicType->a.bitString = $4; } ; NamedBitList: NamedNumberList ; NullType: NULL_SYM { SetupType (&$$, BASICTYPE_NULL, myLineNoG); } ; ExternalType: EXTERNAL_SYM { SetupType (&$$, BASICTYPE_EXTERNAL, myLineNoG); } ; SequenceOpening: SEQUENCE_SYM LineNo LEFTBRACE_SYM { $$ = $2; } ; SequenceType: SequenceOpening ElementTypes RIGHTBRACE_SYM { NamedType *n; SetupType (&$$, BASICTYPE_SEQUENCE, $1); if (AsnListCount ((AsnList*)$2) != 0) { n = (NamedType*) FIRST_LIST_ELMT ((AsnList*)$2); n->type->lineNo = $1; } $$->basicType->a.sequence = $2; if (modulePtrG->tagDefault == AUTOMATIC_TAGS) { AutomaticTagNamed($$->basicType->a.sequence); } } | SequenceOpening RIGHTBRACE_SYM { SetupType (&$$, BASICTYPE_SEQUENCE, $1); /* set up empty list for SEQ with no elmts */ $$->basicType->a.sequence = AsnListNew (sizeof (void*)); } /*| SEQUENCE_SYM LEFTBRACE_SYM error RIGHTBRACE_SYM { PARSE_ERROR(); yyerrok; }*/ ; ElementTypes: ElementTypeList SnaccDirectives { NamedType *lastElmt; if ($2 != NULL) { lastElmt = (NamedType*)LAST_LIST_ELMT ($1); lastElmt->type->attrList = $2; } $$ = $1; } ; ElementTypeList: Extension | ElementType COMMA_SYM SnaccDirectives LineNo ElementTypeList { NamedType *firstElmt; if ($3 != NULL) { firstElmt = (NamedType*)FIRST_LIST_ELMT ($5); firstElmt->type->attrList = $3; } PREPEND ($1, $5); firstElmt = (NamedType*)FIRST_LIST_ELMT ($5); firstElmt->type->lineNo = $4; $$ = $5; } | ElementType { $$ = NEWLIST(); PREPEND ($1,$$); } ; Extension: ELLIPSIS_SYM ExtensionAdditions { $$ = $2; } ; ExtensionAdditions: COMMA_SYM ELLIPSIS_SYM { NamedType *nt; $$ = NEWLIST(); nt = MT(NamedType); SetupType (&nt->type, BASICTYPE_EXTENSION, myLineNoG); nt->type->extensionAddition = TRUE; APPEND(nt, $$); } | COMMA_SYM ExtensionAdditionList OptExtMarker { NamedType *nt; $$ = $2; nt = MT(NamedType); SetupType (&nt->type, BASICTYPE_EXTENSION, myLineNoG); nt->type->extensionAddition = TRUE; APPEND(nt, $$); } | empty { NamedType *nt; $$ = NEWLIST(); nt = MT(NamedType); SetupType (&nt->type, BASICTYPE_EXTENSION, myLineNoG); nt->type->extensionAddition = TRUE; /* PL: wasn't set */ APPEND(nt, $$); } ; ExtensionAdditionList: ExtensionAddition | ExtensionAdditionList COMMA_SYM ExtensionAddition { CONCAT($1, $3); $$ = $1; } ; ExtensionAddition: ElementType { $$ = NEWLIST(); $1->type->extensionAddition = TRUE; APPEND($1, $$); } | LEFTBRACKET_SYM LEFTBRACKET_SYM VersionNumber ExtList RIGHTBRACKET_SYM RIGHTBRACKET_SYM { $$ = $4; } ; ExtList: ExtList COMMA_SYM SnaccDirectives LineNo ElementType { NamedType *lastElmt; $5->type->extensionAddition = TRUE; if ($3 != NULL) { lastElmt = (NamedType*)LAST_LIST_ELMT ($1); lastElmt->type->attrList = $3; } APPEND($5, $1); lastElmt = (NamedType*)LAST_LIST_ELMT ($1); lastElmt->type->lineNo = $4; $$ = $1; } | ElementType { $$ = NEWLIST(); $1->type->extensionAddition = TRUE; APPEND($1,$$); } ; VersionNumber: number COLON_SYM | empty { $$ = -1; } ; OptExtMarker: ELLIPSIS_SYM |empty ; ElementType: NamedType | NamedType OPTIONAL_SYM { $$ = $1; $$->type->optional = TRUE; } | NamedType DEFAULT_SYM NamedValue { /* * this rules uses NamedValue instead of Value * for the stupid choice value syntax (fieldname value) * it should be like a set/seq value (ie with * enclosing { } */ $$ = $1; $$->type->defaultVal = $3; /* * could link value to the elmt type here (done in link_types.c) */ } | COMPONENTS_SYM OF_SYM Type { $$ = MT (NamedType); SetupType (&$$->type, BASICTYPE_COMPONENTSOF, myLineNoG); $$->type->basicType->a.componentsOf = $3; } | identifier COMPONENTS_SYM OF_SYM Type { $$ = MT (NamedType); SetupType (&$$->type, BASICTYPE_COMPONENTSOF, myLineNoG); $$->fieldName = $1; $$->type->basicType->a.componentsOf = $4; } ; SequenceOfType: SEQUENCE_SYM OF_SYM Type { SetupType (&$$, BASICTYPE_SEQUENCEOF, myLineNoG); /* grab line number from first elmt */ if ($3 != NULL) $$->lineNo = $3->lineNo - 1; $$->basicType->a.sequenceOf = $3; } ; SetOpening: SET_SYM LineNo LEFTBRACE_SYM { $$ = $2; } ; SetType: SetOpening ElementTypes RIGHTBRACE_SYM { NamedType *n; SetupType (&$$, BASICTYPE_SET, $1); /* reset first elmt's line number */ if (AsnListCount ((AsnList*)$2) != 0) { n = (NamedType*)FIRST_LIST_ELMT ((AsnList*)$2); n->type->lineNo = $1; } $$->basicType->a.set = $2; if (modulePtrG->tagDefault == AUTOMATIC_TAGS) { AutomaticTagNamed($$->basicType->a.set); } } | SetOpening RIGHTBRACE_SYM { SetupType (&$$, BASICTYPE_SET, $1); /* set up empty elmt list for SET */ $$->basicType->a.set = AsnListNew (sizeof (void*)); } /* | SET_SYM LEFTBRACE_SYM error RIGHTBRACE_SYM { PARSE_ERROR(); yyerrok; } */ ; SetOfType: SET_SYM OF_SYM Type { /* does not allow SET == SET OF ANY Abrev */ SetupType (&$$, BASICTYPE_SETOF, myLineNoG); if ($3 != NULL) $$->lineNo = $3->lineNo; $$->basicType->a.setOf = $3; } ; ChoiceType: CHOICE_SYM LineNo LEFTBRACE_SYM AlternativeTypes RIGHTBRACE_SYM { NamedType *n; SetupType (&$$, BASICTYPE_CHOICE, $2); if (AsnListCount ($4) != 0) { n = (NamedType*)FIRST_LIST_ELMT ($4); n->type->lineNo = $2; } $$->basicType->a.choice = $4; if (modulePtrG->tagDefault == AUTOMATIC_TAGS) { AutomaticTagNamed($$->basicType->a.choice); } } ; AlternativeTypes: AlternativeTypeList SnaccDirectives { NamedType *lastElmt; if ($2 != NULL) { lastElmt = (NamedType*)LAST_LIST_ELMT ($1); lastElmt->type->attrList = $2; } $$ = $1; } ; AlternativeTypeList: NamedType { $$ = NEWLIST(); PREPEND ($1, $$); } | NamedType COMMA_SYM SnaccDirectives AlternativeTypeList { NamedType *firstElmt; if ($3 != NULL) { firstElmt = (NamedType*)FIRST_LIST_ELMT ($4); firstElmt->type->attrList = $3; } PREPEND ($1,$4); $$ = $4; } | ChoiceExtension ; ChoiceExtension: ELLIPSIS_SYM ExtAdditionAlternatives { $$ = $2; } ; ExtAdditionAlternatives: COMMA_SYM ELLIPSIS_SYM { NamedType *nt; $$ = NEWLIST(); nt = MT(NamedType); SetupType (&nt->type, BASICTYPE_EXTENSION, myLineNoG); nt->type->extensionAddition = TRUE; APPEND(nt, $$); } |COMMA_SYM ExtAddList OptExtMarker { $$ = $2; } |empty { NamedType *nt; $$ = NEWLIST(); nt = MT(NamedType); SetupType (&nt->type, BASICTYPE_EXTENSION, myLineNoG); nt->type->extensionAddition = TRUE; APPEND(nt, $$); } ; ExtAddList: ExtAddAlternative | ExtAddList COMMA_SYM SnaccDirectives ExtAddAlternative { CONCAT($1, $4); $$ = $1; } ; ExtAddAlternative: NamedType { $$ = NEWLIST(); PREPEND ($1, $$); } | LEFTBRACKET_SYM LEFTBRACKET_SYM VersionNumber AltList RIGHTBRACKET_SYM RIGHTBRACKET_SYM { $$ = $4; } ; AltList: NamedType { $$ = NEWLIST(); PREPEND ($1, $$); } |AltList COMMA_SYM NamedType { NamedType *firstElmt; if ($1 != NULL) { firstElmt = (NamedType*)FIRST_LIST_ELMT ($1); firstElmt->type->attrList = $1; } PREPEND ($3,$1); $$ = $1; } ; SelectionType: identifier LESSTHAN_SYM Type { /* * the selection type should be replaced after * link with actual type */ SetupType (&$$, BASICTYPE_SELECTION, myLineNoG); $$->basicType->a.selection = MT (SelectionType); $$->basicType->a.selection->typeRef = $3; $$->basicType->a.selection->fieldName = $1; } ; TaggedType: Tag Type { Tag *tag; /* remove next tag if any && IMPLICIT_TAGS */ if ((modulePtrG->tagDefault == IMPLICIT_TAGS) && ($2->tags != NULL) && !LIST_EMPTY ($2->tags)) { tag = (Tag*)FIRST_LIST_ELMT ($2->tags); /* set curr to first */ AsnListFirst ($2->tags); /* set curr to first elmt */ AsnListRemove ($2->tags); /* remove first elmt */ /* * set implicit if implicitly tagged built in type (ie not ref) * (this simplifies the module ASN.1 printer (print.c)) */ if (tag->tclass == UNIV) $2->implicit = TRUE; Free (tag); } PREPEND ($1, $2->tags); $$ = $2; } | Tag IMPLICIT_SYM Type { Tag *tag; /* remove next tag if any */ if (($3->tags != NULL) && !LIST_EMPTY ($3->tags)) { tag = (Tag*)FIRST_LIST_ELMT ($3->tags); /* set curr to first */ AsnListFirst ($3->tags); /* set curr to first elmt */ AsnListRemove ($3->tags); /* remove first elmt */ if (tag->tclass == UNIV) $3->implicit = TRUE; Free (tag); } /* * must check after linking that implicitly tagged * local/import type refs are not untagged choice/any etc */ else if (($3->basicType->choiceId == BASICTYPE_IMPORTTYPEREF) || ($3->basicType->choiceId == BASICTYPE_LOCALTYPEREF) || ($3->basicType->choiceId == BASICTYPE_SELECTION)) $3->implicit = TRUE; /* * all other implicitly tagable types should have tags * to remove - if this else clause fires then it is * probably a CHOICE or ANY type */ else { PrintErrLoc (modulePtrG->asn1SrcFileName, $3->lineNo); fprintf (errFileG, "ERROR - attempt to implicitly reference untagged type\n"); smallErrG = 1; } PREPEND ($1, $3->tags); $$ = $3; } | Tag EXPLICIT_SYM Type { /* insert tag at head of list */ $1->explicit = TRUE; PREPEND ($1, $3->tags); $$ = $3; } ; Tag: LEFTBRACKET_SYM Class ClassNumber RIGHTBRACKET_SYM { $$ = $3; $$->tclass = $2; $$->explicit = FALSE; /* default to false */ /* * keep track of APPLICATION Tags per module * should only be used once */ if (($2 == APPL) && ($$->valueRef == NULL)) { PushApplTag ($$->code, myLineNoG); } } ; ClassNumber: number { $$ = MT (Tag); $$->code = $1; } | DefinedValue { $$ = MT (Tag); $$->code = NO_TAG_CODE; $$->valueRef = $1; } ; Class: UNIVERSAL_SYM { $$ = UNIV; } | APPLICATION_SYM { $$ = APPL; } | PRIVATE_SYM { $$ = PRIV; } | empty { $$ = CNTX; } ; AnyType: ANY_SYM { SetupType (&$$, BASICTYPE_ANY, myLineNoG); } | ANY_SYM DEFINED_SYM BY_SYM identifier { SetupType (&$$, BASICTYPE_ANYDEFINEDBY, myLineNoG); $$->basicType->a.anyDefinedBy = MT (AnyDefinedByType); $$->basicType->a.anyDefinedBy->fieldName = $4; } ; OctetContainingType: OCTET_SYM STRING_SYM CONTAINING_SYM Type { SetupType (&$$, BASICTYPE_OCTETCONTAINING, myLineNoG); $$->basicType->a.stringContaining = $4; } | OCTET_SYM STRING_SYM LEFTPAREN_SYM CONTAINING_SYM Type RIGHTPAREN_SYM { SetupType (&$$, BASICTYPE_OCTETCONTAINING, myLineNoG); $$->basicType->a.stringContaining = $5; } ; BitContainingType: BIT_SYM STRING_SYM CONTAINING_SYM Type { SetupType (&$$, BASICTYPE_BITCONTAINING, myLineNoG); $$->basicType->a.stringContaining = $4; } | BIT_SYM STRING_SYM LEFTPAREN_SYM CONTAINING_SYM Type RIGHTPAREN_SYM { SetupType (&$$, BASICTYPE_BITCONTAINING, myLineNoG); $$->basicType->a.stringContaining = $5; } ; ObjectIdentifierType: OBJECT_IDENTIFIER_SYM { SetupType (&$$, BASICTYPE_OID, myLineNoG); } ; RelativeOIDType: RELATIVE_OID_SYM { SetupType (&$$, BASICTYPE_RELATIVE_OID, myLineNoG); } ; UsefulType: GENERALIZEDTIME_SYM { SetupType (&$$, BASICTYPE_GENERALIZEDTIME, myLineNoG); } | UTCTIME_SYM { SetupType (&$$, BASICTYPE_UTCTIME, myLineNoG); } | OBJECTDESCRIPTOR_SYM { SetupType (&$$, BASICTYPE_OBJECTDESCRIPTOR, myLineNoG); } ; CharStrType: NUMERICSTRING_SYM { SetupType (&$$, BASICTYPE_NUMERIC_STR, myLineNoG); } | PRINTABLESTRING_SYM { SetupType (&$$, BASICTYPE_PRINTABLE_STR, myLineNoG); } | IA5STRING_SYM { SetupType (&$$, BASICTYPE_IA5_STR, myLineNoG); } | BMPSTRING_SYM { SetupType (&$$, BASICTYPE_BMP_STR, myLineNoG); } | UNIVERSALSTRING_SYM { SetupType (&$$, BASICTYPE_UNIVERSAL_STR, myLineNoG); } | UTF8STRING_SYM { SetupType (&$$, BASICTYPE_UTF8_STR, myLineNoG); } | TELETEXSTRING_SYM { SetupType (&$$, BASICTYPE_T61_STR, myLineNoG); } | T61STRING_SYM { SetupType (&$$, BASICTYPE_T61_STR, myLineNoG); } | VIDEOTEXSTRING_SYM { SetupType (&$$, BASICTYPE_VIDEOTEX_STR, myLineNoG); } | VISIBLESTRING_SYM { SetupType (&$$, BASICTYPE_VISIBLE_STR, myLineNoG); } | ISO646STRING_SYM { SetupType (&$$, BASICTYPE_VISIBLE_STR, myLineNoG); } | GRAPHICSTRING_SYM { SetupType (&$$, BASICTYPE_GRAPHIC_STR, myLineNoG); } | GENERALSTRING_SYM { SetupType (&$$, BASICTYPE_GENERAL_STR, myLineNoG); } ; Subtype: Type SubtypeSpec { /* * append new subtype list to existing one (s) if any * with AND relation */ AppendSubtype (&$1->subtypes, $2, SUBTYPE_AND); $$ = $1; } | SET_SYM SizeConstraint OF_SYM Type { Subtype *s; SetupType (&$$, BASICTYPE_SETOF, myLineNoG); $$->basicType->a.setOf = $4; /* add size constraint */ s = MT (Subtype); s->choiceId = SUBTYPE_SINGLE; s->a.single = $2; AppendSubtype (&$$->subtypes, s, SUBTYPE_AND); } | SEQUENCE_SYM SizeConstraint OF_SYM Type { Subtype *s; SetupType (&$$, BASICTYPE_SEQUENCEOF, myLineNoG); $$->basicType->a.sequenceOf = $4; /* add size constraint */ s = MT (Subtype); s->choiceId = SUBTYPE_SINGLE; s->a.single = $2; AppendSubtype (&$$->subtypes, s, SUBTYPE_AND); } ; SubtypeSpec: LEFTPAREN_SYM SubtypeValueSetList RIGHTPAREN_SYM { $$ = $2; } ; SubtypeValueSetList: SubtypeValueSet { $$ = MT (Subtype); $$->choiceId = SUBTYPE_SINGLE; $$->a.single = $1; /* Subtype *s; OR relation between all elmts of in ValueSetList * $$ = MT (Subtype); $$->choiceId = SUBTYPE_OR; $$->a.or = NEWLIST(); s = MT (Subtype); s->choiceId = SUBTYPE_SINGLE; s->a.single = $1; APPEND (s, $$->a.or); */ } | SubtypeValueSetList BAR_SYM SubtypeValueSet { Subtype* s = MT (Subtype); s->choiceId = SUBTYPE_SINGLE; s->a.single = $3; if ($1->choiceId == SUBTYPE_OR) $$ = $1; else { $$ = MT (Subtype); $$->choiceId = SUBTYPE_OR; APPEND($1, $$->a.or); } APPEND(s, $$->a.or); } ; SubtypeValueSet: SingleValue | ContainedSubtype | ValueRange | PermittedAlphabet | SizeConstraint | InnerTypeConstraints | ExtensibleSubtype ; ExtensibleSubtype: ELLIPSIS_SYM { $$ = MT (SubtypeValue); } ; SingleValue: Value { $$ = MT (SubtypeValue); $$->choiceId = SUBTYPEVALUE_SINGLEVALUE; $$->a.singleValue = $1; } ; ContainedSubtype: INCLUDES_SYM Type { $$ = MT (SubtypeValue); $$->choiceId = SUBTYPEVALUE_CONTAINED; $$->a.contained = $2; } ; ValueRange: LowerEndPoint DOT_SYM DOT_SYM UpperEndPoint { $$ = MT (SubtypeValue); $$->choiceId = SUBTYPEVALUE_VALUERANGE; $$->a.valueRange = MT (ValueRangeSubtype); $$->a.valueRange->lowerEndValue = $1; $$->a.valueRange->upperEndValue = $4; } ; LowerEndPoint: LowerEndValue { $$ = MT (ValueRangeEndpoint); $$->valueInclusive = TRUE; $$->endValue = $1; } | LowerEndValue LESSTHAN_SYM { $$ = MT (ValueRangeEndpoint); $$->valueInclusive = FALSE; $$->endValue = $1; } ; UpperEndPoint: UpperEndValue { $$ = MT (ValueRangeEndpoint); $$->valueInclusive = TRUE; $$->endValue = $1; } | LESSTHAN_SYM UpperEndValue { $$ = MT (ValueRangeEndpoint); $$->valueInclusive = FALSE; $$->endValue = $2; } ; LowerEndValue: Value { $$ = $1; } | MIN_SYM { SetupValue (&$$, BASICVALUE_SPECIALINTEGER, myLineNoG); $$->basicValue->a.specialInteger = MIN_INT; } ; UpperEndValue: Value { $$ = $1; } | MAX_SYM { SetupValue (&$$, BASICVALUE_SPECIALINTEGER, myLineNoG); $$->basicValue->a.specialInteger = MAX_INT; } ; SizeConstraint: SIZE_SYM SubtypeSpec { $$ = MT (SubtypeValue); $$->choiceId = SUBTYPEVALUE_SIZECONSTRAINT; $$->a.sizeConstraint = $2; } | LEFTPAREN_SYM SIZE_SYM SubtypeSpec RIGHTPAREN_SYM { $$ = MT (SubtypeValue); $$->choiceId = SUBTYPEVALUE_SIZECONSTRAINT; $$->a.sizeConstraint = $3; } ; PermittedAlphabet: FROM_SYM SubtypeSpec { $$ = MT (SubtypeValue); $$->choiceId = SUBTYPEVALUE_PERMITTEDALPHABET; $$->a.permittedAlphabet = $2; } ; InnerTypeConstraints: WITH_SYM COMPONENT_SYM SingleTypeConstraint { $$ = MT (SubtypeValue); $$->choiceId = SUBTYPEVALUE_INNERSUBTYPE; $$->a.innerSubtype = $3; } | WITH_SYM COMPONENTS_SYM MultipleTypeConstraints { $$ = MT (SubtypeValue); $$->choiceId = SUBTYPEVALUE_INNERSUBTYPE; $$->a.innerSubtype = $3; } ; SingleTypeConstraint: SubtypeSpec { Constraint *constraint; /* this constrains the elmt of setof or seq of */ $$ = MT (InnerSubtype); $$->constraintType = SINGLE_CT; $$->constraints = NEWLIST(); constraint = MT (Constraint); APPEND (constraint, $$->constraints); constraint->valueConstraints = $1; } ; MultipleTypeConstraints: FullSpecification | PartialSpecification ; FullSpecification: LEFTBRACE_SYM TypeConstraints RIGHTBRACE_SYM { $$ = MT (InnerSubtype); $$->constraintType = FULL_CT; $$->constraints = $2; } ; PartialSpecification: LEFTBRACE_SYM ELLIPSIS_SYM COMMA_SYM TypeConstraints RIGHTBRACE_SYM { $$ = MT (InnerSubtype); $$->constraintType = PARTIAL_CT; $$->constraints = $4; } ; TypeConstraints: NamedConstraint { $$ = NEWLIST(); APPEND ($1, $$); } | TypeConstraints COMMA_SYM NamedConstraint { APPEND ($3, $1); $$ = $1; } ; NamedConstraint: identifier Constraint { $$ = $2; $$->fieldRef = $1; } | Constraint ; Constraint: ValueConstraint PresenceConstraint { $$ = MT (Constraint); $$->presenceConstraint = $2; $$->valueConstraints = $1; } ; ValueConstraint: SubtypeSpec { $$ = $1; } | empty { $$ = NULL; } ; PresenceConstraint: PRESENT_SYM { $$ = PRESENT_CT; } | ABSENT_SYM { $$ = ABSENT_CT; } | empty { $$ = EMPTY_CT; } | OPTIONAL_SYM { $$ = OPTIONAL_CT; } ; /*-----------------------------------------------------------------------*/ /* Value Notation Productions */ /*-----------------------------------------------------------------------*/ ValueAssignment: identifier Type GETS_SYM LineNo Value { $$ = MT (ValueDef); $$->definedName = $1; $$->value = $5; $$->value->lineNo = $4; $$->value->type = $2; } ; Value: BuiltinValue | DefinedValue ; DefinedValue: ExternalValueReference { $$ = $1; } | identifier /* a defined value or a named elmt ref */ { /* * for parse, may be set to BASICVALUE_IMPORTEDTYPEREF * by linker */ SetupValue (&$$, BASICVALUE_LOCALVALUEREF, myLineNoG); $$->basicValue->a.localValueRef = MT (ValueRef); $$->basicValue->a.localValueRef->valueName = $1; $$->valueType = BASICTYPE_UNKNOWN; } ; ExternalValueReference: modulereference DOT_SYM LineNo identifier { /* Alloc value with basicValue of importValueRef */ SetupValue (&$$, BASICVALUE_IMPORTVALUEREF, $3); $$->valueType = BASICTYPE_UNKNOWN; $$->basicValue->a.importValueRef = MT (ValueRef); $$->basicValue->a.importValueRef->valueName = $4; $$->basicValue->a.importValueRef->moduleName = $1; /* add entry to this module's import list */ AddPrivateImportElmt (modulePtrG, $4, $1, $3); } ; BuiltinValue: BooleanValue | NullValue | SpecialRealValue | SignedNumber /* IntegerValue or "0" real val*/ { SetupValue (&$$, BASICVALUE_INTEGER, myLineNoG); $$->valueType = BASICTYPE_UNKNOWN; $$->basicValue->a.integer = $1; } | HexString /* OctetStringValue or BinaryStringValue */ { SetupValue (&$$, BASICVALUE_ASCIIHEX, myLineNoG); $$->valueType = BASICTYPE_UNKNOWN; $$->basicValue->a.asciiHex = MT (AsnOcts); $$->basicValue->a.asciiHex->octs = $1; $$->basicValue->a.asciiHex->octetLen = strlen ($1); } | BinaryString /* BinaryStringValue */ { SetupValue (&$$, BASICVALUE_ASCIIBITSTRING, myLineNoG); $$->valueType = BASICTYPE_UNKNOWN; $$->basicValue->a.asciiBitString = MT (AsnOcts); $$->basicValue->a.asciiBitString->octs = $1; $$->basicValue->a.asciiBitString->octetLen = strlen ($1); } | CharString { SetupValue (&$$, BASICVALUE_ASCIITEXT, myLineNoG); $$->valueType = BASICTYPE_UNKNOWN; $$->basicValue->a.asciiText = MT (AsnOcts); $$->basicValue->a.asciiText->octs = $1; $$->basicValue->a.asciiText->octetLen = strlen ($1); } | LEFTBRACE_SYM { LexBeginBraceBalContext(); } BRACEBAL_SYM { /* * LEXICAL TIE IN!! * string returned by BRACEBAL_SYM has * the $1 '{' prepended and includes everything * upto and including '}' that balances $1 */ LexBeginInitialContext(); SetupValue (&$$, BASICVALUE_VALUENOTATION, myLineNoG); $$->basicValue->a.valueNotation = MT (AsnOcts); $$->basicValue->a.valueNotation->octs = $3; $$->basicValue->a.valueNotation->octetLen = strlen ($3); $$->valueType = BASICTYPE_UNKNOWN; } ; BooleanValue: TRUE_SYM { SetupValue (&$$, BASICVALUE_BOOLEAN, myLineNoG); $$->valueType = BASICTYPE_UNKNOWN; $$->basicValue->a.boolean = TRUE; } | FALSE_SYM { SetupValue (&$$, BASICVALUE_BOOLEAN, myLineNoG); $$->valueType = BASICTYPE_UNKNOWN; $$->basicValue->a.boolean = FALSE; } ; SpecialRealValue: PLUS_INFINITY_SYM { SetupValue (&$$, BASICVALUE_SPECIALREAL, myLineNoG); $$->valueType = BASICTYPE_UNKNOWN; $$->basicValue->a.specialReal = PLUS_INFINITY_REAL; } | MINUS_INFINITY_SYM { SetupValue (&$$, BASICVALUE_SPECIALREAL, myLineNoG); $$->valueType = BASICTYPE_UNKNOWN; $$->basicValue->a.specialReal = MINUS_INFINITY_REAL; } ; NullValue: NULL_SYM { /* create a NULL value */ SetupValue (&$$, BASICVALUE_NULL, myLineNoG); $$->valueType = BASICTYPE_UNKNOWN; } ; NamedValue: Value { $$ = MT (NamedValue); $$->value = $1; } | identifier Value { $$ = MT (NamedValue); $$->value = $2; $$->fieldName = $1; } ; ObjectIdentifierValue: LEFTBRACE_SYM ObjIdComponentList RIGHTBRACE_SYM { /* * example OID setup * * for { ccitt foo (1) bar bell (bunt) 2 } * * ccitt * - arcnum is set to number from oid table (oid.c) * foo (1) * - sets up a new value def foo defined as 1 * - makes oid valueref a value ref to foo (doesn't link it tho) * bar * - makes oid valueref a value ref to bar (doesn't link it tho) * bell (bunt) * - sets up a new value def bell defined as a val ref to bunt * - makes oid valueref a value ref to bell (doesn't link it tho) * 2 * - arcnum is set to 2 */ $$ = $2; } ; ObjIdComponentList: ObjIdComponentList ObjIdComponent { OID *o; /* append component */ for (o = $1; o->next != NULL; o = o->next) ; o->next = $2; $$ = $1; } | ObjIdComponent ; ObjIdComponent: NumberForm | NameForm { Value *newVal; /* * if the arcName is a defined arc name like * ccitt or iso etc, fill in the arc number. * otherwise make a value ref to that named value */ $$ = MT (OID); $$->arcNum = OidArcNameToNum ($1); if ($$->arcNum == NULL_OID_ARCNUM) { /* set up value ref to named value */ SetupValue (&newVal, BASICVALUE_LOCALVALUEREF, myLineNoG); newVal->basicValue->a.localValueRef = MT (ValueRef); newVal->valueType = BASICTYPE_INTEGER; newVal->basicValue->a.localValueRef->valueName = $1; $$->valueRef = newVal; } } | NameAndNumberForm ; NumberForm: number { $$ = MT (OID); $$->arcNum = $1; } ; NameForm: identifier ; NameAndNumberForm: identifier LEFTPAREN_SYM NumberForm RIGHTPAREN_SYM { /* Value *newVal; // REN -- 9/23/02 */ $$ = $3; /* shared refs to named numbers name // REN -- 9/23/02 -- SetupValue (&newVal, BASICVALUE_INTEGER, myLineNoG); newVal->basicValue->a.integer = $$->arcNum; newVal->valueType = BASICTYPE_INTEGER; AddNewValueDef (oidElmtValDefsG, $1, newVal); SetupValue (&newVal, BASICVALUE_LOCALVALUEREF, myLineNoG); newVal->basicValue->a.localValueRef = MT (ValueRef); newVal->basicValue->a.localValueRef->valueName = $1; $$->valueRef = newVal; */ Free($1); // REN -- 9/23/02 } | identifier LEFTPAREN_SYM DefinedValue RIGHTPAREN_SYM { /* Value *newVal; // REN -- 9/23/02 */ /* shared refs to named numbers name */ $$ = MT (OID); $$->arcNum = NULL_OID_ARCNUM; /* AddNewValueDef (oidElmtValDefsG, $1, $3); // REN -- 9/23/02 */ $$->valueRef = $3; Free($1); // REN -- 9/23/02 } ; BinaryString: BSTRING_SYM ; HexString: HSTRING_SYM ; CharString: CSTRING_SYM ; number: NUMBER_SYM { if ($1>0x7FFFFFFF) { yyerror("Warning: number out of range"); $$ = 0x7FFFFFFF; } } | NUMBER_ERANGE { yyerror ("Warning: number out of range"); $$ = 0x7FFFFFFF; /* modulePtrG->status = MOD_ERROR; */ } ; identifier: LCASEFIRST_IDENT_SYM ; modulereference: UCASEFIRST_IDENT_SYM ; typereference: UCASEFIRST_IDENT_SYM ; empty: ; /* Snacc compiler directives/extra type info * - encapsulated in special comments */ SnaccDirectives: SnaccDirectiveList | empty { $$ = NULL; } ; SnaccDirectiveList: SnaccDirective { $$ = NEWLIST(); APPEND ($1,$$); } | SnaccDirectiveList SnaccDirective { APPEND ($2,$1); $$ = $1; } ; SnaccDirective: ATTRIB_ASN1_TYPE_ID ':' SnaccDirectiveAsnTypeValue { $$ = MT (SnaccDirective); $$->type = ASN1_TypeID; $$->value.asnTypeVal = $3; } | ATTRIB_C_TYPE_ID ':' SnaccDirectiveCTypeValue { $$ = MT (SnaccDirective); $$->type = C_TypeID; $$->value.cTypeVal = $3; } | SnaccDirectiveBoolType ':' SnaccDirectiveBoolValue { $$ = MT (SnaccDirective); $$->type = $1; $$->value.boolVal = $3; } | SnaccDirectiveStringType ':' CSTRING_SYM { $$ = MT (SnaccDirective); $$->type = $1; $$->value.stringVal = $3; } | SnaccDirectiveIntegerType ':' NUMBER_SYM { $$ = MT (SnaccDirective); $$->type = $1; $$->value.integerVal = $3; } ; SnaccDirectiveAsnTypeValue: UNKNOWN_SYM { $$ = BASICTYPE_UNKNOWN; } | BOOLEAN_SYM { $$ = BASICTYPE_BOOLEAN; } | INTEGER_SYM { $$ = BASICTYPE_INTEGER; } | BITSTRING_SYM { $$ = BASICTYPE_BITSTRING; } | OCTETSTRING_SYM { $$ = BASICTYPE_OCTETSTRING; } | NULL_SYM { $$ = BASICTYPE_NULL; } | OBJECT_IDENTIFIER_SYM { $$ = BASICTYPE_OID; } | REAL_SYM { $$ = BASICTYPE_REAL; } | ENUMERATED_SYM { $$ = BASICTYPE_ENUMERATED; } | SEQUENCE_SYM { $$ = BASICTYPE_SEQUENCE; } | SEQUENCE_OF_SYM { $$ = BASICTYPE_SEQUENCEOF; } | SET_SYM { $$ = BASICTYPE_SET; } | SET_OF_SYM { $$ = BASICTYPE_SETOF; } | CHOICE_SYM { $$ = BASICTYPE_CHOICE; } | ANY_SYM { $$ = BASICTYPE_ANY; } | ANY_DEFINED_BY_SYM { $$ = BASICTYPE_ANYDEFINEDBY; } | LOCAL_TYPE_REF_SYM { $$ = BASICTYPE_LOCALTYPEREF; } | IMPORT_TYPE_REF_SYM { $$ = BASICTYPE_IMPORTTYPEREF; } | NUMERICSTRING_SYM { $$ = BASICTYPE_NUMERIC_STR; } | PRINTABLESTRING_SYM { $$ = BASICTYPE_PRINTABLE_STR; } | IA5STRING_SYM { $$ = BASICTYPE_IA5_STR; } | BMPSTRING_SYM { $$ = BASICTYPE_BMP_STR; } | UNIVERSALSTRING_SYM { $$ = BASICTYPE_UNIVERSAL_STR; } | UTF8STRING_SYM { $$ = BASICTYPE_UTF8_STR; } | TELETEXSTRING_SYM { $$ = BASICTYPE_T61_STR; } | RELATIVE_OID_SYM { $$ = BASICTYPE_RELATIVE_OID; } ; SnaccDirectiveCTypeValue: C_CHOICE_SYM { $$ = C_CHOICE; } | C_LIST_SYM { $$ = C_LIST; } | C_ANY_SYM { $$ = C_ANY; } | C_ANYDEFBY_SYM { $$ = C_ANYDEFINEDBY; } | C_LIB_SYM { $$ = C_LIB; } | C_STRUCT_SYM { $$ = C_STRUCT; } | C_TYPEDEF_SYM { $$ = C_TYPEDEF; } | C_TYPEREF_SYM { $$ = C_TYPEREF; } | C_NO_TYPE_SYM { $$ = C_NO_TYPE; } ; SnaccDirectiveBoolType: ATTRIB_IS_PDU_SYM { $$ = IsPDU; } | ATTRIB_IS_PTR_SYM { $$ = IsPtr; } | ATTRIB_IS_PTR_TYPEDEF_SYM { $$ = IsPtrForTypeDef; } | ATTRIB_IS_PTR_TYPE_REF_SYM { $$ = IsPtrForTypeRef; } | ATTRIB_IS_PTR_IN_CHOICE_SYM { $$ = IsPtrInChoice; } | ATTRIB_IS_PTR_FOR_OPT_SYM { $$ = IsPtrForOpt; } | ATTRIB_IS_ENC_DEC_SYM { $$ = IsEncDec; } | ATTRIB_GEN_TYPEDEF_SYM { $$ = GenTypeDef; } | ATTRIB_GEN_PRINT_ROUTINE_SYM { $$ = GenPrintRoutine; } | ATTRIB_GEN_ENCODE_ROUTINE_SYM { $$ = GenEncodeRoutine; } | ATTRIB_GEN_DECODE_ROUTINE_SYM { $$ = GenDecodeRoutine; } | ATTRIB_GEN_FREE_ROUTINE_SYM { $$ = GenFreeRoutine; } | ATTRIB_IS_BIG_INT_SYM { $$ = IsBigInt; } ; SnaccDirectiveBoolValue: TRUE_SYM { $$ = TRUE; } | FALSE_SYM { $$ = FALSE; } ; SnaccDirectiveStringType: ATTRIB_C_TYPE_NAME_SYM { $$ = C_TypeName; } | ATTRIB_C_FIELD_NAME_SYM { $$ = C_FieldName; } | ATTRIB_OPT_TEST_ROUTINE_SYM { $$ = OptionalTestRoutineName; } | ATTRIB_DEFAULT_FIELD_SYM { $$ = DefaultFieldName; } | ATTRIB_PRINT_ROUTINE_SYM { $$ = PrintRoutineName; } | ATTRIB_ENCODE_ROUTINE_SYM { $$ = EncodeRoutineName; } | ATTRIB_DECODE_ROUTINE_SYM { $$ = DecodeRoutineName; } | ATTRIB_FREE_ROUTINE_SYM { $$ = FreeRoutineName; } | ATTRIB_CHOICE_ID_SYMBOL_SYM { $$ = ChoiceIdSymbol; } | ATTRIB_CHOICE_ID_ENUM_NAME_SYM { $$ = ChoiceIdEnumName; } | ATTRIB_CHOICE_ID_ENUM_FIELD_NAME_SYM { $$ = ChoiceIdEnumFieldName; } ; SnaccDirectiveIntegerType: ATTRIB_CHOICE_ID_VALUE_SYM { $$ = ChoiceIdValue; } ; /* * Macro Syntax definitions **************************/ DefinedMacroType: RosOperationMacroType | RosErrorMacroType | RosBindMacroType | RosUnbindMacroType | RosAseMacroType | RosAcMacroType | MtsasExtensionMacroType | MtsasExtensionsMacroType | MtsasExtensionAttributeMacroType | MtsasTokenMacroType | MtsasTokenDataMacroType | MtsasSecurityCategoryMacroType | AsnObjectMacroType | AsnPortMacroType | AsnRefineMacroType | AsnAbstractBindMacroType | AsnAbstractUnbindMacroType | AsnAbstractOperationMacroType | AsnAbstractErrorMacroType | AfAlgorithmMacroType | AfEncryptedMacroType | AfProtectedMacroType | AfSignatureMacroType | AfSignedMacroType | SnmpObjectTypeMacroType ; DefinedMacroName: OPERATION_SYM { $$ = "OPERATION"; } | ERROR_SYM { $$ = "ERROR"; } | BIND_SYM { $$ = "BIND"; } | UNBIND_SYM { $$ = "UNBIND"; } | ASE_SYM { $$ = "APPLICATION-SERVICE-ELEMENT"; } | AC_SYM { $$ = "APPLICATION-CONTEXT"; } | EXTENSION_SYM { $$ = "EXTENSION"; } | EXTENSIONS_SYM { $$ = "EXTENSIONS"; } | EXTENSIONATTRIBUTE_SYM { $$ = "EXTENSION-ATTRIBUTE"; } | TOKEN_SYM { $$ = "TOKEN"; } | TOKENDATA_SYM { $$ = "TOKEN-DATA"; } | SECURITYCATEGORY_SYM { $$ = "SECURITY-CATEGORY"; } | OBJECT_SYM { $$ = "OBJECT"; } | PORT_SYM { $$ = "PORT"; } | REFINE_SYM { $$ = "REFINE"; } | ABSTRACTBIND_SYM { $$ = "ABSTRACT-BIND"; } | ABSTRACTUNBIND_SYM { $$ = "ABSTRACT-UNBIND"; } | ABSTRACTOPERATION_SYM { $$ = "ABSTRACT-OPERATION"; } | ABSTRACTERROR_SYM { $$ = "ABSTRACT-ERROR"; } | ALGORITHM_SYM { $$ = "ALGORITHM"; } | ENCRYPTED_SYM { $$ = "ENCRYPTED"; } | SIGNED_SYM { $$ = "SIGNED"; } | SIGNATURE_SYM { $$ = "SIGNATURE"; } | PROTECTED_SYM { $$ = "PROTECTED"; } | OBJECTTYPE_SYM { $$ = "OBJECT-TYPE"; } ; /* * Operation Macro (ROS) added by MS 91/08/27 */ RosOperationMacroType: OPERATION_SYM RosOperationMacroBody { $$ = $2; } ; RosOperationMacroBody: RosOpArgument RosOpResult RosOpErrors RosOpLinkedOps { RosOperationMacroType *r; SetupMacroType (&$$, MACROTYPE_ROSOPERATION, myLineNoG); r = $$->basicType->a.macroType->a.rosOperation = MT (RosOperationMacroType); r->arguments = $1; r->result = $2; r->errors = $3; r->linkedOps = $4; } ; RosOpArgument: ARGUMENT_SYM NamedType { $$ = $2; } | empty { $$ = NULL; } ; RosOpResult: RESULT_SYM RosOpResultType { $$ = $2; } | empty { $$ = NULL; } ; RosOpResultType: NamedType | empty { $$ = NULL; } ; RosOpErrors: ERRORS_SYM LEFTBRACE_SYM PossiblyEmptyTypeOrValueList RIGHTBRACE_SYM { $$ = $3; } | empty { $$ = NULL; } ; RosOpLinkedOps: LINKED_SYM LEFTBRACE_SYM PossiblyEmptyTypeOrValueList RIGHTBRACE_SYM { $$ = $3; } | empty { $$ = NULL; } ; /* * ROS ERROR macro - ms 91/08/27 */ RosErrorMacroType: ERROR_SYM RosErrParameter { RosErrorMacroType *r; /* * defines error macro type */ SetupMacroType (&$$, MACROTYPE_ROSERROR, myLineNoG); r = $$->basicType->a.macroType->a.rosError = MT (RosErrorMacroType); r->parameter = $2; } ; RosErrParameter: PARAMETER_SYM NamedType { $$ = $2; } | empty { $$ = NULL; } ; /* * ROS BIND macro - ms 91/09/13 */ RosBindMacroType: BIND_SYM RosBindArgument RosBindResult RosBindError { RosBindMacroType *r; SetupMacroType (&$$, MACROTYPE_ROSBIND, myLineNoG); r = $$->basicType->a.macroType->a.rosBind = MT (RosBindMacroType); r->argument = $2; r->result = $3; r->error = $4; } ; RosBindArgument: ARGUMENT_SYM NamedType { $$ = $2; } | empty { $$ = NULL; } ; RosBindResult: RESULT_SYM NamedType { $$ = $2; } | empty { $$ = NULL; } ; RosBindError: BINDERROR_SYM NamedType { $$ = $2; } | empty { $$ = NULL; } ; /* * ROS UNBIND ms 91/09/13 */ RosUnbindMacroType: UNBIND_SYM RosBindArgument RosBindResult RosUnbindError { RosBindMacroType *r; SetupMacroType (&$$, MACROTYPE_ROSUNBIND, myLineNoG); r = $$->basicType->a.macroType->a.rosUnbind = MT (RosBindMacroType); r->argument = $2; r->result = $3; r->error = $4; } ; RosUnbindError: UNBINDERROR_SYM NamedType { $$ = $2; } | empty { $$ = NULL; } ; /* * ROS APPLICATION-SERVICE-ELEMENT macro ms 91/09/13 */ RosAseMacroType: ASE_SYM RosAseSymmetricAse { RosAseMacroType *r; SetupMacroType (&$$, MACROTYPE_ROSASE, myLineNoG); r = $$->basicType->a.macroType->a.rosAse = MT (RosAseMacroType); r->operations = $2; } | ASE_SYM RosAseConsumerInvokes RosAseSupplierInvokes { RosAseMacroType *r; SetupMacroType (&$$, MACROTYPE_ROSASE, myLineNoG); r = $$->basicType->a.macroType->a.rosAse = MT (RosAseMacroType); r->consumerInvokes = $2; r->supplierInvokes = $3; } ; RosAseSymmetricAse: OPERATIONS_SYM LEFTBRACE_SYM RosAseOperationList RIGHTBRACE_SYM { $$ = $3; } ; RosAseConsumerInvokes: CONSUMERINVOKES_SYM LEFTBRACE_SYM RosAseOperationList RIGHTBRACE_SYM { $$ = $3; } | empty { $$ = NULL; } ; RosAseSupplierInvokes: SUPPLIERINVOKES_SYM LEFTBRACE_SYM RosAseOperationList RIGHTBRACE_SYM { $$ = $3; } | empty { $$ = NULL; } ; RosAseOperationList: ValueList ; /* * ROS APPLICATION-CONTEXT macro ms 91/09/13 */ RosAcMacroType: AC_SYM RosAcNonRoElements BIND_SYM Type UNBIND_SYM Type RosAcRoElements RosAcAbstractSyntaxes { RosAcMacroType *r; SetupMacroType (&$$, MACROTYPE_ROSAC, myLineNoG); r = $$->basicType->a.macroType->a.rosAc = MT (RosAcMacroType); r->nonRoElements = $2; r->bindMacroType = $4; r->unbindMacroType = $6; r->remoteOperations = $7; r->operationsOf = rosAcSymmetricAsesG; r->initiatorConsumerOf = rosAcInitiatorConsumerOfG; r->responderConsumerOf = rosAcResponderConsumerOfG; r->abstractSyntaxes = $8; } ; RosAcNonRoElements: ASES_SYM LEFTBRACE_SYM ValueList RIGHTBRACE_SYM { $$ = $3; } ; RosAcRoElements: REMOTE_SYM OPERATIONS_SYM LEFTBRACE_SYM Value RIGHTBRACE_SYM RosAcSymmetricAses RosAcAsymmetricAses { $$ = $4; } | empty { $$ = NULL; rosAcSymmetricAsesG = NULL; rosAcInitiatorConsumerOfG = NULL; rosAcResponderConsumerOfG = NULL; } ; RosAcSymmetricAses: OPERATIONS_SYM OF_SYM LEFTBRACE_SYM ValueList RIGHTBRACE_SYM { rosAcSymmetricAsesG = $4; } | empty { rosAcSymmetricAsesG = NULL; } ; RosAcAsymmetricAses: RosAcInitiatorConsumerOf RosAcResponderConsumerOf ; RosAcInitiatorConsumerOf: INITIATOR_SYM CONSUMER_SYM OF_SYM LEFTBRACE_SYM ValueList RIGHTBRACE_SYM { rosAcInitiatorConsumerOfG = $5; } | empty { rosAcInitiatorConsumerOfG = NULL; } ; RosAcResponderConsumerOf: RESPONDER_SYM CONSUMER_SYM OF_SYM LEFTBRACE_SYM ValueList RIGHTBRACE_SYM { rosAcResponderConsumerOfG = $5; } | empty { rosAcResponderConsumerOfG = NULL; } ; RosAcAbstractSyntaxes: ABSTRACTSYNTAXES_SYM LEFTBRACE_SYM OidList RIGHTBRACE_SYM { $$ = $3; } | empty { $$ = NULL; } ; OidList: ObjectIdentifierValue { $$ = NEWLIST(); APPEND ($1,$$); } | OidList COMMA_SYM ObjectIdentifierValue { APPEND ($3, $1); $$ = $1; } ; /* * MTSAbstractSvc EXTENSIONS macro */ MtsasExtensionsMacroType: EXTENSIONS_SYM CHOSEN_SYM FROM_SYM LEFTBRACE_SYM PossiblyEmptyValueList RIGHTBRACE_SYM { MtsasExtensionsMacroType *m; SetupMacroType (&$$, MACROTYPE_MTSASEXTENSIONS, myLineNoG); m = $$->basicType->a.macroType->a.mtsasExtensions = MT (MtsasExtensionsMacroType); m->extensions = $5; } ; PossiblyEmptyValueList: ValueList | empty { $$ = NULL; } ; ValueList: Value { $$ = NEWLIST(); APPEND ($1, $$); } | ValueList COMMA_SYM Value { APPEND ($3,$1); $$ = $1; } ; PossiblyEmptyTypeOrValueList: TypeOrValueList | empty { $$ = NULL; } ; TypeOrValueList: TypeOrValue { $$ = NEWLIST(); APPEND ($1, $$); } | TypeOrValueList COMMA_SYM TypeOrValue { APPEND ($3,$1); $$ = $1; } ; TypeOrValue: Type { $$ = MT (TypeOrValue); $$->choiceId = TYPEORVALUE_TYPE; $$->a.type = $1; } | Value { $$ = MT (TypeOrValue); $$->choiceId = TYPEORVALUE_VALUE; $$->a.value = $1; } ; /* * MTSAbstractSvc EXTENSION macro */ MtsasExtensionMacroType: EXTENSION_SYM NamedType MtsasExtDefaultVal MtsasExtCritical { MtsasExtensionMacroType *m; SetupMacroType (&$$, MACROTYPE_MTSASEXTENSION, myLineNoG); m = $$->basicType->a.macroType->a.mtsasExtension = MT (MtsasExtensionMacroType); m->elmtType = $2; m->defaultValue = $3; m->criticalForSubmission = mtsasCriticalForSubmissionG; m->criticalForTransfer = mtsasCriticalForTransferG; m->criticalForDelivery = mtsasCriticalForDeliveryG; mtsasCriticalForSubmissionG = NULL; /* set up for next parse */ mtsasCriticalForTransferG = NULL; mtsasCriticalForDeliveryG = NULL; } | EXTENSION_SYM { SetupMacroType (&$$, MACROTYPE_MTSASEXTENSION, myLineNoG); $$->basicType->a.macroType->a.mtsasExtension = MT (MtsasExtensionMacroType); /* * all fields are NULL in the MtsasExtensionsMacroType * for this production */ } ; MtsasExtDefaultVal: DEFAULT_SYM Value { $$ = $2; } | empty { $$ = NULL; } ; MtsasExtCritical: CRITICAL_SYM FOR_SYM MtsasExtCriticalityList | empty ; MtsasExtCriticalityList: MtsasExtCriticality | MtsasExtCriticalityList COMMA_SYM MtsasExtCriticality ; MtsasExtCriticality: SUBMISSION_SYM { mtsasCriticalForSubmissionG = MT (AsnBool); *mtsasCriticalForSubmissionG = TRUE; } | TRANSFER_SYM { mtsasCriticalForTransferG = MT (AsnBool); *mtsasCriticalForTransferG = TRUE; } | DELIVERY_SYM { mtsasCriticalForDeliveryG = MT (AsnBool); *mtsasCriticalForDeliveryG = TRUE; } ; /* * MTSAbstractSvc X.411 EXTENSION-ATTRIBUTE macro */ MtsasExtensionAttributeMacroType: EXTENSIONATTRIBUTE_SYM { MtsasExtensionAttributeMacroType *m; SetupMacroType (&$$, MACROTYPE_MTSASEXTENSIONATTRIBUTE, myLineNoG); m = $$->basicType->a.macroType->a.mtsasExtensionAttribute = MT (MtsasExtensionAttributeMacroType); m->type = NULL; } | EXTENSIONATTRIBUTE_SYM Type { MtsasExtensionAttributeMacroType *m; SetupMacroType (&$$, MACROTYPE_MTSASEXTENSIONATTRIBUTE, myLineNoG); m = $$->basicType->a.macroType->a.mtsasExtensionAttribute = MT (MtsasExtensionAttributeMacroType); m->type = $2; } ; /* * X.411 MTSAbstractSvc TOKEN macro */ MtsasTokenMacroType: TOKEN_SYM { MtsasTokenMacroType *m; SetupMacroType (&$$, MACROTYPE_MTSASTOKEN, myLineNoG); m = $$->basicType->a.macroType->a.mtsasToken = MT (MtsasTokenMacroType); m->type = NULL; } | TOKEN_SYM Type { MtsasTokenMacroType *m; SetupMacroType (&$$, MACROTYPE_MTSASTOKEN, myLineNoG); m = $$->basicType->a.macroType->a.mtsasToken = MT (MtsasTokenMacroType); m->type = $2; } ; /* * X.411 MTSAS TOKEN-DATA macro type */ MtsasTokenDataMacroType: TOKENDATA_SYM { MtsasTokenDataMacroType *m; SetupMacroType (&$$, MACROTYPE_MTSASTOKENDATA, myLineNoG); m = $$->basicType->a.macroType->a.mtsasTokenData = MT (MtsasTokenDataMacroType); m->type = NULL; } | TOKENDATA_SYM Type { MtsasTokenDataMacroType *m; SetupMacroType (&$$, MACROTYPE_MTSASTOKENDATA, myLineNoG); m = $$->basicType->a.macroType->a.mtsasTokenData = MT (MtsasTokenDataMacroType); m->type = $2; } ; /* * X.411 MTSAS SECURITY-CATEGORY */ MtsasSecurityCategoryMacroType: SECURITYCATEGORY_SYM { MtsasSecurityCategoryMacroType *m; SetupMacroType (&$$, MACROTYPE_MTSASSECURITYCATEGORY, myLineNoG); m = $$->basicType->a.macroType->a.mtsasSecurityCategory = MT (MtsasSecurityCategoryMacroType); m->type = NULL; } | SECURITYCATEGORY_SYM Type { MtsasSecurityCategoryMacroType *m; SetupMacroType (&$$, MACROTYPE_MTSASSECURITYCATEGORY, myLineNoG); m = $$->basicType->a.macroType->a.mtsasSecurityCategory = MT (MtsasSecurityCategoryMacroType); m->type = $2; } ; /* * X.407 Abstract Service Notation Macro Type productions * MS 91/09/14 */ /* * OBJECT Macro X.407 */ AsnObjectMacroType: OBJECT_SYM AsnPorts { AsnObjectMacroType *a; SetupMacroType (&$$, MACROTYPE_ASNOBJECT, myLineNoG); a = $$->basicType->a.macroType->a.asnObject = MT (AsnObjectMacroType); a->ports = $2; } ; AsnPorts: PORTS_SYM LEFTBRACE_SYM AsnPortList RIGHTBRACE_SYM { $$ = $3; } | empty { $$ = NULL; } ; AsnPortList: AsnPort { $$ = NEWLIST(); APPEND ($1, $$); } | AsnPortList COMMA_SYM AsnPort { APPEND ($3, $1); $$ = $1; } ; AsnPort: Value AsnPortType { $$ = MT (AsnPort); $$->portValue = $1; $$->portType = $2; } ; AsnPortType: BOXC_SYM { /* [C] consumer */ $$ = CONSUMER_PORT; } | BOXS_SYM { /* [S] supplier */ $$ = SUPPLIER_PORT; } | empty { /* symmetric */ $$ = SYMMETRIC_PORT; } ; /* * PORT Macro X.407 */ AsnPortMacroType: PORT_SYM AsnOperations { AsnPortMacroType *a; SetupMacroType (&$$, MACROTYPE_ASNPORT, myLineNoG); a = $$->basicType->a.macroType->a.asnPort = MT (AsnPortMacroType); a->abstractOps = $2; a->consumerInvokes = asnConsumerG; a->supplierInvokes = asnSupplierG; } | PORT_SYM { SetupMacroType (&$$, MACROTYPE_ASNPORT, myLineNoG); $$->basicType->a.macroType->a.asnPort = MT (AsnPortMacroType); } ; AsnOperations: ABSTRACTOPS_SYM LEFTBRACE_SYM TypeOrValueList RIGHTBRACE_SYM { $$ = $3; } | AsnConsumer { $$ = NULL; asnConsumerG = $1; asnSupplierG = NULL; } | AsnSupplier { $$ = NULL; asnConsumerG = $1; asnSupplierG = NULL; } | AsnConsumer AsnSupplier { $$ = NULL; asnConsumerG = $1; asnSupplierG = NULL; } | AsnSupplier AsnConsumer { $$ = NULL; asnConsumerG = $1; asnSupplierG = NULL; } ; AsnConsumer: CONSUMERINVOKES_SYM LEFTBRACE_SYM TypeOrValueList RIGHTBRACE_SYM { $$ = $3; } ; AsnSupplier: SUPPLIERINVOKES_SYM LEFTBRACE_SYM TypeOrValueList RIGHTBRACE_SYM { $$ = $3; } ; /* * REFINE Macro X.407 * * just parse it - don't keep any info at the moment */ AsnRefineMacroType: REFINE_SYM AsnObject AS_SYM AsnComponentList { SetupType (&$$, BASICTYPE_UNKNOWN, myLineNoG); } ; AsnComponentList: AsnComponent | AsnComponentList COMMA_SYM AsnComponent ; AsnComponent: AsnObjectSpec AsnPortSpecList ; AsnObjectSpec: AsnObject | AsnObject RECURRING_SYM ; AsnPortSpecList: AsnPortSpec | AsnPortSpecList COMMA_SYM AsnPortSpec ; AsnPortSpec: Value AsnPortType AsnPortStatus { $$ = 0; /* just to quiet yacc warning */ } ; AsnPortStatus: VISIBLE_SYM | PAIRED_SYM WITH_SYM AsnObjectList ; AsnObjectList: AsnObject | AsnObjectList COMMA_SYM AsnObject ; AsnObject: Value { $$ = 0; /* just to quiet yacc warning */ } ; /* * ABSTRACT-BIND Macro X.407 */ AsnAbstractBindMacroType: ABSTRACTBIND_SYM AsnAbstractBindPorts { AsnAbstractBindMacroType *a; SetupMacroType (&$$, MACROTYPE_ASNABSTRACTBIND, myLineNoG); a = $$->basicType->a.macroType->a.asnAbstractBind = MT (AsnAbstractBindMacroType); a->ports = $2; } | ABSTRACTBIND_SYM AsnAbstractBindPorts Type { AsnAbstractBindMacroType *a; SetupMacroType (&$$, MACROTYPE_ASNABSTRACTBIND, myLineNoG); a = $$->basicType->a.macroType->a.asnAbstractBind = MT (AsnAbstractBindMacroType); a->ports = $2; a->type = $3; } ; AsnAbstractBindPorts: TO_SYM LEFTBRACE_SYM AsnPortList RIGHTBRACE_SYM { $$ = $3; } | empty { $$ = NULL; } ; /* * ABSTRACT-UNBIND Macro X.407 */ AsnAbstractUnbindMacroType: ABSTRACTUNBIND_SYM AsnAbstractUnbindPorts { AsnAbstractBindMacroType *a; SetupMacroType (&$$, MACROTYPE_ASNABSTRACTUNBIND, myLineNoG); a = $$->basicType->a.macroType->a.asnAbstractUnbind = MT (AsnAbstractBindMacroType); a->ports = $2; } | ABSTRACTUNBIND_SYM AsnAbstractUnbindPorts Type { AsnAbstractBindMacroType *a; SetupMacroType (&$$, MACROTYPE_ASNABSTRACTUNBIND, myLineNoG); a = $$->basicType->a.macroType->a.asnAbstractUnbind = MT (AsnAbstractBindMacroType); a->ports = $2; a->type = $3; } ; AsnAbstractUnbindPorts: FROM_SYM LEFTBRACE_SYM AsnPortList RIGHTBRACE_SYM { $$ = $3; } | empty { $$ = NULL; } ; /* * ABSTRACT-OPERATION Macro X.407 (same as ROS Operation) */ AsnAbstractOperationMacroType: ABSTRACTOPERATION_SYM RosOperationMacroBody { $$ = $2; $2->basicType->a.macroType->choiceId = MACROTYPE_ASNABSTRACTOPERATION; } ; /* * ABSTRACT-ERROR Macro X.407 (same as ROS Error) */ AsnAbstractErrorMacroType: ABSTRACTERROR_SYM RosErrParameter { SetupMacroType (&$$, MACROTYPE_ASNABSTRACTERROR, myLineNoG); $$->basicType->a.macroType->a.asnAbstractError = MT (RosErrorMacroType); $$->basicType->a.macroType->a.asnAbstractError->parameter = $2; } ; /* * X.509 Authentication Framework ALGORITHM macro type */ AfAlgorithmMacroType: ALGORITHM_SYM PARAMETER_SYM Type { SetupMacroType (&$$, MACROTYPE_AFALGORITHM, myLineNoG); $$->basicType->a.macroType->a.afAlgorithm = $3; } ; /* * X.509 Authentication Framework ENCRYPTED macro type */ AfEncryptedMacroType: ENCRYPTED_SYM Type { SetupMacroType (&$$, MACROTYPE_AFENCRYPTED, myLineNoG); $$->basicType->a.macroType->a.afEncrypted = $2; } ; /* * X.509 Authentication Framework SIGNED macro type */ AfSignedMacroType: SIGNED_SYM Type { SetupMacroType (&$$, MACROTYPE_AFSIGNED, myLineNoG); $$->basicType->a.macroType->a.afSigned = $2; } ; /* * X.509 Authentication Framework SIGNATURE macro type */ AfSignatureMacroType: SIGNATURE_SYM Type { SetupMacroType (&$$, MACROTYPE_AFSIGNATURE, myLineNoG); $$->basicType->a.macroType->a.afSignature = $2; } ; /* * X.509 Authentication Framework PROTECTED macro type * (same as SIGNATURE except for key word) */ AfProtectedMacroType: PROTECTED_SYM Type { SetupMacroType (&$$, MACROTYPE_AFPROTECTED, myLineNoG); $$->basicType->a.macroType->a.afProtected = $2; } ; SnmpObjectTypeMacroType: OBJECTTYPE_SYM SYNTAX_SYM Type ACCESS_SYM SnmpAccess STATUS_SYM SnmpStatus SnmpDescrPart SnmpReferPart SnmpIndexPart SnmpDefValPart { SnmpObjectTypeMacroType *s; SetupMacroType (&$$, MACROTYPE_SNMPOBJECTTYPE, myLineNoG); s = $$->basicType->a.macroType->a.snmpObjectType = MT (SnmpObjectTypeMacroType); s->syntax = $3; s->access = $5; s->status = $7; s->description = $8; s->reference = $9; s->index = $10; s->defVal = $11; } ; SnmpAccess: identifier { if (strcmp ($1, "read-only") == 0) $$ = SNMP_READ_ONLY; else if (strcmp ($1, "read-write") == 0) $$ = SNMP_READ_WRITE; else if (strcmp ($1, "write-only") == 0) $$ = SNMP_WRITE_ONLY; else if (strcmp ($1, "not-accessible") == 0) $$ = SNMP_NOT_ACCESSIBLE; else { yyerror ("ACCESS field of SNMP OBJECT-TYPE MACRO can only be one of \"read-write\", \"write-only\" or \"not-accessible\""); $$ = -1; modulePtrG->status = MOD_ERROR; } Free ($1); } ; SnmpStatus: identifier { if (strcmp ($1, "mandatory") == 0) $$ = SNMP_MANDATORY; else if (strcmp ($1, "optional") == 0) $$ = SNMP_OPTIONAL; else if (strcmp ($1, "obsolete") == 0) $$ = SNMP_OBSOLETE; else if (strcmp ($1, "deprecated") == 0) $$ = SNMP_DEPRECATED; else { yyerror ("STATUS field of SNMP OBJECT-TYPE MACRO can only be one of \"optional\", \"obsolete\" or \"deprecated\""); $$ = -1; modulePtrG->status = MOD_ERROR; } Free ($1); } ; SnmpDescrPart: DESCRIPTION_SYM Value { $$ = $2; } | { $$ = NULL; } ; SnmpReferPart: REFERENCE_SYM Value { $$ = $2; } | { $$ = NULL; } ; SnmpIndexPart: INDEX_SYM LEFTBRACE_SYM TypeOrValueList RIGHTBRACE_SYM { $$ = $3; } | { $$ = NULL; } ; SnmpDefValPart: DEFVAL_SYM LEFTBRACE_SYM Value RIGHTBRACE_SYM { $$ = $3; } | { $$ = NULL; } ; %% void yyerror (char* s) { fprintf (errFileG, "%s(%ld) : %s at symbol \"%s\"\n\n", modulePtrG->asn1SrcFileName, myLineNoG, s, yytext); } /* * given a Module*, the file name associated witht the open * FILE *fPtr, InitAsn1Parser sets up the yacc/lex parser * to parse an ASN.1 module read from fPtr and write the * parse results into the given Module *mod. */ int InitAsn1Parser PARAMS ((mod, fileName, fPtr), Module *mod _AND_ char *fileName _AND_ FILE *fPtr) { yyin = fPtr; /* * reset lexical analyzer input file ptr * (only do this on succesive calls ow yyrestart seg faults */ #ifdef FLEX_IN_USE if (!firstTimeThroughG) yyrestart (fPtr); firstTimeThroughG = FALSE; #endif /* * init modulePtr */ memzero (mod, sizeof (Module)); modulePtrG = mod; mod->asn1SrcFileName = fileName; mod->status = MOD_NOT_LINKED; mod->hasAnys = FALSE; /* init lists to empty */ mod->typeDefs = AsnListNew (sizeof (void*)); mod->valueDefs = AsnListNew (sizeof (void*)); /* * init export list stuff */ exportListG = NULL; exportsParsedG = FALSE; /* * reset line number to 1 */ myLineNoG = 1; /* * reset error count */ parseErrCountG = 0; /* * set up list to hold values defined in parsed oids // REN -- 9/23/02 oidElmtValDefsG = AsnListNew (sizeof (void *)); */ smallErrG = 0; return 0; } /* InitAsn1Parser */ /* * puts the applicatin tag code, tagCode, and line number it was * parsed at into the applTagsG list. If the APPLICATION tag code * is already in the applTagsG list then an error is printed. * and the smallErrG flag set to prevent code production. */ void PushApplTag PARAMS ((tagCode, lineNo), unsigned long tagCode _AND_ unsigned long lineNo) { ApplTag *l; ApplTag *new; int wasDefined = 0; /* make sure not already in list */ for (l = applTagsG; l != NULL; l = l->next) { if (l->tagCode == tagCode) { PrintErrLoc (modulePtrG->asn1SrcFileName, lineNo); fprintf (errFileG, "ERROR - APPLICATION tags can be used only once per ASN.1 module. The tag \"[APPLICATION %ld]\" was previously used on line %ld.\n", tagCode, l->lineNo); wasDefined = 1; smallErrG = 1; } } if (!wasDefined) { new = MT (ApplTag); new->lineNo = lineNo; new->tagCode = tagCode; new->next = applTagsG; applTagsG = new; } } /* PushApplTag */ /* * Empties the applTagsG list. Usually done between modules. */ void FreeApplTags() { ApplTag *l; ApplTag *lTmp; for (l = applTagsG; l != NULL; ) { lTmp = l->next; Free (l); l = lTmp; } applTagsG = NULL; } /* FreeApplTags */ esnacc-ng-1.8.1/compiler/esnacc.xml.in000066400000000000000000000103441302010526100175440ustar00rootroot00000000000000
aconole@bytheb.org
2016 Aaron Conole 2016-04-26
esnacc 1 @VERSION@ Development esnacc esnacc ASN.1 compiler which generates C/C++ code suitable for encoding/decoding BER and PER esnacc ASN.1 File List Description esnacc is an enhanced version of the Sample Neufeld ASN.1 C Compiler. It takes ASN.1 formatted sources and produces C or C++ source code for BER encode and decode routines as well as print and free routines for each type in the given ASN.1 modules. Alternatively, esnacc can produce type tables that can be used for table based/intepreted encoding and decoding. The type table based methods tend to be slower than their C or C++ counterparts, but they usually use less memory (table size vs. object code) Most of the 1990 ASN.1 features are parsed although some do not affect the generated code. Fairly rigorous error checking is performed on the ASN.1 source; any errors detected will be reported (printed to stderr). Each file in the ASN.1 file list should contain a complete ASN.1 module. ASN.1 modules that use IMPORTS feature will be compiled together. The generated source files will include each module's header file in command line order. This means it is important to order the modules from least dependent to most dependent on the command line to avoid type ordering problems. Currently, esnacc assumes that each ASN.1 file given on the command line depends on all of the others from the command line. No attempt is made to only include the header files from modules referenced in the import list for that module. If the target language is C, esnacc generates .c and .h files. If the target language is C++, esnacc generates .cpp and .h files. Options Prints a synopsis of esnacc and exits. AUTHOR Enhanced SNACC was originally written by Michael Sample, but has since been modified by numerous contributors.
esnacc-ng-1.8.1/compiler/readme000066400000000000000000000104061302010526100163400ustar00rootroot00000000000000(RCS control information is at the end of this file.) README: snacc compiler source code - Mike Sample 92 ---------------------------------------------------- Compiling the snacc compiler ---------------------------- The snacc source code can be compiled with ANSI and non-ANSI C compilers. The configure script automatically determines the type of your C compiler and defines __USE_ANSI_C__ accordingly. If you use lex, you should change the YYLMAX value in the lex generated lex-asn1.c file from its measly default value (200 or so) to something like 2048. YYLMAX is the longest token that the lexical analyzer can match. I found this problem when snacc choked on the DESCRIPTION field of an OBJECT-TYPE macro that was longer than 200 characters. GNU flex does not have this problem (and seems to produce smaller code than the old lex). Compiling parse-asn1.y with bison or yacc will produce 61 shift/reduce errors and 2 reduce/reduce errors. These are mostly due to the macros that are parsed. The reduce/reduce errors result from type or value lists in some macros - the a "NULL" value and "NULL" type are both represented by "NULL" - don't worry about this ambiguity. Bizzare syntax errors that arise from these shift-reduce errors can be handled by separating types/values with semi-colons. The length of generated files' names will be truncated to match your system has the posix "pathconf" routine. If it does not the maximum file length will be set at 14 chars. If you want to change this, modify the "MakeBaseFileName" routine in back_ends/c_gen/str_util.c or use the -mf cmd line option. snacc has been successfully installed on SPARCs, HP700s, RS 6000s, and MIPS machines. You may have to fiddle with system include files. Outline of what snacc does -------------------------- The snacc compiler uses yacc and lex (or bison/flex) parser to produce an attributed parse tree for an ASN.1 source file. The main steps of the snacc are (see main() in core/snacc.c): 1. parse USEFUL types module (if given on command line with -u option) related src: core/snacc.c core/lex-asn1.l core/parse-asn1.y core/asn1module.h 2. parse the ASN.1 source file(s) related src: core/snacc.c core/lex-asn1.l core/parse-asn1.y core/asn1module.h 3. link import and local type references to the type proper definitions in the parsed modules (including useful types module). related src: core/link_types.c 4. do parsing for OBJECT IDENTIFIER values. Simple recursive descent parser. Could be expanded to handle more complex values. related src: core/val_parser.c 5. link any value references (some may be internal to OBJECT IDENTIFIERs) related src: core/link_values.c 6. process macros - change type definitions in the macros to separate type definitions and do systemd dependent processing. related src: core/do_macros.c 7. normalize types and values - eg swap COMPONENTS OF and SELECTION types for actual types/field. (and more) related src: core/normalize.c 8. mark recursive type and report any recursion related errors. (e.g. empty recursive types A ::= B B ::= A) related src: core/recursive.c 9. check for sematic errors in each ASN.1 module. related src: core/err_chk.c 10. fill in the C or C++ type and routine naming information. (done before dependency sorting so the sorter can make decisions on the basis of whether a type is ref'd by pointer (last resort)) related src: back_ends/c++_gen/c++_types.c back_ends/c++_gen/c++_rules.c back_ends/c_gen/types_info.c back_ends/c_gen/rules.c 11. do type dependency sorting. Ordered from least dependent to most dependent. Saves some irritations in the C/C++ code. related src: core/dependency.c 12. Generate C/C++ .h and .c/.C files related src: core/snacc.c back_ends/* #------------------------------------------------------------------------------- # $Header: /baseline/SNACC/compiler/readme,v 1.1.1.1 2000/08/21 20:35:59 leonberp Exp $ # $Log: readme,v $ # Revision 1.1.1.1 2000/08/21 20:35:59 leonberp # First CVS Version of SNACC. # # Revision 1.2 1994/09/01 01:37:51 rj # document the changes: # - autoconf stuff # - filename changes. # esnacc-ng-1.8.1/configure.ac000066400000000000000000000046771302010526100156510ustar00rootroot00000000000000# Copyright (c) 2016, Aaron Conole # # Licensed under the GNU General Public License v2 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at: # # http://www.gnu.org/licenses/old-licenses/gpl-2.0.html # # Please note, this may NOT be relicensed under any version of the # GNU General Public License, other than the one specified. # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. m4_define([esnacc_major], [1]) m4_define([esnacc_minor], [8]) m4_define([esnacc_micro], [1]) m4_define([esnacc_interface_age], [1]) m4_define([esnacc_binary_age], [m4_eval(100 * esnacc_minor + esnacc_micro)]) m4_define([esnacc_binary_compat], [1.7.4]) m4_define([esnacc_version], [esnacc_major.esnacc_minor.esnacc_micro]) AC_INIT([esnacc], [esnacc_version]) AC_PREREQ([2.60]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4]) AC_PROG_INSTALL AM_INIT_AUTOMAKE([-Wall foreign subdir-objects]) AC_PROG_CC AC_PROG_CXX AC_USE_SYSTEM_EXTENSIONS m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) AC_PROG_LN_S AC_PROG_LEX test "$LEX" == ":" && AC_MSG_ERROR([Please install lex/flex]) if test "x$LEX" != xflex; then LEX="$SHELL $missing_dir/missing flex" AC_SUBST([LEX_OUTPUT_ROOT], [lex.yy]) AC_SUBST([LEXLIB], ['']) fi AC_CHECK_PROGS(YACC,'bison -y' byacc yacc,no) test x"$YACC" == xno && AC_MSG_ERROR([Please install yacc/bison]) AC_PROG_SED AC_PROG_INSTALL AC_C_CONST AC_C_INLINE AC_TYPE_SIZE_T AC_HEADER_STDC LT_INIT AC_DEFINE([__STDC_LIMIT_MACROS],[1],[C99 requires this define]) AC_CHECK_LIB([m], [pow]) AC_CHECK_FUNCS([strchr getchar memset memcmp memcpy]) AX_PTHREAD ESNACC_CHECK_WIN32 ESNACC_CHECK_WARNINGS AX_CODE_COVERAGE AS_IF([ test "$enable_code_coverage" = "yes"], [ CFLAGS=$CODE_COVERAGE_CFLAGS CXXFLAGS=$CODE_COVERAGE_CXXFLAGS LDFLAGS=$CODE_COVERAGE_LDFLAGS ]) AC_CHECK_XSLTPROC #libtool version interface m4_define([lt_current], [m4_eval(100 * esnacc_minor + esnacc_micro - esnacc_interface_age)]) m4_define([lt_revision], [esnacc_interface_age]) m4_define([lt_age], [m4_eval(esnacc_binary_age - esnacc_interface_age)]) LT_VERSION_INTF="lt_current:lt_revision:lt_age" AC_SUBST(LT_VERSION_INTF) AC_CONFIG_FILES([Makefile]) AC_OUTPUT esnacc-ng-1.8.1/copying000066400000000000000000000430761302010526100147520ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. esnacc-ng-1.8.1/cxx-examples/000077500000000000000000000000001302010526100157635ustar00rootroot00000000000000esnacc-ng-1.8.1/cxx-examples/.gitignore000066400000000000000000000003501302010526100177510ustar00rootroot00000000000000.dirstamp .libs .deps *.log *.trs main src/autotags.cpp src/autotags.h src/rfc1157-snmp.cpp src/rfc1157-snmp.h src/rfc1155-smi.cpp src/rfc1155-smi.h src/vdatest_asn.c src/vdatest_asn.h src/vdatest_asn2.c src/vdatest_asn2.h test.txt esnacc-ng-1.8.1/cxx-examples/automake.mk000066400000000000000000000036231302010526100201260ustar00rootroot00000000000000TESTS += cxx-examples/main check_PROGRAMS += cxx-examples/main cxx_examples_main_SOURCES = \ cxx-examples/src/asnutil.cpp \ cxx-examples/src/asnutil.h \ cxx-examples/src/autotags.cpp \ cxx-examples/src/automatic.cpp \ cxx-examples/src/bitstest.cpp \ cxx-examples/src/gfsi.cpp \ cxx-examples/src/inttest.cpp \ cxx-examples/src/main.cpp \ cxx-examples/src/per_tests.cpp \ cxx-examples/src/rfc1155-smi.cpp \ cxx-examples/src/rfc1157-snmp.cpp \ cxx-examples/src/snmp.cpp \ cxx-examples/src/testbuf.cpp # cxx-examples/src/testsetsorting.cpp # cxx-examples/src/vdatest_asn.asn1 \ # cxx-examples/src/vdatest_asn2.asn1 \ # cxx-examples/src/vdatest.cpp \ # cxx-examples/src/vda_threads.cpp \ # cxx-examples/src/vda_threads.h cxx_examples_main_CXXFLAGS = \ -I$(top_srcdir)/cxx-lib/inc \ -I$(builddir)/cxx-examples/src \ $(PTHREAD_CFLAGS) cxx_examples_main_LDADD = \ cxx-lib/libcxxasn1.la \ $(PTHREAD_LIBS) cxx_examples_main_LDFLAGS = \ $(PTHREAD_CFLAGS) $(top_builddir)/cxx-examples/src/rfc1155-smi.cpp: \ $(top_srcdir)/cxx-examples/src/rfc1155-smi.asn1 \ $(top_builddir)/compiler/esnacc $(top_builddir)/compiler/esnacc -C -mo `dirname $@` $< $(top_builddir)/cxx-examples/src/rfc1157-snmp.cpp: \ $(top_srcdir)/cxx-examples/src/rfc1157-snmp.asn1 \ $(top_builddir)/compiler/esnacc $(top_builddir)/compiler/esnacc -C -mo `dirname $@` \ $< -I $(top_srcdir)/cxx-examples/src $(top_builddir)/cxx-examples/src/autotags.cpp: \ $(top_srcdir)/cxx-examples/src/autotags.asn1 \ $(top_builddir)/compiler/esnacc $(top_builddir)/compiler/esnacc -C -mo `dirname $@` \ $< EXTRA_DIST+= \ cxx-examples/src/autotags.asn1 \ cxx-examples/src/rfc1155-smi.asn1 \ cxx-examples/src/rfc1157-snmp.asn1 CLEANFILES+= \ test.txt \ cxx-examples/src/autotags.cpp \ cxx-examples/src/autotags.h \ cxx-examples/src/rfc1157-snmp.cpp \ cxx-examples/src/rfc1157-snmp.h \ cxx-examples/src/rfc1155-smi.cpp \ cxx-examples/src/rfc1155-smi.h esnacc-ng-1.8.1/cxx-examples/constraints_test/000077500000000000000000000000001302010526100213715ustar00rootroot00000000000000esnacc-ng-1.8.1/cxx-examples/constraints_test/ReadMe.txt000066400000000000000000000023221302010526100232660ustar00rootroot00000000000000======================================================================== CONSOLE APPLICATION : constraints_test ======================================================================== AppWizard has created this constraints_test application for you. This file contains a summary of what you will find in each of the files that make up your constraints_test application. constraints_test.dsp This file (the project file) contains information at the project level and is used to build a single project or subproject. Other users can share the project (.dsp) file, but they should export the makefiles locally. constraints_test.cpp This is the main application source file. ///////////////////////////////////////////////////////////////////////////// Other standard files: StdAfx.h, StdAfx.cpp These files are used to build a precompiled header (PCH) file named constraints_test.pch and a precompiled types file named StdAfx.obj. ///////////////////////////////////////////////////////////////////////////// Other notes: AppWizard uses "TODO:" to indicate parts of the source code you should add to or customize. ///////////////////////////////////////////////////////////////////////////// esnacc-ng-1.8.1/cxx-examples/constraints_test/constraintTest.asn1000066400000000000000000000021071302010526100252010ustar00rootroot00000000000000ConstraintsTest DEFINITIONS IMPLICIT TAGS ::= BEGIN --NameString::=VisibleString (FROM("a".."z"|"A".."Z"|"-.")^SIZE(1..64)) REAL1::=REAL (3..23|55|60..68|3000) REAL2::=REAL (55) INT1::=INTEGER (5..10|45|55..300|34) INT2::=INTEGER (-20) BOOL1::=BOOLEAN (1) NUMSTRING1::=NumericString (FROM("1".."4"|"6")|FROM("1235"|"539")|SIZE(1)|"888") IA5STRING1::=IA5String ("ia5string1".."ia5string3"| "ia5string9"|SIZE(2)|SIZE(4..5)) UNIVERSALSTRING1::=UniversalString(SIZE(15..89|4)|FROM("td"))(SIZE(2)) UNIVERSALSTRING2::=UniversalString(SIZE(15)|FROM("asdf"))(FROM("fghi")) ConstraintTest::=SEQUENCE { integer INTEGER (5..10), integer1 INTEGER (-20), boolean BOOLEAN (1), numericString NumericString ("1234"), ia5String IA5String ("ia5string1".."ia5string3") } TestSetOfConstraints::=SET SIZE(1) OF ConstraintTest TestSequenceOfConstraints::=SEQUENCE SIZE(0<..MAX) OF TestSetOfConstraints TestSet::=SET { testSequenceOfConstraints TestSequenceOfConstraints } IndefLen ::= SEQUENCE { i1 [1] INTEGER, a1 ANY } END esnacc-ng-1.8.1/cxx-examples/constraints_test/constraintTest_main.cpp000066400000000000000000000464341302010526100261400ustar00rootroot00000000000000/* JKG: main test constraints for asn1 */ #include "constraintTest.h" #include "perTest.h" #include "new-types.h" #include #include int constraintTest_main(int argc, char *argv[]) { SNACC::AsnExtension ext; ext; try { std::cout<<"___________________________________"<begin(); i != pList->end(); ++i) { std::cout<<"*****************************************************************"< #include using namespace SNACC; int SetSequence_AlignTest(bool bAlign); int SetOfSequenceOf_AlignTest(bool bAlign); int AnyDefinedBy_AlignTest(bool bAlign); int constraintTest_mainRWC(int argc, char *argv[]) { try { std::cout << "******* START of PER Set/Sequence Alignment Test. ***\n" << std::endl; SetSequence_AlignTest(false); SetSequence_AlignTest(true); std::cout << "******* END of PER Set/Sequence Alignment Test. ***\n" << std::endl; std::cout << "******* START of PER SetOf/SequenceOf Alignment Test. ***\n" << std::endl; SetOfSequenceOf_AlignTest(false); SetOfSequenceOf_AlignTest(true); std::cout << "******* END of PER SetOf/SequenceOf Alignment Test. ***\n" << std::endl; std::cout << "******* START of PER AnyDefinedBy Alignment Test. ***\n" << std::endl; AnyDefinedBy_AlignTest(false); AnyDefinedBy_AlignTest(true); std::cout << "******* END of PER AnyDefinedBy Alignment Test. ***\n" << std::endl; } // END try catch (SnaccException &e) { std::cout << "**************\n" << e.what() << std::endl; } return 0; } int SetSequence_AlignTest(bool bAlign) { try { PerSetChoiceTest A_PerSetChoiceTest; PerSetChoiceTest A_PerSetChoiceTest2; PerSequenceChoiceTest A_PerSequenceChoiceTest; PerSequenceChoiceTest A_PerSequenceChoiceTest2; AsnBufBits b(bAlign); AsnBufBits tmpBufBits(bAlign); AsnBufBits bSet(bAlign); AsnLen bytesDecoded=0; std::cout << "___________________________________" << std::endl; std::cout << "Begin Set/Sequence Handling Testing: bAlign = " << bAlign << std::endl; std::cout << "-----------------------------------" << std::endl; //******************** PER SET TEST ************************** A_PerSetChoiceTest.a = 22; A_PerSetChoiceTest.bDef.choiceId = PerSetChoiceTestChoice::cCid; A_PerSetChoiceTest.bDef.c = new AsnInt(44); { // SETUP ANY values; for testing we load the same value into both ANYs. AsnInt IntValue(77); IntValue.PEnc(tmpBufBits); long ltmpAnyBitLength=tmpBufBits.length(); long ltmpAnyByteLength=ltmpAnyBitLength/8; if (ltmpAnyByteLength*8 < ltmpAnyBitLength) ltmpAnyByteLength++; // ALLOW 0 padded result, octet aligned. unsigned char *ptmpBufBits = tmpBufBits.GetBits(ltmpAnyBitLength); A_PerSetChoiceTest.perAnyTest.anyBuf = new AsnBuf((char *)ptmpBufBits, ltmpAnyByteLength); // NO OID for this test. A_PerSetChoiceTest.perAnyTest2.anyBuf = new AsnBuf((char *)ptmpBufBits, ltmpAnyByteLength); // NO OID for this test. delete[] ptmpBufBits; } A_PerSetChoiceTest.PEnc(b); std::cout << "*** After encode (no OPTIONAL)." << std::endl; std::cout << "INPUT: " << A_PerSetChoiceTest << std::endl; std::cout << "Length of Buffer : " << b.length() << std::endl; b.hexDump(std::cout); std::cout << std::endl; // TEST that we properly reset buffer. std::cout << "Length of Buffer : " << b.length() << std::endl; b.hexDump(std::cout); std::cout << std::endl; A_PerSetChoiceTest2.PDec(b, bytesDecoded); std::cout << "OUTPUT: " << A_PerSetChoiceTest2 << std::endl; std::cout<choiceId = PerSetChoiceTestChoice1::fCid; A_PerSetChoiceTest.e->f = new PerSetChoiceTestChoice1Choice; A_PerSetChoiceTest.e->f->choiceId = PerSetChoiceTestChoice1Choice::gCid; A_PerSetChoiceTest.e->f->g = new AsnInt(66); A_PerSetChoiceTest.PEnc(bSet); std::cout << "*** After encode (with OPTIONAL)." << std::endl; std::cout << "INPUT: " << A_PerSetChoiceTest << std::endl; std::cout << "Length of Buffer : " << bSet.length() << std::endl; bSet.hexDump(std::cout); std::cout << std::endl; A_PerSetChoiceTest2.PDec(bSet, bytesDecoded); std::cout << "OUTPUT Set, with OPTIONAL: " << A_PerSetChoiceTest2 << "\n\n" << std::endl; //******************** PER SEQUENCE TEST ************************** AsnBufBits bSeq(bAlign); AsnBufBits bSeq2(bAlign); A_PerSequenceChoiceTest.bDef.choiceId = PerSequenceChoiceTestChoice::cCid; A_PerSequenceChoiceTest.bDef.c = new AsnInt; *A_PerSequenceChoiceTest.bDef.c = 44; A_PerSequenceChoiceTest.eInteger = 66; A_PerSequenceChoiceTest.PEnc(bSeq); std::cout << "*** SEQUENCE: After encode (no OPTIONAL)." << std::endl; std::cout << "INPUT: " << A_PerSequenceChoiceTest << std::endl; std::cout << "Length of Buffer : " << bSeq.length() << std::endl; b.hexDump(std::cout); std::cout << std::endl; A_PerSequenceChoiceTest2.PDec(bSeq, bytesDecoded); std::cout << "OUTPUT: " << A_PerSequenceChoiceTest2 << std::endl; std::cout< #endif #include #include "asn-incl.h" int constraintTest_main(int argc, char *argv[]); int constraintTest_mainRWC(int argc, char *argv[]); int main(int argc, char* argv[]) { #ifdef WIN32 long memAllocNum = 0; // Set the debug flags for memory leak checking _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG); int debugFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); debugFlag = _CrtSetDbgFlag(debugFlag | _CRTDBG_LEAK_CHECK_DF ); // debugFlag = _CrtSetDbgFlag(debugFlag | // _CRTDBG_DELAY_FREE_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF); // Set a breakpoint on the allocation request number if (memAllocNum > 0) _CrtSetBreakAlloc(memAllocNum); #endif // WIN32 int iStatus = constraintTest_mainRWC(argc, argv); iStatus = constraintTest_main(argc, argv); return iStatus; } esnacc-ng-1.8.1/cxx-examples/constraints_test/new-types.asn1000066400000000000000000000024371302010526100241160ustar00rootroot00000000000000NewTypes DEFINITIONS IMPLICIT TAGS ::= BEGIN myOid RELATIVE-OID ::= { 1 3 4 22 } TestClear ::= SEQUENCE { testClearNested SET{ i1 INTEGER } } TestRelOid ::= SEQUENCE { id RELATIVE-OID, id2 OBJECT IDENTIFIER } TestTagging ::= SEQUENCE { i1 [0] INTEGER, i2 [2] INTEGER OPTIONAL } TestSeqExtensibilityV1 ::= SEQUENCE { i1 [1] INTEGER, i2 [2] INTEGER OPTIONAL, ..., ... } TestSeqExtensibilityV2 ::= SEQUENCE { i1 [1] INTEGER, i2 [2] INTEGER OPTIONAL, ..., i3 [3] INTEGER ... } TestSeqExtensibilityV3 ::= SEQUENCE { i1 [1] INTEGER, i2 [2] INTEGER OPTIONAL, ..., i3 [3] INTEGER, i4 [4] INTEGER ... } TestSetExtensibilityV1 ::= SET { i1 [1] INTEGER, i2 [2] INTEGER OPTIONAL, ..., ... } TestSetExtensibilityV2 ::= SET { i1 [1] INTEGER, i2 [2] INTEGER OPTIONAL, ..., i3 [3] INTEGER ... } TestSetExtensibilityV3 ::= SET { i1 [1] INTEGER, i2 [2] INTEGER OPTIONAL, ..., i3 [3] INTEGER, i4 [4] INTEGER ... } TestChoiceExtensibilityV1 ::= CHOICE { i1 [5] INTEGER, i2 [6] INTEGER, ..., ... } TestChoiceExtensibilityV2 ::= CHOICE { i1 [5] INTEGER, i2 [6] INTEGER, ..., i3 [7] INTEGER, i4 [8] ANY ... } TestChoiceExtensibilityV3 ::= CHOICE { i1 [5] INTEGER, i2 [6] INTEGER, ..., i3 [7] INTEGER, i4 [8] ANY, i5 [9] INTEGER ... } ENDesnacc-ng-1.8.1/cxx-examples/constraints_test/perTest.asn1000066400000000000000000000017031302010526100236040ustar00rootroot00000000000000PerTest DEFINITIONS IMPLICIT TAGS ::= BEGIN PERInt ::= INTEGER PERIntSingleVal ::= INTEGER(4) PERIntSemi ::= INTEGER (0 .. MAX) PERIntFully ::= INTEGER (0 .. 2147483647) PERBool ::= BOOLEAN PERReal ::= REAL PERIA5String ::= IA5String (SIZE(3..4000)) (FROM("hello")) PERNumericString ::= NumericString (FROM("1234")) (SIZE(2)) --(SIZE(2)) (SIZE(MIN..5)) PERPString ::= PrintableString (FROM("this' actually kind of works")) PERVString ::= VisibleString (FROM("This is definitely visible.")) PEROctet ::= OCTET STRING (SIZE(3)) PERBit ::= BIT STRING (SIZE(3..8888)) TestEnum ::= ENUMERATED { a (5), b (16), c (2), d (0) } A::= SET { pERIntFully PERIntFully } ub-telephone-number INTEGER ::= 32 DestructionStatus ::= INTEGER {zeroized (0) } PERSeqOfFull ::= SEQUENCE SIZE (15..30) OF INTEGER (0..15) PERSetOfSemi ::= SET SIZE (4..MAX) OF INTEGER PERSeqOfSingle ::= SEQUENCE SIZE (5) OF INTEGER END esnacc-ng-1.8.1/cxx-examples/constraints_test/perTestSet.asn1000066400000000000000000000025441302010526100242640ustar00rootroot00000000000000PerTestSet DEFINITIONS IMPLICIT TAGS ::= BEGIN PerSetChoiceTest ::= SET { a --RWC;[3]-- INTEGER, bDef [1] CHOICE { c [2] INTEGER, d [4] INTEGER }, e CHOICE { f CHOICE { g [5] INTEGER, h [6] INTEGER }, i CHOICE { j [0] INTEGER, --RWC;Added for test f CHOICE { g [7] INTEGER, h [8] INTEGER } } } OPTIONAL, perAnyTest [9] PerAnyTest, perAnyTest2 [10] ANY } PerSequenceChoiceTest ::= SEQUENCE { a --RWC;[3]-- INTEGER OPTIONAL, bDef [1] CHOICE { c [2] INTEGER, d [4] INTEGER }, fTaggedInteger [2] INTEGER (0..59) DEFAULT 0, eInteger INTEGER } PerSetOfTest ::= SET OF INTEGER PerSequenceOfTest ::= SEQUENCE SIZE(10..11) OF INTEGER PerAnyTest ::= ANY perTestOID2 OBJECT IDENTIFIER ::= { 1 2 3 4 5 6 7 8 9 10 2 } PerTestDefinedByUsage ::= SEQUENCE { id OBJECT IDENTIFIER, anyDefBy ANY DEFINED BY id, i1 INTEGER, i2 INTEGER, i3 INTEGER, i4 INTEGER, id5 RELATIVE-OID OPTIONAL } -- This definition syntax is based on SNMP OBJECT-TYPE; it is a special -- SNACC construct to align the DEFINED BY id with a data type -- (see SNACC docs). perTestDefinedByDesignation OBJECT-TYPE SYNTAX PrintableString ACCESS read-write STATUS mandatory ::= { 1 2 3 4 5 6 7 8 9 10 2 } --pertestOID2 ENDesnacc-ng-1.8.1/cxx-examples/snmpv1_tests/000077500000000000000000000000001302010526100204315ustar00rootroot00000000000000esnacc-ng-1.8.1/cxx-examples/snmpv1_tests/readme.txt000066400000000000000000000010661302010526100224320ustar00rootroot00000000000000 SNMP V1 TEST DATA This directory contains gzip compress tar files which contain SNMP V1 tests. The following two files contain good and bad testcases. SNACC should gracefully handle decoding these files. More information about the testcases can be found at: http://www.ee.oulu.fi/research/ouspg/protos/testing/c06/snmpv1/index.html snmpv1_trap_enc_tests.tgz snmpv1_req_app_tests.tgz To use any of these files extract them into a unique directory and pass the full path of the directory as the first parameter to "snacctest". esnacc-ng-1.8.1/cxx-examples/src/000077500000000000000000000000001302010526100165525ustar00rootroot00000000000000esnacc-ng-1.8.1/cxx-examples/src/asnutil.cpp000066400000000000000000000037021302010526100207370ustar00rootroot00000000000000#include "asnutil.h" using namespace SNACC; AsnLen DecTagLen (unsigned char *bytes) { FUNC("BDecLen()"); AsnLen len; int lenBytes; if (bytes[0] < 128) /* short length */ return bytes[0]; else if (bytes[0] == (unsigned char) 0x080) /* indef len indicator */ return INDEFINITE_LEN; else /* long len form */ { /* * strip high bit to get # bytes left in len */ lenBytes = bytes[0] & (unsigned char) 0x7f; if (lenBytes > sizeof (long int)) { throw BoundsException("length overflow", STACK_ENTRY); } for (len = 0; lenBytes > 0; lenBytes--) len = (len << 8) | (unsigned long int) bytes[1]; return len; } /* not reached */ } void hex2str(const char *pszHex, std::string &str) { FUNC("hex2str()"); bool error = false; int nInt; // int. which has an ascii val. of a character unsigned char *puchIn; // temp pointer to hex // if this is hex it should be divisible by two. if not return an error. if (strlen(pszHex) % 2 != 0) error = true; if (!error) { puchIn = (unsigned char *)pszHex; while (*puchIn != '\0' && !error) { if (sscanf((char*)puchIn, "%2x", &nInt) > 0) { str += (char) nInt; puchIn += 2; } else error = true; } } if (error) throw EXCEPT("invalid hex string",-1); } void fillTestBuffer(unsigned char *test, long length) { int n = 0; for (int i = 0; i < length; i++) { if (n == 219) n = 0; test[i] = n; n++; } } bool checkTestBuffer(const unsigned char *test, long length) { int n = 0; for (int x=0; x < length; x++) { if (n == 219) n = 0; if (test[x] != n) { std::cout << "Died at " << x << std::endl; return false; } n++; } return true; } esnacc-ng-1.8.1/cxx-examples/src/asnutil.h000066400000000000000000000014051302010526100204020ustar00rootroot00000000000000#include "asn-incl.h" #ifdef WIN32 #pragma warning(disable: 4305 4309 4101) #endif /* prototypes */ SNACC::AsnLen DecTagLen (unsigned char *bytes); void bittests(void); void inttests(void); void vdaTestThreadLocks(); void run_snmp_tests(char *path); void TestSetSorting(void); void hex2str(const char *pszHex, std::string &str); void fillTestBuffer(unsigned char *test, long length); bool checkTestBuffer(const unsigned char *test, long length); typedef void * GFSI_HANDLE; /* Generic File System Interface (GFSI) */ char * GFSI_GetFirstFile(GFSI_HANDLE *gfsi_handle, char *path, char *extension=NULL); char * GFSI_GetNextFile(GFSI_HANDLE *gfsi_handle, char *extension=NULL); void GFSI_Close(GFSI_HANDLE *gfsi_handle); esnacc-ng-1.8.1/cxx-examples/src/automatic.cpp000066400000000000000000000075011302010526100212470ustar00rootroot00000000000000#include "autotags.h" static SNACC::Human * getHuman(const char *name, int age, bool isBiblical, const char *firstWords = NULL) { SNACC::Human *h = new SNACC::Human(); h->name = name; if (firstWords) h->first_words = new SNACC::UTF8String(firstWords); h->age = new SNACC::HumanChoice(); if (isBiblical) { h->age->biblical = new SNACC::HumanChoice::Biblical(age); h->age->choiceId = SNACC::HumanChoice::biblicalCid; } else { h->age->modern = new SNACC::HumanChoice::Modern(age); h->age->choiceId = SNACC::HumanChoice::modernCid; } return h; } int automaticTests() { struct Tests { const unsigned char bytes[256]; size_t byte_len; const char *enc_bytes; SNACC::Human *h; } t[] = { { {0x30,0x0B,0x80,0x04,0x41,0x64,0x61,0x6D,0xA2,0x03,0x81,0x01,0x5A,}, 13, NULL, getHuman("Adam", 90, false) }, { {0x30,0x0C,0x80,0x04,0x41,0x64,0x61,0x6D,0xA2,0x04,0x80,0x02,0x03, 0x84,}, 14, NULL, getHuman("Adam", 900, true) }, { {0x30,0x1A,0x80,0x04,0x41,0x64,0x61,0x6D,0x81,0x0D,0x67,0x6F,0x6F, 0x20,0x67,0x6F,0x6F,0x20,0x67,0x61,0x20,0x67,0x61,0xA2,0x03,0x81, 0x01,0x5A,}, 28, NULL, getHuman("Adam", 90, false, "goo goo ga ga") }, { {0x30,0x1B,0x80,0x04,0x41,0x64,0x61,0x6D,0x81,0x0D,0x67,0x6F,0x6F, 0x20,0x67,0x6F,0x6F,0x20,0x67,0x61,0x20,0x67,0x61,0xA2,0x04,0x80, 0x02,0x03,0x84,}, 29, NULL, getHuman("Adam", 900, true, "goo goo ga ga") }, }; size_t i; for(i = 0; i < (sizeof(t) / sizeof(t[0])); i++) { std::cout << "T[" << i << "]: Starting HUMAN test" << std::endl; bool fail_dec = false, fail_enc = false; bool fail_name = false; bool fail_age = false; bool fail_firstwords = false; SNACC::AsnBuf b((const char *)(t[i].bytes), t[i].byte_len); SNACC::AsnLen l; SNACC::Human h; try { h.BDec(b, l); if (h.name != t[i].h->name) { fail_name = true; } if (h.age->choiceId != t[i].h->age->choiceId) { fail_age = true; } else { if (h.age->choiceId == SNACC::HumanChoice::biblicalCid) { if (*(h.age->biblical) != *(t[i].h->age->biblical)) { fail_age = true; } } else { if (*(h.age->modern) != *(t[i].h->age->modern)) { fail_age = true; } } } } catch (SNACC::SnaccException &e) { fail_dec = true; } if (fail_dec || fail_name || fail_age || fail_firstwords) { std::cout << "D:F(" << i << "): " << fail_dec << "," << fail_name << "," << fail_age << "," << fail_firstwords << std::endl; return 1; } SNACC::AsnBuf benc; SNACC::AsnBuf expected((const char *)(t[i].bytes), t[i].byte_len); try { h.BEnc(benc); if (!(benc == expected)) { fail_enc = true; } } catch (SNACC::SnaccException &e) { fail_enc = true; } if (fail_enc || fail_name || fail_age || fail_firstwords) { std::cout << "E:F(" << i << "): " << fail_enc << "," << fail_name << "," << fail_age << "," << fail_firstwords << std::endl; return 1; } } return 0; } esnacc-ng-1.8.1/cxx-examples/src/autotags.asn1000066400000000000000000000004011302010526100211600ustar00rootroot00000000000000World-Schema DEFINITIONS AUTOMATIC TAGS ::= BEGIN Human ::= SEQUENCE { name UTF8String, first-words UTF8String DEFAULT "Hello World", age CHOICE { biblical INTEGER (1..1000), modern INTEGER (1..100) } OPTIONAL } END esnacc-ng-1.8.1/cxx-examples/src/bitstest.cpp000066400000000000000000000050651302010526100211250ustar00rootroot00000000000000#include "asnutil.h" using namespace SNACC; typedef struct test_table { char *input; unsigned char result[20]; bool nblFlag; } AsnBitTestTable; AsnBitTestTable gBitTestTable[]= // input // result { { "'00000101'B", {0x03, 0x02, 0x00, 0x05}, false }, { "'00000101'B", {0x03, 0x02, 0x00, 0x05}, true }, { "'1'B", {0x03, 0x02,0x07,0x80}, false }, { "'1'B", {0x03, 0x02,0x07,0x80}, true }, { "'1111000000000000'B", { 0x03, 0x03, 0x00, 0xF0, 0x00}, false }, { "'1111000000000000'B", { 0x03, 0x02, 0x04, 0xF0}, true }, { "'0000000000001111'B", { 0x03, 0x03, 0x00, 0x00, 0x0F}, false }, { "'00001'B", { 0x03, 0x02, 0x03, 0x08 }, false }, { "'00010'B", { 0x03, 0x02, 0x03, 0x10 }, false }, { "'00010'B", { 0x03, 0x02, 0x04, 0x10 }, true }, { "'00'B", { 0x03, 0x01, 0x00 }, true }, { "'0'B", { 0x03, 0x02, 0x07, 0x00 }, false }, { "''B", { 0x03, 0x01, 0x00 }, true }, { NULL, 0, false } }; void bittests(void) { std::cout << "*** Start of AsnBits tests ***\n"; for (int index=0; gBitTestTable[index].input != NULL; index++) { AsnBits asnBits(gBitTestTable[index].input); asnBits.UseNamedBitListRules(gBitTestTable[index].nblFlag); AsnBuf expectedResult((const char *)&gBitTestTable[index].result[0], DecTagLen(gBitTestTable[index].result+1) + 2); AsnBuf result; AsnLen bytesEncoded; std::cout << "AsnBits test " << index << " matches expected result? "; try { asnBits.BEnc(result); if (!(result == expectedResult)) { std::string str; int i; int ch; std::cout << "NO!\n"; std::cout << "FAILED!\n"; std::cout << "Expected Result: "; expectedResult.hexDump(std::cout); std::cout << "\n"; std::cout << "\nActual Result: "; result.hexDump(std::cout); std::cout << "\n"; } else { std::cout << "YES!\n"; } } catch (SnaccException &e) { std::cout << "Encode FAILED: \n"; std::cout << "Error: " << e.what() << std::endl; std::cout << "Stack:\n"; e.getCallStack(std::cout); } } std::cout << "*** End of AsnBits tests ***\n"; } esnacc-ng-1.8.1/cxx-examples/src/gfsi.cpp000066400000000000000000000070001302010526100202030ustar00rootroot00000000000000#include #include #include #if defined(WIN32) || defined(WIN16) #include #include #include #include #include #else #include #include #include #endif #include "asnutil.h" typedef void * GFSI_HANDLE; /* Generic File System Interface (GFSI) */ // GFSI_GetFirstFile: // PURPOSE: Returns first file in a path // char *GFSI_GetFirstFile(GFSI_HANDLE *gfsi_handle, char *path, char *extension) { char *fn = NULL; #ifdef WIN32 char real_path[256]; WIN32_FIND_DATA findData; *gfsi_handle = NULL; if (extension == NULL) sprintf(real_path,"%s\\*.*",path); else sprintf(real_path,"%s\\*.%s", path, extension); do { if (fn == NULL) *gfsi_handle = (GFSI_HANDLE) FindFirstFile(real_path, &findData); else FindNextFile((HANDLE) *gfsi_handle, &findData); if (*gfsi_handle != NULL && (int) *gfsi_handle != -1) fn = strdup(findData.cFileName); } while ((gfsi_handle != INVALID_HANDLE_VALUE) && (findData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)); #else struct dirent *dirEntry = NULL; *gfsi_handle = NULL; *gfsi_handle = (GFSI_HANDLE) opendir(path); if (*gfsi_handle != NULL) { if (extension != NULL) { while ((dirEntry = readdir( (DIR *) *gfsi_handle)) != NULL) { fn = strstr(dirEntry->d_name, extension); if (fn != NULL) { fn = strdup(dirEntry->d_name); break; } } } else { while ((dirEntry = readdir( (DIR *) *gfsi_handle)) != NULL) { fn = dirEntry->d_name; if ((fn != NULL) && (strcmp(fn,".") != 0) && (strcmp(fn, "..") != 0)) { fn = strdup(dirEntry->d_name); break; } } } } #endif return fn; } // END OF FUNCTION GFSI_GetFirstFile // GFSI_GetNextFile: // PURPOSE: Returns next file in a path // char *GFSI_GetNextFile( GFSI_HANDLE *gfsi_handle, char *extension) { char *fn = NULL; #ifdef WIN32 WIN32_FIND_DATA findData; bool bDone = false; // NOTE: We ignore the extension paramater for the WIN32 Case do { if (FindNextFile((HANDLE) *gfsi_handle, &findData)) { if (findData.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY) fn = strdup(findData.cFileName); } else { bDone = true; } } while (!bDone && (fn == NULL)); #else struct dirent *dirEntry = NULL; if (extension != NULL) { while ((dirEntry = readdir( (DIR *) *gfsi_handle)) != NULL) { fn = strstr(dirEntry->d_name, extension); if (fn != NULL) { fn = strdup(dirEntry->d_name); break; } } } else { if ((dirEntry = readdir( (DIR *) *gfsi_handle)) != NULL) { fn = strdup(dirEntry->d_name); } } #endif return fn; } // END OF FUNCTION GFSI_GetNextFile // GFSI_Close: // void GFSI_Close( GFSI_HANDLE *gfsi_handle ) { #ifdef WIN32 FindClose((HANDLE) *gfsi_handle); #else if (*gfsi_handle != NULL) { closedir((DIR *) *gfsi_handle); } #endif } // END OF FUNCTION GFSI_Close long findFileSize(char *fileName) { struct stat buf; int result; /* Get data associated with "stat.c": */ result = stat(fileName, &buf); /* Check if statistics are valid: */ if (result != 0) return 0; else return(buf.st_size); } // EOF acl_FileFuncs.cpp esnacc-ng-1.8.1/cxx-examples/src/inttest.cpp000066400000000000000000000076361302010526100207640ustar00rootroot00000000000000#include "asnutil.h" using namespace SNACC; typedef struct test_table { char *input; unsigned char result[20]; bool unsignedFlag; } AsnIntTestTable; AsnIntTestTable gIntTestTable[]= // input // result { { "1234", {0x02, 0x02, 0x04, 0xD2}, true }, { "-3628", {0x02, 0x02, 0xf1, 0xD4}, true }, { "2047483647", {0x02, 0x04, 0x7a,0x0a,0x1e,0xff}, true }, { "-2047483648", {0x02, 0x04, 0x85,0xf5,0xe1,0x00}, true }, { "0xffffffff", {0x02, 0x01, 0xff}, false }, { "0xffffffff", {0x02, 0x05, 0x00,0xff,0xff,0xff,0xff}, true }, { "0x0000ffff", {0x02, 0x03,0x00,0xff,0xff}, true }, { "0x0000ffff", {0x02, 0x03,0x00,0xff,0xff}, true }, { "0x000fffff", {0x02,0x03,0x0f,0xff,0xff}, false }, { "0x000001", {0x02, 0x01, 0x01}, false }, { "0x0080", {0x02, 0x02, 0x00, 0x80}, true }, { "0x0080", {0x02, 0x02, 0x00, 0x80}, false }, { "0xff81", {0x02, 0x01, 0x81}, false }, { "0xff81", {0x02,0x03,0x00,0xff,0x81}, true }, { "5247483647", //bad {0x02, 0x04, 0x7f,0xff,0xff,0xff}, true }, { NULL, NULL, false, } }; #define gCT 11 int convTests[gCT] = { 0, -1, -5, -256, 256, 16, -10000, 10000, 655335, -655335,-1000000 }; void inttests(void) { FUNC("intTests()"); try { std::cout << "** Conversion tests **\n"; for (int i=0; i < gCT; i++) { AsnInt n(convTests[i]); int x = n; if (x == convTests[i]) { std::cout.width(10); std::cout << convTests[i] << " test SUCCESS!\n"; } else { std::cout.width(10); std::cout << convTests[i] << " FAILED!\n"; std::cout << "Input: " << convTests[i] << "\n"; std::cout << "Result: " << x << "\n"; } } std::cout << "** End Conversion tests **\n\n"; for (int testIndex = 0; gIntTestTable[testIndex].input != NULL; testIndex++) { if (gIntTestTable[testIndex].unsignedFlag) std::cout << "AsnInt (unsigned) Test " << testIndex << ":"; else std::cout << "AsnInt ( signed ) Test " << testIndex << ":"; AsnInt asnInt (gIntTestTable[testIndex].input, gIntTestTable[testIndex].unsignedFlag); AsnBuf expectedResult((const char *)gIntTestTable[testIndex].result, DecTagLen(gIntTestTable[testIndex].result + 1) + 2); AsnBuf result; try { asnInt.BEnc(result); std::cout << "INTEGER encoding matches expected result? "; if (result == expectedResult) { std::cout << "YES!" << std::endl; } else { std::cout << "NO!" << std::endl; std::cout << "Input: " << gIntTestTable[testIndex].input << std::endl; std::cout << "Expected Result: "; std::cout << std::ios_base::hex << expectedResult; std::cout << std::endl; std::cout << "Actual Result: "; std::cout << std::ios_base::hex << result; std::cout << std::endl; } } catch (SnaccException &se) { std::cout << "AsnInt encode/decode test failed:" << std::endl; std::cout << "Error: " << se.what() << std::endl; std::cout << "Stack: \n"; se.getCallStack(std::cout); } } } catch(SnaccException &e) { std::cout << "Int test failed:\n"; std::cout << "ERROR STRING: "; std::cout << e.what() << "\n"; std::cout.flush(); std::cout << "*** Int Test ***\n"; } } esnacc-ng-1.8.1/cxx-examples/src/main.cpp000066400000000000000000000125711302010526100202100ustar00rootroot00000000000000#include "asnutil.h" #include #ifdef WIN32 #include #endif void newBufTest(); int automaticTests(); using namespace SNACC; void doubleDecodeTest(void) { char buf[] = {0x04,0x01,0x31,0x04,0x01,0x32}; AsnBuf asnBuf(buf, 6); AsnLen len; AsnOcts octs; try { std::cout << "*** doubleDecodeTest ***\n"; if (octs.BDecPdu(asnBuf, len)) { if (octs.c_ustr()[0] == '1') { std::cout << "First OCTET STRING value: " << octs.c_ustr()[0] << std::endl; if (octs.BDecPdu(asnBuf, len)) { if (octs.c_ustr()[0] == '2') { std::cout << "Second OCTET STRING value: " << octs.c_ustr()[0] << std::endl; } else { std::cout << "Unexpected result for second OCTET STRING: " << octs.c_ustr()[0] << std::endl; } } else { std::cout << "Decode of second OCTET STRING failed!\n"; } } else { std::cout << "ERROR: Unexpected result for first OCTET STRING: " << octs.c_ustr()[0] << std::endl; } } else { std::cout << "Decode of double OCTET STRING encoded FAILED!\n"; } std::cout << "*** doubleDecodeTest ***\n"; } catch(SnaccException &e) { std::cout << "Double decode test failed:\n"; std::cout << "ERROR STRING: "; std::cout << e.what() << "\n"; std::cout.flush(); std::cout << "*** doubleDecodeTest ***\n"; } } void octsTest(void) { unsigned char buf[] = {0x04,0x14,0x31,0x32,0x33,0x34,0x35,0x36,0x37, 0x38,0x39,0x30,0x41,0x42,0x43,0x44,0x45,0x46, 0x47,0x48,0x49,0x50}; AsnBuf asnBuf((char *)buf, 22); size_t i; AsnLen len = 22; AsnOcts octs; try { std::cout << "*** start of AsnOcts tests ***\n"; if (octs.BDecPdu(asnBuf, len)) { if (memcmp(octs.c_ustr(), &buf[2], octs.Len()) == 0) { for (i = 0; i < 20; i++) { std::cout << "OCTET STRING value: " << octs.c_ustr()[i] << std::endl; } } else { for (i = 0; i < 20; i++) { std::cout << "ERROR: Unexpected result for OCTET STRING: " << octs.c_ustr()[i] << std::endl; } } } else { std::cout << "Decode of OCTET STRING encoded FAILED!\n"; } std::cout << "*** End of AsnOcts tests ***\n"; } catch(SnaccException &e) { std::cout << "Octs test failed:\n"; std::cout << "ERROR STRING: "; std::cout << e.what() << "\n"; std::cout.flush(); std::cout << "*** End of AsnOcts tests ***\n"; } } void fillTest(void) { unsigned char buf[] = { 0x24, 0x80, 0x24, 0x80, 0x04, 0x01, 0xaa, 0x04, 0x01, 0xbb, 0x00, 0x00, 0x04, 0x01, 0xcc, 0x24, 0x80, 0x04, 0x01, 0xdd, 0x04, 0x01, 0xee, 0x24, 0x80, 0x24, 0x80, 0x24, 0x80, 0x24, 0x80, 0x04, 0x01, 0xff, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x11, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x22, 0x00, 0x00, 0x04, 0x01, 0x33, 0x00, 0x00 }; AsnBuf asnBuf((char *)buf, sizeof(buf)); AsnLen len = sizeof(buf); AsnOcts octs; try { std::cout << "*** start of Recursive Fill tests ***\n"; octs.BDec(asnBuf, len); std::cout << std::endl; octs.Print(std::cout); std::cout << std::endl; std::cout << len; std::cout << "*** End of Recursive Fill tests ***\n"; } catch(SnaccException &e) { std::cout << "Octs test failed:\n"; std::cout << "ERROR STRING: "; std::cout << e.what() << "\n"; std::cout.flush(); std::cout << "*** End of Recursive Fill tests ***\n"; } } int main(int argc, char *argv[]) { #ifdef WIN32 long memAllocNum = 0; // Set the debug flags for memory leak checking _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG); int debugFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); debugFlag = _CrtSetDbgFlag(debugFlag | _CRTDBG_LEAK_CHECK_DF ); if (memAllocNum > 0) { _CrtSetBreakAlloc(memAllocNum); } #endif // WIN32 char *snmpPath=NULL; try { newBufTest(); if (argc > 1) { snmpPath = argv[1]; } octsTest(); doubleDecodeTest(); inttests(); bittests(); if (snmpPath != NULL) { run_snmp_tests(snmpPath); } fillTest(); if (automaticTests()) { std::cout << "Automatic test failure." << std::endl; } } catch (SnaccException &e) { std::cout << "\n**** Caught SnaccException ****\n"; std::cout << "What: " << e.what() << std::endl; std::cout << "Call Stack:\n"; e.getCallStack(std::cout); } return 0; } esnacc-ng-1.8.1/cxx-examples/src/per_tests.cpp000066400000000000000000000003631302010526100212700ustar00rootroot00000000000000 // per_tests.cpp // This set of routines test the Packed Encoding Rule functionality. // There will be numerous references to the PER requirements document. // int Perform_Per_Tests() { } // END Perform_Per_Tests() // EOF per_tests.cppesnacc-ng-1.8.1/cxx-examples/src/readme.txt000066400000000000000000000023261302010526100205530ustar00rootroot00000000000000======================================================================== DYNAMIC LINK LIBRARY : vdatestDLL ======================================================================== AppWizard has created this vdatestDLL DLL for you. This file contains a summary of what you will find in each of the files that make up your vdatestDLL application. vdatestDLL.dsp This file (the project file) contains information at the project level and is used to build a single project or subproject. Other users can share the project (.dsp) file, but they should export the makefiles locally. vdatestDLL.cpp This is the main DLL source file. vdatestDLL.h This file contains your DLL exports. ///////////////////////////////////////////////////////////////////////////// Other standard files: StdAfx.h, StdAfx.cpp These files are used to build a precompiled header (PCH) file named vdatestDLL.pch and a precompiled types file named StdAfx.obj. ///////////////////////////////////////////////////////////////////////////// Other notes: AppWizard uses "TODO:" to indicate parts of the source code you should add to or customize. ///////////////////////////////////////////////////////////////////////////// esnacc-ng-1.8.1/cxx-examples/src/rfc1155-smi.asn1000066400000000000000000000123201302010526100212100ustar00rootroot00000000000000-- file: asn1specs/1155_smi.asn1 -- -- this file is used in ../c{,++}-examples/snmp/ -- -- $Header: /baseline/SNACC/c++-examples/src/rfc1155-smi.asn1,v 1.2 2003/12/17 19:05:03 gronej Exp $ -- $Log: rfc1155-smi.asn1,v $ -- Revision 1.2 2003/12/17 19:05:03 gronej -- SNACC baseline merged with PER v1_7 tag -- -- Revision 1.1.2.1 2003/11/05 14:58:56 gronej -- working PER code merged with esnacc_1_6 -- -- Revision 1.1 2002/07/02 17:25:21 leonberp -- moved from vdatest -- -- Revision 1.2 2002/04/09 19:19:21 vracarl -- rebuilt -- -- Revision 1.2 2002/02/28 21:41:28 vracarl -- changed private to myprivate because it's a C++ keyword -- -- Revision 1.1.1.1 2000/08/21 20:36:15 leonberp -- First CVS Version of SNACC. -- -- Revision 1.3 1995/07/27 08:29:16 rj -- rfc1155-smi.asn1, rfc1157-snmp.asn1 and rfc1213-mib2.asn1 renamed from 1155-smi.asn1, 1157-snmp.asn1 and 1213-mib2.asn1 to accomodate to snacc's new file name generation scheme. -- -- Revision 1.2 1995/07/25 19:53:12 rj -- changed `_' to `-' in file names. -- -- Revision 1.1 1994/08/31 23:08:26 rj -- first check-in. -- RFC1155-SMI DEFINITIONS ::= BEGIN EXPORTS -- EVERYTHING internet, directory, mgmt, experimental, myprivate, enterprises, OBJECT-TYPE, ObjectName, ObjectSyntax, SimpleSyntax, ApplicationSyntax, NetworkAddress, IpAddress, Counter, Gauge, TimeTicks, Opaque; -- the path to the root internet OBJECT IDENTIFIER ::= { iso org(3) dod(6) 1 } directory OBJECT IDENTIFIER ::= { internet 1 } mgmt OBJECT IDENTIFIER ::= { internet 2 } experimental OBJECT IDENTIFIER ::= { internet 3 } -- Commented out because private is a C++ keyword LTV -- private OBJECT IDENTIFIER ::= { internet 4 } myprivate OBJECT IDENTIFIER ::= { internet 4 } enterprises OBJECT IDENTIFIER ::= { myprivate 1 } -- definition of object types OBJECT-TYPE MACRO ::= BEGIN TYPE NOTATION ::= "SYNTAX" type (TYPE ObjectSyntax) "ACCESS" Access "STATUS" Status VALUE NOTATION ::= value (VALUE ObjectName) Access ::= "read-only" | "read-write" | "write-only" | "not-accessible" Status ::= "mandatory" | "optional" | "obsolete" END -- names of objects in the MIB ObjectName ::= OBJECT IDENTIFIER -- syntax of objects in the MIB ObjectSyntax ::= CHOICE { simple SimpleSyntax, -- note that simple SEQUENCEs are not directly -- mentioned here to keep things simple (i.e., -- prevent mis-use). However, application-wide -- types which are IMPLICITly encoded simple -- SEQUENCEs may appear in the following CHOICE application-wide ApplicationSyntax } SimpleSyntax ::= CHOICE { number INTEGER, string OCTET STRING, object OBJECT IDENTIFIER, empty NULL } ApplicationSyntax ::= CHOICE { address NetworkAddress, counter Counter, gauge Gauge, ticks TimeTicks, arbitrary Opaque -- other application-wide types, as they are -- defined, will be added here } -- application-wide types NetworkAddress ::= CHOICE { internet IpAddress } IpAddress ::= [APPLICATION 0] -- in network-byte order IMPLICIT OCTET STRING (SIZE (4)) Counter ::= [APPLICATION 1] IMPLICIT INTEGER (0..4294967295) Gauge ::= [APPLICATION 2] IMPLICIT INTEGER (0..4294967295) TimeTicks ::= [APPLICATION 3] IMPLICIT INTEGER (0..4294967295) Opaque ::= [APPLICATION 4] -- arbitrary ASN.1 value, IMPLICIT OCTET STRING -- "double-wrapped" END esnacc-ng-1.8.1/cxx-examples/src/rfc1157-snmp.asn1000066400000000000000000000117571302010526100214140ustar00rootroot00000000000000-- file: asn1specs/1157_snmp.asn1 -- -- this file is used in ../c{,++}-examples/snmp/ -- -- $Header: /baseline/SNACC/c++-examples/src/rfc1157-snmp.asn1,v 1.2 2003/12/17 19:05:03 gronej Exp $ -- $Log: rfc1157-snmp.asn1,v $ -- Revision 1.2 2003/12/17 19:05:03 gronej -- SNACC baseline merged with PER v1_7 tag -- -- Revision 1.1.2.1 2003/11/05 14:58:56 gronej -- working PER code merged with esnacc_1_6 -- -- Revision 1.1 2002/07/02 17:25:21 leonberp -- moved from vdatest -- -- Revision 1.2 2002/04/09 19:19:22 vracarl -- rebuilt -- -- Revision 1.1.1.1 2000/08/21 20:36:15 leonberp -- First CVS Version of SNACC. -- -- Revision 1.3 1995/07/27 08:29:17 rj -- rfc1155-smi.asn1, rfc1157-snmp.asn1 and rfc1213-mib2.asn1 renamed from 1155-smi.asn1, 1157-snmp.asn1 and 1213-mib2.asn1 to accomodate to snacc's new file name generation scheme. -- -- Revision 1.2 1995/07/25 19:53:13 rj -- changed `_' to `-' in file names. -- -- Revision 1.1 1994/08/31 23:08:27 rj -- first check-in. -- RFC1157-SNMP DEFINITIONS ::= BEGIN IMPORTS ObjectName, ObjectSyntax, NetworkAddress, IpAddress, TimeTicks FROM RFC1155-SMI; -- top-level message Message ::= SEQUENCE { version -- version-1 for this RFC INTEGER { version-1(0) }, community -- community name OCTET STRING, data -- e.g., PDUs if trivial PDUs -- authentication is being used } -- protocol data units PDUs ::= CHOICE { get-request GetRequest-PDU, get-next-request GetNextRequest-PDU, get-response GetResponse-PDU, set-request SetRequest-PDU, trap Trap-PDU } -- PDUs GetRequest-PDU ::= [0] IMPLICIT PDU GetNextRequest-PDU ::= [1] IMPLICIT PDU GetResponse-PDU ::= [2] IMPLICIT PDU SetRequest-PDU ::= [3] IMPLICIT PDU PDU ::= SEQUENCE { request-id INTEGER, error-status -- sometimes ignored INTEGER { noError(0), tooBig(1), noSuchName(2), badValue(3), readOnly(4), genErr(5) }, error-index -- sometimes ignored INTEGER, variable-bindings -- values are sometimes ignored VarBindList } Trap-PDU ::= [4] IMPLICIT SEQUENCE { enterprise -- type of object generating -- trap, see sysObjectID in [5] OBJECT IDENTIFIER, agent-addr -- address of object generating NetworkAddress, -- trap generic-trap -- generic trap type INTEGER { coldStart(0), warmStart(1), linkDown(2), linkUp(3), authenticationFailure(4), egpNeighborLoss(5), enterpriseSpecific(6) }, specific-trap -- specific code, present even INTEGER, -- if generic-trap is not -- enterpriseSpecific time-stamp -- time elapsed between the last TimeTicks, -- (re)initialization of the -- network -- entity and the generation of the -- trap variable-bindings -- "interesting" information VarBindList } -- variable bindings VarBind ::= SEQUENCE { name ObjectName, value ObjectSyntax } VarBindList ::= SEQUENCE OF VarBind END esnacc-ng-1.8.1/cxx-examples/src/snmp.cpp000066400000000000000000000032061302010526100202340ustar00rootroot00000000000000#include "asnutil.h" #include "rfc1155-smi.h" #include "rfc1157-snmp.h" #include using namespace SNACC; /* * FUNCTION: test_snmp_file() * * Attempt to decode the SNMP file and indicate success or failure to std::cout */ void test_snmp_file(char *pszfn) { FUNC("test_snmp_file"); Message snmpObject; AsnBuf inputBuf(pszfn); std::cout << "SNMP test [" << pszfn << "]\n"; AsnLen bytesDecoded = 0; try { snmpObject.BDec(inputBuf, bytesDecoded); std::cout << "\n"; } catch (std::bad_alloc &) { std::cout << "Caught bad alloc!\n"; } catch (SnaccException &) { std::cout << "test_snmp_file() failure " << pszfn << "\n"; } std::cout.flush(); } /************************************************************************ FUNCTION: run_snmp_tests() Description: This functions traverses through a directory containing SNMP V1 objects and uses test_snmp_test() to decode them. The SNMP objects distributed with eSNACC should all decode succesfully. ************************************************************************/ void run_snmp_tests(char *path) { char *fn = NULL; char fullPath[256]; GFSI_HANDLE gfsi_handle; std::cout << "\n*** SNMP V1 TESTS ***\n\n"; fn = GFSI_GetFirstFile(&gfsi_handle, path); if (fn == NULL) { std::cout << "ERROR: Bath path or directory is empty\n"; } while (fn != NULL) { sprintf(fullPath,"%s/%s",path,fn); test_snmp_file(fullPath); fn = GFSI_GetNextFile(&gfsi_handle); } GFSI_Close(&gfsi_handle); std::cout << "\n*** END OF SNMP V1 TESTS ***\n"; } /* end of traverseDir() */ esnacc-ng-1.8.1/cxx-examples/src/testbuf.cpp000066400000000000000000000060361302010526100207370ustar00rootroot00000000000000#include "asn-buf.h" #include "asnutil.h" void newBufTest() { std::cout << "*** Testing AsnBuf ****\n"; try { SNACC::AsnBuf testBufExcept; testBufExcept.GetByte(); } catch (SNACC::SnaccException &e) { std::cout << "Caught buffer exception as expected: " << e.what() << "\n"; } std::fstream fs("test.txt"); unsigned char test[10000]; int j; try { fillTestBuffer(&test[0], 10000); // file test std::filebuf fb; fb.open("test.txt", std::ios_base::out | std::ios_base::binary); fb.sputn((char *)&test[0], 10000); fb.close(); SNACC::AsnBuf fileBuf("test.txt"); if (fileBuf.length() != 10000) { std::cout << "ERROR: AsnBuf() file length check failed!\n"; } else { char fileData[10000]; try { fileBuf.GetSeg(&fileData[0], 10000); if (memcmp(fileData, test, 10000) != 0) { std::cout << "ERROR: AsnBuf() file data check failed!\n"; } } catch(...) { std::cout << "ERROR: AsnBuf() file GetSeg() failed!\n"; } } SNACC::AsnBuf buf2[1000]; for (j = 0; j < 1; j++) { SNACC::AsnBuf tmpBuf((char *)test,4200); #ifdef _DEBUG tmpBuf.status(std::cout); #endif tmpBuf.ResetMode(); char ch = tmpBuf.GetByte(); char ch2 = tmpBuf.GetByte(); std::cout << "ch == " << (int)ch << " ch2 == " << (int)ch2 << "\n"; buf2[j].PutSegRvs((char *)test, 10000); #ifdef _DEBUG buf2[j].status(std::cout); #endif SNACC::AsnBuf buf; buf = buf2[j]; buf.ResetMode(); if (buf.length() != 10000) { std::cout << "length() after PutSegRvs() test FAILED!\n"; } std::stringstream ss, ss2; ss << buf; buf.ResetMode(); ss2 << buf; #ifdef _DEBUG buf.status(std::cout); #endif buf.ResetMode(); const char *ps = ss.str().data(); // buf.GetSeg(10000) checkTestBuffer((unsigned char *) ps, 10000); if ((ss.str().length() == 10000) && (memcmp(test, ps, 10000) == 0)) { std::cout << "ss is good!" << std::endl; } else { std::cout << "[" << j << "] ss is not good!" << std::endl; } const char *ps2 = ss2.str().data(); if (ss2.str().length() == 10000 && memcmp(test, ps2, 10000) == 0){ std::cout << "ss2 is good!" << std::endl; } else{ std::cout << "[" << j << "] ss2 is not good" << std::endl; } } } catch (std::exception &e) { std::cout << "Caught Standard Exception: " << e.what() << std::endl; } catch (...) { std::cout << "Caught un-handled exception!" << std::endl; } std::cout << "*** end of AsnBuf test ***\n"; } esnacc-ng-1.8.1/cxx-examples/src/testsetsorting.cpp000066400000000000000000000067441302010526100223720ustar00rootroot00000000000000#include "asnutil.h" #include "vdatest_asn.h" using namespace SNACC; void multiCardSetTest(); typedef struct set_test_table { AsnType *asnType; char *input; char *derSorted; } SetTestTable; TestSetSorting1 testSetSorting1_AsnType; VDATestSetOfAny testSetOfAny_AsnType; SetTestTable gSetSortingTable[]= { { // SET // INTEGER // OBJECT IDENTIFER // OCTET STRING // BIT STRING &testSetSorting1_AsnType, "311F05000202112206034C02010403112233030200FF1301313000310405000500", // hex input "311F02021122030200FF0403112233050006034C02013000310405000500130131" // hex result }, { &testSetOfAny_AsnType, "31050500020111", // set of NULLs input "31050201110500" // result }, { &testSetOfAny_AsnType, "310B02021122130132030200FF", // input "310B02021122030200FF130132" // result }, { &testSetOfAny_AsnType, "318030800202112204011100000000", "310B3080020211220401110000" }, { &testSetOfAny_AsnType, "318005000000", "31020500" }, { NULL, NULL, NULL } }; void TestSetSorting(void) { int i = 0; while (gSetSortingTable[i].input != NULL) { AsnLen bytesDecoded=0, bytesEncoded; //TestSetSorting1 testSetSorting1; int ch; std::string input, result; hex2str(gSetSortingTable[i].input, input); hex2str(gSetSortingTable[i].derSorted, result); std::stringstream ssInput(input); std::stringstream ssResult(result); AsnBuf inputBuf(ssInput); AsnBuf expectedResultBuf(ssResult); AsnBuf outputBuf; inputBuf.ResetMode(); expectedResultBuf.ResetMode(); gSetSortingTable[i].asnType->BDec(inputBuf, bytesDecoded); bytesEncoded = gSetSortingTable[i].asnType->BEnc(outputBuf); if (bytesEncoded != bytesDecoded) { std::cout << "Encoded / Decode byte length mismatch!!!\n"; } if (outputBuf == expectedResultBuf) { std::cout << "SET sorting SUCCESS!\n"; } else { std::cout << "SET sorting FAILURE!\n"; std::string str; std::cout << "Expected result: "; expectedResultBuf.hexDump(std::cout); std::cout << std::endl; std::cout << "Actual result : "; outputBuf.ResetMode(); outputBuf.hexDump(std::cout); std::cout << std::endl; } i++; } multiCardSetTest(); } void checkBuf(AsnBuf &b) { Deck::const_iterator i; for (i = b.deck().begin(); i != b.deck().end(); i++) { Card *tmpCard = *i; } } void multiCardSetTest() { OctetStringSetOf octsSet; unsigned char test[10213]; fillTestBuffer(test,10213); octsSet.insert(octsSet.end(), SNACC::AsnOcts())->Set((char*)test, 10213); std::cout << "**** LARGE SET OF OCTET STRING TEST ****\n"; AsnBuf tmpBuf; AsnLen bytesEncoded = octsSet.BEnc(tmpBuf); checkBuf(tmpBuf); AsnLen bytesDecoded = 0; std::stringstream ss; ss << tmpBuf; OctetStringSetOf octsSet2; tmpBuf.ResetMode(); octsSet2.BDec(tmpBuf, bytesDecoded); if (bytesEncoded != bytesDecoded) { std::cout << "Bytes encoded/decoded do not match\n"; } if (checkTestBuffer(octsSet2.front().c_ustr(), octsSet2.front().Len())) { std::cout << "SUCCESS!\n"; } else { std::cout << "FAILURE!\n"; } std::cout << "**** END OF LARGE SET OF OCTET STRING TEST ****\n"; } esnacc-ng-1.8.1/cxx-examples/src/vda_threads.cpp000066400000000000000000000114401302010526100215420ustar00rootroot00000000000000 // // vda_threads.cpp #include "vda_threads.h" #ifdef _BEGIN_SNACC_NAMESPACE using namespace SNACC; #endif // for WIN32 threaded functions are void functions. // for pthread threaded functions return void pointers. // #ifdef WIN32 long vdaTestThreadsKickoff2(void( __cdecl *start_address )( void * ), int lThreadCount, struct ThreadNumberDef *&plThread); void vdaTestThreads_Perform(void *f); #else long vdaTestThreadsKickoff2( void * (*start_address )( void * ), int lThreadCount, struct ThreadNumberDef *&plThread); void * vdaTestThreads_Perform(void *f); #endif bool vdaTestThreads_CheckStatus( struct ThreadNumberDef *plThreadNumber, long lThreadCount); void AsnIntTest_NOPRINT(); // NOT THREAD SAFE. DO NOT CALL FROM A THREAD!! // void vdaSleep(long lSleep) { #if defined (WIN32) Sleep (lSleep); #else usleep(lSleep*100); #endif } // // This routine will generate a given number of threads and execute various // SNACC operations to test threads. // long vdaTestThreadsKickoff(int lThreadCount, struct ThreadNumberDef *&plThread) { long status=vdaTestThreadsKickoff2(vdaTestThreads_Perform, lThreadCount, plThread); return(status); } #ifdef WIN32 long vdaTestThreadsKickoff2(void( __cdecl *start_address )( void * ), int lThreadCount, struct ThreadNumberDef *&plThread) #else long vdaTestThreadsKickoff2(void * (*start_address )( void * ), int lThreadCount, struct ThreadNumberDef *&plThread) #endif { FUNC("vdaTestThreadsKickoff2()"); long status=0; #ifndef NO_THREADS long count=0; plThread=(struct ThreadNumberDef *)calloc(lThreadCount, sizeof(struct ThreadNumberDef)); bool bThreadRunning = true; int i; try { // for (i=0; i < lThreadCount; i++) { // Perform initialization. plThread[i].lThreadNumber = i; plThread[i].lThreadStatus = VDATHREAD_STATUS_NOT_DEFINED; } // for (i=0; i < lThreadCount; i++) { // Create threads. #if defined (WIN32) _beginthread(start_address, 0, &plThread[i]); #else pthread_create (&plThread[i].thread, NULL, start_address, (void *)&plThread[i]); #endif vdaSleep(3); } // END for lThreadCount. } catch (SnaccException &e) { e.push(STACK_ENTRY); throw; } #endif return(status); } // // long vdaTestThreadsFinish(int lThreadCount, struct ThreadNumberDef *plThread) { #ifndef NO_THREADS FUNC("vdaTestThreadsFinish()"); long status=0; long count=0; bool bThreadRunning = true; try { while (bThreadRunning) { // Wait until all threads have finished. bThreadRunning = vdaTestThreads_CheckStatus(plThread, lThreadCount); } if (plThread) free(plThread); } catch (SnaccException &e) { e.push(STACK_ENTRY); throw; } return(status); #else return (0); #endif } // // long vdaTestThreads(int lThreadCount) { FUNC("vdaTestThreads()"); long status=0; long count=0; bool bThreadRunning = true; struct ThreadNumberDef *plThread=NULL; try { status = vdaTestThreadsKickoff(lThreadCount, plThread); if (status == 0) { // give threads a chance to start status = vdaTestThreadsFinish(lThreadCount, plThread); } } catch (SnaccException &e) { e.push(STACK_ENTRY); throw; } return(status); } // return true if there are threads still running // bool vdaTestThreads_CheckStatus( struct ThreadNumberDef *plThreadNumber, long lThreadCount) { bool bResult=false; #ifndef NO_THREADS for (int i=0; i < lThreadCount; i++) { if (plThreadNumber[i].lThreadStatus != VDATHREAD_STATUS_DONE) bResult = true; } // END for lThreadCount if (!bResult) { std::cout << "ALL ThreadNumber Tests Passed, DONE!\n"; std::cout.flush(); } #endif // No Threads return(bResult); } void vdaTestThreadsLock_Perform(void *f_INPUT) { vdaTestThreads(*(long *)f_INPUT); } // // #ifdef WIN32 void vdaTestThreads_Perform(void *f_INPUT) #else void * vdaTestThreads_Perform(void *f_INPUT) #endif { #ifndef NO_THREADS int err = 0; struct ThreadNumberDef *f=(struct ThreadNumberDef *)f_INPUT; f->lThreadStatus = VDATHREAD_STATUS_STARTED; int VDATEST_COUNT=5; // PERFORM thread test operation(s). for (int i=0; i < VDATEST_COUNT; i++) { threadLock(); std::cout << "Thread #" << f->lThreadNumber << "\n"; threadUnlock(); } threadLock(); std::cout << "Thread #" << f->lThreadNumber << " DONE!\n"; std::cout.flush(); threadUnlock(); f->lThreadStatus = VDATHREAD_STATUS_DONE; #endif // NO_THREADS } // EOF vda_threads.cpp esnacc-ng-1.8.1/cxx-examples/src/vda_threads.h000066400000000000000000000016461302010526100212160ustar00rootroot00000000000000// vda_threads.h // #include #include #if defined (WIN32) #include #include "process.h" #include #include #include #include #else #define _REENTRANT #ifndef NO_THREADS #include "pthread.h" #endif #include "unistd.h" #endif /* WIN32 */ #include "asn-incl.h" #ifdef _BEGIN_SNACC_NAMESPACE using namespace SNACC; #endif #ifndef NO_THREADS long vdaTestThreads(int lThreadCount); bool vdaTestThreads_CheckStatus( struct ThreadNumberDef *plThreadNumber, long lThreadCount); void vdaSleep(long lSleep); struct ThreadNumberDef { long lThreadNumber; long lThreadStatus; #ifndef WIN32 pthread_t thread; #endif }; #define VDATHREAD_STATUS_NOT_DEFINED 1 #define VDATHREAD_STATUS_STARTED 2 #define VDATHREAD_STATUS_DONE 3 long vdaTestThreadsFinish(int lThreadCount, struct ThreadNumberDef *plThread); #endif //NO_THREADS // EOF vda_threads.h esnacc-ng-1.8.1/cxx-examples/src/vdatest.cpp000066400000000000000000001432751302010526100207440ustar00rootroot00000000000000 #include #include #include "asn-incl.h" #include "vda_threads.h" #include #include using namespace SNACC; #include "vdatest_asn.h" #include "vdatest_asn2.h" short traverseDir(char *path); void test_AsnOid(); void ANY_DEFINED_BY_test(); void ANY_DEFINED_BY_test_2(); int append_test(); void Test_ASN_1_Strings(); void test_big_buffer(); void test_timing(); #define TEST_ENCODE_BUF 1 #define TEST_DECODE_BUF 2 void XML_test(); void AsnIntTest(); AsnInt AAA(22); //test constructors AsnInt AA2(0); //test constructors long vdaTestThreads(int lThreadCount); void vdaTestThreadLocks(); long vdaTestPrintThreadLocks(); void test_IndefiniteLengthEncoding(); using namespace VDATestModule2Namespace; // // int vdatest_main(int argc, char *argv[]) { /*if (argc > 1) { traverseDir(argv[1]); exit(0); }*/ test_IndefiniteLengthEncoding(); #ifdef BOUNDS_CHECKER_TEST_WITHOUT_THREADS vdaTestPrintThreadLocks(); return(0); vdaTestThreadLocks(); vdaTestThreads(55); // AVOIDS problems with above; must be performed last. #endif //ifdef BOUNDS_CHECKER_TEST_WITHOUT_THREADS try { ANY_DEFINED_BY_test(); test_AsnOid(); AsnIntTest(); ANY_DEFINED_BY_test_2(); XML_test(); test_timing(); test_big_buffer(); // THE FOLLOWING TEST also tests SET OF ordering. // ALSO, it must be last since an error condition is trapped. append_test(); } catch ( SnaccException &e ) { std::cout << "ERROR: " << e.what() << "\n"; std::cout << "Call stack:\n"; e.getCallStack(std::cout); std::cout << "\n"; } std::cout << "####### END OF vdatest TESTS #########\n"; std::cout.flush(); return 1; } // Excercise ANY code // void ANY_DEFINED_BY_test() { FUNC("ANY_DEFINED_BY_test()"); AsnOid testOid3_UNKNOWN("1.2.3.4.5.5.5.5.6"); AsnBuf buf; TestDefinedByUsage A, A2, A3; PrintableString prtblStr, prtblStr2; PrintableString *pPrtblStr = NULL; prtblStr = "THIS IS A TEST"; //pB->Set("THIS IS A TEST", strlen("THIS IS A TEST")+1); A.id = testOID2; A.anyDefBy.value = prtblStr.Clone(); A.i1 = 1; A.i2 = 2; A.i3 = 3; A.i4 = 4; // Encode TestDefinedByUsage into a buffer // if (! A.BEnc(buf)) throw SNACC_EXCEPT("Encode of TestDefinedByUsage failed!"); // Decode buffer into a different TestDefinedByUsage to demonstrate the // automatic decoding the ANY DEFINED BY. // unsigned long bytesDecoded=0; A2.BDec(buf, bytesDecoded); // Check the OID to determine if this is the ANY you are looking for. // if (A2.id == testOID2) { // You must cast the ANY to the type you expect. It's up to the // application to do the proper casting. // pPrtblStr = (PrintableString *)A2.anyDefBy.value; std::cout << "ANY_DEFINED_BY_test: Good id, == testOID2." << pPrtblStr->c_str() << "\n"; } else { std::cout << "ANY_DEFINED_BY_test: ***** Bad id, EXPECTED testOID2.\n"; } std::cout.flush(); A.id = testOid3_UNKNOWN; //A.anyDefBy.value = new AsnAnyBuffer((char *)data, len); buf.ResetMode(); if (! A.BEnc(buf)) throw SNACC_EXCEPT("Encode of TestDefinedByUsage failed!"); // There are three methods for assigning an AsnType to an ANY // // // METHOD 1 // // This demonstrates the preferred method of storing any valid AsnType // into an ANY. // Encode buffer into ANY. A.id = testOid3_UNKNOWN; AsnBuf Buf2; if (! prtblStr.BEnc(Buf2)) throw SNACC_EXCEPT("Encode into ANY failed!"); A.anyDefBy.BDec(Buf2, bytesDecoded); // clean up delete A.anyDefBy.value; A.anyDefBy.value = NULL; // METHOD 2 // // Now if this is an ANY DEFINED BY you don't have to encode the AsnType // into the ANY. You copy the AsnType that corresponds to the oid in the // (id). NOTE:: This can cause an application to crash if hand-set by the // developer. Be Careful! // A.id = testOid3_UNKNOWN; A.anyDefBy.value = prtblStr.Clone(); // clean up delete A.anyDefBy.value; A.anyDefBy.value = NULL; // METHOD 3 // // Assign a buffer containing the ASN.1 to an ANY. // A.id = testOid3_UNKNOWN; if (pPrtblStr) { AsnBuf buf4; pPrtblStr->BEnc(buf4); A.anyDefBy.BDec(buf4, bytesDecoded); A3 = A; // FOR next test... } // END IF pPrtblStr // clean up delete A.anyDefBy.value; A.anyDefBy.value = NULL; // ################################## // "ai" is set ONLY if the OID is not in ANY DEFINED BY table OR // if the definition is ANY (not ANY DEFINED BY). if (A3.anyDefBy.ai == NULL) //THEN, we did not recognize the OID.A3.id == testOID2) { AsnBuf Buf2; A3.anyDefBy.BEnc(Buf2); if (A3.id == testOid3_UNKNOWN)// WE KNOW WHAT IT IS and have to check explicitely { PrintableString tmpPrtblStr; unsigned long bytesDecoded=0; tmpPrtblStr.BDec(Buf2, bytesDecoded); std::cout << "ANY_DEFINED_BY_test: Good id, == testOid3_UNKNOWN." << tmpPrtblStr.c_str() << "\n"; } } else { std::cout << "ANY_DEFINED_BY_test: Bad id, <> testOid3_UNKNOWN.\n"; } std::cout.flush(); } // // // THIS Version tests the newly added ability of the SNACC compiler to handle // multiple Object-Type definitions in separate .asn files. void ANY_DEFINED_BY_test_2() { FUNC("ANY_DEFINED_BY_test()"); AsnOid testOid3_UNKNOWN("1.2.3.4.5.5.5.5.6"); AsnBuf buf; TestDefinedByUsage_2 A, A2, A3; PrintableString prtblStr; PrintableString *pPrtblStr = NULL; prtblStr = "THIS IS A TEST"; A.id = testOID2_2; A.anyDefBy.value = prtblStr.Clone(); // Test encoding and decoding of type and contains an ANY DEFINED BY. // if (! A.BEnc(buf)) { throw SNACC_EXCEPT("Encode of TestDefinedByUsage_2 failed!"); } unsigned long bytesDecoded=0; A2.BDec(buf, bytesDecoded); // Test extraction of ANY DEFINED BY // // First check the oid to make to determine the syntax that is // stored in the ANY. It's up to the application to perform this // check correctly. // if (A2.id == testOID2_2) { // Is this is an ANY DEFINED by the syntax is already decoded into the // correct ASN.1 type. It up to the application to perform the // proper casting though. Note: if a copy is desired call the Clone() // method and then cast. // pPrtblStr = (PrintableString *)A2.anyDefBy.value; std::cout << "ANY_DEFINED_BY_test: Good id, == testOID2_2." << pPrtblStr->c_str() << "\n"; } else { std::cout << "ANY_DEFINED_BY_test: Bad id, <> testOID2_2.\n"; } std::cout.flush(); // Use this method to assign a previously encoded value to the ANY DEFINED BY. // Note: buf contains an encoded value from above // A3.id = testOid3_UNKNOWN; buf.ResetMode(); A3.anyDefBy.BDec(buf, bytesDecoded); // Use this method to enode any AsnType into an AsnAny (or AsnAnyDefinedBy) // if (! prtblStr.BEnc(buf)) throw SNACC_EXCEPT("Encoding of PrintableString into AsnAny failed!"); A.anyDefBy.BDec(buf, bytesDecoded); } // // void XML_test() { FUNC("XML_test()"); std::strstream os; TestSequence testSequence; AsnOcts TmpSNACCOcts; AsnBuf TmpBuf; AsnBuf buf; char Aarray[]= { (char )0x30,(char )0x2d,(char )0x02,(char )0x15, (char )0x00,(char )0x94,(char )0x76,(char )0x92,(char )0xae, (char )0x87,(char )0x71,(char )0x0e,(char )0x50,(char )0xf9, (char )0xd5,(char )0x35,(char )0x49,(char )0xda,(char )0xa2, (char )0x40 }; /*TestAllAsnPrimativeTypes ::= SEQUENCE { octs OCTET STRING, boolTest BOOLEAN, oid OBJECT IDENTIFIER OPTIONAL, bitString [2] IMPLICIT BIT STRING, integer INTEGER, enumTest ENUMERATED {A(11), B(12), C(13) }, real REAL OPTIONAL, null NULL }*/ testSequence.testAllPrimatives.octsName.Set(Aarray, sizeof(Aarray)); testSequence.testAllPrimatives.boolTestName = true; testSequence.testAllPrimatives.oidName = new AsnOid(testOID); char *pData="TES";//(char)0xa5, (char)0xa5, (char)0xa5}; testSequence.testAllPrimatives.bitStringName.Set((const unsigned char*)pData, 24); testSequence.testAllPrimatives.integerName = 55; testSequence.testAllPrimatives.enumTestName = TestAllAsnPrimativeTypesEnum::aA; testSequence.testAllPrimatives.realName = new AsnReal(44.2); TmpSNACCOcts.Set("this is a test of SetOf", strlen("this is a test of SetOf")+1); AsnBuf Buf2; if (! TmpSNACCOcts.BEnc(Buf2)) throw SNACC_EXCEPT("Encoding TmpSNACCOCts failed!"); testSequence.testSetOfAny.insert(testSequence.testSetOfAny.end(),SNACC::AsnAny()); unsigned long bytesDecoded=0; testSequence.testSetOfAny.back().BDec(Buf2, bytesDecoded); testSequence.directoryString.choiceId = DirectoryString::printableStringCid; testSequence.directoryString.printableString = new DirectoryString::PrintableString_; *testSequence.directoryString.printableString = "Printable String TEST"; // testSequence.testSet = new VDATestSet; // ALLOW all defaults... if (! testSequence.BEnc(buf) ) throw SNACC_EXCEPT("Encoding of testSequence failed!"); std::cout << "######################################\n"; std::cout << "### PrintXML test ##################\n"; std::ofstream ofs("vdatest.xml"); testSequence.PrintXML(ofs); std::cout << "### END PrintXML test ##############\n"; std::cout << "######################################\n"; std::cout.flush(); } int append_test() { FUNC("append_test()"); VDATestSequence testSeq; VDATestSet testSet; VDATestSet testSet2; VDATestSet testSetBER; VDATestSetOfAny testSetOfAny; char testSeqBlobTbl[] = { 0x30, 0x06, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02 }; // SET OF Integers, 04 tag, 01 length, 01 then 02 data. char testSetBlobTbl[] = { 0x31, 0x06, 0x02, 0x01, 0x01, 0x04, 0x01, 0x02 }; char testSetBlobTblVaryLengths[] = { 0x31, 54, 0x04, 0x01, 0x71, 0x04, 0x02, 0x72, 0x72, 0x04, 0x03, 0x72, 0x73, 0x74, 0x04, 0x03, 0x74, 0x72, 0x73, 0x04, 0x05, 0x74, 0x72, 0x73, 0x73, 0x73, 0x04, 0x03, 0x74, 0x72, 0x79, 0x04, 0x03, 0x74, 0x72, 0x78, 0x04, 0x03, 0x74, 0x72, 0x77, 0x04, 0x03, 0x74, 0x72, 0x76, 0x04, 0x03, 0x74, 0x72, 0x75, 0x04, 0x03, 0x74, 0x72, 0x74 }; // THESE SHOULD all be ordered char testSetBlobBERTbl[] = { 0x31, 0x06, 0x02, 0x01, 0x02, 0x04, 0x01, 0x01 }; //RWC;? 0x03?;char testSetOfAnyBlobTbl[] = { 0x31, 0x08, 0x03, 0x02, 0x04, 0x0F, 0x03, 0x02, 0x05, 0x0E }; char testSetOfAnyBlobTbl[] = { 0x31, 0x08, 0x04, 0x02, 0x04, 0x0F, 0x04, 0x02, 0x05, 0x0E }; char testNullBitString[] = { 0x03, 0x01, 0x00 }; char testBit1BitString[] = { 0x03, 0x02, 0x02, 0x20}; // 2 unused bits, data 0x20 (2nd bit set). AsnOid TestOid; // the following tables are DER encoded results for // VDATestSequence, VDATestSet, and VDATestSetOfAny. Decode // these tables and then re-encode them to determine if we // come up with the same results. // // note: this doesn't test every scenario. // AsnBuf buf; AsnBuf testNullBitStringBlob(&testNullBitString[0], 3); AsnBuf testNullBitStringBlob2; AsnBits snaccNullBitString(8); // 8 bits with nothing set VDATestBitString snaccNullBitString3(8); // RWC;12/18/00; THIS SET of tests require that the Named Bit rules // be applied. Named Bit rules are set only for declared ASN SNACC // compiler processed Bit Strings, not for "AsnBits" declared vars // as in "snaccNullBitString" above. // THIS 1st test should not produce 030100. //ENCODE_BUF_NO_ALLOC(&snaccNullBitString3, &testNullBitStringBlob2); SequenceOfDefaults AA; AA.defBitstring = new ClassList(8); if (! AA.defBitstring->BEnc(buf) ) throw SNACC_EXCEPT("Encoding of DEFAULT BIT STRING failed!"); if (buf == testNullBitStringBlob) { std::cout << "NULL BIT STRING 1 TEST PASSED!\n"; std::cout.flush(); } else { std::cout << "NULL BIT STRING TEST 1 FAILED!\n"; std::cout << "ENCODED VALUE IS:\n"; buf.hexDump(std::cout); std::cout << "\nIT SHOULD BE:\n"; testNullBitStringBlob.hexDump(std::cout); std::cout << "\n"; std::cout.flush(); } if (! snaccNullBitString3.BEnc(buf) ) throw SNACC_EXCEPT("Encoding of NULL BIT STRING failed!"); if (buf == testNullBitStringBlob) { std::cout << "NULL BIT STRING 2 TEST PASSED!\n"; std::cout.flush(); } else { std::cout << "NULL BIT STRING TEST 2 FAILED!\n"; std::cout << "ENCODED VALUE IS:\n"; buf.hexDump(std::cout); std::cout << "\nIT SHOULD NOT BE:\n"; testNullBitStringBlob.hexDump(std::cout); std::cout << "\n"; std::cout.flush(); } // Now let's test a bits string that has more than one octet that is null. // The resulting encoding should look like the testNullBitString above. AsnBuf bufAA; AA.defBitstring->Set(17); if (! AA.defBitstring->BEnc(bufAA) ) throw SNACC_EXCEPT("Encoding of NULL BIT STRING failed"); if (bufAA == testNullBitStringBlob) { std::cout << "Multiple null octets NULL BIT STRING test 3 passed!\n"; std::cout.flush(); } else { std::cout << "Multiple null octets NULL BIT STRING TEST 3 FAILED!\n"; std::cout << "ENCODED VALUE IS:\n"; bufAA.hexDump(std::cout); std::cout << "\nIT SHOULD BE:\n"; testNullBitStringBlob.hexDump(std::cout); std::cout << "\n"; std::cout.flush(); } // Test BIT STRING with only the first bit set. // AsnBuf tmpBuf(testBit1BitString, 4); AsnBuf tmpBlob; AsnBits snaccBitStr; snaccBitStr.UseNamedBitListRules(false); snaccBitStr.Set(6); snaccBitStr.SetBit(2); if (snaccBitStr.IsEmpty()) std::cout << "ERROR: Bitstring is empty!\n"; AsnBuf bufAA2; if (! snaccBitStr.BEnc(bufAA2) ) throw SNACC_EXCEPT("Encoding of BIT with only 1st bit set failed!"); if (bufAA2 == tmpBuf) { std::cout << "Bitstring with first bit set and uneven bit count PASSED!\n"; std::cout.flush(); } else { std::cout << "Bitstring with first bit set and uneven bit count FAILED!\n"; std::cout << "BitString Encoded as:\n"; bufAA2.hexDump(std::cout); std::cout << "It should be:\n"; tmpBuf.hexDump(std::cout); std::cout << "\n"; std::cout.flush(); } memset(&snaccBitStr, 0, sizeof(snaccBitStr)); if (! snaccBitStr.IsEmpty()) std::cout << "ERROR: Bitstring expected to by empty!\n"; // sequence of to integers // AsnBuf testSeqBlob( &testSeqBlobTbl[0], 8); AsnBuf testSeqBlob2; // sequence of two octet strings // AsnBuf testSetBlob( &testSetBlobTbl[0], 8); AsnBuf testSetBlobBER( &testSetBlobBERTbl[0] , 8); AsnBuf testSetBlobVaryingLengths( &testSetBlobTblVaryLengths[0], 56); AsnBuf testSetBlob2; AsnBuf testSetBlobDER2; // sequence of two ANYs. In this case the any's are two BIT STRINGS // AsnBuf testSetOfAnyBlob( &testSetOfAnyBlobTbl[0] , 10); AsnBuf testSetOfAnyBlob2; // Decode, Encode, and Compare Test Sequence // unsigned long bytesDecoded=0; testSeq.BDec(testSeqBlob, bytesDecoded); if (! testSeq.BEnc(testSeqBlob2) ) throw SNACC_EXCEPT("Re-encode of testSeq failed!"); if (testSeqBlob2 == testSeqBlob) std::cout << "Passed Sequence test ...\n"; else std::cout << "Failed Sequence test ...\n"; // Decode, Encode, and Compare Test Set // testSet.BDec(testSetBlob, bytesDecoded); testSetBlob.ResetMode(); if (! testSet.BEnc(testSetBlob2) ) throw SNACC_EXCEPT("Re-encode of testSet failed!"); testSetBlob2.hexDump(std::cout); std::cout<> 8)); buf[j] = tempnum; } #else int j; unsigned long tempnum; buf = (unsigned long *)actual; for ( j = 0; j < Len/4; j++ ) { tempnum = (buf[j] << 16) | (buf[j] >> 16); buf[j] = ((tempnum & 0xff00ff00L) >> 8) | ((tempnum & 0x00ff00ffL) << 8); } #endif } else #ifdef WIN32 buf = (unsigned short *)actual; #else buf = (unsigned long *)actual; #endif // Compare the strings stat = strncmp((const char *)expected, (const char *)actual, Len); return stat; } void Test_ASN_1_Strings() { // RFC 2253 Test Data //unsigned char RFC2253TestData[] = { 0x4c, 0x75, 0xC4, 0x8d, 0x69, 0xC4, 0x87, 0x00, 0x00 }; //const int RFC2253TestDataLen = 9; // RFC 2279 Test Data Section 4 (Examples) Example 1 unsigned char RFC2279TestData1[] = { 0x41, 0xE2, 0x89, 0xA2, 0xCE, 0x91, 0x2E, 0x00 }; unsigned char RFC2279TestResult1[] = {0x00, 0x41, 0x22, 0x62, 0x03, 0x91, 0x00, 0x2E }; // RFC 2279 Test Data Section 4 (Examples) Example 2 unsigned char RFC2279TestData2[] = { 0xED ,0x95 ,0x9C ,0xEA, 0xB5, 0xAD, 0xEC, 0x96, 0xB4,0x00 }; unsigned char RFC2279TestResult2[] = { 0xD5, 0x5C, 0xAD, 0x6D, 0xC5, 0xB4 }; // RFC 2279 Test Data Section 4 (Examples) Example 3 unsigned char RFC2279TestData3[] = { 0xE6, 0x97, 0xA5, 0xE6, 0x9C, 0xAC, 0xE8, 0xAA, 0x9E }; unsigned char RFC2279TestResult3[] = { 0x65, 0xE5, 0x67, 0x2C, 0x8A, 0x9E }; // RFC 2279 Test Data Section 4 (Examples) Example 4 //unsigned char UTF8TestData4[] = { 0x00,0x4c,0x80, 0x80,0x01, 0x0d, 0x00, 0x69, 0x01, 0x07, 0x00, 0x00 }; // unsigned char RFC2279TestResult4[] = { 0x const int RFC2279TestData1Len = 8; const int RFC2279TestData2Len = 10; //const int RFC2279TestData3Len = 9; //const int RFC2279TestData4Len = 12; const int RFC2279TestResult1Len = 8; const int RFC2279TestResult2Len = 6; const int RFC2279TestResult3Len = 6; // Universal String is 4 bytes long /*char universal_string[] = { 0x00, 0x00,0x00,0x4c,0x00, 0x00,0x00, 0x75,0x00, 0x00, 0x01, 0x0d, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x01, 0x07, 0x00, 0x00,0x00,0x00 }; */ wchar_t wc_universal_string[] = { 0x0000004c, 0x00000075, 0x0000010d, 0x00000069, 0x00000107, 0x00000000 }; char bmp_string[] = {0x00, 'T', 0x00, 'E', 0x00, 'S', 0x00, 'T'}; std::wstring bmpTest; int universal_stringLen = 24; long status=0; UniversalString unvStr; PrintableString prtblStr; PrintableString prtblStr2; UTF8String C; PrintableString AP; BMPString D; wchar_t *pWchar=NULL; char *tempChar = NULL; int i; std::string utf8Form; std::cout << "######### Test_ASN_1_Strings: START OF TEST ####\n"; unvStr = &wc_universal_string[0]; // Excercise UniversalString code // std::cout << "UniversalString:\n"; unvStr.getAsUTF8(utf8Form); std::cout << "UTF8 Form:\n" << utf8Form.c_str() << "\n"; std::cout << "UniversalString Results \n"; std::cout.setf(std::ios::hex); tempChar = (char *)pWchar; for (i=0; i < universal_stringLen+1/2; i++) { std::cout << "0x"<< (int)tempChar[i]; std::cout << " "; if ((tempChar[i+1] == 0x00) && (tempChar[i+2] == 0x00) && (tempChar[i+3] == 0x00) && (tempChar[i+4] == 0x00)) i = universal_stringLen+10; // Exit } std::cout << "\n"; std::cout.setf(std::ios::dec); std::cout.flush(); std::cout << "######### Test_ASN_1_Strings: END OF TEST ####\n\n"; std::cout << "######### Test_ASN_1_Strings: START OF TEST ####\n\n"; std::cout << "\n"; // cout << "Test_ASN_1_Strings: pWchar of A=" << TmpChar << "\n"; // Exercise PrintableString // prtblStr = "blah PrintableString"; std::cout << "PrinableString:\nnarrow form: " << prtblStr.c_str() << "\n"; std::cout << "######### Test_ASN_1_Strings: START OF TESTS ####\n"; std::cout << "Test 1 input data is: \n"; std::cout.setf(std::ios::hex); outhex (RFC2279TestData1, RFC2279TestData1Len); std::cout << "\n"; std::cout.setf(std::ios::dec); std::cout.flush(); prtblStr2 = (const char *)&RFC2279TestData1[0]; //utf8Str = prtblStr2; C = AP; // TEST Multi-byte assignment to single-byte ASN.1 def. std::cout << "Test 1 Expected Result:\n"; outhex(RFC2279TestResult1, RFC2279TestResult1Len); C.set((char *)RFC2279TestData1);//, RFC2279TestData1Len); std::wstring wideString; wideString = C; // WORKS; Transform the UTF-8 to Wide Character char *ptr2=C.getAsUTF8(); std::cout << "\nTest 1 Actual Test Result(Intel platforms will have bytes flipped):\n"; if (ptr2 && wideString.length()) { outhex((unsigned char *)ptr2, RFC2279TestResult1Len); status = utf8compare (RFC2279TestResult1, (wchar_t*)wideString.c_str(), RFC2279TestData1Len); if (status != 0) std::cout << "Actual Results do not compare with expectd results\n"; else std::cout << "######### Results compare\n"; } else std::cout << "ptr2 is NULL, which is in error\n"; std::cout << "\n"; std::cout << "Test 2 input data is: \n"; std::cout.setf(std::ios::hex); outhex (RFC2279TestData2, RFC2279TestData2Len); std::cout << "\n"; std::cout.setf(std::ios::dec); std::cout.flush(); AP = (char *)RFC2279TestData2; C = AP; // TEST Multi-byte assignment to single-byte ASN.1 def. std::cout << "Test 2 Expected Result:\n"; outhex (RFC2279TestResult2, RFC2279TestResult2Len); C = (char *)RFC2279TestData2; wideString = C; // Transform the UTF-8 to Wide Character ptr2 = C.getAsUTF8(); std::cout << "\nTest 2 Actual Test Result(Intel platforms will have bytes flipped):\n"; if (ptr2 != NULL && wideString.length() != 0) { outhex ((unsigned char *)ptr2, RFC2279TestResult2Len); status = utf8compare (RFC2279TestResult2, (wchar_t*)wideString.c_str(), RFC2279TestResult2Len); if (status != 0) std::cout << "Actual Results do not compare with expectd results\n"; else std::cout << "######### Results compare\n"; } else std::cout << "wideString is NULL, which is in error\n"; std::cout << "\n"; std::cout << "\n"; std::cout << "Test 3 input data is: \n"; std::cout.setf(std::ios::hex); outhex (RFC2279TestData2, RFC2279TestData2Len); std::cout << "\n"; std::cout.setf(std::ios::dec); std::cout.flush(); AP = (char *)RFC2279TestData3; C = AP; // TEST Multi-byte assignment to single-byte ASN.1 def. std::cout << "Test 3 Expected Result:\n"; outhex (RFC2279TestResult3, RFC2279TestResult3Len); //C.Set((char *)RFC2279TestData3, RFC2279TestData3Len); C = (char *)RFC2279TestData3; wideString = C; // Transform the UTF-8 to Wide Character ptr2 = C.getAsUTF8(); std::cout << "\nTest 3 Actual Test Result(Intel platforms will have bytes flipped):\n"; if (ptr2 && wideString.length() != 0) { outhex ((unsigned char *)ptr2, RFC2279TestResult3Len); status = utf8compare (RFC2279TestResult3, (wchar_t*)wideString.c_str(), RFC2279TestResult3Len); if (status != 0) std::cout << "Actual Results do not compare with expectd results\n"; else std::cout << "######### Results compare\n"; } else std::cout << "wideString.c_str() is NULL, which is in error\n"; std::cout << "\n"; std::cout << "######### Test_ASN_1_Strings: END OF TEST 3 ####\n\n"; std::cout << "\n"; std::cout << "######### Test_ASN_1_Strings: START OF TESTS ####\n"; std::cout << "Test 4 input data is: \n"; outhex ((unsigned char *)bmp_string, 8); std::cout << "\n"; bmpTest += 'T'; bmpTest += 'E'; bmpTest += 'S'; bmpTest += 'T'; //D.Set((char *)bmpTest, 8); D = bmpTest; std::wstring tmpwString; tmpwString = D; ptr2 = D.getAsUTF8(); std::cout << "Test 4 actual BMPString -> wstring is:\n"; outhex ((unsigned char *)ptr2, 8); std::cout << "\n"; std::cout << "######### Test_ASN_1_Strings: END OF TEST 4 ####\n\n"; std::cout << "\n"; std::cout.flush(); } void test_big_buffer() { char pchBuffer[200000]; AsnBuf *pM=new AsnBuf; AsnOcts N; unsigned long bytesDecoded=0; memset(pchBuffer, 'A', 200000); N.Set(pchBuffer, 200000); N.BEnc(*pM); std::cout << "test_big_buffer: Octet STring encoded length of 200000 byte buf=" << pM->length() << "\n"; N.BDec(*pM, bytesDecoded); delete pM; } // #include #include #include #include #include void test_timingDoTestPrint(long BYTE_COUNT, long iCount, int new_flag, long lTestType); void test_timing() { #ifdef TESTS_ALREADY_DONE test_timingDoTestPrint(90000, iCount, 0, TEST_ENCODE_BUF); test_timingDoTestPrint(90000, iCount, 1, TEST_ENCODE_BUF); test_timingDoTestPrint(90000, iCount, 0, TEST_DECODE_BUF); test_timingDoTestPrint(90000, iCount, 1, TEST_DECODE_BUF); test_timingDoTestPrint(90000, iCount, 0, TEST_ENCODE_BUF); test_timingDoTestPrint(90000, iCount, 0, TEST_DECODE_BUF); test_timingDoTestPrint(90000, iCount, 2, TEST_ENCODE_BUF); test_timingDoTestPrint(90000, iCount, 2, TEST_DECODE_BUF); #endif //RELEASE Version //test_timing: Start. //test_timing: OLD ENCODE_BUF iCount=1000, Time=10.160000, single=0.010160 Size=90000bytes. //test_timing: Start. //test_timing: NEW ENCODE_BUF iCount=1000, Time=2.640000, single=0.002640 Size=90000bytes. //DEBUG Version //test_timing: Start. //test_timing: OLD ENCODE_BUF iCount=1000, Time=14.060000, single=0.014060 Size=90000bytes. //test_timing: Start. //test_timing: NEW ENCODE_BUF iCount=1000, Time=6.860000, single=0.006860 Size=90000bytes. //test_timing: Start. //test_timing: OLD DECODE_BUF iCount=1000, Time=7.910000, single=0.007910 Size=90000bytes. //test_timing: Start. //test_timing: NEW DECODE_BUF iCount=1000, Time=1.210000, single=0.001210 Size=90000bytes. } double test_timingDoTest(long BYTE_COUNT, long iCount, int new_flag, long lTestType); void test_timingDoTestPrint(long lByteCount, long iCount, int new_flag, long lTestType) { double dSingle; double dResult; char *lpszNewFlag; char *lpszTypeFlag="TEST"; dResult = test_timingDoTest(lByteCount, iCount, new_flag,lTestType); dSingle = dResult / iCount; if (new_flag) lpszNewFlag = "NEW"; else lpszNewFlag = "OLD"; if (lTestType == TEST_ENCODE_BUF) lpszTypeFlag = "ENCODE_BUF"; else if (lTestType == TEST_DECODE_BUF) lpszTypeFlag = "DECODE_BUF"; printf("test_timing: %s %s iCount=%d, Time=%f, single=%f Size=%ldbytes.\n", lpszNewFlag, lpszTypeFlag, iCount, dResult, dSingle, lByteCount); } #ifndef WIN32 //artificially fix symbols. #define _timeb timeb #define _ftime ftime #endif double test_timingDoTest(long BYTE_COUNT, long iCount, int new_flag, long lTestType) { double dTime, dTime2, dSingle; struct _timeb timebuffer; UTF8String AA; UTF8String *pAA; // CANNOT use "AA" due to SNACC limitation where it does // not free previous memory on subsequent decodes!!!#@$% AsnBuf *pBB=NULL; AsnBuf *pCANNEDTmpEncodedBuf=NULL; AsnBuf *pCANNEDEncodedBuf=NULL; int i; char *pChar=(char *)calloc(1, BYTE_COUNT); unsigned long bytesDecoded=0; printf("test_timing: Start.\n"); memset((void *)pChar, 'R', BYTE_COUNT); //AA.Set("Test 1", strlen("Test 1")); AA = (const char *)pChar; free((void *)pChar); AA.BEnc(*pCANNEDTmpEncodedBuf); // FOR DECODE_BUF ops. pCANNEDEncodedBuf = new AsnBuf(*pCANNEDTmpEncodedBuf); delete pCANNEDTmpEncodedBuf; // need to copy to avoid oversized buffer // from ENCODE_BUF ops. _ftime( &timebuffer); dTime = timebuffer.time; dTime += (.001) * timebuffer.millitm; for (i=0; i < iCount; i++) { pBB = NULL; if (new_flag==2) // newest, from Pierce (RWC). { if (lTestType == TEST_ENCODE_BUF) { AA.BEnc(*pBB); delete pBB; } else if (lTestType == TEST_DECODE_BUF) { pAA = new UTF8String; pAA->BDec(*pCANNEDEncodedBuf, bytesDecoded); delete pAA; } } else if (new_flag) { if (lTestType == TEST_ENCODE_BUF) { AA.BEnc(*pBB); delete pBB; } else if (lTestType == TEST_DECODE_BUF) { pAA = new UTF8String; pAA->BDec(*pCANNEDEncodedBuf, bytesDecoded); delete pAA; } } else { if (lTestType == TEST_ENCODE_BUF) { AA.BEnc(*pBB); delete pBB; } else if (lTestType == TEST_DECODE_BUF) { pAA = new UTF8String; AA.BDec(*pCANNEDEncodedBuf, bytesDecoded); delete pAA; } } } _ftime( &timebuffer); dTime2 = timebuffer.time; dTime2 += (.001) * timebuffer.millitm; dSingle = dTime2 - dTime; return(dSingle); } // This function demonstrates/tests the new AsnInt BigInteger logic. void AsnIntTest() { AsnInt A,B,H; int /*AsnIntType*/ CInt; AsnBuf b; AsnLen bytesDecoded=0; char TmpData[7]={0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x00 }; bool bFlag; int i; //######### convert string into Hex ########################## H = AsnInt("0x20FF"); if (H == 767) std::cout << "\nAsnIntTest: SUCCESSFUL string to hex conversion, " << H << ".\n"; else std::cout << "AsnIntTest: UNSUCCESSFUL string to hex conversion, " << H << ".\n"; H = AsnInt("0xF0"); if (H == 15) std::cout << "AsnIntTest: SUCCESSFUL string to hex conversion, " << H << ".\n"; else std::cout << "AsnIntTest: UNSUCCESSFUL string to hex conversion, " << H << ".\n"; //######### check small integer.############################## A = 20; A.BEnc(b); B.BDec(b, bytesDecoded); if (bytesDecoded) { if (B == 20) std::cout << "AsnIntTest: SUCCESSFUL integer encode/decode, " << B << ".\n"; else std::cout << "AsnIntTest: UNSUCCESSFUL integer encode/decode, " << B << ".\n"; } //######### check positive multi-byte integer.########################### // A.Set((const unsigned char *)TmpData, 7); A.BEnc(b); bytesDecoded = 0; B.BDec(b, bytesDecoded); if (bytesDecoded == 9 && B.length() == 7/*for Data*/) { bFlag = true; // Start out assuming all data is good. const unsigned char *pBuf=B.c_str(); for (int i=0; i < 7; i++) if (pBuf[i] != (unsigned char)TmpData[i]) bFlag = false; if (bFlag) { std::cout << "AsnIntTest: SUCCESSFUL 7 byte integer encode/decode, " << ".\n"; char buf[200]; sprintf(buf, "%xx%xx%xx%xx%xx%xx%xx.\n", pBuf[0], pBuf[2], pBuf[2], pBuf[3], pBuf[4], pBuf[5], pBuf[6]); std::cout << buf; } else std::cout << "AsnIntTest: UNSUCCESSFUL 7 byte integer encode/decode, " << ".\n"; } else std::cout << "AsnIntTest: UNSUCCESSFUL length 7 byte integer encode/decode, bytesDecoded=" << bytesDecoded << ".\n"; //######### check assignment of multi-byte integer to a small int variable. // try { CInt = B; // Attempt to assign 7 byte integer to 4 byte variable. std::cout << "AsnIntTest: UNSUCCESSFUL ERROR on large integer assign to too small long." << ".\n"; } catch (...) { std::cout << "AsnIntTest: SUCCESSFUL ERROR (catch) on large integer assign to too small long." << ".\n"; } //######### check negative small integer.############################## // bytesDecoded = 0; A = -20; A.BEnc(b); B.BDec(b, bytesDecoded); if (bytesDecoded) { if (B == -20) std::cout << "AsnIntTest: SUCCESSFUL negative integer encode/decode, " << B << ".\n"; else std::cout << "AsnIntTest: UNSUCCESSFUL negative integer encode/decode, " << B << ".\n"; } //######### check sign-extended negative large integer, with known size.## // char TmpData2[128]; for (i=0; i < 128; i++) TmpData2[i] = (char)0xa0; // negative MSB. TmpData2[0] = (char)0xff; TmpData2[1] = (char)0xff; TmpData2[2] = (char)0xff; TmpData2[3] = (char)0xff; bytesDecoded = 0; A.Set((unsigned char *)TmpData2, 128); A.BEnc(b); // EXPECT 4 less bytes encoded due to sign extension. bytesDecoded = 0; B.BDec(b, bytesDecoded); if (B.length() == 124/*for Data*/) { bFlag = true; // Start out assuming all data is good. const unsigned char *pBuf=B.c_str(); for (i=0; i < 124; i++) if (pBuf[i] != (unsigned char)TmpData2[i]) bFlag = false; if (bFlag) { std::cout << "AsnIntTest: SUCCESSFUL 124 byte negative integer encode/decode, " << ".\n"; char buf[200]; sprintf(buf, "%2.2xx%2.2xx%2.2xx%2.2xx%2.2xx%2.2xx%2.2xx.\n", pBuf[0], pBuf[2], pBuf[2], pBuf[3], pBuf[4], pBuf[5], pBuf[6]); std::cout << buf; unsigned char *pBuf3 = NULL; // RESET for next operation. size_t length; B.getPadded(pBuf3, length, size_t(128)); bFlag = true; // Start out assuming all data is good. for (int i=0; i < 4; i++) if (pBuf3[i] != (char)0xff) bFlag = false; if (!bFlag || length != 128) std::cout << "AsnIntTest: UNSUCCESSFUL 128 byte negative integer GetSignedBitExtendedData(...).\n"; else std::cout << "AsnIntTest: SUCCESSFUL 128 byte negative integer GetSignedBitExtendedData(...).\n"; if (pBuf3) free(pBuf3); } else std::cout << "AsnIntTest: UNSUCCESSFUL 124 byte negative integer encode/decode, " << ".\n"; } else std::cout << "AsnIntTest: UNSUCCESSFUL length 124 byte integer encode/decode, bytesDecoded=" << bytesDecoded << ".\n"; //######### check sign-extended positive large integer, with known size.## // for (i=0; i < 128; i++) TmpData2[i] = (char)0x0a; //NON-negative MSB. TmpData2[0] = (char)0x00; TmpData2[1] = (char)0x00; TmpData2[2] = (char)0x00; TmpData2[3] = (char)0x00; bytesDecoded = 0; A.Set((const unsigned char *)TmpData2, 128); A.BEnc(b); // EXPECT 4 less bytes encoded due to sign extension. bytesDecoded = 0; B.BDec(b, bytesDecoded); if (B.length() == 124/*for Data*/) { bFlag = true; // Start out assuming all data is good. { const unsigned char *pBuf= B.c_str(); for (i=0; i < 124; i++) if (pBuf[i] != (unsigned char)TmpData2[i]) bFlag = false; } if (bFlag) { unsigned char *pBuf; std::cout << "AsnIntTest: SUCCESSFUL 124 byte integer encode/decode, " << ".\n"; char buf[200]; sprintf(buf, "%2.2xx%2.2xx%2.2xx%2.2xx%2.2xx%2.2xx%2.2xx.\n", pBuf[0], pBuf[2], pBuf[2], pBuf[3], pBuf[4], pBuf[5], pBuf[6]); std::cout << buf; pBuf = NULL; // RESET for next operation. size_t length; B.getPadded(pBuf, length, size_t(128)); bFlag = true; // Start out assuming all data is good. for (int i=0; i < 4; i++) if (pBuf[i] != (char)0x00) bFlag = false; if (!bFlag || length != 128) std::cout << "AsnIntTest: UNSUCCESSFUL 128 byte positive integer GetSignedBitExtendedData(...).\n"; } else std::cout << "AsnIntTest: UNSUCCESSFUL 124 byte positive integer encode/decode, " << ".\n"; } else std::cout << "AsnIntTest: UNSUCCESSFUL length 124 byte positive integer encode/decode, bytesDecoded=" << bytesDecoded << ".\n"; std::cout.flush(); } // // #define OIDString "1.2.3.4.5.6.7.8.9.10" #define OIDString2 "1.2.840.10040.4.1" void test_AsnOid() { AsnOid tmpoid(OIDString); AsnOid tmpoid2(OIDString2); char ptmpoid2Data[]={(char )0x2a, (char )0x86, (char )0x48, (char )0xce, (char )0x38, (char )0x04, (char )0x01}; AsnOid *poid = new AsnOid; long arrLength=19, arcNumArrOUTLen; unsigned long arcNumArr[]={1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, (unsigned long)-1 }; unsigned long *arcNumArrOUT=(unsigned long *)calloc(100, sizeof(unsigned long)); *poid = tmpoid; // TEST "=" operator. char *ptr = poid->GetChar(); if (strcmp(OIDString, ptr) != 0) std::cout << "test_AsnOid: UNSUCCESSFUL AsnOid(\"1.2.3.4.5.6.7.8.9.10\") = " << ptr << "\n"; else std::cout << "test_AsnOid: SUCCESSFUL AsnOid(\"1.2.3.4.5.6.7.8.9.10\") = " << ptr << "\n"; delete poid; free(ptr); poid = new AsnOid; poid->Set(arcNumArr, arrLength); arcNumArrOUTLen = poid->NumArcs(); poid->GetOidArray(arcNumArrOUT); delete poid; if (arcNumArrOUTLen != 19) std::cout << "test_AsnOid:: UNSUCCESSFUL long array extraction, extracted length=" << arcNumArrOUTLen << "\n"; for (int i=0; i < arcNumArrOUTLen; i++) if (arcNumArrOUT[i] != arcNumArr[i]) std::cout << "test_AsnOid:: UNSUCCESSFUL long array extraction." << arcNumArrOUT[i] << "," << arcNumArr[i] << "\n"; if (tmpoid == OIDString) std::cout << "test_AsnOid:: SUCCESSFUL OID String Comparison." << "\n"; if (tmpoid != "1.2.333.333.333") std::cout << "test_AsnOid:: SUCCESSFUL NOT OID String Comparison." << "\n"; if (arcNumArrOUT) free(arcNumArrOUT); AsnOid TmpOid3; TmpOid3.Set(ptmpoid2Data, 7); if (TmpOid3 != tmpoid2) std::cout << "test_AsnOid:: UNSUCCESSFUL id_dsa OID String Comparison (bad news, bob)." << "\n"; } //#include "vdatest_asn.h" TestSequence testSequence; //RWC;GLOBAL in order to share thread start logic. //RWC; (NOT GOOD DESIGN PRACTICE, but good for test). // // void vdaTestPrintThreads_Perform(void *f_INPUT) { struct ThreadNumberDef *f=(struct ThreadNumberDef *)f_INPUT; f->lThreadStatus = VDATHREAD_STATUS_STARTED; int VDATEST_COUNT=20; std::cout << "\n########################## vdaTestPrintThreads_Perform" << f->lThreadNumber << "\n"; // PERFORM thread test operation(s). for (int i=0; i < VDATEST_COUNT; i++) { testSequence.Print(std::cout); } //printf("ThreadNumber Test = %d DONE!\n", f->lThreadNumber); std::cout << "\n########################## DONE ThreadNumber Test = " << f->lThreadNumber << "\n"; std::cout.flush(); f->lThreadStatus = VDATHREAD_STATUS_DONE; } long vdaTestPrintThreadLocks() { long status=0; unsigned long bytesDecoded=0; //struct ThreadNumberDef *plThread=NULL; AsnOcts TmpSNACCOcts; AsnBuf TmpBuf; char Aarray[]= { (char )0x30,(char )0x2d,(char )0x02,(char )0x15, (char )0x00,(char )0x94,(char )0x76,(char )0x92,(char )0xae, (char )0x87,(char )0x71,(char )0x0e,(char )0x50,(char )0xf9, (char )0xd5,(char )0x35,(char )0x49,(char )0xda,(char )0xa2, (char )0x40 }; /*TestAllAsnPrimativeTypes ::= SEQUENCE { octs OCTET STRING, boolTest BOOLEAN, oid OBJECT IDENTIFIER OPTIONAL, bitString [2] IMPLICIT BIT STRING, integer INTEGER, enumTest ENUMERATED {A(11), B(12), C(13) }, real REAL OPTIONAL, null NULL }*/ // testSequence.testAllPrimatives = new TestAllAsnPrimativeTypes; //testSequence.testAllPrimatives->octsName. // Set("This is an OCTET STRING test", strlen("This is an OCTET STRING test")+1); testSequence.testAllPrimatives.octsName.Set(Aarray, sizeof(Aarray)); testSequence.testAllPrimatives.boolTestName = true; testSequence.testAllPrimatives.oidName = new AsnOid; *testSequence.testAllPrimatives.oidName = testOID; char *pData="TES";//(char)0xa5, (char)0xa5, (char)0xa5; testSequence.testAllPrimatives.bitStringName.Set((const unsigned char*)pData, 24); testSequence.testAllPrimatives.integerName = 55; testSequence.testAllPrimatives.enumTestName = TestAllAsnPrimativeTypesEnum::aA; testSequence.testAllPrimatives.realName = new AsnReal; *testSequence.testAllPrimatives.realName = 44.2; //testSequence.nullName TmpSNACCOcts.Set("this is a test of SetOf", strlen("this is a test of SetOf")+1); AsnBuf Buf3; TmpSNACCOcts.BEnc(Buf3); testSequence.testSetOfAny.insert(testSequence.testSetOfAny.end(), SNACC::AsnAny()); testSequence.testSetOfAny.back().BDec(Buf3, bytesDecoded); if (testSequence.directoryString.choiceId == DirectoryString::teletexStringCid) delete testSequence.directoryString.teletexString; // FOR SOME reason, the default constructor of a DirectoryString // Creates a TeletexString. testSequence.directoryString.choiceId = DirectoryString::printableStringCid; testSequence.directoryString.printableString = new DirectoryString::PrintableString_; *testSequence.directoryString.printableString = "Printable String TEST!"; testSequence.BEnc(TmpBuf); // Be sure it encodes... return(status); } // // void test_IndefiniteLengthEncoding() { FUNC("test_IndefiniteLengthEncoding"); ContentInfo A, A2; unsigned long bytesDecoded=0; /* create IndefiniteLength encoding of ContentInfo. */ AlgorithmIdentifier SNACCAlgId, SNACCAlgId2; AsnBuf *pBufAlgId=NULL; char ptrParams[]={(char)0x30, (char)0x12, (char)0x13, (char)0x10, 'T', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', ' ', 't', 'e', 's', 't', '.', '\n' }; AsnBuf BufParams(ptrParams, sizeof(ptrParams)); #ifndef SKIP_IndefiniteLength_ENCODING char ptr[]={(char)0x30, (char)0x80, (char)0x13, (char)0x10, 'T', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', ' ', 't', 'e', 's', 't', '.', '\n', (char)0x00, (char)0x00 /* Terminate IndefiniteLength */}; #else // RWC;TEST. char ptr[]={(char)0x30, (char)0x12, (char)0x13, (char)0x10, 'T', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', ' ', 't', 'e', 's', 't', '.', '\n' }; #endif AsnBuf bufAlgId; AsnBuf tmpBuf; AsnBuf DBuf(ptr, sizeof(ptr)); // THIS is the Any, with encoding tag // and indefinite length encoding length. // // FIRST, test outer envelope indefinite length sequencd SNACCAlgId.algorithm.PutChar("1.2.3.4.5"); // IGNORE option element. SNACCAlgId.parameters = new AsnAny; SNACCAlgId.parameters->BDec(BufParams, bytesDecoded); if (! SNACCAlgId.BEnc(bufAlgId) ) throw SNACC_EXCEPT("Error encoding SNACCAlgId"); // Attempt out envelope IndefiniteLength decode. // // Artificially make indefinite length. // unsigned long iAsnBufLength = bufAlgId.length(); char *ptr2 = bufAlgId.GetSeg(iAsnBufLength);//10000); for (unsigned int i=0; i < iAsnBufLength; i++) { if ((ptr2[i] == (char)0x13) && (ptr2[i+1] == (char)0x10)) { // LOOK for text char ptr4[10000]; ptr2[i+1] = (char)0x80; // REPLACE length. ptr2[i-1] += 2; // Add 2 to sequence length count. ptr2[1] += 2; // Add 2 to outer length count. memcpy(ptr4, ptr2, iAsnBufLength); ptr4[iAsnBufLength] = '\0'; ptr4[iAsnBufLength+1] = '\0'; pBufAlgId = new AsnBuf(ptr4, iAsnBufLength+2); // IndefninteLength termination of EXPLICIT tag. break; free(ptr2); } // END if found proper location to override. } if (pBufAlgId) { SNACCAlgId.BDec(*pBufAlgId, bytesDecoded ); // WILL throw exception if error bufAlgId = *pBufAlgId; delete pBufAlgId; pBufAlgId = NULL; } // END IF pBufAlgId // // SECOND, test inner envelope indefinite length sequencd A.contentType.PutChar("1.2.3.4.5"); A.content.BDec(DBuf, bytesDecoded); if (! A.BEnc(tmpBuf) ) throw SNACC_EXCEPT("Encoding failed!"); // RWC; if indefinite length encoding test, override EXPLICIT // RWC; tag of ContentInfo with indefinite length flag as well. // AsnBuf *ptmpBuf = NULL; if (ptr[1] == (char)0x80) { iAsnBufLength = tmpBuf.length(); char *ptr2=tmpBuf.GetSeg(iAsnBufLength); for (unsigned int i=1; i < iAsnBufLength; i++) { if ((ptr2[i] == (char)0x30) && (ptr2[i+1] == (char)0x80)) { ptr2[i-1] = (char)0x80; // MAKE outer envelope CI indefinite as well... ptr2[1] += 2; // Add 2 bytes to outer envelope count. char ptr4[10000]; memcpy(ptr4, ptr2, iAsnBufLength); ptr4[iAsnBufLength] = '\0'; ptr4[iAsnBufLength+1] = '\0'; ptmpBuf = new AsnBuf(ptr4, iAsnBufLength+2); // IndefninteLength termination of EXPLICIT tag. break; } // END if found proper location to override. } if (ptr2) delete ptr2; } // END if 0x80 check char *ptr3 = NULL; if (ptmpBuf) { A2.BDec(*ptmpBuf, bytesDecoded); // WILL throw exception if error. delete ptmpBuf; ptmpBuf = new AsnBuf; A2.content.BEnc(*ptmpBuf); // GET just the content. iAsnBufLength = ptmpBuf->length(); ptr3 = ptmpBuf->GetSeg(iAsnBufLength); delete ptmpBuf; } // END IF ptmpBuf if (ptr3 && iAsnBufLength != sizeof(ptr) || memcmp(ptr3, ptr, sizeof(ptr)) != 0) std::cout << "test_IndefiniteLengthEncoding:: ERROR in IndefiniteLength decoding.\n" << " Decoded Length=" << iAsnBufLength; delete ptr3; } // EOF vdatest.cpp esnacc-ng-1.8.1/cxx-examples/src/vdatest_asn.asn1000066400000000000000000000073201302010526100216530ustar00rootroot00000000000000VdaTestModule DEFINITIONS EXPLICIT TAGS ::= -- DEFINITIONS IMPLICIT TAGS ::= BEGIN TestSetSorting1 ::= SET { null NULL, num INTEGER, oid OBJECT IDENTIFIER, octs OCTET STRING, bits BIT STRING, ps PrintableString, seq SEQUENCE OF INTEGER, set VDATestSetOfAny } OctetStringSetOf ::= SET OF OCTET STRING VDATestSequence ::= SEQUENCE OF INTEGER VDATestSet ::= SET { setItem1 OCTET STRING, setItem2 INTEGER } VDATestSetOfAny ::= SET OF ANY VDATestBitString ::= BIT STRING SequenceOfDefaults ::= SEQUENCE { defBool [0] BOOLEAN DEFAULT FALSE, defBitstring [1] ClassList DEFAULT { unclassified }, defInteger [2] Version DEFAULT v3, defEnumerated [3] Enumeration DEFAULT one } Enumeration ::= ENUMERATED { one(1), two(2), three(3) } ClassList ::= BIT STRING { unmarked (0), unclassified (1), restricted (2), confidential (3), secret (4), topSecret (25) } Version ::= INTEGER { v1(0), v2(1), v3(2) } --unclassified INTEGER ::= 1 DirectoryString ::= CHOICE { teletexString TeletexString (SIZE (1..MAX)), printableString PrintableString (SIZE (1..MAX)), universalString UniversalString (SIZE (1..MAX)), utf8String UTF8String (SIZE (1..MAX)), bmpString BMPString (SIZE(1..MAX)) } testOID OBJECT IDENTIFIER ::= { 1 2 3 4 5 6 7 8 9 10 } TestAllAsnPrimativeTypes ::= SEQUENCE { octsName OCTET STRING, boolTestName BOOLEAN, oidName OBJECT IDENTIFIER OPTIONAL, bitStringName [2] IMPLICIT BIT STRING, integerName INTEGER, enumTestName ENUMERATED { aA(11), aB(12), aC(13) }, realName REAL OPTIONAL, nullName NULL } TestSequence ::= SEQUENCE { seqOfDefaults SequenceOfDefaults OPTIONAL, testSet VDATestSet, testSetOfAny VDATestSetOfAny, directoryString DirectoryString, testAllPrimatives TestAllAsnPrimativeTypes } -- THE FOLLOWING DEFINITIONS test the ANY DEFINED BY table setup/usage. testOID2 OBJECT IDENTIFIER ::= { 1 2 3 4 5 6 7 8 9 10 2 } TestDefinedByUsage ::= SEQUENCE { id OBJECT IDENTIFIER, anyDefBy ANY DEFINED BY id, i1 INTEGER, i2 INTEGER, i3 INTEGER, i4 INTEGER } TestDefinedByType ::= SEQUENCE { octsName OCTET STRING, boolTestName BOOLEAN } maxSIBperMsg INTEGER ::= 16 --CompleteSIB-List ::= SEQUENCE (SIZE (1..maxSIBperMsg)) OF CompleteSIBshort CompleteSIB-List ::= SEQUENCE OF CompleteSIBshort (SIZE (1..maxSIBperMsg)) CompleteSIBshort ::= SEQUENCE { a INTEGER -- Assume that this sequence has some data } -- This definition syntax is based on SNMP OBJECT-TYPE; it is a special -- SNACC construct to align the DEFINED BY id with a data type -- (see SNACC docs). testDefinedByDesignation OBJECT-TYPE SYNTAX PrintableString ACCESS read-write STATUS mandatory ::= { 1 2 3 4 5 6 7 8 9 10 2 } --testOID2 -- This section tests the ability of the esnacc compiler to allow an Integer -- definition to be used to specify a tag. AppTagList ::= INTEGER { appTagTest101(101), appTagTest102(102), appTagTest103(103) } appTag20 INTEGER ::= 20 appTag21 INTEGER ::= 21 Application-TagTest ::= SEQUENCE { i1Tag [0] INTEGER (0..23), i2Tag [appTag20] INTEGER (0..59), i4Tag [UNIVERSAL appTag21] INTEGER (0..59), i5Tag [2] INTEGER (0..59) DEFAULT 0 } --RWC;DOES NOT WORK;i3Tag [APPLICATION appTagTest103] INTEGER, Application-TagChoice ::= CHOICE { i1Choice [0] INTEGER (0..23), i2Choice [appTag20] INTEGER (0..59), i3Choice [UNIVERSAL appTag21] INTEGER (0..59), --RWC;TEST TO CAUSE Choice ERROR;i2Choice2nd [20] INTEGER (0..59), i4Choice [2] INTEGER } END esnacc-ng-1.8.1/cxx-examples/src/vdatest_asn2.asn1000066400000000000000000000032671302010526100217430ustar00rootroot00000000000000VdaTestModule2 -- DEFINITIONS EXPLICIT TAGS ::= DEFINITIONS IMPLICIT TAGS ::= BEGIN --snacc namespace: "VDATestModule2Namespace" -- THE FOLLOWING DEFINITIONS test the ANY DEFINED BY table setup/usage. -- This specific file tests the SNACC run-time and compiler's ability to -- handle 2 sets of ANY DEFINED BY table loads (test of new feature). testOID2-2 OBJECT IDENTIFIER ::= { 1 2 3 4 5 6 7 8 9 10 4 } TestDefinedByUsage-2 ::= SEQUENCE { id OBJECT IDENTIFIER, anyDefBy ANY DEFINED BY id } TestDefinedByType-2 ::= SEQUENCE { octsName OCTET STRING, boolTestName BOOLEAN } AlgorithmIdentifier ::= SEQUENCE { algorithm OBJECT IDENTIFIER, parameters ANY OPTIONAL } --PSpecifiedEmptyIdentifier ::= AlgorithmIdentifier --pSpecifiedEmptyIdentifier AlgorithmIdentifier ::= { id-pSpecified(2), PSpecifiedEmptyIdentifier ::= AlgorithmIdentifier --{ id-pSpecified(2), --OCTET STRING (SIZE (0)) } nullOctetString OCTET STRING (SIZE(0)) ::= {} --pSpecifiedEmptyIdentifier2 AlgorithmIdentifier ::= { id-pSpecified, --nullOctetString } -- This last definition syntax is based on SNMP OBJECT-TYPE; it is a special -- SNACC construct to align the DEFINED BY id with a data type -- (see SNACC docs). testDefinedByDesignation2 OBJECT-TYPE SYNTAX PrintableString ACCESS read-write STATUS mandatory ::= { 1 2 3 4 5 6 7 8 9 10 4 } --testOID2-2 ContentInfo ::= SEQUENCE { contentType ContentType, content [0] EXPLICIT ANY } --RWC;DEFINED BY contentType } ContentType ::= OBJECT IDENTIFIER -- -- STRICTLY for testing; the PrintXML(...) produces bad "<", ">" chars on this -- definition. AAA ::= SEQUENCE OF AlgorithmIdentifier END esnacc-ng-1.8.1/cxx-lib/000077500000000000000000000000001302010526100147135ustar00rootroot00000000000000esnacc-ng-1.8.1/cxx-lib/.gitignore000066400000000000000000000000451302010526100167020ustar00rootroot00000000000000.dirstamp .libs .deps libesnaccxx.pc esnacc-ng-1.8.1/cxx-lib/asn-useful.asn1000066400000000000000000000060121302010526100175600ustar00rootroot00000000000000ASN-USEFUL DEFINITIONS ::= BEGIN -- file: .../asn1specs/asn-useful.asn1 -- -- NOTE: every one of these types is marked as a PDU so the compiler -- will produce the encode and decode routines that -- enc/dec the top tag/len pairs, not just the content decoders. -- (only nec for re-generating the library files "asn_useful.[ch]"). -- The isPdu field does not affect how this module is linked -- with other modules during compilation. -- -- (type DEF comment directives immediately follow the "::=") -- -- MS 92 -- -- $Header: /baseline/SNACC/c++-lib/asn-useful.asn1,v 1.1.1.1 2000/08/21 20:36:08 leonberp Exp $ -- $Log: asn-useful.asn1,v $ -- Revision 1.1.1.1 2000/08/21 20:36:08 leonberp -- First CVS Version of SNACC. -- -- Revision 1.3 1995/07/24 15:12:35 rj -- useful.asn1 renamed to asn-useful.asn1 to accomodate to snacc's new file name generation scheme. -- -- Revision 1.2 1994/08/28 09:54:19 rj -- comment leader fixed. -- -- Revision 1.1 1994/08/28 09:51:15 rj -- first check-in. ObjectDescriptor ::= -- isPdu:"TRUE" -- [UNIVERSAL 7] IMPLICIT OCTET STRING NumericString ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 18] IMPLICIT OCTET STRING PrintableString ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 19] IMPLICIT OCTET STRING TeletexString ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 20] IMPLICIT OCTET STRING T61String ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 20] IMPLICIT OCTET STRING VideotexString ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 21] IMPLICIT OCTET STRING IA5String ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 22] IMPLICIT OCTET STRING GraphicString ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 25] IMPLICIT OCTET STRING VisibleString ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 26] IMPLICIT OCTET STRING ISO646String ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 26] IMPLICIT OCTET STRING GeneralString ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 27] IMPLICIT OCTET STRING UTCTime ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 23] IMPLICIT OCTET STRING GeneralizedTime ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 24] IMPLICIT OCTET STRING EXTERNAL ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 8] IMPLICIT SEQUENCE { direct-reference OBJECT IDENTIFIER OPTIONAL, indirect-reference INTEGER OPTIONAL, data-value-descriptor ObjectDescriptor OPTIONAL, encoding CHOICE { single-ASN1-type [0] OCTET STRING, -- should be ANY octet-aligned [1] IMPLICIT OCTET STRING, arbitrary [2] IMPLICIT BIT STRING } } -- new UNIVERSAL types -- UniversalString ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 28] IMPLICIT OCTET STRING BMPString ::= --snacc isPdu:"TRUE" -- [UNIVERSAL 30] IMPLICIT OCTET STRING END -- of ASN-USEFUL type definitions esnacc-ng-1.8.1/cxx-lib/automake.mk000066400000000000000000000042531302010526100170560ustar00rootroot00000000000000lib_LTLIBRARIES += cxx-lib/libcxxasn1.la nobase_include_HEADERS += cxx-lib/inc/asn-buf.h \ cxx-lib/inc/asn-chartraits.h \ cxx-lib/inc/asn-config.h \ cxx-lib/inc/asn-incl.h \ cxx-lib/inc/asn-list.h \ cxx-lib/inc/asn-listset.h \ cxx-lib/inc/asn-usefultypes.h \ cxx-lib/inc/init.h \ cxx-lib/inc/meta.h \ cxx-lib/inc/snaccdll.h \ cxx-lib/inc/snaccexcept.h \ cxx-lib/inc/tcl-if.h cxx_lib_libcxxasn1_la_SOURCES = \ cxx-lib/src/asn-null.cpp \ cxx-lib/src/asn-oid.cpp \ cxx-lib/src/asn-RelativeOid.cpp \ cxx-lib/src/asn-PERGeneral.cpp \ cxx-lib/src/snaccdll.cpp \ cxx-lib/src/snaccexcept.cpp \ cxx-lib/src/tkAppInit.c \ cxx-lib/src/asn-enum.cpp \ cxx-lib/src/asn-extension.cpp \ cxx-lib/src/asn-any.cpp \ cxx-lib/src/asn-type.cpp \ cxx-lib/src/asn-buf.cpp \ cxx-lib/src/asn-int.cpp \ cxx-lib/src/asn-tag.cpp \ cxx-lib/src/asn-stringtype.cpp \ cxx-lib/src/asn-bufbits.cpp \ cxx-lib/src/asn-real.cpp \ cxx-lib/src/asn-usefultypes.cpp \ cxx-lib/src/asn-bool.cpp \ cxx-lib/src/hash.cpp \ cxx-lib/src/meta.cpp \ cxx-lib/src/asn-octs.cpp \ cxx-lib/src/vda_threads2.cpp \ cxx-lib/src/print.cpp \ cxx-lib/src/tcl-if.cpp \ cxx-lib/src/asn-bits.cpp \ cxx-lib/src/asn-len.cpp \ cxx-lib/src/asn-fileseg.cpp \ cxx-lib/src/asn-rvsbuf.cpp cxx_lib_libcxxasn1_la_WIN32_FLAGS= cxx_lib_libcxxasn1_la_WIN32_LIBADD= cxx_lib_libcxxasn1_la_WIN32_LDFLAGS= if WIN32 cxx_lib_libcxxasn1_la_WIN32_FLAGS += -DSNACCDLL_EXPORTS=1 \ ${PTHREAD_INCLUDES} endif cxx_lib_libcxxasn1_la_CXXFLAGS = \ $(PTHREAD_CFLAGS) \ $(cxx_lib_libcxxasn1_la_WIN32_FLAGS) \ -I$(top_srcdir) \ -I$(top_srcdir)/cxx-lib \ -I$(top_srcdir)/cxx-lib/src \ -I$(top_srcdir)/cxx-lib/inc cxx_lib_libcxxasn1_la_CFLAGS = \ $(PTHREAD_CFLAGS) \ $(cxx_lib_libcxxasn1_la_WIN32_FLAGS) \ -I$(top_srcdir) \ -I$(top_srcdir)/cxx-lib \ -I$(top_srcdir)/cxx-lib/src \ -I$(top_srcdir)/cxx-lib/inc cxx_lib_libcxxasn1_la_LIBADD = \ $(PTHREAD_LIBS) \ $(cxx_lib_libcxxasn1_la_WIN32_LIBADD) cxx_lib_libcxxasn1_la_LDFLAGS = \ $(LDFLAGS) \ $(PTHREAD_CFLAGS) \ $(all_lib_LDFLAGS) \ $(cxx_lib_libcxxasn1_la_WIN32_LDFLAGS) EXTRA_DIST += \ cxx-lib/libesnaccxx.pc.in pkgconfig_DATA += cxx-lib/libesnaccxx.pc DISTCLEANFILES += cxx-lib/libesnaccxx.pc esnacc-ng-1.8.1/cxx-lib/cppasn1/000077500000000000000000000000001302010526100162605ustar00rootroot00000000000000esnacc-ng-1.8.1/cxx-lib/cppasn1/cppasn1.vcproj.vspscc000066400000000000000000000004621302010526100223540ustar00rootroot00000000000000"" { "FILE_VERSION" = "9237" "ENLISTMENT_CHOICE" = "NEVER" "PROJECT_FILE_RELATIVE_PATH" = "" "NUMBER_OF_EXCLUDED_FILES" = "0" "ORIGINAL_PROJECT_FILE_PATH" = "file:C:\\MyProjects\\SNACC\\c++-lib\\cppasn1\\cppasn1.vcproj" "NUMBER_OF_NESTED_PROJECTS" = "0" "SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROJECT" } esnacc-ng-1.8.1/cxx-lib/cppasn1/stdafx.cpp000066400000000000000000000004371302010526100202610ustar00rootroot00000000000000// stdafx.cpp : source file that includes just the standard includes // snaccDLL.pch will be the pre-compiled header // stdafx.obj will contain the pre-compiled type information #include "stdafx.h" // TODO: reference any additional headers you need in STDAFX.H // and not in this file esnacc-ng-1.8.1/cxx-lib/cppasn1/stdafx.h000066400000000000000000000014121302010526100177200ustar00rootroot00000000000000// stdafx.h : include file for standard system include files, // or project specific include files that are used frequently, but // are changed infrequently // #if !defined(AFX_STDAFX_H__0ED4C143_4AB0_11D3_803D_0000863260D8__INCLUDED_) #define AFX_STDAFX_H__0ED4C143_4AB0_11D3_803D_0000863260D8__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // Insert your headers here #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers #include // TODO: reference additional headers your program requires here //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_STDAFX_H__0ED4C143_4AB0_11D3_803D_0000863260D8__INCLUDED_) esnacc-ng-1.8.1/cxx-lib/inc/000077500000000000000000000000001302010526100154645ustar00rootroot00000000000000esnacc-ng-1.8.1/cxx-lib/inc/asn-buf.h000066400000000000000000000242111302010526100171700ustar00rootroot00000000000000#ifndef _ASN_BUF_H #define _ASN_BUF_H 1 #if defined(WIN32) #if defined(_MSC_VER) #pragma warning(disable: 4100 4702 4710 4514 4786 4251 4018 4146 4284) #pragma warning(push,3) #endif #include #include #include #include #include #include //#include #if defined(_MSC_VER) #pragma warning(pop) #endif #else // WIN32 #include #include #include #include #include #include #include //#include #endif // WIN32 #ifndef SNACCDLL_API #ifdef WIN32 #ifdef SNACCDLL_EXPORTS #define SNACCDLL_API __declspec(dllexport) #else #ifdef SNACCDLL_NONE #define SNACCDLL_API #else #define SNACCDLL_API __declspec(dllimport) #endif #endif #else #define SNACCDLL_API #endif #endif #define _SEG_SIZE 4096 namespace SNACC { // Forward declarations class Card; class AsnFileSeg; class AsnBits; typedef unsigned long AsnLen; typedef std::deque Deck; struct SNACCDLL_API AsnBufLoc { Deck::iterator m_card; long m_offset; }; class SNACCDLL_API AsnBuf { public: AsnBuf(); AsnBuf(const char* seg, size_t segLen); AsnBuf(const std::stringstream& ss); AsnBuf(std::streambuf* sb); AsnBuf(const AsnBuf& o); AsnBuf(const char* pFilename); ~AsnBuf() { clear(); } AsnBuf& operator=(const AsnBuf& o); bool operator==(const AsnBuf& b) const; bool operator<(const AsnBuf& rhs) const; void PutByteRvs(char byte); void PutSegRvs(const char* seg, size_t segLen); void PutSegRvs(const unsigned char *seg, size_t segLen) { PutSegRvs((const char*)seg, segLen); } void PutStream(std::streambuf *sb); void skip(size_t skipBytes); char PeekByte() const; char GetByte() const; unsigned char GetUByte() const { return (unsigned char)GetByte();} // unsigned long GetSeg(char* seg, long segLen) const; void GetSeg(char* seg, long segLen) const; void GetUSeg(unsigned char* seg, long segLen) const { GetSeg((char*)seg, segLen); } char* GetSeg(long segLen) const; void GetSeg(std::string& str, long segLen = 0) const; AsnFileSeg* GetFileSeg(long segLen) const; void PutFileSeg(AsnFileSeg* fs); void UnGetBytes(long lBytesToPutBack) const; void GrabAny(AsnBuf& anyBuf, SNACC::AsnLen& bytesDecoded) const; const Deck& deck() const { return m_deck; } const Card& card() const { return **m_card; } unsigned long length() const; void insert(const AsnBuf& that); long splice(AsnBuf& b); void hexDump(std::ostream& os) const; #ifdef _DEBUG void status(std::ostream& os); #endif AsnBufLoc GetReadLoc() const; void SetReadLoc(const AsnBufLoc& bl) const; void ResetMode(std::ios_base::openmode mode = std::ios_base::in) const; private: void clear(); protected: mutable SNACC::Deck::iterator m_card; mutable SNACC::Deck m_deck; }; class SNACCDLL_API AsnBufBits { private: std::streambuf* m_pbuf; // Stream buffer containing the bits bool m_isInternalBuf; // Indicates if streambuf is internal bool bAlign; unsigned char m_ucWriteCharBuf[2]; int m_iWriteBitPos; unsigned char m_ucReadCharBuf[2]; // Read character buffer int m_iReadBitPos; // Number of bits read from char buffer unsigned long m_ulNumBits; // Number of bits in the streambuf? unsigned long m_ulBitsLeft; // Number of bits in the streambuf public: AsnBufBits(std::streambuf *pbuf, bool bAligned = false) { m_pbuf = pbuf; // APPLICATION relinquishes memory. m_isInternalBuf = false; bAlign = bAligned; Clear(); } AsnBufBits(bool bAligned = false) { //m_pbuf = new std::strstreambuf; m_pbuf = new std::stringbuf; m_isInternalBuf = true; bAlign = bAligned; Clear(); } void Clear() { m_ucWriteCharBuf[0] = 0x00; m_iWriteBitPos = 8; m_ucReadCharBuf[0] = 0x00; m_iReadBitPos = 8; m_ulNumBits = 0; m_ulBitsLeft = 0; } ~AsnBufBits(){ if (m_isInternalBuf && m_pbuf) delete m_pbuf; } bool IsAligned() { return bAlign; } /* AsnBufBits & operator=(const AsnBufBits &buf) { if(this != &buf) { m_pbuf = buf.m_pbuf; m_ucWriteCharBuf[0] = buf.m_ucWriteCharBuf[0]; m_iWriteBitPos = buf.m_iWriteBitPos; m_ucReadCharBuf[0] = buf.m_ucReadCharBuf[0]; m_iReadBitPos = buf.m_iReadBitPos; m_ulNumBits = buf.m_ulNumBits; m_ulBitsLeft = buf.m_ulBitsLeft; } return *this; } */ bool operator<(AsnBufBits &rhs); unsigned char MaskBits(unsigned char cCharToMask, int iBitsToMask); unsigned long PutBits(const unsigned char* seg, unsigned long numBits); unsigned char* GetBits(unsigned long numBits); unsigned long GetBits(AsnBits& bits, unsigned long numBits); bool GetBit(); unsigned char GetByte(); unsigned long length(){ return m_ulBitsLeft; } int OctetAlignWrite(); int OctetAlignRead(); void hexDump(std::ostream &os); void AppendTo(AsnBufBits &bufBitsOut); AsnBufBits(const AsnBufBits& buf); AsnBufBits& operator=(const AsnBufBits& buf); private: unsigned char ReadByte(); // Reads next byte from the stream }; // Class for handling memory based encodings. It // writes into the stream in reverse. // class SNACCDLL_API AsnRvsBuf : public std::streambuf { public: AsnRvsBuf(char *preFilled, size_t segSize); AsnRvsBuf(const char *seg, size_t segSize); AsnRvsBuf(const AsnBuf& otherBuf); explicit AsnRvsBuf(long segSize = _SEG_SIZE); virtual ~AsnRvsBuf(); const char *str() { return m_pStart; } int pcount() { return ( (m_buf + m_segSize) - m_pStart ); } long max_size() const {return m_segSize;} friend class AsnBuf; protected: virtual int_type underflow(); virtual int_type overflow(int c = EOF); virtual std::streamsize xsputn(const char *s, std::streamsize n); virtual std::streambuf::pos_type seekoff(std::streambuf::off_type off, std::ios_base::seekdir way, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out); virtual std::streambuf::pos_type seekpos(std::streambuf::pos_type sp, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out); private: char *m_buf; char *m_pStart; char *m_pReadLoc; long m_segSize; bool m_bDeleteable; }; // Used to store the location of a large object // (OCTET STRING or ANY) within an AsnBuf card that // contains a file (i.e. filebuf). // class SNACCDLL_API AsnFileSeg : public std::streambuf { public: explicit AsnFileSeg(const char *pFilename); explicit AsnFileSeg(AsnFileSeg *afs, unsigned long segLen); AsnFileSeg(const AsnFileSeg &o); ~AsnFileSeg(); unsigned long size() { return m_segSize; } protected: virtual int_type underflow(); virtual int_type uflow(); virtual int_type overflow(int = EOF) { return EOF; } virtual std::streamsize xsgetn(char *s, std::streamsize n); virtual std::streamsize xsputn(const char *, std::streamsize ) { return overflow(); } virtual pos_type seekoff(off_type off, std::ios_base::seekdir way, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out); virtual pos_type seekpos(pos_type sp, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out); private: long m_offset; long m_segSize; char *m_filename; std::filebuf *m_fb; }; // Expanding buffer which contains a deque of streambufs. // This allows for non-contiguous memory to be used for // encoding. Each element (or card) in the deque (deck) // can be a file or memory based. // // Deck contains a streambuf * and a bool flag that indicates // whether or not the streambuf can be deleted. // enum AsnBufType { FILE_TYPE=0, RVS_BUF_TYPE, IN_MEM_TYPE, EXT_MEM_TYPE } ; class Card : public std::pair { public: #if 0 Card() { m_cDataR = 0x00; m_cDataW = 0x00; m_iBitPosW = 0; m_iBitPosR = 0; first = NULL; second = EXT_MEM_TYPE; } #endif Card(std::streambuf *sb) { m_cDataR = 0x00; m_cDataW = 0x00; m_iBitPosW = 0; m_iBitPosR = 0; first = sb; second = EXT_MEM_TYPE; } Card(const std::stringstream &ss) { m_cDataR = 0x00; m_cDataW = 0x00; m_iBitPosW = 0; m_iBitPosR = 0; first = ss.rdbuf(); second = EXT_MEM_TYPE; } Card(AsnRvsBuf *pRvsBuf) { m_cDataR = 0x00; m_cDataW = 0x00; m_iBitPosW = 0; m_iBitPosR = 0; first = pRvsBuf; second = RVS_BUF_TYPE; } Card(AsnFileSeg *pFs) { m_cDataR = 0x00; m_cDataW = 0x00; m_iBitPosW = 0; m_iBitPosR = 0; first = pFs; second = FILE_TYPE; } Card(const Card &o) : std::pair(o) { m_cDataR = 0x00; m_cDataW = 0x00; m_iBitPosW = 0; m_iBitPosR = 0; first = o.first; second = o.second; } virtual ~Card() { if (second != EXT_MEM_TYPE) delete first; } int BitPosW(){return m_iBitPosW;} int SetBitPosW(int newBitPos){m_iBitPosW = newBitPos; return m_iBitPosW;} int BitPosR(){return m_iBitPosR;} int SetBitPosR(int newBitPos){m_iBitPosR = newBitPos; return m_iBitPosR;} char cDataW(){return m_cDataW;} char cDataW(char chr){m_cDataW=chr; return m_cDataW;} char cDataR(){return m_cDataR;} char cDataR(char chr){m_cDataR=chr; return m_cDataR;} long size(); // number of bytes stored in card long length(); // number of bytes not read from card #ifdef _DEBUG const char * bufTypeStr(); // return a string discribing the bufType #endif void resetType(AsnBufType type) {second = type;} std::streambuf * rdbuf() {return first;} const std::streambuf * rdbuf() const {return first;} enum AsnBufType bufType() const {return second;} private: int m_iBitPosW; int m_iBitPosR; char m_cDataW; char m_cDataR; }; } // end namespace SNACC SNACCDLL_API void sortSet(std::list &bufList); SNACCDLL_API std::ostream & operator<<(std::ostream &os, const SNACC::AsnBuf &b); #endif // _ASN_BUF_H esnacc-ng-1.8.1/cxx-lib/inc/asn-chartraits.h000066400000000000000000000141431302010526100205630ustar00rootroot00000000000000#ifndef _asn_chartraits_h #define _asn_chartraits_h 1 #include // For memmove, memset, memchr #include namespace std { /// char_traits unsigned char specialization template<> struct char_traits { typedef unsigned char char_type; typedef int int_type; typedef streampos pos_type; typedef streamoff off_type; typedef mbstate_t state_type; static void assign(char_type& __c1, const char_type& __c2) { __c1 = __c2; } static bool eq(const char_type& __c1, const char_type& __c2) { return __c1 == __c2; } static bool lt(const char_type& __c1, const char_type& __c2) { return __c1 < __c2; } static int compare(const char_type* __s1, const char_type* __s2, size_t __n) { return memcmp(__s1, __s2, __n); } static size_t length(const char_type* __s) { return strlen((char *)__s); } static const char_type* find(const char_type* __s, size_t __n, const char_type& __a) { return static_cast(memchr(__s, __a, __n)); } static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) { return static_cast(memmove(__s1, __s2, __n)); } static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) { return static_cast(memcpy(__s1, __s2, __n)); } static char_type* assign(char_type* __s, size_t __n, char_type __a) { return static_cast(memset(__s, __a, __n)); } static char_type to_char_type(const int_type& __c) { return static_cast(__c); } // To keep both the byte 0xff and the eof symbol 0xffffffff // from ending up as 0xffffffff. static int_type to_int_type(const char_type& __c) { return static_cast(__c); } static bool eq_int_type(const int_type& __c1, const int_type& __c2) { return __c1 == __c2; } static int_type eof() { return static_cast(EOF); } static int_type not_eof(const int_type& __c) { return (__c == eof()) ? 0 : __c; } }; #if defined(HPUX) || defined(HPUX32) || defined(SCO_SV) // wchar specialization for HP-UX template<> struct char_traits { typedef wchar_t char_type; typedef wint_t int_type; typedef streamoff off_type; typedef streampos pos_type; typedef mbstate_t state_type; static void assign(char_type& __c1, const char_type& __c2) { __c1 = __c2; } static bool eq(const char_type& __c1, const char_type& __c2) { return __c1 == __c2; } static bool lt(const char_type& __c1, const char_type& __c2) { return __c1 < __c2; } static int compare(const char_type* __s1, const char_type* __s2, size_t __n) { return wcsncmp(__s1, __s2, __n); } static size_t length(const char_type* __s) { return wcslen(__s); } static const char_type* find(const char_type* __s, size_t __n, const char_type& __a) { char_type *tmp_wcs = wcschr(__s, __a); if (tmp_wcs == NULL) return NULL; if (__n > 0 && wcslen(tmp_wcs) > __n) return NULL; return tmp_wcs; } static char_type* move(char_type* __s1, const char_type* __s2, int_type __n) { return (char_type *) memmove((void *)__s1, (void *)__s2, __n*sizeof(char_type)); } static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) { return wcsncpy(__s1, __s2, __n); } static char_type* assign(char_type* __s, size_t __n, char_type __a) { return (char_type *) memset((char *)__s, __a, sizeof(char_type)*__n); } static char_type to_char_type(const int_type& __c) { return char_type(__c); } static int_type to_int_type(const char_type& __c) { return int_type(__c); } static bool eq_int_type(const int_type& __c1, const int_type& __c2) { return __c1 == __c2; } static int_type eof() { return static_cast(WEOF); } static int_type not_eof(const int_type& __c) { return eq_int_type(__c, eof()) ? 0 : __c; } }; #elif defined(SunOS) // wchar_t specialization template<> struct char_traits { typedef wchar_t char_type; typedef wint_t int_type; typedef streamoff off_type; typedef streampos pos_type; typedef mbstate_t state_type; static void assign(char_type& __c1, const char_type& __c2) { __c1 = __c2; } static bool eq(const char_type& __c1, const char_type& __c2) { return __c1 == __c2; } static bool lt(const char_type& __c1, const char_type& __c2) { return __c1 < __c2; } static int compare(const char_type* __s1, const char_type* __s2, size_t __n) { return wmemcmp(__s1, __s2, __n); } static size_t length(const char_type* __s) { return wcslen(__s); } static const char_type* find(const char_type* __s, size_t __n, const char_type& __a) { return wmemchr(__s, __a, __n); } static char_type* move(char_type* __s1, const char_type* __s2, int_type __n) { return wmemmove(__s1, __s2, __n); } static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) { return wmemcpy(__s1, __s2, __n); } static char_type* assign(char_type* __s, size_t __n, char_type __a) { return wmemset(__s, __a, __n); } static char_type to_char_type(const int_type& __c) { return char_type(__c); } static int_type to_int_type(const char_type& __c) { return int_type(__c); } static bool eq_int_type(const int_type& __c1, const int_type& __c2) { return __c1 == __c2; } static int_type eof() { return static_cast(WEOF); } static int_type not_eof(const int_type& __c) { return eq_int_type(__c, eof()) ? 0 : __c; } }; #endif // HP-UX or SunOS } // namespace std #endif // _asn_chartraits_h esnacc-ng-1.8.1/cxx-lib/inc/asn-config.h000066400000000000000000000160071302010526100176650ustar00rootroot00000000000000// file: .../c++-lib/inc/asn-config.h - decoder alloc routines and buffer routines and other configuration stuff. // // MS 92/06/18 // Copyright (C) 1992 Michael Sample and the University of British Columbia // // This library is free software; you can redistribute it and/or // modify it provided that this copyright/license information is retained // in original form. // // If you modify this file, you must clearly indicate your changes. // // This source code is distributed in the hope that it will be // useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // // $Header: /baseline/SNACC/c++-lib/inc/asn-config.h,v 1.22 2002/11/07 16:28:50 leonberp Exp $ // $Log: asn-config.h,v $ // Revision 1.22 2002/11/07 16:28:50 leonberp // latest runtime library changes // // Revision 1.21 2002/05/29 19:26:05 leonberp // removed PDU_MEMBERS_MACRO and added BDecPDU and BEncPDU to AsnType // // Revision 1.20 2002/05/29 18:55:31 leonberp // removed dependency on policy.h and snacc.h // // Revision 1.19 2002/05/22 15:40:40 leonberp // Ported to Solaris with GCC 3.0.3 // // Revision 1.18 2002/05/10 16:39:33 leonberp // latest changes for release 2.2 // includes integrating asn-useful into C & C++ runtime library, the compiler changes that go along with that, SnaccException changes for C++ runtime and compiler // // Revision 1.17 2001/10/29 12:01:16 nicholar // Removed #defines for Asn1New, Asn1Free, etc. // // Revision 1.16 2001/08/24 15:34:23 leonberp // Moved list template logic to asn-list.h // // Revision 1.15 2001/08/16 21:23:27 rwc // Updated to reflect customer's need to integrate __SGI_STL_PORT // instead of the standard MS Windows STL library. Minor // change for includes. // // Revision 1.14 2001/07/25 15:36:32 sfl // Yet another change for ; REMOVED reference to which // caused CML to not compile. // // Revision 1.13 2001/07/19 16:02:35 sfl // Yet more string.h changes. // // Revision 1.12 2001/07/18 18:40:55 rwc // Updates due to newly modified SNACC namespace additions. The SNACC compilier // was also modified (by Pierce) to create only .cpp, not .C which broke some of the // make file rules. // // Revision 1.11 2001/07/12 19:33:32 leonberp // Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. // // Revision 1.10 2001/06/28 21:38:01 rwc // Updated to remove referneces to vdacerr, which originally replaced the cerr standard error output. // Updated all references in macros and source that printed to vdacerr. All code now performs an // ASN_THROW(...) exception. // // Revision 1.9 2001/06/28 15:28:38 rwc // ADDED "SNACCASN" namespace definition to all SNACC data structures. // This should not affect most applications since we do not have any name // conflicts. // ALSO, combined all ASN primitive data type includes into asn-incl.h. // // Revision 1.8 2001/06/19 15:14:58 grafb // Re-ordered includes and removed redundant includes for g++ 3.0 compile // // Revision 1.7 2001/06/18 17:47:22 rwc // Updated to reflect newly added C++ Exception error handling, instead of "C" longjmp and setjmp calls. // Changes made to both the compiler and the SNACC C++ run-time library. // // Revision 1.6 2001/01/23 20:51:44 rwc // Updated to allow NOVDADER_RULES to disable VDA additions (except for new string // class handling, e.g. PrintableString; had to allow). Several sources are now disabled from // the build if NOVDADER_RULES config item is chosen. Builds, but untested. // // Revision 1.5 2001/01/11 18:19:38 rwc // Updated to now define the VDADER_RULES, SNACC_DEEP_COPY in asn-config.h and not have these settings // in the C++ pre-processor command line. // // Revision 1.4 2000/12/01 14:54:11 rwc // Updated to place a ".h" on the #include WIN32 include // to support SCO port by customer. // // Revision 1.3 2000/11/02 14:56:12 rwc // Updated to #ifdef WIN32 around #pragma for Unix warnings. // // Revision 1.2 2000/10/24 14:54:40 rwc // Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. // SOME warnings persist due to difficulty in modifying the SNACC compiler to // properly build clean source; also some files are built by Lex/Yacc. // // Revision 1.1.1.1 2000/08/21 20:36:11 leonberp // First CVS Version of SNACC. // // Revision 1.7 1995/09/07 18:48:36 rj // AsnIntType and AsnUIntType introduced to replace (unsigned) long int at a lot of places. // they shall provide 32 bit integer types on all platforms. // // Revision 1.6 1995/07/25 20:19:00 rj // changed `_' to `-' in file names. // // Revision 1.5 1995/02/13 14:47:46 rj // settings for IEEE_REAL_FMT/IEEE_REAL_LIB moved from {c_lib,c++_lib}/inc/asn_config.h to acconfig.h. // // Revision 1.4 1994/10/08 04:17:59 rj // code for meta structures added (provides information about the generated code itself). // // code for Tcl interface added (makes use of the above mentioned meta code). // // virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included. // // made Print() const (and some other, mainly comparison functions). // // several `unsigned long int' turned into `size_t'. // // Revision 1.3 1994/09/01 00:58:47 rj // redundant code moved into ../../config.h.bot; semicolon removed from end of macro texts. // // Revision 1.2 1994/08/28 10:00:47 rj // comment leader fixed. // // Revision 1.1 1994/08/28 09:20:29 rj // first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. #ifndef _asn_config_h_ #define _asn_config_h_ #ifndef WIN32 #include /* for wchar_t on UNIX */ #endif // RWC;VDA; added to support optional DLL build. #ifndef SNACCDLL_API #ifdef WIN32 #ifdef SNACCDLL_EXPORTS #define SNACCDLL_API __declspec(dllexport) #else #ifdef SNACCDLL_NONE #define SNACCDLL_API #else #define SNACCDLL_API __declspec(dllimport) #endif #endif #else #define SNACCDLL_API #endif #endif #ifndef NO_NAMESPACE #define _BEGIN_SNACC_NAMESPACE namespace SNACC { #define _END_SNACC_NAMESPACE } #else #define _BEGIN_SNACC_NAMESPACE #define _END_SNACC_NAMESPACE #endif // RWC;1/8/01; the following defines allow an application to default // the definitions for the SFL, ACL, and CML builds. #define USE_EXP_BUF 1 // used not only by AsnInt (asn-int.h), but by AsnNameDesc (meta.h) as well: #if SIZEOF_INT == 4 # define I int #else # if SIZEOF_LONG == 4 # define I long # elif SIZEOF_SHORT == 4 # define I short # else # define I int # endif #endif #ifdef I typedef I AsnIntType; typedef unsigned I AsnUIntType; # undef I #else # error "can't find integer type which is 4 bytes in size" #endif /* used to test if optionals are present */ #define NOT_NULL( ptr) ((ptr) != NULL) #ifdef WIN32 #if defined(_MSC_VER) #pragma warning( disable : 4127 4611 4710 4800 ) // IGNORE constant conditional expression. #endif #endif #endif /* conditional include */ esnacc-ng-1.8.1/cxx-lib/inc/asn-incl.h000066400000000000000000001310541302010526100173450ustar00rootroot00000000000000// file: .../c++-lib/inc/asn-incl.h - C++ class SNACCDLL_API // // // NEW HISTORY started once all SNACC class definitions move to a single file. // #ifndef SNACC_CXX_ASN_INCL_H #define SNACC_CXX_ASN_INCL_H #include "asn-config.h" #include "asn-buf.h" #ifdef WIN32 #if defined(_MSC_VER) #pragma warning(push,3) #endif #include #include #if defined(_MSC_VER) #pragma warning(pop) #endif #else // WIN32 #include #include #include "asn-chartraits.h" #if defined(SunOS) || defined(SCO_SV) || defined(HPUX) || defined(HPUX32) namespace std { typedef basic_string wstring; } #endif // SunOS #endif //WIN32 #if TCL #include #undef VOID #endif #if META #include "meta.h" #endif void SNACCDLL_API BDEC_2ND_EOC_OCTET(const SNACC::AsnBuf& b, SNACC::AsnLen& bytesDecoded); _BEGIN_SNACC_NAMESPACE typedef std::list ConstraintFailList; //######################################################################## #if SIZEOF_INT == 4 #define UL unsigned int #elif SIZEOF_LONG == 4 #define UL unsigned long #elif SIZEOF_SHORT == 4 #define UL unsigned short #else #define UL unsigned int #endif typedef UL AsnTag; // Tag Id's byte len #define TB sizeof(SNACC::AsnTag) // The MAKE_TAG_ID macro generates the TAG_ID rep for the // the given class/form/code (rep'd in long integer form) // if the class/form/code are constants the compiler (should) // calculate the tag completely --> zero runtime overhead. // This is good for efficiently comparing tags in switch statements // (decoding) etc. because run-time bit fiddling (eliminated) minimized #define MAKE_TAG_ID( cl, fm, cd)\ ((((UL)(cl)) << ((TB-1)*8)) | (((UL)(fm)) << ((TB-1)*8)) | (MAKE_TAG_ID_CODE(((UL)(cd))))) #define MAKE_TAG_ID_CODE( cd)\ ((cd < 31) ? (MAKE_TAG_ID_CODE1 (cd)):\ ((cd < 128) ? (MAKE_TAG_ID_CODE2 (cd)):\ ((cd < 16384) ? (MAKE_TAG_ID_CODE3 (cd)):\ (MAKE_TAG_ID_CODE4 (cd))))) #define MAKE_TAG_ID_CODE1(cd) ((UL)cd << ((TB-1)*8)) #define MAKE_TAG_ID_CODE2(cd) ((31l << ((TB-1)*8)) | (cd << ((TB-2)*8))) #define MAKE_TAG_ID_CODE3(cd) ((31l << ((TB-1)*8))\ | ((cd & 0x3f80) << 9)\ | (0x0080 << ((TB-2)*8))\ | ((cd & 0x007F) << ((TB-3)*8))) #define MAKE_TAG_ID_CODE4(cd) ((31l << ((TB-1)*8))\ | ((cd & 0x1fc000) << 2)\ | (0x0080 << ((TB-2)*8))\ | ((cd & 0x3f80) << 1)\ | (0x0080 << ((TB-3)*8))\ | ((cd & 0x007F) << ((TB-4)*8))) typedef enum BER_CLASS { ANY_CLASS = -2, NULL_CLASS = -1, UNIV = 0, APPL = (1 << 6), CNTX = (2 << 6), PRIV = (3 << 6) } BER_CLASS; typedef enum BER_FORM { ANY_FORM = -2, NULL_FORM = -1, PRIM = 0, CONS = (1 << 5) } BER_FORM; typedef enum BER_UNIV_CODE { NO_TAG_CODE = 0, BOOLEAN_TAG_CODE = 1, INTEGER_TAG_CODE, BITSTRING_TAG_CODE, OCTETSTRING_TAG_CODE, NULLTYPE_TAG_CODE, OID_TAG_CODE, OD_TAG_CODE, EXTERNAL_TAG_CODE, REAL_TAG_CODE, ENUM_TAG_CODE, UTF8STRING_TAG_CODE = 12, RELATIVE_OID_TAG_CODE = 13, SEQ_TAG_CODE = 16, SET_TAG_CODE, NUMERICSTRING_TAG_CODE, PRINTABLESTRING_TAG_CODE, TELETEXSTRING_TAG_CODE, VIDEOTEXSTRING_TAG_CODE, IA5STRING_TAG_CODE, UTCTIME_TAG_CODE, GENERALIZEDTIME_TAG_CODE, GRAPHICSTRING_TAG_CODE, VISIBLESTRING_TAG_CODE, GENERALSTRING_TAG_CODE, UNIVERSALSTRING_TAG_CODE = 28, BMPSTRING_TAG_CODE = 30 } BER_UNIV_CODE; #define TT61STRING_TAG_CODE TELETEXSTRING_TAG_CODE #define ISO646STRING_TAG_CODE VISIBLESTRING_TAG_CODE /* * the TAG_ID_[CLASS/FORM/CODE] macros are not * super fast - try not to use during encoding/decoding */ #define TAG_ID_CLASS(tid) ( (tid & (0xC0 << ((TB-1)*8))) >> ((TB-1)*8)) #define TAG_ID_FORM(tid) ( (tid & (0x20 << ((TB-1)*8))) >> ((TB-1)*8)) /* * TAG_IS_CONS evaluates to true if the given AsnTag type * tag has the constructed bit set. */ #define TAG_IS_CONS(tag) ((tag) & (CONS << ((TB-1)*8))) #define EOC_TAG_ID 0 /* * tag encoders. given constant exprs for class SNACCDLL_API form & code in the * source, these can be optimized by the compiler (eg * do the shifts and bitwise ors etc) */ #define BEncTag1( b, class, form, code)\ 1;\ b.PutByteRvs((unsigned char)((class) | (form) | (code))) #define BEncTag2( b, class, form, code)\ 2;\ b.PutByteRvs(code);\ b.PutByteRvs((char)((class) | (form) | 31)) #define BEncTag3( b, class, form, code)\ 3;\ b.PutByteRvs((code) & 0x7F);\ b.PutByteRvs((char)(0x80 | (char)((code) >> 7)));\ b.PutByteRvs((class) | (form) | 31) #define BEncTag4( b, class, form, code)\ 4;\ b.PutByteRvs((code) & 0x7F);\ b.PutByteRvs((char)(0x80 | (char)((code) >> 7)));\ b.PutByteRvs((char)(0x80 | (char)((code) >> 14)));\ b.PutByteRvs((class) | (form) | 31) #define BEncTag5( b, class, form, code)\ 5;\ b.PutByteRvs((code) & 0x7F);\ b.PutByteRvs((char)(0x80 | (char)((code) >> 7)));\ b.PutByteRvs((char)(0x80 | (char)((code) >> 14)));\ b.PutByteRvs((char)(0x80 | (char)((code) >> 21)));\ b.PutByteRvs((class) | (form) | 31) AsnLen SNACCDLL_API PEncTag(AsnBufBits& b, unsigned char ucClass, unsigned char form, long code, long lByteCount); AsnTag SNACCDLL_API BDecTag(const AsnBuf& b, AsnLen& bytesDecoded); AsnTag SNACCDLL_API PDecTag(AsnBufBits& bufBits, AsnLen& bitsDecoded); long SNACCDLL_API BytesInTag(AsnTag tag); long SNACCDLL_API BytesInLen(AsnLen len); //######################################################################## #define INDEFINITE_LEN ~0UL // max unsigned value used for indef rep #define MAX_OCTS 1048576 // 1 meg #define l_16k 16384 #ifdef USE_INDEF_LEN #define BEncEocIfNec(b)\ BEncEoc (b) #define BEncConsLen(b, len)\ 2 + BEncIndefLen (b) // include len for EOC */ #else // default -- use definite length -- usually faster // and smaller encodings #define BEncEocIfNec(b) 0; // do nothing #define BEncConsLen(b, len)\ BEncDefLen (b, len) #endif #define BEncIndefLen( b)\ 1;\ b.PutByteRvs (0x80) /* * use if you know the encoded length will be 0 >= len <= 127 * Eg for booleans, nulls, any resonable integers and reals * * NOTE: this particular Encode Routine does NOT return the length * encoded (1). The length counter must be explicity incremented */ #define BEncDefLenTo127( b, len)\ b.PutByteRvs ((unsigned char) len) AsnLen SNACCDLL_API BDecLen(const AsnBuf& b, AsnLen& bytesDecoded); AsnLen SNACCDLL_API BEncDefLen(AsnBuf& b, AsnLen len); AsnLen SNACCDLL_API BEncEoc(AsnBuf& b); void SNACCDLL_API BDecEoc(const AsnBuf& b, AsnLen& bytesDecoded); AsnLen SNACCDLL_API PEncDefLenTo127(AsnBufBits& b, int len); AsnLen SNACCDLL_API PEncLen_16kFragment(AsnBufBits& b, int len); AsnLen SNACCDLL_API PEncLen_1to16k(AsnBufBits& b, int len); // Indent function used in Print() functions void SNACCDLL_API Indent(std::ostream& os, unsigned short i); //######################################################################## AsnLen SNACCDLL_API PEncLen_16kFragment(AsnBufBits &b, int len); AsnLen SNACCDLL_API PEncLen_1to16k(AsnBufBits &b, int len); //Forward definition class AsnType; typedef struct SNACCDLL_API ContainedSubtype{ AsnType *containedSubtype; }ContainedSubtype; typedef struct SNACCDLL_API SizeConstraint{ unsigned long lowerBound; unsigned long upperBound; int upperBoundExists; }SizeConstraint; typedef struct SNACCDLL_API ValueRange{ long lowerBound; long upperBound; int upperBoundExists; }ValueRange; typedef struct SNACCDLL_API PermittedAlphabet{ unsigned char* ucApha; }PermittedAlphabet; class SNACCDLL_API PERGeneral { protected: virtual AsnLen EncodeGeneral(AsnBufBits& b) const; virtual AsnLen Interpret(AsnBufBits& b, long offset) const = 0; virtual long lEncLen() const { return 0; } virtual void Clear() = 0; virtual void DecodeGeneral(AsnBufBits& b, AsnLen& bitsDecoded); virtual void Deterpret(AsnBufBits&b, AsnLen& bitsDecoded, long offset) = 0; virtual void Allocate(long size) = 0; }; class SNACCDLL_API AsnType { protected: ContainedSubtype *containedSubtypes; public: virtual ~AsnType(); virtual AsnType* Clone() const = 0; virtual const char* typeName() const = 0; /* JKG: virtual constraint check function added 7/29/03 */ /* function returns 1 on error and 0 on success */ virtual int checkConstraints(ConstraintFailList* ) const { return 0; } virtual void BDec(const AsnBuf &b, AsnLen &bytesDecoded) = 0; virtual AsnLen BEnc(AsnBuf &b) const = 0; virtual void PDec(AsnBufBits &, AsnLen &) {} virtual AsnLen PEnc(AsnBufBits &) const { return 0; } bool BEncPdu(AsnBuf &b, AsnLen &bytesEncoded) const; bool BDecPdu(const AsnBuf &b, AsnLen &bytesDecoded); virtual void Print(std::ostream& os, unsigned short indent = 0) const = 0; #if META static const AsnTypeDesc _desc; virtual const AsnTypeDesc* _getdesc() const; virtual AsnType* _getref(const char* membername, bool create = false); private: const char* _typename() const; #if TCL public: virtual int TclGetDesc(Tcl_DString* ) const; virtual int TclGetVal(Tcl_Interp* ) const; virtual int TclSetVal(Tcl_Interp* , const char* val); virtual int TclUnsetVal(Tcl_Interp* , const char* membernames); #endif // TCL #endif // META }; //######################################################################## //######################################################################## typedef std::pair StringPair; class ConsStringDeck : public std::deque< StringPair > { public: ConsStringDeck(AsnTag baseTag = OCTETSTRING_TAG_CODE) {m_baseTag = baseTag;} virtual ~ConsStringDeck(); void Fill(const AsnBuf &b, AsnLen elmtLen, AsnLen &bytesDecoded); void Collapse(std::string &str); private: AsnTag m_baseTag; }; //######################################################################## class SNACCDLL_API AsnNull: public AsnType { public: virtual AsnType* Clone() const { return new AsnNull(*this); } virtual const char* typeName() const { return "AsnNull"; } AsnLen BEncContent (AsnBuf &) const { return 0; } void BDecContent (const AsnBuf &b, AsnTag tagId, AsnLen elmtLen, AsnLen &bytesDecoded); AsnLen BEnc (AsnBuf &b) const; void BDec (const AsnBuf &b, AsnLen &bytesDecoded); AsnLen PEnc (AsnBufBits &b) const; void PDec (AsnBufBits &b, AsnLen &bitsDecoded); void Print(std::ostream& os, unsigned short indent = 0) const; void PrintXML (std::ostream &os, const char *lpszTitle=NULL) const; #if META static const AsnNullTypeDesc _desc; const AsnTypeDesc *_getdesc() const; #if TCL int TclGetVal (Tcl_Interp *) const; int TclSetVal (Tcl_Interp *, const char *val); #endif /* TCL */ #endif /* META */ }; //######################################################################## class SNACCDLL_API AsnBool: public AsnType { protected: bool value; public: AsnBool (const bool val = false) { value = val; } virtual AsnType* Clone() const { return new AsnBool(*this);} virtual const char* typeName() const { return "AsnBool"; } operator bool() const { return value; } AsnBool &operator = (bool newvalue) { value = newvalue; return *this; } AsnLen BEnc (AsnBuf &b) const; void BDec (const AsnBuf &b, AsnLen &bytesDecoded); AsnLen BEncContent (AsnBuf &b) const; void BDecContent (const AsnBuf &b, AsnTag tagId, AsnLen elmtLen, AsnLen &bytesDecoded); AsnLen PEnc (AsnBufBits &b) const; void PDec (AsnBufBits &b, AsnLen &bitsDecoded); void Print(std::ostream& os, unsigned short indent = 0) const; void PrintXML (std::ostream &os, const char *lpszTitle=NULL) const; char* checkBoolSingleVal(const bool m_SingleVal)const; #if META static const AsnBoolTypeDesc _desc; const AsnTypeDesc *_getdesc() const; #if TCL int TclGetVal (Tcl_Interp *) const; int TclSetVal (Tcl_Interp *, const char *val); #endif // TCL #endif // META }; //######################################################################## class SNACCDLL_API AsnOcts: public AsnType { public: // constructor always copies strings so destructor can always delete AsnOcts() {m_pFileSeg = NULL; } AsnOcts (const char *str) { m_pFileSeg = NULL; m_str.assign(str); } AsnOcts (const char *str, const size_t len) { m_pFileSeg = NULL; m_str.assign(str, len); } AsnOcts (const AsnOcts &o); // AsnOcts (const std::filebuf &fb); virtual ~AsnOcts(); virtual const SizeConstraint* SizeConstraints(int &sizeList)const { sizeList = 0; return NULL;} virtual AsnType* Clone() const { return new AsnOcts(*this); } virtual const char* typeName() const { return "AsnOcts"; } AsnOcts &operator = (const AsnOcts &o) { return SetEqual(o); } AsnOcts &operator = (const char *str) { return SetEqual(str); } AsnOcts &SetEqual(const AsnOcts &o) { m_str = o.m_str; return *this; } AsnOcts &SetEqual(const char *str) { m_str.assign(str); return *this; } void Set (const char *str, size_t len); size_t Len() const; long length(){return (long)Len();} long length()const{return (long)Len();} void clear(){m_str.erase();} const std::string & data() const; const char * c_str() const; const unsigned char * c_ustr() const; bool operator == (const AsnOcts &o) const; bool operator != (const AsnOcts &o) const; AsnLen BEncContent (AsnBuf &b) const; void BDecContent (const AsnBuf &b, AsnTag tagId, AsnLen elmtLen, AsnLen &bytesDecoded); AsnLen BEnc (AsnBuf &b) const ; void BDec (const AsnBuf &b, AsnLen &bytesDecoded); AsnLen PEnc (AsnBufBits &b)const; void PDec (AsnBufBits &b, AsnLen &bitsDecoded); void Print(std::ostream& os, unsigned short indent = 0) const; void PrintXML (std::ostream &os, const char *lpszTitle=NULL, const char *lpszType=NULL) const; protected: AsnLen EncodeGeneral(AsnBufBits &b)const; void DecodeGeneral(AsnBufBits &b, AsnLen &bitsDecoded); AsnLen EncodeWithSizeConstraint(AsnBufBits &b)const; void DecodeWithSizeConstraint(AsnBufBits &b, AsnLen &bitsDecoded); long FindSizeConstraintBounds(int &iSCLowerBound, int &iSCUpperBound)const; private: void BDecConsOcts (const AsnBuf &b, AsnLen elmtLen, AsnLen &bytesDecoded); void FillStringDeck(AsnBuf &b, AsnLen elmtLen, AsnLen &bytesDecoded); // IF AsnOcts length is < MAX_OCTS, store in AsnString base mutable std::string m_str; // IF AsnOcts length is > MAX_OCTS, store in m_FileBuf; mutable AsnFileSeg *m_pFileSeg; }; //######################################################################## class SNACCDLL_API AsnBits: public AsnType { public: AsnBits(const char *stringForm=NULL); AsnBits (size_t numBits) { bits=NULL;nblFlag = false; Set (numBits); } AsnBits (const unsigned char *bitOcts, size_t numBits) {bits=NULL; nblFlag = false; Set (bitOcts, numBits); } AsnBits (const AsnBits &b) { bits=NULL; Set (b); } ~AsnBits(); virtual const SizeConstraint* SizeConstraints(int &sizeList)const { sizeList = 0; return NULL;} virtual AsnType* Clone() const { return new AsnBits(*this); } virtual const char* typeName() const { return "AsnBits"; } AsnBits &operator = (const AsnBits &b) { Set (b); return *this; } // overwrite existing bits and bitLen values void Set (size_t numBits); void Set (const unsigned char *bitOcts, size_t numBits); void Set (const AsnBits &b); AsnBits & SetEqual(const char *stringForm); AsnBits & operator = (const char *stringForm); bool operator == (const AsnBits &ab) const { return BitsEquiv (ab); } bool operator != (const AsnBits &ab) const { return !BitsEquiv (ab); } void SetSize(size_t); bool soloBitCheck(size_t); void SetBit (size_t); void ClrBit (size_t); bool GetBit (size_t) const; bool IsEmpty() const; long FindSizeConstraintBounds(int &iSCLowerBound, int &iSCUpperBound)const; void UseNamedBitListRules(bool flag) { nblFlag = flag; } void clear(){if(bits) delete[] bits; bits = NULL; bitLen = 0;} size_t BitLen() const { return bitLen; } const unsigned char* data() const { return bits; } size_t length() const { return ((bitLen+7)/8); } size_t encLen() const; virtual void Allocate(long size); AsnLen BEncContent (AsnBuf &b) const; void BDecContent (const AsnBuf &b, AsnTag tagId, AsnLen elmtLen, AsnLen &bytesDecoded); AsnLen BEnc (AsnBuf &b) const; void BDec (const AsnBuf &b, AsnLen &bytesDecoded); AsnLen EncodeGeneral (AsnBufBits &b)const; void DecodeGeneral (AsnBufBits &b, AsnLen &bitsDecoded); AsnLen EncodeWithSizeConstraint (AsnBufBits &b)const; void DecodeWithSizeConstraint (AsnBufBits &b, AsnLen &bitsDecoded); AsnLen PEnc (AsnBufBits &b) const; void PDec (AsnBufBits &b, AsnLen &bitsDecoded); void Print(std::ostream& os, unsigned short indent = 0) const; void PrintXML (std::ostream &os, const char *lpszTitle=NULL) const; #if META static const AsnBitsTypeDesc _desc; const AsnTypeDesc *_getdesc() const; #if TCL int TclGetVal (Tcl_Interp *) const; int TclSetVal (Tcl_Interp *, const char *val); #endif /* TCL */ #endif /* META */ private: bool BitsEquiv (const AsnBits &ab) const; void BDecConsBits (const AsnBuf &b, AsnLen elmtLen, AsnLen &bytesDecoded); protected: size_t bitLen; unsigned char* bits; bool nblFlag; }; extern SNACCDLL_API char numToHexCharTblG[]; #define TO_HEX(fourBits) (numToHexCharTblG[(fourBits) & 0x0F]) //######################################################################## class SNACCDLL_API AsnInt : public AsnType, protected PERGeneral { protected: unsigned char *m_bytes; unsigned long m_len; void storeDERInteger(const unsigned char *pDataCopy, long dataLen, bool unsignedFlag); void Clear(){if(m_bytes) delete[] m_bytes; /*RWC*/ m_bytes = NULL; m_len = 0;} long lEncLen()const{return length();} char getByte(long offset)const{return m_bytes[offset];} void putByte(long offset, unsigned char cByte); virtual AsnLen Interpret(AsnBufBits &b,long offset)const; virtual void Deterpret(AsnBufBits &b, AsnLen &bitsDecoded, long offset); virtual void Allocate(long size); public: AsnInt (AsnIntType val=0); AsnInt (const char *str, bool unsignedFlag = true); AsnInt (const AsnOcts &o, bool unsignedFlag = true); AsnInt (const char *str, const size_t len, bool unsignedFlag = true); AsnInt (const AsnInt &that);//generate this virtual ~AsnInt (); virtual const ValueRange* ValueRanges(int &sizeVRList)const { sizeVRList = 0; return NULL;} virtual AsnType* Clone() const { return new AsnInt(*this); } virtual const char* typeName() const { return "AsnInt"; } operator AsnIntType() const; bool operator == (AsnIntType o) const; bool operator != (AsnIntType o) const { return !operator==(o);} bool operator == (const AsnInt &o) const; bool operator != (const AsnInt &o) const; bool operator < (const AsnInt &o) const; AsnInt & operator = (const AsnInt &o);//generate this //unsigned char* Append_m_bytes(const unsigned char* AppendBytes, unsigned long templen); long length()const{ return m_len; } long length(void){ return m_len; } const unsigned char * c_str(void) const { return m_bytes; } void getPadded(unsigned char *&data, size_t &len, const size_t padToSize=0) const; int checkConstraints (ConstraintFailList* pConstraintFails)const; void Set(const unsigned char *str, size_t len, bool unsignedFlag=true); void Set(AsnIntType i); AsnLen BEnc (AsnBuf &b) const; void BDec (const AsnBuf &b, AsnLen &bytesDecoded); AsnLen BEncContent (AsnBuf &b) const; void BDecContent (const AsnBuf &b, AsnTag tagId, AsnLen elmtLen, AsnLen &bytesDecoded); virtual AsnLen PEnc (AsnBufBits &b)const; AsnLen PEncSemiConstrained (AsnBufBits &b, long lowerBound )const; AsnLen PEncFullyConstrained (AsnBufBits &b, long lowerBound, long upperBound)const; void PDecSemiConstrained(AsnBufBits &b, long lowerBound, AsnLen &bitsDecoded); void PDecFullyConstrained (AsnBufBits &b, long lowerBound, long upperBound, AsnLen &bitsDecoded); void PDec (AsnBufBits &b, AsnLen &bitsDecoded); void Print(std::ostream& os, unsigned short indent = 0) const; void PrintXML (std::ostream &os, const char *lpszTitle=NULL) const; #if META static const AsnIntTypeDesc _desc; const AsnTypeDesc *_getdesc() const; #if TCL int TclGetVal (Tcl_Interp *) const; int TclSetVal (Tcl_Interp *, const char *val); #endif /* TCL */ #endif /* META */ }; //######################################################################## class SNACCDLL_API AsnEnum : public AsnInt { public: AsnEnum(int val = 0) : AsnInt(val) {} AsnLen BEnc(AsnBuf& b) const; void BDec(const AsnBuf& b, AsnLen& bytesDecoded); virtual AsnType *Clone() const { return new AsnEnum(*this); } virtual const char* typeName() const { return "AsnEnum"; } long IndexedVal(long* penumList, long numVals) const; void SetIndex(long* penumList, long numVals, long index); #if META static const AsnEnumTypeDesc _desc; const AsnTypeDesc* _getdesc() const; #if TCL int TclGetVal(Tcl_Interp * ) const; int TclSetVal(Tcl_Interp * , const char* val); #endif /* TCL */ #endif /* META */ }; //######################################################################## class SNACCDLL_API AsnReal : public AsnType { protected: double value; public: AsnReal():value (0.0){} AsnReal (double val):value (val){} virtual AsnType *Clone() const { return new AsnReal(*this); } virtual const char* typeName() const { return "AsnReal"; } operator double() const { return value; } AsnReal &operator = (double newvalue) { value = newvalue; return *this; } AsnLen BEncContent (AsnBuf &b) const; void BDecContent (const AsnBuf &b, AsnTag tagId, AsnLen elmtLen, AsnLen &bytesDecoded); AsnLen BEnc (AsnBuf &b) const; void BDec (const AsnBuf &b, AsnLen &bytesDecoded); AsnLen PEnc (AsnBufBits &b)const; void PDec (AsnBufBits &b, AsnLen &bitsDecoded); void Print(std::ostream& os, unsigned short indent = 0) const; void PrintXML (std::ostream &os, const char *lpszTitle=NULL) const; char* checkRealSingleVal(const double m_SingleVal)const; char* checkRealValRange(const double m_Lower, const double m_Upper) const; #if META static const AsnRealTypeDesc _desc; const AsnTypeDesc *_getdesc() const; #if TCL int TclGetVal (Tcl_Interp *) const; int TclSetVal (Tcl_Interp *, const char *val); #endif /* TCL */ #endif /* META */ }; extern const AsnReal PLUS_INFINITY; extern const AsnReal MINUS_INFINITY; //######################################################################## class SNACCDLL_API AsnRelativeOid : public AsnType { public: AsnRelativeOid() { Init(); } AsnRelativeOid(const AsnRelativeOid& o) { Init(); Set(o); } AsnRelativeOid(const char* pszOID) { Init(); Set(pszOID); } virtual ~AsnRelativeOid(); AsnRelativeOid& operator=(const AsnRelativeOid& o) { Set(o); return *this; } operator const char*() const; virtual AsnType* Clone() const { return new AsnRelativeOid(*this); } virtual const char* typeName() const { return "AsnRelativeOid"; } size_t Len() const { return octetLen; } const char* Str() const { return oid; } bool operator==(const AsnRelativeOid& o) const { return OidEquiv(o); } bool operator==(const char* o) const; bool operator!=(const AsnRelativeOid& o) const { return !operator==(o); } bool operator!=(const char* o) const { return !operator==(o); } bool operator<(const AsnRelativeOid& o) const; unsigned long NumArcs() const; void GetOidArray(unsigned long oidArray[]) const; void Set(const char* szOidCopy); void Set(const char* encOid, size_t len); void Set(const AsnRelativeOid& o); void Set(unsigned long arcNumArr[], unsigned long arrLength); AsnLen BEnc(AsnBuf& b) const; void BDec(const AsnBuf& b, AsnLen& bytesDecoded); AsnLen BEncContent(AsnBuf& b) const; void BDecContent(const AsnBuf& b, AsnTag tagId, AsnLen elmtLen, AsnLen& bytesDecoded); AsnLen PEnc(AsnBufBits& b) const; void PDec(AsnBufBits& b, AsnLen& bitsDecoded); void Print(std::ostream& os, unsigned short indent = 0) const; void PrintXML(std::ostream& os, const char* lpszTitle = NULL) const; #if META static const AsnRelativeOidTypeDesc _desc; const AsnTypeDesc* _getdesc() const; #if TCL int TclGetVal(Tcl_Interp* ) const; int TclSetVal(Tcl_Interp* , const char* val); #endif /* TCL */ #endif /* META */ protected: size_t octetLen; char* oid; mutable char* m_lpszOidString; bool m_isRelative; private: void Init() { octetLen = 0; oid = NULL; m_lpszOidString = NULL; m_isRelative = true; } bool OidEquiv(const AsnRelativeOid& o) const; void createDottedOidStr() const; }; //######################################################################## class SNACCDLL_API AsnOid : public AsnRelativeOid { public: AsnOid(); AsnOid(const char* pszOID); AsnOid(const AsnOid &that):AsnRelativeOid(that) {m_isRelative = false;} virtual AsnType* Clone() const { return new AsnOid(*this); } virtual const char* typeName() const { return "AsnOid"; } // get a copy of the OID's NULL-terminated dotted string notation char* GetChar() const { return strdup(operator const char*()); } // set from a number-dot null term string void PutChar(const char* szOidCopy) { Set(szOidCopy); } AsnOid operator+(const AsnRelativeOid& ro) const; AsnOid& operator+=(const AsnRelativeOid& ro); #if META static const AsnOidTypeDesc _desc; const AsnTypeDesc* _getdesc() const; #endif /* META */ }; //######################################################################## //hash.h #define TABLESIZE 256 #define INDEXMASK 0xFF #define INDEXSHIFT 8 typedef void *Table[TABLESIZE]; typedef unsigned int Hash; typedef struct HashSlot { int leaf; Hash hash; void *value; Table *table; } HashSlot; Hash MakeHash (const char *str, size_t len); Table *InitHash(); int Insert (Table *table, void *element, Hash hash); int CheckFor (Table *table, Hash hash); int CheckForAndReturnValue (Table *table, Hash hash, void **value); //######################################################################## /* this is put into the hash table with the int or oid as the key */ class SNACCDLL_API AnyInfo { public: int anyId; // will be a value from the AnyId enum AsnOid oid; // will be zero len/null if intId is valid AsnIntType intId; AsnType *typeToClone; }; class SNACCDLL_API AsnAny: public AsnType { public: static Table *oidHashTbl; // all AsnAny class SNACCDLL_API instances static Table *intHashTbl; // share these tables mutable AnyInfo *ai; // points to entry in hash tbl for this type AsnType *value; AsnBuf *anyBuf; // used if ai == null AsnAny() { ai = NULL; value = NULL; anyBuf=NULL;} AsnAny(const AsnAny &o) { ai = NULL; value = NULL; anyBuf = NULL; *this = o; } virtual ~AsnAny(); AsnAny &operator = (const AsnAny &o); virtual AsnType* Clone() const { return new AsnAny(*this); } virtual const char* typeName() const { return "AsnAny"; } static void AsnAnyDestroyHashTbls(); // Recursive call to destroy table during destruction static void AsnAnyDestroyHashTbl(Table *&pHashTbl); // class SNACCDLL_API level methods static void InstallAnyByInt (AsnIntType intId, int anyId, AsnType *type); static void InstallAnyByOid (AsnOid &oid, int anyId, AsnType *type); int GetId() const { return ai ? ai->anyId : -1; } void SetTypeByInt (const AsnInt& id) const; void SetTypeByOid (const AsnOid &id) const; AsnLen BEnc (AsnBuf &b) const; void BDec (const AsnBuf &b, AsnLen &bytesDecoded); void BDecContent (const AsnBuf &b, AsnTag tag, AsnLen len, AsnLen &bytesDecoded); AsnLen PEnc (AsnBufBits &b) const; void PDec (AsnBufBits &b, AsnLen &bitsDecoded); void Print(std::ostream& os, unsigned short indent = 0) const; void PrintXML(std::ostream &os, const char *lpszTitle=NULL) const; #if TCL int TclGetDesc (Tcl_DString *) const; int TclGetVal (Tcl_DString *) const; int TclSetVal (Tcl_Interp *, const char *val); int TclUnSetVal (Tcl_Interp *, const char *member); #endif /* TCL */ }; //######################################################################## // SNACC ASN.1 String Types // class SNACCDLL_API AsnString : public std::string, public AsnType, protected PERGeneral { public: AsnString(const char* str = NULL) { operator=(str); } AsnString(const std::string& str) { operator=(str); } AsnString(const AsnString& aStr) : std::string() { operator=(aStr.c_str()); } AsnString& operator=(const char* str); AsnString& operator=(const std::string& str) { assign(str); return *this; } void Set(const char* str){operator=(str);} virtual const SizeConstraint* SizeConstraints(int &sizeList)const { sizeList = 0; return NULL;} virtual const char* PermittedAlphabet(int &sizeAlpha) const; int cvt_LDAPtoStr (char *in_string, char **char_ptr); int cvt_StrtoLDAP (wchar_t *in_string, char **char_ptr); AsnLen BEnc(AsnBuf &b) const; void BDec(const AsnBuf &b, AsnLen& bytesDecoded); AsnLen BEncContent(AsnBuf &b) const; void BDecContent(const AsnBuf &b, AsnTag tagId, AsnLen elmtLen, AsnLen& bytesDecoded); AsnLen PEnc(AsnBufBits &b)const; void PDec(AsnBufBits &b, AsnLen &bitsDecoded); int checkConstraints (ConstraintFailList* pConstraintFails)const; const char* checkStringTypPermittedAlpha(const char* m_Alpha, long m_AlphaSize)const; // each string type must implement these methods // // tagCode should be implemented to return the ASN.1 tag corresponding to the // character string type. // // the check method should be implemented to enforce any rules imposed on the // character string type. virtual BER_UNIV_CODE tagCode(void) const = 0; virtual bool check() const { return true; } void Print(std::ostream& os, unsigned short indent = 0) const; void PrintXML(std::ostream& os, const char *lpszTitle = NULL) const; protected: void Clear() { erase(); } char* getChar(long offset)const; int numBits()const; void putChar(char* seg){append(seg, 1);} int findB2(int B)const; AsnLen EncodeWithSizeConstraint(AsnBufBits &b)const; void DecodeWithSizeConstraint(AsnBufBits &b, AsnLen &bitsDecoded); long FindSizeConstraintBounds(int &iSCLowerBound, int &iSCUpperBound)const; virtual AsnLen Interpret(AsnBufBits &b, long offset)const; virtual long lEncLen()const{return length();} virtual void Deterpret(AsnBufBits &b, AsnLen &bitsDecoded, long offset); virtual void Allocate(long){/*std::string automatically allocates mem*/}; private: void BDecConsString(const AsnBuf &b, AsnLen elmtLen, AsnLen &bytesDecoded); }; class SNACCDLL_API NumericString : public AsnString { public: NumericString(const char* str = NULL) : AsnString(str) { } NumericString(const std::string& str) : AsnString(str) { } NumericString& operator=(const char* str) { AsnString::operator=(str); return *this;} NumericString& operator=(const std::string& str) { AsnString::operator=(str); return *this; } AsnType* Clone() const { return new NumericString(*this); } const char* typeName() const { return "NumericString"; } BER_UNIV_CODE tagCode() const { return NUMERICSTRING_TAG_CODE; } virtual const SizeConstraint* SizeConstraints(int &sizeList)const; const char* PermittedAlphabet(int &alphaSize) const; bool check() const; // Enforce string rules }; class SNACCDLL_API PrintableString : public AsnString { public: PrintableString(const char* str = NULL) : AsnString(str) { } PrintableString(const std::string& str) : AsnString(str) { } PrintableString& operator=(const char* str) { AsnString::operator=(str); return *this;} PrintableString& operator=(const std::string& str) { AsnString::operator=(str); return *this; } AsnType* Clone() const { return new PrintableString(*this); } const char* typeName() const { return "PrintableString"; } BER_UNIV_CODE tagCode() const { return PRINTABLESTRING_TAG_CODE; } virtual const SizeConstraint* SizeConstraints(int &sizeList)const { sizeList = 0; return NULL;} const char* PermittedAlphabet(int &sizeAlpha) const; bool check() const; // Enforce string rules }; class SNACCDLL_API TeletexString : public AsnString { public: TeletexString(const char* str = NULL) : AsnString(str) {} TeletexString(const std::string& str) : AsnString(str) {} TeletexString& operator=(const char* str) { AsnString::operator=(str); return *this;} TeletexString& operator=(const std::string& str) { AsnString::operator=(str); return *this; } AsnType* Clone() const { return new TeletexString(*this); } const char* typeName() const { return "TeletexString"; } BER_UNIV_CODE tagCode() const { return TELETEXSTRING_TAG_CODE; } }; // T61String -- Alternate name for TeletexString typedef TeletexString T61String; class SNACCDLL_API VideotexString : public AsnString { public: VideotexString(const char* str = NULL) : AsnString(str) {} VideotexString(const std::string& str) : AsnString(str) {} VideotexString& operator=(const char* str) { AsnString::operator=(str); return *this;} VideotexString& operator=(const std::string& str) { AsnString::operator=(str); return *this; } AsnType* Clone() const { return new VideotexString(*this); } const char* typeName() const { return "VideotexString"; } BER_UNIV_CODE tagCode() const { return VIDEOTEXSTRING_TAG_CODE; } }; class SNACCDLL_API IA5String : public AsnString { public: IA5String(const char* str = NULL) : AsnString(str) { } IA5String(const std::string& str) : AsnString(str) { } IA5String& operator=(const char* str) { AsnString::operator=(str); return *this;} IA5String& operator=(const std::string& str) { AsnString::operator=(str); return *this;} AsnType* Clone() const { return new IA5String(*this); } const char* typeName() const { return "IA5String"; } BER_UNIV_CODE tagCode() const { return IA5STRING_TAG_CODE; } virtual const SizeConstraint* SizeConstraints(int &sizeList)const { sizeList = 0; return NULL;} const char* PermittedAlphabet(int &sizeAlpha) const; bool check() const; // Enforce string rules }; class SNACCDLL_API GraphicString : public AsnString { public: GraphicString(const char* str = NULL) : AsnString(str) {} GraphicString(const std::string& str) : AsnString(str) {} GraphicString& operator=(const char* str) { AsnString::operator=(str); return *this;} GraphicString& operator=(const std::string& str) { AsnString::operator=(str); return *this; } AsnType* Clone() const { return new GraphicString(*this); } const char* typeName() const { return "GraphicString"; } BER_UNIV_CODE tagCode() const { return GRAPHICSTRING_TAG_CODE; } }; class SNACCDLL_API VisibleString : public AsnString { public: VisibleString(const char* str = NULL) : AsnString(str){ } VisibleString(const std::string& str) : AsnString(str){ } VisibleString& operator=(const char* str) { AsnString::operator=(str); return *this;} VisibleString& operator=(const std::string& str) { AsnString::operator=(str); return *this; } AsnType* Clone() const { return new VisibleString(*this); } const char* typeName() const { return "VisibleString"; } BER_UNIV_CODE tagCode() const { return VISIBLESTRING_TAG_CODE; } virtual const SizeConstraint* SizeConstraints(int &sizeList)const { sizeList = 0; return NULL;} const char* PermittedAlphabet(int &sizeAlpha) const; bool check() const; // Enforce string rules }; // ISO646String -- Alternate name for VisibleString typedef VisibleString ISO646String; class SNACCDLL_API GeneralString : public AsnString { public: GeneralString(const char* str = NULL) : AsnString(str) {} GeneralString(const std::string& str) : AsnString(str) {} GeneralString& operator=(const char* str) { AsnString::operator=(str); return *this;} GeneralString& operator=(const std::string& str) { AsnString::operator=(str); return *this; } AsnType* Clone() const { return new GeneralString(*this); } const char* typeName() const { return "GeneralString"; } BER_UNIV_CODE tagCode() const { return GENERALSTRING_TAG_CODE; } }; // Multi-byte character based definitions... BMP, Universal, UTF8. class SNACCDLL_API WideAsnString : public std::wstring, public AsnType, protected PERGeneral { public: WideAsnString(const char* str = NULL) { set(str); } WideAsnString(const std::string& str) { set(str.c_str()); } WideAsnString(const std::wstring& wstr) { assign(wstr); } // each string type must implement these methods // // tagCode should be implemented to return the ASN.1 tag corresponding to the // character string type. // // the check method should be implemented to enforce any rules imposed on the // character string type. virtual BER_UNIV_CODE tagCode() const = 0; // virtual bool check() const = 0; virtual const SizeConstraint* SizeConstraints(int &sizeList)const { sizeList = 0; return NULL;} AsnLen BEnc(AsnBuf &b) const; void BDec(const AsnBuf &b, AsnLen &bytesDecoded); virtual AsnLen BEncContent(AsnBuf &b) const = 0; virtual void BDecContent(const AsnBuf &b, AsnTag tagId, AsnLen elmtLen, AsnLen &bytesDecoded) = 0; AsnLen PEnc(AsnBufBits &b)const; void PDec(AsnBufBits &b, AsnLen &bitsDecoded); void Print(std::ostream& os, unsigned short indent = 0) const; void PrintXML(std::ostream &os, const char *lpszTitle) const; int checkConstraints (ConstraintFailList* pConstraintFails)const; const char* checkStringTypPermittedAlpha(const char* m_Alpha, long m_AlphaSize)const; virtual bool check() const { return true; } virtual const char* PermittedAlphabet(int &sizeAlpha)const { sizeAlpha = 0; return NULL;}; void set(const char* str); void getAsUTF8(std::string &utf8String) const; char* getAsUTF8() const; protected: void Clear() { erase(); } void putWideChar(wchar_t* seg){append(seg, 1);} long lEncLen()const{return length();} wchar_t* getWideChar(long offset)const; virtual AsnLen Interpret(AsnBufBits &b, long offset)const; virtual void Deterpret(AsnBufBits &b, AsnLen &bitsDecoded, long offset); virtual void Allocate(long){/*std::string automatically allocates mem*/}; AsnLen CombineConsString(const AsnBuf &b, AsnLen elmtLen, std::string& encStr); }; class SNACCDLL_API BMPString : public WideAsnString { public: BMPString(const char* str = NULL) : WideAsnString(str) {} BMPString(const std::string& str) : WideAsnString(str) {} BMPString(const std::wstring& wstr) : WideAsnString(wstr) {} BMPString& operator=(const char* str) { set(str); return *this;} BMPString& operator=(const std::string& str) { set(str.c_str()); return *this; } BMPString& operator=(const std::wstring& wstr) { assign(wstr); return *this; } AsnType* Clone() const { return new BMPString(*this); } const char* typeName() const { return "BMPString"; } BER_UNIV_CODE tagCode() const { return BMPSTRING_TAG_CODE; } AsnLen BEncContent(AsnBuf &b) const; void BDecContent(const AsnBuf &b, AsnTag tagId, AsnLen elmtLen, AsnLen &bytesDecoded); }; class SNACCDLL_API UniversalString : public WideAsnString { public: UniversalString(const char* str = NULL) : WideAsnString(str) {} UniversalString(const std::string& str) : WideAsnString(str) {} UniversalString(const std::wstring& wstr) : WideAsnString(wstr) {} UniversalString& operator=(const char* str) { set(str); return *this;} UniversalString& operator=(const std::string& str) { set(str.c_str()); return *this; } UniversalString& operator=(const std::wstring& wstr) { assign(wstr); return *this; } AsnType* Clone() const { return new UniversalString(*this); } const char* typeName() const { return "UniversalString"; } BER_UNIV_CODE tagCode() const { return UNIVERSALSTRING_TAG_CODE; } AsnLen BEncContent(AsnBuf &b) const; void BDecContent(const AsnBuf &b, AsnTag tagId, AsnLen elmtLen, AsnLen &bytesDecoded); /*void PDecConstent(const AsnBuf&b, AsnTag tagId, AsnLen elmtLen, * AsnLen &bytesDecoded); */ }; class SNACCDLL_API UTF8String : public WideAsnString { public: UTF8String(const char* str = NULL) : WideAsnString(str) {} UTF8String(const std::string& str) : WideAsnString(str) {} UTF8String(const std::wstring& wstr) : WideAsnString(wstr) {} UTF8String& operator=(const char* str) { set(str); return *this;} UTF8String& operator=(const std::string& str) { set(str.c_str()); return *this; } UTF8String& operator=(const std::wstring& wstr) { assign(wstr); return *this; } AsnType* Clone() const { return new UTF8String(*this); } const char* typeName() const { return "UTF8String"; } BER_UNIV_CODE tagCode() const { return UTF8STRING_TAG_CODE; } AsnLen BEncContent(AsnBuf &b) const; void BDecContent(const AsnBuf &b, AsnTag tagId, AsnLen elmtLen, AsnLen &bytesDecoded); }; //######################################################################## // Time Classes // class SNACCDLL_API UTCTime : public VisibleString { public: UTCTime(const char* str = NULL) : VisibleString(str) {} UTCTime(const std::string& str) : VisibleString(str) {} UTCTime& operator=(const char* str) { VisibleString::operator=(str); return *this;} UTCTime& operator=(const std::string& str) { VisibleString::operator=(str); return *this; } AsnType* Clone() const { return new UTCTime(*this); } const char* typeName() const { return "UTCTime"; } // ASN.1 tag for the character string BER_UNIV_CODE tagCode() const { return UTCTIME_TAG_CODE; } }; class SNACCDLL_API GeneralizedTime : public VisibleString { public: GeneralizedTime(const char* str = NULL) : VisibleString(str) {} GeneralizedTime(const std::string& str) : VisibleString(str) {} GeneralizedTime& operator=(const char* str) { VisibleString::operator=(str); return *this;} GeneralizedTime& operator=(const std::string& str) { VisibleString::operator=(str); return *this; } AsnType* Clone() const { return new GeneralizedTime(*this); } const char* typeName() const { return "GeneralizedTime"; } BER_UNIV_CODE tagCode() const { return GENERALIZEDTIME_TAG_CODE; } }; // Object Descriptor class class SNACCDLL_API ObjectDescriptor : public GraphicString { public: ObjectDescriptor(const char* str = NULL) : GraphicString(str) {} ObjectDescriptor(const std::string& str) : GraphicString(str) {} ObjectDescriptor& operator=(const char* str) { GraphicString::operator=(str); return *this;} ObjectDescriptor& operator=(const std::string& str) { GraphicString::operator=(str); return *this; } AsnType* Clone() const { return new ObjectDescriptor(*this); } const char* typeName() const { return "ObjectDescriptor"; } BER_UNIV_CODE tagCode() const { return OD_TAG_CODE; } }; //######################################################################## // AnyDefinedBy is currently the same as AsnAny: typedef AsnAny AsnAnyDefinedBy; /* JKG -- 01/27/2004 AsnExtension class added in support for ASN.1 Extensibility syntax */ class SNACCDLL_API AsnExtension : public AsnType { public: std::list extList; AsnExtension() {} AsnExtension(const AsnExtension &ext) { operator=(ext);} ~AsnExtension() {} AsnType* Clone() const { return new AsnExtension(*this); } const char* typeName() const { return "AsnExtension"; } void operator=(const AsnExtension& ext){extList = ext.extList;} int checkConstraints(ConstraintFailList* ) const { return 0; } void BDec(const AsnBuf&, AsnLen&) {/* Implemented in generated code */} void PDec(AsnBufBits&, AsnLen&) {/* Implemented in generated code */} AsnLen BEnc(AsnBuf& b) const; AsnLen PEnc(AsnBufBits& b) const; void Print (std::ostream& os, unsigned short indent = 0) const; void PrintXML (std::ostream &, const char * = NULL) const {} }; void SNACCDLL_API threadLock(); void SNACCDLL_API threadUnlock(); void SNACCDLL_API threadDestroy(); extern "C" { void SNACCDLL_API SNACC_CleanupMemory(); } //######################################################################## //######################################################################## _END_SNACC_NAMESPACE // Overload of operator<< to stream out an AsnType SNACCDLL_API std::ostream& operator<<(std::ostream& os, const SNACC::AsnType& a); #include "snaccexcept.h" #include "asn-usefultypes.h" #endif esnacc-ng-1.8.1/cxx-lib/inc/asn-list.h000066400000000000000000000177771302010526100174120ustar00rootroot00000000000000// file: .../c++-lib/inc/asn-list.h - List template classes // // #ifdef _MSC_VER #pragma warning(disable: 4189) // Disable local var initialized warning #pragma warning(disable: 4786) // Disable symbols truncated warning #endif #include ////////////////////////// // Base List template // //////////////////////// template class List { protected: unsigned long count; struct ListElmt { T *elmt; struct ListElmt *next, *prev; } *first, *last; mutable ListElmt *curr; public: List() { count = 0; first = curr = last = NULL; } virtual ~List() { RemoveAll(); } List(const List &that); List& operator=(const List& that); void SetCurrElmt (unsigned long index) const; unsigned long GetCurrElmtIndex(void) const; void SetCurrToFirst(void) const { curr = first; } void SetCurrToLast(void) const { curr = last; } // reading member fcns T *Curr() { return curr ? curr->elmt : NULL; } T *First() { return count > 0 ? first->elmt : NULL; } T *Last() { return count > 0 ? last->elmt : NULL; } T *Next() { return curr && curr->next ? curr->next->elmt : NULL; } T *Prev() { return curr && curr->prev ? curr->prev->elmt : NULL; } int Count() const { return count; } const T *Curr() const { return curr ? curr->elmt : NULL; } const T *First() const { return count > 0 ? first->elmt : NULL; } const T *Last() const { return count > 0 ? last->elmt : NULL; } const T *Next() const { return curr && curr->next ? curr->next->elmt : NULL; } const T *Prev() const { return curr && curr->prev ? curr->prev->elmt : NULL; } const T *GoNext() const { if (curr) curr = curr->next; return Curr(); } const T *GoPrev() const { if (curr) curr = curr->prev; return Curr(); } // routines that move the curr elmt T *GoNext() { if (curr) curr = curr->next; return Curr(); } T *GoPrev() { if (curr) curr = curr->prev; return Curr(); } // write & alloc fcns - returns new elmt T * Append(); // add elmt to end of list T * Prepend(); // add elmt to begginning of list // write & alloc & copy - returns list after copying elmt List& AppendCopy (const List &list); List& AppendCopy (const T& elmt); // add elmt to end of list List& PrependCopy (const T& elmt); // add elmt to begginning of list // Special append -- does not copy element void AppendNoCopy(T* pElmt); void convertTo(std::list &stdList); void convertFrom(const std::list &stdList); // Remove current element from list void RemoveCurrFromList(); // Remove all elements from list void RemoveAll(); }; ////////////////////////// // Base List template // // CODE // /////////////////////// template void List::convertTo(std::list &stdList) { // PIERCE: Note should I clear stdList first? // SetCurrToFirst(); for (; Curr() != NULL; GoNext()) { stdList.push_back(*Curr()); } } // Copy elements from stdList into this list. // template void List::convertFrom(const std::list &stdList) { RemoveAll(); typename std::list::const_iterator ci; ci = stdList.begin(); for (; ci != stdList.end(); ci++) AppendCopy(*ci); } template void List::SetCurrElmt (unsigned long index) const { unsigned long i; curr = first; for (i = 0; (i < (count-1)) && (i < index); i++) curr = curr->next; } template unsigned long List::GetCurrElmtIndex(void) const { unsigned long int i; ListElmt *tmp; if (curr != NULL) { for (i = 0, tmp = first; tmp != NULL; i++) { if (tmp == curr) return i; else tmp = tmp->next; } } return count; } // alloc new list elmt, put at end of list // and return the component type template T * List::Append() { ListElmt *newElmt; newElmt = new ListElmt; newElmt->elmt = new T; newElmt->next = NULL; if (last == NULL) { newElmt->prev = NULL; first = last = newElmt; } else { newElmt->prev = last; last->next = newElmt; last = newElmt; } count++; return (curr = newElmt)->elmt; } /* List::Append */ // alloc new list elmt, put at end of list // and add the component template void List::AppendNoCopy(T* pElmt) { if (pElmt == NULL) return; ListElmt *newElmt; newElmt = new ListElmt; newElmt->elmt = pElmt; newElmt->next = NULL; if (last == NULL) { newElmt->prev = NULL; first = last = newElmt; } else { newElmt->prev = last; last->next = newElmt; last = newElmt; } count++; } /* List::AppendNoCopy */ // alloc new list elmt, put at beggining of list // and return the component type template T * List::Prepend() { ListElmt *newElmt; newElmt = new ListElmt; newElmt->elmt = new T; newElmt->prev = NULL; if (first == NULL) { newElmt->next = NULL; first = last = newElmt; } else { newElmt->next = first; first->prev = newElmt; first = newElmt; } count++; return (curr = newElmt)->elmt; } /* AsnList::Prepend */ template List& List::AppendCopy (const List& list) { ListElmt* pTemp = list.first; ListElmt* pLast = list.last; // Append all but the last element while (pTemp != pLast) { AppendCopy(*pTemp->elmt); pTemp = pTemp->next; } // Append the last element if (pTemp != NULL) AppendCopy(*pTemp->elmt); return *this; } template List& List::AppendCopy (const T& elmt) { ListElmt *newElmt; newElmt = new ListElmt; newElmt->elmt = new T; *newElmt->elmt = elmt; newElmt->next = NULL; if (last == NULL) { newElmt->prev = NULL; first = last = newElmt; } else { newElmt->prev = last; last->next = newElmt; last = newElmt; } count++; return *this; } /* AppendAndCopy */ template List& List::PrependCopy (const T& elmt) { ListElmt *newElmt; newElmt = new ListElmt; newElmt->elmt = new T; *newElmt->elmt = elmt; newElmt->prev = NULL; if (first == NULL) { newElmt->next = NULL; first = last = newElmt; } else { newElmt->next = first; first->prev = newElmt; first = newElmt; } count++; return *this; } /* PrependAndCopy */ template void List::RemoveCurrFromList() { ListElmt *del_elmt; if (curr != NULL) { del_elmt = curr; count--; if (count == 0) first = last = curr = NULL; else if (curr == first) { curr = first= first->next; first->prev = NULL; } else if (curr == last) { curr = last = last->prev; last->next = NULL; } else { curr->prev->next = curr->next; curr->next->prev = curr->prev; curr = curr->next; } delete del_elmt->elmt; delete del_elmt; } } template void List::RemoveAll() { curr = first; while (curr != NULL) { ListElmt* next = curr->next; delete curr->elmt; delete curr; curr = next; } count = 0; first = NULL; last = NULL; } template List::List(const List &that) { count = 0; first = curr = last = NULL; operator=(that); } template List& List::operator=(const List& that) { if (this != &that) AppendCopy(that); return *this; } #if 0 #if META const SNACC::AsnTypeDesc AsnList::_desc (NULL, NULL, false, SNACC::AsnTypeDesc::SET_or_SEQUENCE_OF, NULL); const SNACC::AsnTypeDesc *AsnList::_getdesc() const { return &_desc; } #if TCL int AsnList::TclGetVal (Tcl_Interp *interp) const { return TCL_ERROR; } int AsnList::TclSetVal (Tcl_Interp *interp, const char *valstr) { return TCL_ERROR; } #endif /* TCL */ #endif /* META */ #endif /* 0 */ esnacc-ng-1.8.1/cxx-lib/inc/asn-listset.h000066400000000000000000000374511302010526100201150ustar00rootroot00000000000000// // File: asn-listset.h // // Contents: AsnList, AsnSeqOf, AsnSetOf template classes // // #ifndef SNACC_ASN_LISTSET_H #define SNACC_ASN_LISTSET_H #ifdef _MSC_VER #pragma warning(disable: 4786) // Disable symbols truncated warning #endif #ifdef WIN32 #include #include #include #endif ///////////////////////////////// // Abstract AsnList template // /////////////////////////////// template class AsnList : public std::list, public SNACC::AsnType, public SNACC::PERGeneral { public: // Appends newly inserted element to list and returns its iterator typename std::list::iterator append(const T& x = T()) { return this->insert(this->end(), x); } // encode and decode routines virtual SNACC::AsnLen PEnc(SNACC::AsnBufBits& b) const; virtual SNACC::AsnLen BEnc(SNACC::AsnBuf& b) const = 0; virtual SNACC::AsnLen BEncContent(SNACC::AsnBuf& b) const; virtual void PDec(SNACC::AsnBufBits& b, SNACC::AsnLen& bytesDecoded); virtual void BDec(const SNACC::AsnBuf& b, SNACC::AsnLen& bytesDecoded) = 0; virtual void BDecContent(const SNACC::AsnBuf& b, SNACC::AsnTag tagId, SNACC::AsnLen elmtLen, SNACC::AsnLen& bytesDecoded); virtual const char* typeName() const = 0; virtual int checkConstraints(SNACC::ConstraintFailList* pConstraintFails) const; void PrintXML(std::ostream& os, const char* lpszTitle = NULL) const; void Print(std::ostream& os, unsigned short indent) const; // int checkListConstraints(SNACC::ConstraintFailList* pConstraintFails) const; /*JKG--8/12/03--*/ char* checkSOfVRange(long m_Lower, long m_Upper) const; char* checkSOfSingleVal(long m_SingleVal) const; virtual SNACC::SizeConstraint* SizeConstraints() const { return NULL; } // virtual SNACC::SizeConstraint* SizeConstraints() { return NULL; } virtual void Allocate(long size) {} virtual void Clear() { this->clear(); } virtual SNACC::AsnLen Interpret(SNACC::AsnBufBits& b, long offset) const; virtual void Deterpret(SNACC::AsnBufBits& b, SNACC::AsnLen& bitsDecoded, long offset); // virtual long lEncLen() const { return size(); } }; ////////////////////////////////// // Abstract AsnList template // // CODE // /////////////////////////////// template void AsnList::Deterpret(SNACC::AsnBufBits& b, SNACC::AsnLen& bitsDecoded, long offset) { append()->PDec(b, bitsDecoded); } template SNACC::AsnLen AsnList::Interpret(SNACC::AsnBufBits& b, long offset) const { FUNC("AsnList::Interpret()"); typename AsnList::const_iterator i = this->begin(); while ((i != this->end()) && (offset > 0)) { ++i; --offset; } if (i != this->end()) return i->PEnc(b); else throw SNACC_EXCEPT("Null element found in List"); } template SNACC::AsnLen AsnList::PEnc(SNACC::AsnBufBits& b) const { FUNC("AsnList::PEnc()"); if (!SizeConstraints()) return EncodeGeneral(b); else { SNACC::AsnLen sum = 0; if (SizeConstraints()->upperBoundExists == 0) { if (this->size() != (unsigned int) SizeConstraints()->lowerBound) { throw EXCEPT("Number of elements in AsnList does not match singlevalue constraint", ENCODE_ERROR); } for (typename AsnList::const_iterator i = this->begin(); i != this->end(); ++i) sum += i->PEnc(b); } else if (SizeConstraints()->upperBoundExists == 1) { if ((this->size() < SizeConstraints()->lowerBound) || (this->size() > SizeConstraints()->upperBound)) { throw EXCEPT("Number of elements in AsnList is not within the size constraint", ENCODE_ERROR); } unsigned char pStr[] = {0x00, 0x00, 0x00, 0x00}; long tempRange = SizeConstraints()->upperBound - SizeConstraints()->lowerBound; int minBitsNeeded = 0; while (tempRange > 0) { tempRange -= (long)(1 << minBitsNeeded); minBitsNeeded += 1; } sum += b.OctetAlignWrite(); long minBytesNeeded = minBitsNeeded / 8; minBitsNeeded %= 8; long numExtra = this->size() - SizeConstraints()->lowerBound; if (minBytesNeeded > 0) { pStr[0] = (unsigned char)(numExtra >> minBitsNeeded); sum += b.PutBits(pStr, 8); } pStr[0] = (unsigned char)numExtra; pStr[0] <<= 8 - minBitsNeeded; sum += b.PutBits(pStr, minBitsNeeded); sum += b.OctetAlignWrite(); } else { if (this->size() < SizeConstraints()->lowerBound) { throw EXCEPT("Number of elements in AsnList is below the minimum size constraint", ENCODE_ERROR); } SNACC::AsnInt listLen(this->size() - SizeConstraints()->lowerBound); sum += b.OctetAlignWrite(); listLen.PEnc(b); sum += b.OctetAlignWrite(); } // Encode the elements for (typename AsnList::const_iterator i = this->begin(); i != this->end(); ++i) sum += i->PEnc(b); return sum; } } // template void AsnList::PDec(SNACC::AsnBufBits& b, SNACC::AsnLen& bitsDecoded) { // Remove existing elements this->clear(); if (!SizeConstraints()) { DecodeGeneral(b, bitsDecoded); } else if (SizeConstraints()->upperBoundExists == 0) { for (unsigned int i = 0; i < SizeConstraints()->lowerBound; i++) append()->PDec(b, bitsDecoded); } else if (SizeConstraints()->upperBoundExists == 1) { long tempRange = SizeConstraints()->upperBound - SizeConstraints()->lowerBound; int minBitsNeeded = 0; int minBytesNeeded = 0; long decodeSize = 0; unsigned char *pStr; while (tempRange > 0) { tempRange -= (long)(1 << minBitsNeeded); minBitsNeeded += 1; } minBytesNeeded = minBitsNeeded / 8; minBitsNeeded = minBitsNeeded % 8; bitsDecoded += b.OctetAlignRead(); if (minBytesNeeded > 0) { pStr = b.GetBits(8); bitsDecoded += 8; decodeSize <<= 8; decodeSize |= (long)pStr[0]; delete [] pStr; } pStr = b.GetBits(minBitsNeeded); bitsDecoded += minBitsNeeded; if (minBitsNeeded > 0) { decodeSize <<= minBitsNeeded; pStr[0] >>= (8 - minBitsNeeded); decodeSize |= (long)pStr[0]; } decodeSize += SizeConstraints()->lowerBound; bitsDecoded += b.OctetAlignRead(); for (int i = 0; i < decodeSize; i++) append()->PDec(b, bitsDecoded); delete [] pStr; } else { bitsDecoded += b.OctetAlignRead(); SNACC::AsnInt listLen; listLen.PDec(b, bitsDecoded); bitsDecoded += b.OctetAlignRead(); int tempLen = listLen + SizeConstraints()->lowerBound; for (int i = 0; i < tempLen; i++) append()->PDec(b, bitsDecoded); } } template char* AsnList::checkSOfSingleVal(long m_SingleVal) const { char* pError = NULL; if (this->size() != m_SingleVal) { char cTmperr[200]; sprintf(cTmperr, "_______\nList--SingleValue Constraints:\n_______\nError: --Invalid Number of Elements in List--\nNumber of Elements: %d must match the Constraint Single Value: %d \n", this->size(), m_SingleVal); pError = strdup(cTmperr); } return pError; } template char* AsnList::checkSOfVRange(long m_Lower, long m_Upper) const { char* pError = NULL; if (this->size() < m_Lower) { char cTmperr[200]; sprintf(cTmperr, "_______\nList--Valuerange Constraints:\n_______\nError: --Not Enough Elements In List--\nNumber of Elements: %d is below the Lower Limit: %d \n", this->size(), m_Lower); pError = strdup(cTmperr); } if (this->size() > m_Upper) { char cTmperr[200]; sprintf(cTmperr, "_______\nList--Valuerange Constraints:\n_______\nError: --Too Many Elements In List--\nNumber of Elements: %d is above the Upper Limit: %d \n", this->size(), m_Upper); pError = strdup(cTmperr); } return pError; } template int AsnList::checkConstraints(SNACC::ConstraintFailList* pConstraintFails) const { for (typename AsnList::const_iterator i = this->begin(); i != this->end(); ++i) i->checkConstraints(pConstraintFails); return 0; } template SNACC::AsnLen AsnList::BEncContent(SNACC::AsnBuf& b) const { SNACC::AsnLen sum = 0; for (typename AsnList::const_reverse_iterator i = this->rbegin(); i != this->rend(); ++i) sum += i->BEnc(b); return sum; } template void AsnList::BDecContent(const SNACC::AsnBuf& b, SNACC::AsnTag , SNACC::AsnLen elmtLen, SNACC::AsnLen& bytesDecoded) { SNACC::AsnLen localBytesDecoded = 0; while ((elmtLen == INDEFINITE_LEN) || (localBytesDecoded < elmtLen)) { if (elmtLen == INDEFINITE_LEN) { if (b.PeekByte() == EOC_TAG_ID) { SNACC::BDecEoc(b, localBytesDecoded); break; } } append()->BDec(b, localBytesDecoded); } bytesDecoded += localBytesDecoded; } // AsnList::BDecContent() // template void AsnList::Print(std::ostream& os, unsigned short indent) const { os << "OF "; ++indent; if (this->empty()) os << "is EMPTY\n"; else { os << this->front().typeName() << " \n"; for (typename AsnList::const_iterator i = this->begin(); i != this->end(); ++i) { SNACC::Indent(os, indent); i->Print(os, indent); } SNACC::Indent(os, --indent); } os << "}\n"; } // AsnList::Print() template void AsnList::PrintXML(std::ostream& os, const char* lpszTitle) const { if (this->empty()) os << "-- Void --\n"; else { //os << "<" << first->elmt->typeName() << ">" << endl; for (typename AsnList::const_iterator i = this->begin(); i != this->end(); ++i) i->PrintXML(os, lpszTitle); //os << "elmt->typeName() << ">" << endl; } } // AsnList::PrintXML() ////////////////////////// // AsnSeqOf template // //////////////////////// template #if (_MSC_VER <= 1200) // 6.0 or earlier class SNACCDLL_API AsnSeqOf : public AsnList #else class AsnSeqOf : public AsnList #endif { public: SNACC::AsnLen BEnc(SNACC::AsnBuf &b) const; void BDec(const SNACC::AsnBuf &b, SNACC::AsnLen &bytesDecoded); void Print(std::ostream& os, unsigned short indent = 0) const; void PrintXML(std::ostream& os, const char* lpszTitle = NULL) const; //virtual int checkConstraints(ConstraintFailList* pConstraintFails)const; }; ////////////////////////// // AsnSeqOf template // // CODE // //////////////////////// template SNACC::AsnLen AsnSeqOf::BEnc(SNACC::AsnBuf& b) const { SNACC::AsnLen l = this->BEncContent(b); l += SNACC::BEncDefLen(b, l); l += BEncTag1(b, SNACC::UNIV, SNACC::CONS, SNACC::SEQ_TAG_CODE); return l; } template void AsnSeqOf::BDec(const SNACC::AsnBuf& b, SNACC::AsnLen& bytesDecoded) { // Clear the existing contents this->clear(); SNACC::AsnTag tagId = SNACC::BDecTag(b, bytesDecoded); if (tagId != MAKE_TAG_ID (SNACC::UNIV, SNACC::CONS, SNACC::SEQ_TAG_CODE)) { throw SNACC::InvalidTagException(this->typeName(), tagId, __FILE__, __LINE__, "AsnSeqOf:BDec()"); } SNACC::AsnLen elmtLen; elmtLen = SNACC::BDecLen(b, bytesDecoded); this->BDecContent(b, tagId, elmtLen, bytesDecoded); } template void AsnSeqOf::Print(std::ostream& os, unsigned short indent) const { os << "{ -- " << this->typeName() << " SEQUENCE OF "; ++indent; if (this->empty()) os << "is EMPTY\n"; else { os << this->front().typeName() << " \n"; for (typename AsnSeqOf::const_iterator i = this->begin(); i != this->end(); ++i) { SNACC::Indent(os, indent); i->Print(os, indent); } SNACC::Indent(os, --indent); } os << "}\n"; } template void AsnSeqOf::PrintXML(std::ostream& os, const char* lpszTitle) const { if (lpszTitle) { os << "<" << lpszTitle; os << " typeName=\"" << this->typeName() << "\""; } else os << "<" << this->typeName(); os << " type=\"SEQUENCE_OF\">\n"; AsnList::PrintXML(os, lpszTitle); if (lpszTitle) os << ""; else os << "typeName() << ">"; } //////////////////////// // AsnSetOf template // ////////////////////// template #if (_MSC_VER <= 1200) // 6.0 or earlier class SNACCDLL_API AsnSetOf : public AsnList #else class AsnSetOf : public AsnList #endif { public: SNACC::AsnLen PEnc(SNACC::AsnBufBits& b) const; SNACC::AsnLen BEnc(SNACC::AsnBuf& b) const; SNACC::AsnLen BEncContent(SNACC::AsnBuf& b) const; void BDec(const SNACC::AsnBuf& b, SNACC::AsnLen& bytesDecoded); void PDec(SNACC::AsnBufBits& b, SNACC::AsnLen& bitsDecoded); void Print(std::ostream& os, unsigned short indent = 0) const; void PrintXML(std::ostream& os, const char* lpszTitle = NULL) const; //virtual int checkCosntraints(ConstraintFailList* pConstraintFails); }; //////////////////////// // AsnSetOf template // // CODE // ////////////////////// template SNACC::AsnLen AsnSetOf::BEnc(SNACC::AsnBuf& b) const { SNACC::AsnLen l = BEncContent(b); l += SNACC::BEncDefLen(b, l); l += BEncTag1(b, SNACC::UNIV, SNACC::CONS, SNACC::SET_TAG_CODE); return l; } template SNACC::AsnLen AsnSetOf::BEncContent(SNACC::AsnBuf& b) const { SNACC::AsnLen totalLen = BEncEocIfNec(b); // Encode each component of the SET OF into the AsnBuf list; std::list bufList; for (typename AsnSetOf::const_iterator i = this->begin(); i != this->end(); ++i) { SNACC::AsnBuf& bufRef = *bufList.insert(bufList.end(), SNACC::AsnBuf()); totalLen += i->BEnc(bufRef); } // Sort array of AsnBuf according to DER rules for SET OF // bufList.sort(); std::list::reverse_iterator ri; for (ri = bufList.rbegin(); ri != bufList.rend(); ++ri) b.splice(*ri); return totalLen; } template void AsnSetOf::BDec(const SNACC::AsnBuf& b, SNACC::AsnLen& bytesDecoded) { // Clear the existing elements this->clear(); SNACC::AsnTag tagId = SNACC::BDecTag(b, bytesDecoded); if (tagId != MAKE_TAG_ID (SNACC::UNIV, SNACC::CONS, SNACC::SET_TAG_CODE)) { throw SNACC::InvalidTagException(this->typeName(), tagId, __FILE__,__LINE__,"AsnSetOf::BDec()"); } SNACC::AsnLen elmtLen; elmtLen = SNACC::BDecLen(b, bytesDecoded); this->BDecContent(b, tagId, elmtLen, bytesDecoded); } // // template void AsnSetOf::PDec(SNACC::AsnBufBits& b, SNACC::AsnLen& bitsDecoded) { // Clear the existing elements this->clear(); SNACC::AsnInt intSetOfLength; intSetOfLength.PDec(b, bitsDecoded); for (int i = 0; i < intSetOfLength; i++) this->append()->PDec(b, bitsDecoded); } template SNACC::AsnLen AsnSetOf::PEnc(SNACC::AsnBufBits& b) const { SNACC::AsnInt intSetOfLength(this->size()); intSetOfLength.PEnc(b); SNACC::AsnLen totalLen = 0; std::list bufList; // Encode each component of the SET OF into the AsnBuf list for (typename AsnSetOf::const_iterator i = this->begin(); i != this->end(); ++i) { SNACC::AsnBufBits& bufRef = *bufList.insert(bufList.end(), SNACC::AsnBufBits(b.IsAligned())); totalLen += i->PEnc(bufRef); } bufList.sort(); std::list::iterator iBuf; for (iBuf = bufList.begin(); iBuf != bufList.end(); ++iBuf) iBuf->AppendTo(b); return totalLen; } // end of AsnSetOf::PEnc() template void AsnSetOf::Print(std::ostream& os, unsigned short indent) const { os << "{ -- " << this->typeName() << " SET OF "; ++indent; if (this->empty()) os << "is EMPTY\n"; else { os << this->front().typeName() << " \n"; for (typename AsnSetOf::const_iterator i = this->begin(); i != this->end(); ++i) { SNACC::Indent(os, indent); i->Print(os, indent); } SNACC::Indent(os, --indent); } os << "}\n"; } template void AsnSetOf::PrintXML(std::ostream& os, const char* lpszTitle) const { if (lpszTitle) { os << "<" << lpszTitle; os << " typeName=\"" << this->typeName() << "\""; } else os << "<" << this->typeName(); os << " type=\"SET_OF\">"; AsnList::PrintXML(os); if (lpszTitle) os << ""; else os << "typeName() << ">"; } /* template int ListsEquiv (AsnList& l1, AsnList& l2) { if (l1.Count() != l2.Count()) return false; l1.SetCurrToFirst(); l2.SetCurrToFirst(); for (; l1.Curr() != NULL; l1.GoNext(), l2.GoNext()) { if (*l1.Curr() != *l2.Curr()) { return false; } } return true; } */ #endif // SNACC_ASN_LISTSET_H esnacc-ng-1.8.1/cxx-lib/inc/asn-usefultypes.h000066400000000000000000000040551302010526100210100ustar00rootroot00000000000000 _BEGIN_SNACC_NAMESPACE class SNACCDLL_API EXTERNALChoice: public AsnType { public: enum ChoiceIdEnum { NoChoiceCid=-1, single_ASN1_typeCid = 0, octet_alignedCid = 1, arbitraryCid = 2 }; enum ChoiceIdEnum choiceId; union { void * NoChoice; AsnOcts *single_ASN1_type; AsnOcts *octet_aligned; AsnBits *arbitrary; }; EXTERNALChoice() {Init();} EXTERNALChoice(const EXTERNALChoice& that); public: void Init(void); virtual ~EXTERNALChoice() {Clear();} void Clear(); AsnType* Clone() const { return new EXTERNALChoice(*this); } const char* typeName() const { return "EXTERNALChoice"; } EXTERNALChoice &operator = (const EXTERNALChoice &that); AsnLen BEncContent (AsnBuf &b) const; void BDecContent (const AsnBuf &b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded/*, s env*/); AsnLen BEnc (AsnBuf &b) const; void BDec (const AsnBuf &b, AsnLen &bytesDecoded/*, s env*/); AsnLen PEnc (AsnBufBits &b) const; void Print(std::ostream& os, unsigned short indent = 0) const; void PrintXML (std::ostream &os, const char *lpszTitle=NULL) const; }; class SNACCDLL_API EXTERNAL: public AsnType { public: AsnOid *direct_reference; AsnInt *indirect_reference; ObjectDescriptor *data_value_descriptor; EXTERNALChoice *encoding; EXTERNAL() {Init();} void Init(void); virtual ~EXTERNAL() {Clear();} void Clear(); EXTERNAL(const EXTERNAL& that); public: AsnType* Clone() const { return new EXTERNAL(*this); } const char* typeName() const { return "EXTERNAL"; } EXTERNAL &operator = (const EXTERNAL &that); AsnLen BEncContent (AsnBuf &b) const; void BDecContent (const AsnBuf &b, AsnTag tag, AsnLen elmtLen, AsnLen &bytesDecoded/*, s env*/); AsnLen BEnc (AsnBuf &b) const; void BDec (const AsnBuf &b, AsnLen &bytesDecoded/*, s env*/); AsnLen PEnc (AsnBufBits &b) const; void Print(std::ostream& os, unsigned short indent = 0) const; void PrintXML (std::ostream &os, const char *lpszTitle=NULL) const; }; _END_SNACC_NAMESPACE esnacc-ng-1.8.1/cxx-lib/inc/init.h000066400000000000000000000007251302010526100166040ustar00rootroot00000000000000/* * file: .../c++-lib/inc/init.h * * $Header: /baseline/SNACC/c++-lib/inc/init.h,v 1.1.1.1 2000/08/21 20:36:12 leonberp Exp $ * $Log: init.h,v $ * Revision 1.1.1.1 2000/08/21 20:36:12 leonberp * First CVS Version of SNACC. * * Revision 1.1 1995/07/27 09:22:35 rj * new file: .h file containing a declaration for a function defined in a C++ file, but with C linkage. * */ extern #ifdef __cplusplus "C" #endif int Snacc_Init (Tcl_Interp *interp); esnacc-ng-1.8.1/cxx-lib/inc/meta.h000066400000000000000000000156341302010526100165740ustar00rootroot00000000000000// file: .../c++-lib/inc/meta.h // // $Header: /baseline/SNACC/c++-lib/inc/meta.h,v 1.3 2004/02/09 20:38:19 nicholar Exp $ // $Log: meta.h,v $ // Revision 1.3 2004/02/09 20:38:19 nicholar // Updated AsnOid and AsnRelativeOid classes // // Revision 1.2 2001/07/12 19:33:33 leonberp // Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. // // Revision 1.1.1.1 2000/08/21 20:36:12 leonberp // First CVS Version of SNACC. // // Revision 1.6 1997/02/28 13:39:43 wan // Modifications collected for new version 1.3: Bug fixes, tk4.2. // // Revision 1.5 1995/09/07 18:50:04 rj // long int replaced by newly introduced AsnIntType. // it shall provide a 32 bit integer type on all platforms. // // Revision 1.4 1995/08/17 15:23:47 rj // introducing an AsnEnumTypeDesc class SNACCDLL_API with its own TclGetDesc2 function that returns the value names but omits the numeric values. // utility function AsnSe_TypeDesc::mandatmemberr added. // #include #include struct AsnNameDesc { const char *const name; const AsnIntType value; }; struct AsnTypeDesc; struct AsnMemberDesc // description of CHOICE member; base class SNACCDLL_API for AsnSe_MemberDesc { const char *const name; const AsnTypeDesc *const desc; AsnMemberDesc (const char *, const AsnTypeDesc *); AsnMemberDesc(); #if TCL virtual int TclGetDesc (Tcl_DString *) const; virtual int TclGetDesc2 (Tcl_DString *) const; #endif }; struct AsnSe_MemberDesc: AsnMemberDesc // _ == t/quence; description of SET or SEQUENCE member { bool optional; AsnSe_MemberDesc (const char *, const AsnTypeDesc *, bool); AsnSe_MemberDesc(); #if TCL int TclGetDesc2 (Tcl_DString *) const; #endif }; typedef AsnMemberDesc AsnChoiceMemberDesc; typedef AsnSe_MemberDesc AsnSetMemberDesc; typedef AsnSe_MemberDesc AsnSequenceMemberDesc; struct AsnModuleDesc; class SNACCDLL_API AsnType; struct AsnTypeDesc { const AsnModuleDesc *module; const char *const name; // NULL for basic types const bool pdu; const enum Type // NOTE: keep this enum in sync with the typenames[] { VOID, ALIAS, INTEGER, REAL, NUL_, // sic! (can't fight the ubiquitous NULL #define) BOOLEAN, ENUMERATED, BIT_STRING, OCTET_STRING, OBJECT_IDENTIFIER, RELATIVE_OID, SET, SEQUENCE, SET_OF, SEQUENCE_OF, CHOICE, ANY } type; AsnType *(*create)(); static const char *const typenames[]; AsnTypeDesc (const AsnModuleDesc *, const char *, bool ispdu, Type, AsnType *(*create)()); virtual const AsnModuleDesc *getmodule() const; virtual const char *getname() const; virtual bool ispdu() const; virtual Type gettype() const; virtual const AsnNameDesc *getnames() const; //virtual const AsnMemberDesc *getmembers() const; #if TCL virtual int TclGetDesc (Tcl_DString *) const; virtual int TclGetDesc2 (Tcl_DString *) const; #endif }; struct AsnNamesTypeDesc: AsnTypeDesc { const AsnNameDesc *const names; AsnNamesTypeDesc (const AsnModuleDesc *, const char *, bool ispdu, Type, AsnType *(*create)(), const AsnNameDesc *); const AsnNameDesc *getnames() const; #if TCL int TclGetDesc (Tcl_DString *) const; // for BIT STRING and INTEGER, ENUMERATED has its own: int TclGetDesc2 (Tcl_DString *) const; #endif }; struct AsnEnumTypeDesc: AsnNamesTypeDesc { AsnEnumTypeDesc (const AsnModuleDesc *, const char *, bool ispdu, Type, AsnType *(*create)(), const AsnNameDesc *); #if TCL int TclGetDesc2 (Tcl_DString *) const; #endif }; struct AsnMembersTypeDesc: AsnTypeDesc { AsnMembersTypeDesc (const AsnModuleDesc *, const char *, bool ispdu, Type, AsnType *(*create)()); #if TCL int TclGetDesc (Tcl_DString *) const; #endif }; struct AsnChoiceTypeDesc: AsnMembersTypeDesc { const AsnChoiceMemberDesc *const members; AsnChoiceTypeDesc (const AsnModuleDesc *, const char *, bool ispdu, Type, AsnType *(*create)(), const AsnChoiceMemberDesc *); int choicebyname (const char *name) const; const char *choicebyvalue (int value) const; #if TCL int TclGetDesc2 (Tcl_DString *) const; #endif }; struct AsnSe_TypeDesc: AsnMembersTypeDesc { const AsnSe_MemberDesc *const members; AsnSe_TypeDesc (const AsnModuleDesc *, const char *, bool ispdu, Type, AsnType *(*create)(), const AsnSe_MemberDesc *); #if TCL int mandatmemberr (Tcl_Interp *interp, const char *membername) const; int TclGetDesc2 (Tcl_DString *) const; #endif }; struct AsnListTypeDesc: AsnTypeDesc { const AsnTypeDesc *const base; AsnListTypeDesc (const AsnModuleDesc *, const char *, bool ispdu, Type, AsnType *(*create)(), const AsnTypeDesc *); #if TCL int TclGetDesc (Tcl_DString *) const; #endif }; struct AsnAliasTypeDesc: AsnTypeDesc { const AsnTypeDesc *const alias; AsnAliasTypeDesc (const AsnModuleDesc *, const char *, bool ispdu, Type, AsnType *(*create)(), const AsnTypeDesc *); const AsnModuleDesc *getmodule() const; const char *getname() const; bool ispdu() const; Type gettype() const; const AsnNameDesc *getnames() const; //const AsnMemberDesc *getmembers() const; #if TCL int TclGetDesc (Tcl_DString *) const; #endif }; typedef AsnTypeDesc AsnRealTypeDesc; typedef AsnTypeDesc AsnNullTypeDesc; typedef AsnTypeDesc AsnBoolTypeDesc; typedef AsnNamesTypeDesc AsnIntTypeDesc; typedef AsnNamesTypeDesc AsnBitsTypeDesc; typedef AsnTypeDesc AsnOctsTypeDesc; typedef AsnTypeDesc AsnOidTypeDesc; typedef AsnTypeDesc AsnRelativeOidTypeDesc; typedef AsnSe_TypeDesc AsnSetTypeDesc; typedef AsnSe_TypeDesc AsnSequenceTypeDesc; struct AsnModuleDesc { const char *const name; const AsnTypeDesc **const types; }; extern const AsnModuleDesc *asnModuleDescs[]; #if TCL //\[sep]---------------------------------------------------------------------------------------------------------------------------- // designed to be used with Tcl_SplitList(): argument list that automagically frees itself when it goes out of scope: struct Args { int c; char **v; Args(); virtual ~Args(); }; //\[sep]---------------------------------------------------------------------------------------------------------------------------- // file that automagically closes itself when it goes out of scope: struct TmpFD { int fd; TmpFD() { fd = -1; } TmpFD (int _fd) { fd = _fd; } ~TmpFD() { if (fd > 0) ::close (fd); } int operator = (int _fd){ return fd = _fd; } // operator int() { return fd; } }; //\[sep]---------------------------------------------------------------------------------------------------------------------------- // hack to cope with Tcl's inability to handle binary strings: extern int debinify (Tcl_Interp *interp, const char *in, size_t len); extern int binify (Tcl_Interp *interp, const char *str, char *buf, size_t *len); //\[sep]---------------------------------------------------------------------------------------------------------------------------- #endif /* TCL */ esnacc-ng-1.8.1/cxx-lib/inc/snaccdll.h000066400000000000000000000014741302010526100174260ustar00rootroot00000000000000 // The following ifdef block is the standard way of creating macros which make exporting // from a DLL simpler. All files within this DLL are compiled with the SNACCDLL_EXPORTS // symbol defined on the command line. this symbol should not be defined on any project // that uses this DLL. This way any other project whose source files include this file see // SNACCDLL_API functions as being imported from a DLL, wheras this DLL sees symbols // defined with this macro as being exported. #ifdef SNACCDLL_EXPORTS #define SNACCDLL_API __declspec(dllexport) #else #define SNACCDLL_API __declspec(dllimport) #endif // This class is exported from the snaccDLL.dll class SNACCDLL_API CSnaccDLL { public: CSnaccDLL(void); // TODO: add your methods here. }; extern SNACCDLL_API int nSnaccDLL; SNACCDLL_API int fnSnaccDLL(void); esnacc-ng-1.8.1/cxx-lib/inc/snaccexcept.h000066400000000000000000000131601302010526100201360ustar00rootroot00000000000000// FILE: asnexcept.h // #ifndef _SNACCEXCEPT_H_ #define _SNACCEXCEPT_H_ #ifdef WIN32 #if defined(_MSC_VER) #pragma warning(disable: 4514) #pragma warning(push,3) #endif #include #if defined(_MSC_VER) #pragma warning(pop) #endif #else #include #endif #include "asn-config.h" #define STACK_DEPTH 20 #define STACK_ENTRY __FILE__,__LINE__,_func #define FUNC(_funcStr) const char *_func = _funcStr; #define EXCEPT(_what, _err) SNACC::SnaccException(STACK_ENTRY, _what, _err) #define SNACC_EXCEPT(_what) SNACC::SnaccException(STACK_ENTRY, _what) #define SNACC_MEMORY_EXCEPT(s,v) SNACC::MemoryException(s,v,STACK_ENTRY) #define DEFAULT_ERROR_CODE -256 _BEGIN_SNACC_NAMESPACE // SNACC ERROR CODES #define ERRBASE 6000 #define SNACC_OK 0 #define MEMORY_ERROR (ERRBASE + 1) // Memory allocation failed #define BOUNDS_ERROR (ERRBASE + 2) // Length of object is invalid #define INVALID_TAG (ERRBASE + 3) // Invalid ASN.1 Tag for object #define INVALID_ANY (ERRBASE + 4) // Invalid ANY #define DECODE_ERROR (ERRBASE + 5) // Decoded past end of data #define RESTRICTED_TYPE_ERROR (ERRBASE + 6) // Restricted type check failed #define INTEGER_ERROR (ERRBASE + 7) // Integer related errors #define PARAMETER_ERROR (ERRBASE + 8) // Invalid parameter #define OID_ERROR (ERRBASE + 9) // OID related error #define FILE_IO_ERROR (ERRBASE + 10) // File error #define BUFFER_ERROR (ERRBASE + 11) // Buffer error #define ENCODE_ERROR (ERRBASE + 12) // General encode error #define CONSTRAINT_ERROR (ERRBASE + 13) //Constraint out of range enum ConstraintErrorCode{ INTEGER_VALUE_RANGE = 0, INTEGER_SINGLE_VALUE, STRING_SIZE_SINGLE_VALUE, STRING_SIZE_VALUE_RANGE, STRING_PERMITTED_ALPHA, STRING_NORMAL_ALPHA, WIDE_STRING_SIZE_SINGLE_VALUE, WIDE_STRING_SIZE_VALUE_RANGE, WIDE_STRING_PERMITTED_ALPHA, WIDE_STRING_NORMAL_ALPHA, OCTS_SIZE_SINGLE_VALUE, OCTS_SIZE_VALUE_RANGE, BITS_SIZE_SINGLE_VALUE, BITS_SIZE_VALUE_RANGE, SET_OF_SIZE_SINGLE_VALUE, SET_OF_SIZE_VALUE_RANGE, SEQ_OF_SIZE_SINGLE_VALUE, SEQ_OF_SIZE_VALUE_RANGE }; extern const char *ConstraintErrorStringList[]; typedef struct _CallStack { const char *file; const char *function; long line_number; } CallStack; class SNACCDLL_API SnaccException: public std::exception { public: SnaccException(long errorCode=SNACC_OK) throw(); SnaccException(const char *file, long line_number, const char *function=NULL, const char *whatStr=NULL, long errorCode=DEFAULT_ERROR_CODE) throw(); virtual const char * what() const throw(); void push(const char *file, long line_number, const char *function=NULL) throw(); virtual ~SnaccException() throw(); virtual void getCallStack(std::ostream &os) const; const CallStack * getCallStack(void) const { return stack; } SnaccException & operator=(const SnaccException &o); short getStackPos() { return stackPos; } long m_errorCode; protected: // first element in array is populated by the constructor. All other // elements in the array are populated by push(). // short stackPos; CallStack stack[STACK_DEPTH]; std::string m_whatStr; }; class SNACCDLL_API InvalidTagException : public SnaccException { public: InvalidTagException(const char *type, long tagId, const char *file, long line_number, const char *function) throw(); virtual const char * what(void) const throw(); private: char wrongTagInfo[128]; }; class SNACCDLL_API FileException : public SnaccException { public: enum FileErrType {OPEN=1, CREATE, READ, WRITE}; FileException(const char *fileName, enum FileErrType errType, const char *file, long line_number, const char *function) throw(); virtual const char * what(void) const throw(); private: char whatStr[512]; }; class SNACCDLL_API MemoryException : public SnaccException { public: MemoryException(long memorySize, const char *variable, const char *file, long line_number, const char *function) throw(); const char *what() const throw(); private: char memoryInfo[128]; }; class SNACCDLL_API BoundsException : public SnaccException { public: BoundsException(const char *whatStr, const char *file, long line_number, const char *function) throw() :SnaccException(file, line_number, function, whatStr, BOUNDS_ERROR) {}; }; class SNACCDLL_API DecodeException : public SnaccException { public: DecodeException(const char *file, long line_number, const char *function) throw() :SnaccException(file, line_number, function, "Decode past end of data", DECODE_ERROR) {}; }; class SNACCDLL_API ParameterException : public SnaccException { public: ParameterException(const char *whatStr, const char *file, long line_number, const char *function) throw() :SnaccException(file, line_number, function, whatStr, PARAMETER_ERROR) {}; }; class SNACCDLL_API OidException : public SnaccException { public: OidException (const char *whatStr, const char *file, long line_number, const char *function) throw() :SnaccException(file, line_number, function, whatStr, OID_ERROR) {}; }; class SNACCDLL_API BufferException : public SnaccException { public: BufferException (const char *whatStr, const char *file, long line_number, const char *function) throw() :SnaccException(file, line_number, function, whatStr, BUFFER_ERROR) {}; }; class SNACCDLL_API ConstraintException : public SnaccException { public: ConstraintException (const char *whatStr, const char *file, long line_number, const char *function) throw() :SnaccException(file, line_number, function, whatStr, CONSTRAINT_ERROR) {}; }; _END_SNACC_NAMESPACE #endif // _SNACCEXCEPT_H_ esnacc-ng-1.8.1/cxx-lib/inc/tcl-if.h000066400000000000000000000041651302010526100170210ustar00rootroot00000000000000// file: .../c++-lib/inc/tcl-if.h // // $Header: /baseline/SNACC/c++-lib/inc/tcl-if.h,v 1.1.1.1 2000/08/21 20:36:12 leonberp Exp $ // $Log: tcl-if.h,v $ // Revision 1.1.1.1 2000/08/21 20:36:12 leonberp // First CVS Version of SNACC. // // Revision 1.5 1997/01/01 23:27:22 rj // `typename' appears to be a reserved word in gcc 2.7, so prefix it with `_' // // Revision 1.4 1995/09/07 18:50:34 rj // duplicate code merged into a new function SnaccTcl::gettypedesc(). // // Revision 1.3 1995/08/17 15:06:43 rj // snacced.[hC] renamed to tcl-if.[hC]. // class SNACCDLL_API SnaccEd renamed to SnaccTcl. // // Revision 1.2 1995/07/27 09:53:25 rj // comment leader fixed // // Revision 1.1 1995/07/27 09:52:12 rj // new file: tcl interface used by snacced. #ifdef DEBUG #include #endif class SNACCDLL_API SnaccTcl { Tcl_Interp *interp; Tcl_HashTable modules, types, files; Tcl_HashEntry *create(); const AsnTypeDesc *gettypedesc (const char *cmdname, const char *type_name); public: SnaccTcl (Tcl_Interp *); ~SnaccTcl(); int create (int argc, char **argv); int openfile (int argc, char **argv); int finfo (int argc, char **argv); int read (int argc, char **argv); int write (int argc, char **argv); int closefile (int argc, char **argv); int modulesinfo (int argc, char **argv); int typesinfo (int argc, char **argv); int typeinfo (int argc, char **argv); int info (int argc, char **argv); int getval (int argc, char **argv); int setval (int argc, char **argv); int unsetval (int argc, char **argv); int test (int argc, char **argv); #ifdef DEBUG void ckip (Tcl_Interp *i) { assert (i == interp); } #endif }; class SNACCDLL_API ASN1File { const AsnTypeDesc *type; AsnType *pdu; char *fn; int fd; off_t filesize; public: ASN1File (const AsnTypeDesc *); ASN1File (const AsnTypeDesc *, const char *fn, int fd); virtual ~ASN1File(); bool bad(); operator AsnType * () { return pdu; } int finfo (Tcl_Interp *); int read (Tcl_Interp *, const char *fn=NULL); int write (Tcl_Interp *, const char *fn=NULL); }; esnacc-ng-1.8.1/cxx-lib/libesnaccxx.pc.in000066400000000000000000000005001302010526100201420ustar00rootroot00000000000000# Enhanced SNACC pkg-config source file PREFIX=@prefix@ EXEC_PREFIX=@exec_prefix@ LIBDIR=@libdir@ INCLUDEDIR=@includedir@ Name: libesnaccxx Description: Enhanced SNACC Compiler development support and libs for C++ Version: @VERSION@ Requires: Conflicts: Libs: -L${LIBDIR} -lcxxasn1 Cflags: -I${INCLUDEDIR}/cxx-lib/inc esnacc-ng-1.8.1/cxx-lib/readme000066400000000000000000000020451302010526100160740ustar00rootroot00000000000000(RCS control information is at the end of this file.) C++ ASN.1 library README ------------------------ This directory contains the class definitions and the encode, decode, free and print methods for all of the built-in ASN.1 types. It also contains buffer routines. The makefile will produce one or two libraries, libasn1c++.a and libasn1tcl.a. Whether the tcl library is to be generated or not is determined at configuration time. In addition to the normal C++ libraries contents, the Tcl library contains the meta code and the Tcl interface described in the documentation. #------------------------------------------------------------------------------- # $Header: /baseline/SNACC/c++-lib/readme,v 1.1.1.1 2000/08/21 20:36:08 leonberp Exp $ # $Log: readme,v $ # Revision 1.1.1.1 2000/08/21 20:36:08 leonberp # First CVS Version of SNACC. # # Revision 1.3 1995/07/24 15:45:53 rj # mention meta code and tcl interface and their additional libary. # # Revision 1.2 1994/09/01 00:55:55 rj # textual change to adapt to change of directory tree. # esnacc-ng-1.8.1/cxx-lib/src/000077500000000000000000000000001302010526100155025ustar00rootroot00000000000000esnacc-ng-1.8.1/cxx-lib/src/asn-PERGeneral.cpp000066400000000000000000000063451302010526100207210ustar00rootroot00000000000000#include "asn-incl.h" #ifdef WIN32 #if defined(_MSC_VER) #pragma warning(disable: 4100 4710 4251 4018) #pragma warning(push,3) #endif #include #if defined(_MSC_VER) #pragma warning(pop) #endif #else #include #endif #include _BEGIN_SNACC_NAMESPACE AsnLen PERGeneral::EncodeGeneral(AsnBufBits &b)const { AsnLen len = 0; unsigned long l_64kFrag = l_16k * 4; unsigned long count = 0; unsigned long x = 0; unsigned long y = 0; unsigned long tempLen = lEncLen(); unsigned char ch = 0x00; unsigned char *c = NULL; long offset = 0; if(tempLen >= l_16k) { /*there is more than 16k bytes of data*/ count = (tempLen / l_64kFrag); for(x=0; x < count; x++) { len += b.OctetAlignWrite(); len += PEncLen_16kFragment(b, 4); len += b.OctetAlignWrite(); for(y = 0; y < l_64kFrag; y++) { len += Interpret(b, offset); offset++; } } tempLen -= count * l_64kFrag; count = tempLen / l_16k; if(count != 0) { len += b.OctetAlignWrite(); len += PEncLen_16kFragment(b, count); len += b.OctetAlignWrite(); for(y = 0; y < (l_16k * count); y++) { len += Interpret(b, offset); offset++; } } tempLen -= (l_16k * count); if(tempLen == 0) { ch = 0x00; c = &ch; len += b.OctetAlignWrite(); len += b.PutBits(c, 8); return len; } } /*if there are less than 128 bytes of data*/ if(tempLen < 128) { len += b.OctetAlignWrite(); len += PEncDefLenTo127(b, tempLen); len += b.OctetAlignWrite(); for(y = 0; y < tempLen; y++) { len += Interpret(b, offset); offset++; } } else if(tempLen >= 128 && tempLen < l_16k) { len += b.OctetAlignWrite(); /*if there is less than 16k bytes of data*/ /*and more than 127 bytes of data*/ len += PEncLen_1to16k(b, tempLen); len += b.OctetAlignWrite(); for(y = 0; y < tempLen; y++) { len += Interpret(b, offset); offset++; } } return len; } void PERGeneral::DecodeGeneral(AsnBufBits &b, AsnLen &bitsDecoded) { unsigned char* seg; unsigned long templen = 0; long offset = 0; Clear(); bitsDecoded += b.OctetAlignRead(); seg = (unsigned char*)b.GetBits(8); bitsDecoded += 8; while((seg[0] & 0xC0) == 0xC0) { seg[0] &= 0x3F; templen = (unsigned long)seg[0]; templen *= l_16k; Allocate(templen); bitsDecoded += b.OctetAlignRead(); while(templen) { Deterpret(b, bitsDecoded, offset); offset++; templen--; } bitsDecoded += b.OctetAlignRead(); free(seg); seg = (unsigned char*)b.GetBits(8); bitsDecoded += 8; } if((seg[0] & 0xC0) == 0x80) { seg[0] &= 0x3F; templen = (unsigned long)seg[0]; templen <<= 8; free(seg); seg = (unsigned char*)b.GetBits(8); bitsDecoded += 8; templen |= (unsigned long)seg[0]; Allocate(templen); bitsDecoded += b.OctetAlignRead(); while(templen) { Deterpret(b, bitsDecoded, offset); offset++; templen--; } } else if((seg[0] & 0x80) == 0x00) { seg[0] &= 0x7F; templen = (unsigned long)seg[0]; Allocate(templen); bitsDecoded += b.OctetAlignRead(); while(templen) { Deterpret(b, bitsDecoded, offset); offset++; templen--; } } free(seg); } _END_SNACC_NAMESPACE esnacc-ng-1.8.1/cxx-lib/src/asn-RelativeOid.cpp000066400000000000000000000306551302010526100212050ustar00rootroot00000000000000// file: .../c++-lib/src/asn-relativeoid.cpp - RELATIVE OBJECT IDENTIFIER // // Joseph Grone // 14/01/04 // // This library is free software; you can redistribute it and/or // modify it provided that this copyright/license information is retained // in original form. // // If you modify this file, you must clearly indicate your changes. // // This source code is distributed in the hope that it will be // useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // #include "asn-incl.h" #if defined(_MSC_VER) #pragma warning(push, 3) #endif #include #if defined(_MSC_VER) #pragma warning(pop) #endif #include _BEGIN_SNACC_NAMESPACE AsnRelativeOid::~AsnRelativeOid() { if (oid != NULL) delete[] oid; if (m_lpszOidString != NULL) delete[] m_lpszOidString; } AsnRelativeOid::operator const char*() const { if (m_lpszOidString == NULL) createDottedOidStr(); return m_lpszOidString; } bool AsnRelativeOid::operator==(const char* o) const { if (o == NULL) return false; if (m_lpszOidString == NULL) createDottedOidStr(); if (strcmp(m_lpszOidString, o) == 0) return true; else return false; } bool AsnRelativeOid::operator<(const AsnRelativeOid& o) const { if (octetLen < o.octetLen) return true; else if (octetLen > o.octetLen) return false; else return (memcmp(oid, o.oid, octetLen) < 0); } unsigned long int AsnRelativeOid::NumArcs() const { unsigned long numArcs = 0; // For each arc... for (size_t i = 0; i < octetLen; ++i) { // Skip octets in this arc number with the 'more' bit set while ((i < octetLen) && (oid[i] & 0x80)) ++i; ++numArcs; } // If this is not a relative OID, add one to the number of arcs because the // first two arcs are munged together if (!m_isRelative && (numArcs > 0)) ++numArcs; return numArcs; } void AsnRelativeOid::GetOidArray(unsigned long oidArray[]) const { FUNC("AsnRelativeOid::GetOidArray()"); unsigned long iArc = 0; for (size_t i = 0; i < octetLen; ++i) { while ((i < octetLen) && (oid[i] & 0x80)) { oidArray[iArc] <<= 7; oidArray[iArc] |= oid[i++] & 0x7F; } if (i == octetLen) throw OidException("Invalid encoded OID", STACK_ENTRY); oidArray[iArc] <<= 7; oidArray[iArc] |= oid[i] & 0x7F; // If this is not a relative OID and this is the first arc number, // unmunge this arc number if (!m_isRelative && (iArc == 0)) { oidArray[1] = oidArray[0]; oidArray[0] /= 40; if (oidArray[0] > 2) oidArray[0] = 2; oidArray[1] -= oidArray[0] * 40; ++iArc; } ++iArc; } } void AsnRelativeOid::Set(const char* szOidCopy) { FUNC("AsnRelativeOid::Set()"); if (szOidCopy == NULL) throw ParameterException("szOidCopy == NULL", STACK_ENTRY); // Check that the string doesn't begin with a period if (*szOidCopy == '.') throw OidException("Invalid OID string format", STACK_ENTRY); // Parse the string into a vector of long integers std::vector intArray; const char* pIntStr = szOidCopy; while (*pIntStr != '\0') { if (*pIntStr == '.') ++pIntStr; const char* pEnd = pIntStr; while ((*pEnd != '\0') && (*pEnd != '.')) { if ((*pEnd < '0') || (*pEnd > '9')) { throw OidException("Invalid character in OID string.", STACK_ENTRY); } ++pEnd; } if (pEnd == pIntStr) throw OidException("Invalid OID string format", STACK_ENTRY); intArray.push_back((unsigned long)atol(pIntStr)); pIntStr = pEnd; } // Create a temporary array from the vector unsigned long* pTempArray = new unsigned long[intArray.size()]; if (pTempArray == NULL) throw SNACC_MEMORY_EXCEPT(intArray.size() * sizeof(long), "pTempArray"); // Copy the arc numbers into the temporary array for (unsigned int i = 0; i < intArray.size(); ++i) pTempArray[i] = intArray[i]; Set(pTempArray, intArray.size()); delete[] pTempArray; // Copy the string value m_lpszOidString = new char[strlen(szOidCopy) + 1]; if (m_lpszOidString == NULL) throw SNACC_MEMORY_EXCEPT(strlen(szOidCopy) + 1, "m_lpszOidString"); strcpy(m_lpszOidString, szOidCopy); } void AsnRelativeOid::Set(const char* encOid, size_t len) { FUNC("AsnRelativeOid::Set()"); delete[] oid; delete[] m_lpszOidString; m_lpszOidString = NULL; octetLen = len; oid = new char[octetLen]; if (oid == NULL) throw SNACC_MEMORY_EXCEPT(octetLen, "AsnRelativeOid::oid"); memcpy(oid, encOid, octetLen); } void AsnRelativeOid::Set(const AsnRelativeOid& o) { FUNC("AsnRelativeOid::Set()"); if (this != &o) { Set(o.oid, o.octetLen); if (o.m_lpszOidString != NULL) { m_lpszOidString = new char[strlen(o.m_lpszOidString) + 1]; if (m_lpszOidString == NULL) { throw SNACC_MEMORY_EXCEPT(strlen(o.m_lpszOidString) + 1, "AsnRelativeOid::m_lpszOidString"); } strcpy(m_lpszOidString, o.m_lpszOidString); } } } void AsnRelativeOid::Set (unsigned long arcNumArr[], unsigned long arrLength) { FUNC("AsnRelativeOid::Set()"); if ((arcNumArr == NULL) || (arrLength < 1)) { throw ParameterException("Invalid arguments in AsnRelativeOid::Set()", STACK_ENTRY); } char *buf = new char[arrLength * 5]; // Sized according to length char *tmpBuf = buf; // For each arc number... unsigned int totalLen = 0; unsigned int i; for (i = 0; (i < arrLength) && (arcNumArr[i] != (unsigned long)-1); ++i) { unsigned long tmpArcNum = arcNumArr[i]; if ((i == 0) && !m_isRelative) { // If not a relative OID, munge together first oid arc numbers if ((arrLength < 2) || (arcNumArr[1] == (unsigned long)-1)) { throw ParameterException("Invalid parameter to AsnRelativeOid::Set()", STACK_ENTRY); } if (tmpArcNum > 2) { throw OidException("First arc number must be 0, 1, or 2", STACK_ENTRY); } tmpArcNum *= 40; tmpArcNum += arcNumArr[++i]; } // Calculate encoded length for this arc number unsigned long tmpNum = tmpArcNum; unsigned int arcLen = 0; do { ++arcLen; tmpNum >>= 7; } while (tmpNum > 0); // Write the encoded bytes in reverse order -- all bytes except last // have MSB set bool isLast = true; unsigned int j = arcLen; do { tmpBuf[--j] = (char)(tmpArcNum & 0x7F); tmpArcNum >>= 7; if (!isLast) tmpBuf[j] |= 0x80; else isLast = false; } while (j > 0); // Update the total encoded length and the tmpBuf pointer totalLen += arcLen; tmpBuf += arcLen; } // end of for each arc number loop // Set this encoded OID value as the new value Set(buf, totalLen); delete[] buf; } // end of AsnRelativeOid::Set() AsnLen AsnRelativeOid::BEnc(AsnBuf& b) const { AsnLen l = BEncContent(b); l += BEncDefLen(b, l); if (m_isRelative) { l += BEncTag1(b, UNIV, PRIM, RELATIVE_OID_TAG_CODE); } else { l += BEncTag1(b, UNIV, PRIM, OID_TAG_CODE); } return l; } void AsnRelativeOid::BDec(const AsnBuf& b, AsnLen& bytesDecoded) { FUNC("AsnRelativeOid::BDec()"); // Decode the tag AsnTag tagId = BDecTag(b, bytesDecoded); if ((m_isRelative && (tagId != MAKE_TAG_ID(UNIV, PRIM, RELATIVE_OID_TAG_CODE))) || (!m_isRelative && (tagId != MAKE_TAG_ID(UNIV, PRIM, OID_TAG_CODE)))) { throw InvalidTagException(typeName(), tagId, STACK_ENTRY); } AsnLen elmtLen = BDecLen(b, bytesDecoded); BDecContent(b, tagId, elmtLen, bytesDecoded); } AsnLen AsnRelativeOid::BEncContent(AsnBuf& b) const { b.PutSegRvs(oid, octetLen); return octetLen; } void AsnRelativeOid::BDecContent(const AsnBuf& b, AsnTag /* tagId */, AsnLen elmtLen, AsnLen& bytesDecoded) { FUNC("AsnRelativeOid::BDecContent()"); if (elmtLen == INDEFINITE_LEN) throw BoundsException("indefinite length on primitive", STACK_ENTRY); if (elmtLen < 1) throw OidException("invalid length of OID", STACK_ENTRY); delete[] oid; delete[] m_lpszOidString; m_lpszOidString = NULL; octetLen = elmtLen; oid = new char[octetLen]; if (oid == NULL) throw MemoryException(octetLen, "AsnRelativeOid::oid", STACK_ENTRY); b.GetSeg(oid, octetLen); bytesDecoded += elmtLen; } // end of AsnRelativeOid::BDecContent() AsnLen AsnRelativeOid::PEnc(AsnBufBits& b) const { AsnLen len = PEncDefLenTo127(b, octetLen); len += b.OctetAlignWrite(); b.PutBits((unsigned char*)oid, octetLen * 8); len += octetLen * 8; return len; } void AsnRelativeOid::PDec (AsnBufBits &b, AsnLen &bitsDecoded) { unsigned char* seg = b.GetBits(8); bitsDecoded += 8; unsigned long lseg = (unsigned long)seg[0]; delete [] seg; if (lseg > 0) { bitsDecoded += b.OctetAlignRead(); seg = b.GetBits(lseg * 8); bitsDecoded += lseg * 8; Set((const char*)seg, lseg); delete [] seg; } } // Prints an AsnRelativeOid in ASN.1 Value Notation. // Decodes the oid to get the individual arc numbers void AsnRelativeOid::Print(std::ostream& os, unsigned short /*indent*/) const { unsigned long numArcs = NumArcs(); os << "{"; if (numArcs > 0) { unsigned long* arcArray = new unsigned long[numArcs]; for(unsigned long n = 0; n < numArcs; n++) arcArray[n] = 0; GetOidArray(arcArray); for (unsigned long i = 0; i < numArcs; ++i) os << " " << arcArray[i]; delete[] arcArray; } else os << "-- void --"; os << "}"; } // AsnRelativeOid::Print void AsnRelativeOid::PrintXML (std::ostream &os, const char *lpszTitle) const { const char* xmlTag; if (m_isRelative) xmlTag = "RELATIVE-OID"; else xmlTag = "OID"; if (lpszTitle) os << "<" << lpszTitle << " type=\"" << xmlTag << "\">"; else os << '<' << xmlTag << ">\n"; Print(os); if (lpszTitle) os << ""; else os << "\n"; } #if META const AsnRelativeOidTypeDesc AsnRelativeOid::_desc(NULL, NULL, false, AsnTypeDesc::RELATIVE_OID, NULL); const AsnTypeDesc *AsnRelativeOid::_getdesc() const { return &_desc; } #if TCL int AsnRelativeOid::TclGetVal (Tcl_Interp *interp) const { if (oid) { strstream buf; buf << *this; buf.str()[strlen(buf.str())-1] = '\0'; // chop the trailing '}' Tcl_SetResult (interp, buf.str()+1, TCL_VOLATILE); // copy without leading '{' } return TCL_OK; } int AsnRelativeOid::TclSetVal (Tcl_Interp *interp, const char *valstr) { if (!*valstr) { delete[] oid; oid = NULL; octetLen = 0; delete[] m_lpszOidString; m_lpszOidString = NULL; return TCL_OK; } Args arc; if (Tcl_SplitList (interp, (char*)valstr, &arc.c, &arc.v) != TCL_OK) return TCL_ERROR; if (m_isRelative && (arc.c < 1)) { Tcl_AppendResult (interp, "relative oid must contain at least one number", NULL); Tcl_SetErrorCode (interp, "SNACC", "ILLARC", "<1", NULL); return TCL_ERROR; } if (!m_isRelative && (arc.c < 2)) { Tcl_AppendResult (interp, "oid must contain at least two numbers", NULL); Tcl_SetErrorCode (interp, "SNACC", "ILLARC", "<2", NULL); return TCL_ERROR; } unsigned long* pLongArray = new unsigned long[arc.c]; for (int i=0; i 2) firstNum = 2; arcNum -= firstNum * 40; sprintf(tempArcStr, "%ld.%ld", firstNum, arcNum); } else sprintf(tempArcStr, "%ld", arcNum); isFirst = false; } else sprintf(tempArcStr, ".%ld", arcNum); // Append the temporary arc string to the temporary std::string tempBuf.append(tempArcStr); } m_lpszOidString = new char[tempBuf.length() + 1]; strcpy(m_lpszOidString, tempBuf.c_str()); } _END_SNACC_NAMESPACE esnacc-ng-1.8.1/cxx-lib/src/asn-any.cpp000066400000000000000000000432121302010526100175560ustar00rootroot00000000000000// file: .../c++-lib/src/asn-any.C // // MS 92 // Copyright (C) 1992 Michael Sample and the University of British Columbia // // This library is free software; you can redistribute it and/or // modify it provided that this copyright/license information is retained // in original form. // // If you modify this file, you must clearly indicate your changes. // // This source code is distributed in the hope that it will be // useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // // // $Header: /baseline/SNACC/c++-lib/src/asn-any.cpp,v 1.49 2004/03/22 18:30:17 leonberp Exp $ // $Log: asn-any.cpp,v $ // Revision 1.49 2004/03/22 18:30:17 leonberp // Fixed Linux warnings. // // Revision 1.48 2004/03/03 20:19:01 gronej // took out readLoc from choice's BDecContent generation, and made new // put-back logic to put back a tag and a length so you can properly decode // an unkown any // // Revision 1.47 2004/03/02 14:34:01 gronej // added proto for new AsnAny bdeccontent with a tag and a length passed in the parameter list // (only occurs in presence of extension additions) // // Revision 1.46 2004/02/11 19:08:48 nicholar // Updated Print() function so no longer uses global indent // // Revision 1.45 2004/02/04 14:59:27 gronej // Fixed a TON of memory leaks // // Revision 1.44 2003/12/17 19:05:03 gronej // SNACC baseline merged with PER v1_7 tag // // Revision 1.41.2.7 2003/12/04 20:47:10 gronej // Moved bAlign out of all PEnc calls and into AsnBufBits as a member // An AsnBufBits is now invoked with a bAlign parameter defaulted to false // // Revision 1.41.2.6 2003/12/04 16:47:53 colestor // Changed AsnBufBits &m_buf to *m_pbuf for Linux builds to compile. // // Revision 1.41.2.5 2003/12/04 02:59:27 colestor // Added PEnc/PDec functionality for both AsnAny ANY and ANYDefinedBy logic. // Tested! // // Revision 1.41.2.4 2003/12/03 14:17:29 colestor // Added PEnc/PDec for ANYs (untested). // // Revision 1.41.2.3 2003/11/05 14:58:54 gronej // working PER code merged with esnacc_1_6 // // Revision 1.41.2.2 2003/10/22 12:45:58 gronej // Updating PER compiler // // Revision 1.41.2.1 2003/10/02 17:15:24 gronej // Updating PER compiler // // Revision 1.41 2003/04/08 18:21:34 leonberp // changed SM_NO_THREADS to NO_THREADS // // Revision 1.40 2003/03/12 16:20:23 mcphersc // Added SM_NO_THREAD around destroy // // Revision 1.39 2003/01/06 16:20:07 leonberp // Changed BDec() and BDecContent() to use const AsnBufs // // Revision 1.38 2002/12/22 01:20:52 colestor // (RWC)Updated PrintXML(...) details to better match specification for SEQUENCE OF and SET OF logic. // // Revision 1.37 2002/12/17 20:27:40 leonberp // made BEnc() and BEncContent() const // // Revision 1.36 2002/12/12 16:41:04 leonberp // added copy constructor to AsnAny // // Revision 1.35 2002/12/11 21:39:49 leonberp // added call to anyBuf->hexDump() so unkown ANYs will be printed // // Revision 1.34 2002/12/09 20:24:33 leonberp // changed BEnc() to not use splice // // Revision 1.33 2002/12/06 18:10:27 leonberp // fixed bug in AsnBuf copy constructor // // Revision 1.32 2002/12/03 21:27:35 leonberp // renamed AsnBuf::insert to AsnBuf::append // // Revision 1.31 2002/11/25 18:39:48 colestor // (RWC) Updates from testing with Pierce. Specifically, AsnBuf and AsnAny // length updates. // // Revision 1.30 2002/11/25 16:06:27 leonberp // fixed bug in cleanup (destructor code) // // Revision 1.29 2002/11/18 20:58:12 leonberp // removed old comments // // Revision 1.28 2002/11/08 17:28:32 leonberp // fixed bug. anyBuf was not checked for NULL prior to dereferencing // // Revision 1.27 2002/10/23 21:02:48 leonberp // fixed AsnBuf references and fixed clock skew problem // // Revision 1.26 2002/10/23 10:51:10 mcphersc // Changed BUF_TYPE to AsnBuf // // Revision 1.25 2002/10/09 19:37:55 leonberp // new AsnBuf integration // // Revision 1.24 2002/09/17 19:21:06 vracarl // AsnAnyBuffer changes // // Revision 1.23 2002/06/17 16:19:58 nicholar // Changed AsnAny to use int's rather than AsnInt's for ANY DEFINED BY INTEGER's. // // Revision 1.22 2002/06/17 14:53:06 bodins // no message // // Revision 1.21 2002/05/10 16:39:34 leonberp // latest changes for release 2.2 // includes integrating asn-useful into C & C++ runtime library, the compiler changes that go along with that, SnaccException changes for C++ runtime and compiler // // Revision 1.20 2001/11/21 19:23:12 leonberp // changed SetTypeByOid to take a const object // // Revision 1.19 2001/10/24 17:04:25 rwc // AsnAny and IndefiniteLength length determination logic was updated. // // Revision 1.18 2001/10/16 04:26:49 leonberp // added a destructor for the any tables // // Revision 1.17 2001/10/15 18:00:06 leonberp // mem leak fixes // // Revision 1.16 2001/10/15 17:14:19 leonberp // mem leak fixes // // Revision 1.15 2001/10/11 22:26:31 rwc // Newly tested memory leak fixes. // // Revision 1.14 2001/10/09 13:52:30 rwc // Memory leak testing updates. // // Revision 1.13 2001/09/18 12:59:30 nicholar // Fixed bug in AsnAny assignment operator. // // Revision 1.12 2001/08/29 22:04:17 leonberp // enchanced Clone() to allocate a new pointe AND COPY the object // // Revision 1.11 2001/08/29 17:01:47 leonberp // no message // // Revision 1.10 2001/08/27 21:25:40 leonberp // I 'const' enchanced CSM_Buffer and update all code that references it // // Revision 1.9 2001/07/12 19:33:35 leonberp // Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. // // Revision 1.8 2001/07/10 21:03:08 rwc // Removed previous fix by Tex for ANY DEFINED BY logic. // // Revision 1.6 2001/06/28 15:29:48 rwc // ADDED "SNACCASN" namespace definition to all SNACC data structures. // This should not affect most applications since we do not have any name // conflicts. // ALSO, combined all ASN primitive data type includes into asn-incl.h. // // Revision 1.5 2001/06/18 17:47:42 rwc // Updated to reflect newly added C++ Exception error handling, instead of "C" longjmp and setjmp calls. // Changes made to both the compiler and the SNACC C++ run-time library. // // Revision 1.4 2001/04/23 15:37:04 rwc // Further SNACC ANY DEFINED BY update testing fixes (for the SFL). // // Revision 1.3 2001/04/18 16:28:40 rwc // Updated test for ANY DEFINED BY updates. Now supports default CSM_Buffer (AsnAnyBuffer) result if // OID is not recognized. // // Revision 1.2 2001/01/22 20:18:46 rwc // Updates to test newly added ASN.1 XML output. // // Revision 1.1.1.1 2000/08/21 20:36:08 leonberp // First CVS Version of SNACC. // // Revision 1.6 1997/02/28 13:39:43 wan // Modifications collected for new version 1.3: Bug fixes, tk4.2. // // Revision 1.5 1997/02/16 20:26:01 rj // check-in of a few cosmetic changes // // Revision 1.4 1995/07/24 20:12:48 rj // changed `_' to `-' in file names. // // Revision 1.3 1994/10/08 04:18:20 rj // code for meta structures added (provides information about the generated code itself). // // code for Tcl interface added (makes use of the above mentioned meta code). // // virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included. // // made Print() const (and some other, mainly comparison functions). // // several `unsigned long int' turned into `size_t'. // // Revision 1.2 1994/08/28 10:01:10 rj // comment leader fixed. // // Revision 1.1 1994/08/28 09:20:55 rj // first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. #include "asn-incl.h" _BEGIN_SNACC_NAMESPACE SNACCDLL_API Table *AsnAny::oidHashTbl = NULL; SNACCDLL_API Table *AsnAny::intHashTbl = NULL; long SM_DetermineLengthBuf(AsnBuf &SNACCinputBuf, AsnLen elmtLen0, int bFirstTimeFlag=false); long SM_DetermineLengthBuf(AsnBuf &SNACCinputBuf); class AnyTableDestructor { public: ~AnyTableDestructor() { AsnAny::AsnAnyDestroyHashTbls(); } }; static AnyTableDestructor __anyTableDestructor; // Define this ANY value's type to the one that the given id hashes // to in the ANY table. void AsnAny::SetTypeByInt (const AsnInt& id) const { Hash hash; void *anyInfo; /* use int as hash string */ hash = MakeHash ((const char*)id.c_str(), id.length()); if (CheckForAndReturnValue (intHashTbl, hash, &anyInfo)) ai = (AnyInfo*) anyInfo; else ai = NULL; /* indicates failure */ } /* SetAnyTypeByInt */ // Define this ANY value's type to the one that the given id hashes // to in the ANY table. void AsnAny::SetTypeByOid (const AsnOid &id) const { Hash hash; void *anyInfo; /* use encoded oid as hash string */ hash = MakeHash (id.Str(), id.Len()); if (CheckForAndReturnValue (oidHashTbl, hash, &anyInfo)) ai = (AnyInfo*) anyInfo; else ai = NULL; /* indicates failure */ //RWC;4/16/01; lastly, clear ->value in case loaded previously. } /* SetAnyTypeByOid */ // Given an integer, intId, to hash on, the type and it's anyId // are installed in the integer id hash tbl void AsnAny::InstallAnyByInt (AsnIntType intId, int anyId, AsnType *type) { AnyInfo *a; Hash h; a = new AnyInfo; // Oid will be NULL and 0 len by default constructor a->anyId = anyId; a->intId = intId; a->typeToClone = type; if (AsnAny::intHashTbl == NULL) AsnAny::intHashTbl = InitHash(); AsnInt intval = intId; h = MakeHash ((const char*)intval.c_str(), intval.length()); if ( ! Insert (AsnAny::intHashTbl, a, h) ) { delete a->typeToClone; delete a; } } /* InstallAnyByInt */ // // void AsnAny::AsnAnyDestroyHashTbls() // Added for static call to destroy special; at end. { if (oidHashTbl) { AsnAnyDestroyHashTbl(oidHashTbl); } if (intHashTbl) { AsnAnyDestroyHashTbl(intHashTbl); } } // // void AsnAny::AsnAnyDestroyHashTbl(Table *&pHashTbl) // Added for static call to destroy special; at end. { HashSlot *pHash; AnyInfo *pA; int i; for (i=0; i < TABLESIZE; i++) if ((*pHashTbl)[i]) { pHash = (HashSlot *)(*pHashTbl)[i]; pA = (AnyInfo *)pHash->value; if (pHash->table) AsnAnyDestroyHashTbl(pHash->table); else if (pA->typeToClone) { delete pA->typeToClone; delete pA; } delete pHash; } delete[] pHashTbl; pHashTbl = NULL; } // // given an OBJECT IDENTIFIER, oid, to hash on, the type and it's anyId // are installed in the OBJECT IDENTIFIER id hash tbl void AsnAny::InstallAnyByOid (AsnOid &oid, int anyId, AsnType *type) { AnyInfo *a; Hash h; a = new AnyInfo; a->anyId = anyId; a->oid = oid; // copy given oid a->typeToClone = type; h = MakeHash (oid.Str(), oid.Len()); if (AsnAny::oidHashTbl == NULL) AsnAny::oidHashTbl = InitHash(); if (! Insert (AsnAny::oidHashTbl, a, h)) { delete a->typeToClone; delete a; } } /* InstallAnyByOid */ // // AsnLen AsnAny::PEnc(AsnBufBits &b) const { std::stringbuf *pbufStr=new std::stringbuf; //MEMORY released by ~AsnBufBits. AsnBufBits TmpBufBits(pbufStr); AsnOcts tmpAnyLoadOcts; unsigned char *pBits; long lAnyBitCount, lAnyByteCount; unsigned long lLength=0; FUNC("AsnAny::PEnc()"); if (value != NULL) // HANDLE the case where we know the syntax. { value->PEnc(TmpBufBits); lAnyBitCount = TmpBufBits.length(); pBits = TmpBufBits.GetBits(lAnyBitCount); lAnyByteCount = lAnyBitCount/8; if (lAnyByteCount*8 < lAnyBitCount) lAnyByteCount++; // ZERO padded here. tmpAnyLoadOcts.Set((const char *)pBits, lAnyByteCount); delete[] pBits; lLength = tmpAnyLoadOcts.PEnc(b); } // IF value else if (anyBuf != NULL) // HANDLE the case with just a BLOB of data. { anyBuf->ResetMode(); lLength = anyBuf->length(); char *ptr = anyBuf->GetSeg(lLength); if (ptr && lLength) { tmpAnyLoadOcts.Set(ptr, lLength); // BYTE count here. lLength = tmpAnyLoadOcts.PEnc(b); // BIT count returned. } // END IF any data in ANY. delete[] ptr; } // IF value/anyBuf else throw EXCEPT("Unknown any with no value", ENCODE_ERROR); if(pbufStr) delete pbufStr; return(lLength); } // END AsnAny::PEnc(...) // // void AsnAny::PDec(AsnBufBits &b, AsnLen &bitsDecoded) { AsnBufBits tmpBufBits; AsnOcts tmpAnyLoadOcts; AsnLen tmpBitsDecoded=0; FUNC("AsnAny::PDec"); // ai will be NULL if this is an ANY (not an ANY DEFINED BY) if (ai != NULL) { // the type is already known clone it and use it's BDec to decode the // ASN.1 // value = ai->typeToClone->Clone(); if (value == NULL) { throw SnaccException(STACK_ENTRY, "typeToClone->Clone() failed", INVALID_ANY); } // IF value == NULL else { tmpAnyLoadOcts.PDec(b, bitsDecoded); // OUTER OctetString // OUTER "bitsDecoded" returned to caller. if (tmpAnyLoadOcts.length()) { tmpBufBits.PutBits((unsigned char *)tmpAnyLoadOcts.c_ustr(), tmpAnyLoadOcts.length()*8); value->PDec(tmpBufBits, tmpBitsDecoded); // DECODE actual known value. } // END IF tmpBitsDecoded } // END IF value == NULL } // IF ai != NULL else // JUST load BLOB of data in "anyBuf" { tmpAnyLoadOcts.PDec(b, bitsDecoded); // OUTER OctetString // OUTER "bitsDecoded" returned to caller. if (tmpAnyLoadOcts.length()) { if(this->anyBuf) delete this->anyBuf; this->anyBuf = new AsnBuf((char *)tmpAnyLoadOcts.c_str(), tmpAnyLoadOcts.length()); } // END IF any data in ANY. } // END IF ai != NULL } // END AsnAny::PDec(...) // FUNCTION: BEnc() // PUPROSE: Encode ANY DEFINED BY if "value" is present otherwise encode ANY if // anyBuf is present. If neither is present an exception is thrown. // AsnLen AsnAny::BEnc (AsnBuf &b) const { FUNC("AsnAny::BEnc()"); if (value != NULL) return value->BEnc(b); else if (anyBuf != NULL) { anyBuf->ResetMode(); b.insert(*anyBuf); return anyBuf->length(); } else throw EXCEPT("Unknown any with no value", ENCODE_ERROR); } // BDec() // // Decoded ANY DEFINED BY or UNKNOWN ANY from 'b'. If an ANY DEFINED // BY is found it's will be decoded into value. If an UNKNOWN ANY is // found it's binary values will be copied into 'anyBuf'. // void AsnAny::BDec (const AsnBuf &b, AsnLen &bytesDecoded) { FUNC("AsnAny::BDec"); // ai will be NULL if this is an ANY (not an ANY DEFINED BY) if (ai == NULL) { anyBuf = new AsnBuf; b.GrabAny(*anyBuf, bytesDecoded); } else { // the type is already known clone it and use it's BDec to decode the // ASN.1 // value = ai->typeToClone->Clone(); if (value == NULL) { throw SnaccException(STACK_ENTRY, "typeToClone->Clone() failed", INVALID_ANY); } else value->BDec (b, bytesDecoded); } } /* JKG -- added 03/03/04 for support of unkown any's in extension additions */ /* This BDecContent function was written specifically to handle the decoding of unknown any's */ /* that happened because of extension additions. It is not intended for use with decoding */ /* known any's. ALL extension additions that are not in the root extension list are unkown */ /* any's and these are the ONLY any's that should call this function. */ void AsnAny::BDecContent (const AsnBuf &b, AsnTag tag, AsnLen len, AsnLen &bytesDecoded) { long lBytesToUnget = 0; lBytesToUnget += BytesInLen(len); lBytesToUnget += BytesInTag(tag); b.UnGetBytes(lBytesToUnget); anyBuf = new AsnBuf; b.GrabAny(*anyBuf, bytesDecoded); } void AsnAny::Print(std::ostream& os, unsigned short indent) const { if (value != NULL) value->Print(os, indent); else if (anyBuf != NULL) { os << "UNKNOWN ANY hex dump: "; anyBuf->hexDump(os); } } void AsnAny::PrintXML (std::ostream &os, const char *lpszTitle) const { if (lpszTitle) os << "<" << lpszTitle << " type=\"ANY\">"; else os << ""; Print(os); if (lpszTitle) os << "\n"; else os << "\n"; } AsnAny::~AsnAny() { delete this->value; this->value = NULL; delete this->anyBuf; this->anyBuf = NULL; } AsnAny &AsnAny::operator = (const AsnAny &o) { FUNC("AsnAny::operator="); ai = o.ai; // pointer into Any Table delete value; value = NULL; delete anyBuf; anyBuf = NULL; // NOW, take care of special CSM_Buffer copy, if present. if (o.value != NULL) { value = o.value->Clone(); if (value == NULL) throw SnaccException(STACK_ENTRY,"AsnType::Clone() failed",INVALID_ANY); } else if (o.anyBuf != NULL) { anyBuf = new AsnBuf(*o.anyBuf); } return *this; } extern "C" { void SNACCDLL_API SNACC_CleanupMemory() { #ifndef NO_THREADS threadDestroy(); // ONLY necessary if a thread lock is created (and it is // important to clear all memory leaks before exiting. #endif AsnAny::AsnAnyDestroyHashTbls(); // FINAL call, to clear static tables, // before exiting. } } // END extern "C" _END_SNACC_NAMESPACE esnacc-ng-1.8.1/cxx-lib/src/asn-bits.cpp000066400000000000000000000547671302010526100177510ustar00rootroot00000000000000// file: .../c++-lib/src/asn-bits.C - AsnBits (ASN.1 BIT STRING) Type // // Mike Sample // 92/07/02 // Copyright (C) 1992 Michael Sample and the University of British Columbia // // This library is free software; you can redistribute it and/or // modify it provided that this copyright/license information is retained // in original form. // // If you modify this file, you must clearly indicate your changes. // // This source code is distributed in the hope that it will be // useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // /*#include */ #include "asn-incl.h" #include #include _BEGIN_SNACC_NAMESPACE char SNACCDLL_API numToHexCharTblG[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; AsnBits::AsnBits(const char *stringForm) { bits=NULL; nblFlag = false; bitLen = 0; if (stringForm) operator=(stringForm); } AsnBits::~AsnBits() { delete[] bits; } // Initializes the bits string with a bit string numBits in length. // All bits are zeroed. void AsnBits::Set (size_t numBits) { if (numBits > 0) { bitLen = numBits; size_t octetLen = (bitLen+7)/8; if (bits) delete[] bits; bits = new unsigned char[octetLen]; memset (bits, 0, octetLen); // init to zeros } } // initializes a BIT STRING with the given string and bit length // Copies the bits from bitsOcts. void AsnBits::Set (const unsigned char *bitOcts, size_t numBits) { if (bitOcts != bits) { if (bits) delete[] bits; bitLen = numBits; size_t octetLen = (bitLen+7)/8; bits = new unsigned char[octetLen]; memcpy (bits, bitOcts, octetLen); } } // initializes a BIT STRING by copying another BIT STRING's bits void AsnBits::Set (const AsnBits &b) { if (&b != this) { delete[] bits; bits = NULL; bitLen = b.bitLen; nblFlag = b.nblFlag; size_t octetLen = (bitLen+7)/8; if (octetLen) { bits = new unsigned char[octetLen]; memcpy (bits, b.bits, octetLen); } } } // PIERCE 8-28-2001 removed ReSet members // #if 0 // Initializes the bits string with a bit string numBits in length. // All bits are zeroed. void AsnBits::ReSet (size_t numBits) { delete[] bits; Set (numBits); } // frees old bits value and then re-initializes the // BIT STRING with the given string and bit length // Copies the bitOcts into bits. void AsnBits::ReSet (const char *bitOcts, size_t numBits) { if (bitOcts != bits) { delete[] bits; Set (bitOcts, numBits); } } // frees old bits value and then re-initializes the // BIT STRING by copying another BIT STRING's bits void AsnBits::ReSet (const AsnBits &b) { if (&b != this) // avoid b = b; probs { delete[] bits; Set (b); } } #endif // Returns true if the given BIT STRING is the same as this one bool AsnBits::BitsEquiv (const AsnBits &ab) const { size_t octetsLessOne = (bitLen-1)/8; size_t unusedBits; unusedBits = bitLen % 8; if (unusedBits != 0) unusedBits = 8 - unusedBits; if (!bitLen && !ab.bitLen) return true; // trailing bits may not be significant return bitLen == ab.bitLen && !memcmp (bits, ab.bits, octetsLessOne) && (bits[octetsLessOne] & (0xFF << unusedBits)) == (ab.bits[octetsLessOne] & (0xFF << unusedBits)); } /* AsnBits::BitsEquiv */ void AsnBits::SetSize(size_t newsize) { if(bitLen < newsize) { size_t newLength = (newsize + 7) / 8; unsigned char *tmpBits = new unsigned char[ newLength ]; memset(tmpBits, 0, newLength); memcpy((char*)tmpBits, (const char*)bits, std::min(length(), newLength)); delete [] bits; bits = new unsigned char[ newLength ]; memcpy((char*)bits, (const char*)tmpBits, newLength); delete [] tmpBits; } bitLen = newsize; } // set given bit to 1. Most signif. bit is bit 0, least signif bit is bitLen-1 void AsnBits::SetBit (size_t bit) { FUNC("AsnBits::SetBit"); if (bit < bitLen) { size_t octet = bit/8; size_t octetsBit = 7 - (bit % 8); // bit zero is first/most sig bit in octet bits[octet] |= 1 << octetsBit; } else { throw ParameterException("Parameter is larger than BIT STRING size", STACK_ENTRY); } } /* AsnBits::SetBit */ // Clr bit. Most signif. bit is bit 0, least signif bit is bitLen-1 void AsnBits::ClrBit (size_t bit) { FUNC("AsnBits::ClrBit"); if (bit < bitLen) { size_t octet = bit/8; size_t octetsBit = 7 - (bit % 8); // bit zero is first/most sig bit in octet bits[octet] &= ~(1 << octetsBit); } else { throw ParameterException("Parameter is larger than BIT STRING size", STACK_ENTRY); } } /* AsnBits::ClrBit */ // returns given bit. Most signif. bit is bit 0, least signif bit is bitLen-1. // Returns false if the given bit index is out of range. bool AsnBits::GetBit (size_t bit) const { if (bit < bitLen) { size_t octet = bit/8; size_t octetsBit = 7 - (bit % 8); // bit zero is first/most sig bit in octet return !!(bits[octet] & (1 << octetsBit)); } return false; } /* AsnBits::GetBit */ // Returns true if the bit string is empty bool AsnBits::IsEmpty () const { size_t i = 0; if (bits == NULL) return true; if (bitLen <= 0) return true; for (i = 0; i < bitLen; i++) { if (GetBit(i) == 1) return false; } return true; } /* AsnBits::IsEmpty */ // Encodes the content (included unused bits octet) of the BIT STRING // to the given buffer. AsnLen AsnBits::BEncContent (AsnBuf &b) const { size_t unusedBits; size_t byteLen; unsigned int i; //bool bStop; // IF bitstring is a NamedBitList if (nblFlag) { // Calculate last octet. // size_t finalOctet; if (bitLen <= 8) finalOctet = 0; else if (bitLen % 8 == 0) finalOctet = ((bitLen / 8) - 1); else finalOctet = bitLen / 8; // The final octet is the last octet which has at least // one bit set. Loop backwards starting with the // last octet (calculated above) until you find an // that has at least one bit set (it's value is not 0). // if (bits != NULL) for (; finalOctet > 0 && bits[finalOctet] == 0; finalOctet--); // Calculate unsigned bits in final octet // if (bits == NULL || (finalOctet == 0 && bits[0] == 0)) { byteLen = 0; unusedBits = 0; } else { // Calculate how many trailing bits are unset in the // last octet. unusedBits=0; for (i = 0; i < 8 && ! (bits[finalOctet] & (0x01 << i)); i++) unusedBits++; byteLen = finalOctet + 1; } } else { // If this is not a NamedBitList Calculate the unusedBits // as ( (BitLen() / 8) + 1) * 8 ) - BitLen(); // // In other words it's the number of bits not used by // the BIT STRING specification, not the number of unset // bits in the the final subsequent octet. unusedBits = bitLen % 8; if (unusedBits != 0) unusedBits = 8 - unusedBits; byteLen = (bitLen+7)/8; } b.PutSegRvs (bits, byteLen); // unusedBits = (bitLen % 8); // if (unusedBits != 0) // unusedBits = 8 - unusedBits; b.PutByteRvs ((unsigned char)unusedBits); return byteLen + 1; } /* AsnBits::BEncContent */ // Decodes a BER BIT STRING from the given buffer and stores // the value in this object. void AsnBits::BDecContent (const AsnBuf &b, AsnTag tagId, AsnLen elmtLen, AsnLen &bytesDecoded) { FUNC("AsnBits::BDecContent"); if (elmtLen == INDEFINITE_LEN || elmtLen > b.length()) { throw MemoryException(elmtLen, "elmtLen requests for too much data", STACK_ENTRY); } /* * tagId is encoded tag shifted into long int. * if CONS bit is set then constructed bit string */ if (tagId & 0x20000000) BDecConsBits (b, elmtLen, bytesDecoded); else /* primitive octet string */ { if (elmtLen == INDEFINITE_LEN) throw BoundsException("indefinite length on primitive", STACK_ENTRY); if (elmtLen > b.length() || elmtLen <= 0) throw BoundsException("length problem on decoding content", STACK_ENTRY); bytesDecoded += elmtLen; elmtLen--; unsigned int iUnusedBitLen= (unsigned int)b.GetByte(); if (iUnusedBitLen > 7) throw BoundsException("Length problem - Unused bits > 7", STACK_ENTRY); bitLen = (elmtLen * 8) - iUnusedBitLen; bits = new unsigned char[elmtLen]; b.GetUSeg (bits, elmtLen); } } /* AsnBits::BDecContent */ size_t AsnBits::encLen() const { size_t unusedBits; size_t byteLen; unsigned int i; //bool bStop; // IF bitstring is a NamedBitList if (nblFlag) { // Calculate last octet. // size_t finalOctet; if (bitLen <= 8) finalOctet = 0; else if (bitLen % 8 == 0) finalOctet = ((bitLen / 8) - 1); else finalOctet = bitLen / 8; // The final octet is the last octet which has at least // one bit set. Loop backwards starting with the // last octet (calculated above) until you find an // that has at least one bit set (it's value is not 0). // if (bits != NULL) for (; finalOctet > 0 && bits[finalOctet] == 0; finalOctet--); // Calculate unsigned bits in final octet // if (bits == NULL || (finalOctet == 0 && bits[0] == 0)) { byteLen = 0; unusedBits = 0; } else { // Calculate how many trailing bits are unset in the // last octet. unusedBits=0; for (i = 0; i < 8 && ! (bits[finalOctet] & (0x01 << i)); i++) unusedBits++; byteLen = finalOctet + 1; } } else { return BitLen(); } return ( (byteLen * 8) - unusedBits); } AsnLen AsnBits::EncodeGeneral(AsnBufBits &b)const { AsnLen len = 0; unsigned long l_64kFrag = l_16k * 4; unsigned long count = 0; unsigned long x = 0; unsigned long tempLen = encLen(); unsigned char ch = 0x00; unsigned char *c = NULL; long offset = 0; if(tempLen >= l_16k) { /*there is more than 16k bits of data*/ count = (tempLen / l_64kFrag); for(x=0; x < count; x++) { len += b.OctetAlignWrite(); len += PEncLen_16kFragment(b, 4); len += b.OctetAlignWrite(); len += b.PutBits((unsigned char*)&bits[offset / 8], l_64kFrag); offset += l_64kFrag; } tempLen -= count * l_64kFrag; count = tempLen / l_16k; if(count != 0) { len += b.OctetAlignWrite(); len += PEncLen_16kFragment(b, count); len += b.OctetAlignWrite(); len += b.PutBits((unsigned char*)&bits[offset / 8], (count * l_16k) ); offset += (count * l_16k); } tempLen -= (l_16k * count); if(tempLen == 0) { ch = 0x00; c = &ch; len += b.OctetAlignWrite(); len += b.PutBits(c, 8); return len; } } /*if there are less than 128 bits of data*/ if(tempLen < 128) { len += b.OctetAlignWrite(); len += PEncDefLenTo127(b, tempLen); len += b.OctetAlignWrite(); len += b.PutBits((unsigned char*)&bits[offset / 8], tempLen); offset += tempLen; } else if(tempLen >= 128 && tempLen < l_16k) { len += b.OctetAlignWrite(); /*if there is less than 16k bits of data*/ /*and more than 127 bits of data*/ len += PEncLen_1to16k(b, tempLen); len += b.OctetAlignWrite(); len += b.PutBits((unsigned char*)&bits[offset / 8], tempLen); offset += tempLen; } return len; } void AsnBits::Allocate(long size) { char* temp = new char[(((bitLen + size)/ 8) + 1)]; memcpy(temp, bits, length()); size += bitLen; clear(); bitLen = size; bits = new unsigned char[((bitLen / 8) + 1)]; memcpy(bits, temp, length()); delete [] temp; } void AsnBits::DecodeGeneral(AsnBufBits &b, AsnLen &bitsDecoded) { unsigned char* seg; unsigned long templen = 0; long offset = 0; clear(); bitsDecoded += b.OctetAlignRead(); seg = (unsigned char*)b.GetBits(8); bitsDecoded += 8; while((seg[0] & 0xC0) == 0xC0) { seg[0] &= 0x3F; templen = (unsigned long)seg[0]; templen *= l_16k; b.OctetAlignRead(); Allocate(templen); delete [] seg; seg = b.GetBits(templen); memcpy(&bits[offset / 8], seg, ((templen + 7) / 8)); bitsDecoded += templen; bitsDecoded += b.OctetAlignRead(); offset += templen; delete [] seg; seg = (unsigned char*)b.GetBits(8); bitsDecoded += 8; } if((seg[0] & 0xC0) == 0x80) { seg[0] &= 0x3F; templen = (unsigned long)seg[0]; templen <<= 8; delete [] seg; seg = (unsigned char*)b.GetBits(8); bitsDecoded += 8; templen |= (unsigned long)seg[0]; bitsDecoded += b.OctetAlignRead(); Allocate(templen); delete [] seg; seg = b.GetBits(templen); memcpy(&bits[offset / 8], seg, ((templen + 7) / 8)); bitsDecoded += templen; offset += templen; } else if((seg[0] & 0x80) == 0x00) { seg[0] &= 0x7F; templen = (unsigned long)seg[0]; bitsDecoded += b.OctetAlignRead(); Allocate(templen); delete [] seg; seg = b.GetBits(templen); memcpy(&bits[offset / 8], seg, ((templen + 7) / 8)); bitsDecoded += templen; offset += templen; } delete [] seg; } long AsnBits::FindSizeConstraintBounds(int &iSCLowerBound, int &iSCUpperBound)const { int count = 0; int numsizeconstraints; const SizeConstraint* sizeConstraints = SizeConstraints(numsizeconstraints); while(count < numsizeconstraints) { if((unsigned)iSCUpperBound < sizeConstraints[count].lowerBound) { iSCUpperBound = sizeConstraints[count].lowerBound; } if( sizeConstraints[count].upperBoundExists == 1 && (unsigned)iSCUpperBound < sizeConstraints[count].upperBound) { iSCUpperBound = sizeConstraints[count].upperBound; } if( (unsigned)iSCLowerBound > sizeConstraints[count].lowerBound ) { iSCLowerBound = sizeConstraints[count].lowerBound; } count++; } return ( (iSCUpperBound - iSCLowerBound) + 1); } AsnLen AsnBits::EncodeWithSizeConstraint (AsnBufBits &b)const { AsnLen len = 0; int numSizeConstraints; const SizeConstraint* sizeConstraints = SizeConstraints(numSizeConstraints); int iSCLowerBound = sizeConstraints[0].lowerBound; int iSCUpperBound = iSCLowerBound; int minBitsNeeded = 0; int minBytesNeeded = 0; long Range = FindSizeConstraintBounds(iSCLowerBound, iSCUpperBound); long tempRange = Range - 1; long size = bitLen; unsigned char* temp = NULL; long tempLength = 0; unsigned char* pStr = new unsigned char[1]; while(tempRange > 0) { tempRange -= (long)(1 << minBitsNeeded); minBitsNeeded += 1; } if(Range > 1) { if( (iSCUpperBound > 16) && b.IsAligned()) { len += b.OctetAlignWrite(); } if(size > iSCUpperBound) { size = iSCUpperBound; } if(size < iSCLowerBound) { size = iSCLowerBound; } minBytesNeeded = minBitsNeeded / 8; minBitsNeeded = minBitsNeeded % 8; size -= iSCLowerBound; if(minBytesNeeded > 0) { pStr[0] = (unsigned char)(size >> minBitsNeeded); len += b.PutBits(pStr, 8); } pStr[0] = (unsigned char)size; pStr[0] <<= 8 - minBitsNeeded; len += b.PutBits(pStr, minBitsNeeded); } if( (iSCUpperBound > 16) && b.IsAligned()) { len += b.OctetAlignWrite(); } if((unsigned)bitLen < (unsigned)iSCLowerBound) { tempLength = iSCLowerBound - bitLen; len += b.PutBits((unsigned char*)bits, bitLen); temp = new unsigned char[(tempLength + 7) / 8]; memset(temp, 0, (tempLength + 7) / 8); len += b.PutBits(temp, tempLength); delete [] temp; } else if((unsigned)bitLen > (unsigned)iSCUpperBound) { len += b.PutBits((unsigned char*)bits, iSCUpperBound); } else { len += b.PutBits((unsigned char*)bits, bitLen); } delete [] pStr; return len; } void AsnBits::DecodeWithSizeConstraint(AsnBufBits &b, AsnLen &bitsDecoded) { FUNC("AsnBits::DecodeWithSizeConstraint"); int numSizeConstraints; const SizeConstraint* sizeConstraints = SizeConstraints(numSizeConstraints); int iSCLowerBound = sizeConstraints[0].lowerBound; int iSCUpperBound = iSCLowerBound; int minBitsNeeded = 0; int minBytesNeeded = 0; long Range = FindSizeConstraintBounds(iSCLowerBound, iSCUpperBound); long tempRange = Range - 1; long decodeSize = 0; unsigned char* seg; unsigned char* pStr = new unsigned char[1]; clear(); while(tempRange > 0) { tempRange -= (long)(1 << minBitsNeeded); minBitsNeeded += 1; } if(Range > 1) { if( (iSCUpperBound > 16) && b.IsAligned()) { bitsDecoded += b.OctetAlignRead(); } minBytesNeeded = minBitsNeeded / 8; minBitsNeeded = minBitsNeeded % 8; if(minBytesNeeded > 0) { delete [] pStr; pStr = b.GetBits(8); bitsDecoded += 8; decodeSize <<= 8; decodeSize |= (long)pStr[0]; } delete [] pStr; pStr = b.GetBits(minBitsNeeded); bitsDecoded += minBitsNeeded; if(minBitsNeeded > 0) { decodeSize <<= minBitsNeeded; pStr[0] >>= (8 - minBitsNeeded); decodeSize |= (long)pStr[0]; } } decodeSize += iSCLowerBound; if(decodeSize > iSCUpperBound) { delete [] pStr; throw EXCEPT("String size not withing restricted bounds", RESTRICTED_TYPE_ERROR); } if( (iSCUpperBound > 16) && b.IsAligned()) { bitsDecoded += b.OctetAlignRead(); } bitLen = decodeSize; bits = new unsigned char[((decodeSize + 7) /8)]; seg = b.GetBits(decodeSize); memcpy(bits, seg, ((decodeSize + 7) / 8)); bitsDecoded += decodeSize; delete [] seg; delete [] pStr; } AsnLen AsnBits::PEnc (AsnBufBits &b) const { AsnLen len = 0; int numSizeConstraints; const SizeConstraint* sizeConstraints = SizeConstraints(numSizeConstraints); if(sizeConstraints == NULL && numSizeConstraints == 0 ) { len = EncodeGeneral(b); } else { len = EncodeWithSizeConstraint(b); } return len; } void AsnBits::PDec (AsnBufBits &b, AsnLen &bitsDecoded) { int numSizeConstraints; const SizeConstraint* sizeConstraints = SizeConstraints(numSizeConstraints); if(sizeConstraints == NULL && numSizeConstraints == 0 ) { DecodeGeneral(b, bitsDecoded); } else { DecodeWithSizeConstraint(b, bitsDecoded); } } AsnLen AsnBits::BEnc (AsnBuf &b) const { AsnLen l; l = BEncContent (b); l += BEncDefLen (b, l); l += BEncTag1 (b, UNIV, PRIM, BITSTRING_TAG_CODE); return l; } void AsnBits::BDec (const AsnBuf &b, AsnLen &bytesDecoded) { FUNC("AsnBits::BDec"); AsnLen elmtLen; AsnTag tag; tag = BDecTag (b, bytesDecoded); if ((tag != MAKE_TAG_ID (UNIV, PRIM, BITSTRING_TAG_CODE)) && (tag != MAKE_TAG_ID (UNIV, CONS, BITSTRING_TAG_CODE))) { throw InvalidTagException(typeName(), tag, STACK_ENTRY); } elmtLen = BDecLen (b, bytesDecoded); BDecContent (b, tag, elmtLen, bytesDecoded); } /* * decodes a seq of universally tagged bits until either EOC is * encountered or the given len decoded. Return them in a * single concatenated bit string */ void AsnBits::BDecConsBits (const AsnBuf &b, AsnLen elmtLen, AsnLen &bytesDecoded) { FUNC("AsnBits::BDecConsBits ()"); ConsStringDeck deck(BITSTRING_TAG_CODE); ConsStringDeck::iterator i; deck.Fill(b, elmtLen, bytesDecoded); // Check all but the last card to make sure it's set to zero // // This enforces the constructed BIT STRING rule which states // the unused bits must 0 except for the last component. // i = deck.begin(); for (; i < (deck.end() - 1); i++) { if (i->first[0] != 0) throw EXCEPT("Constructed BIT STRING contains a component with a unused bits value other than 0", DECODE_ERROR); } } /* BDecConsBits */ // prints the BIT STRING to the given ostream. void AsnBits::Print(std::ostream& os, unsigned short /*indent*/) const { size_t octetLen = (bitLen+7)/8; os << "'"; for (unsigned int i = 0; i < octetLen; i++) os << TO_HEX (bits[i] >> 4) << (TO_HEX (bits[i])); os << "'H -- BIT STRING bitlen = " << bitLen << " --"; } void AsnBits::PrintXML(std::ostream &os, const char *lpszTitle) const { os << ""; if (lpszTitle) os << lpszTitle; os << "-"; Print(os); os << "\n"; } AsnBits & AsnBits::operator=(const char *stringForm) { return SetEqual(stringForm); } // operator=(const char *) // // create AsnBits object from the BINARY string form // // example: // '1001'B // AsnBits & AsnBits::SetEqual(const char *stringForm) { FUNC("AsnBits::operator=()"); char *pend = NULL; char *pbegin = NULL; pend = (char *)strstr(stringForm, "'B"); pbegin = (char *)strstr(stringForm,"'"); if (pend == NULL || pbegin == NULL) { throw ParameterException("Invalid string form for BIT STRING", STACK_ENTRY); } pbegin++; // Set length Set(pend - pbegin); for (int i=0; (pbegin + i) != pend; i++) { // if ASCII 0 if (pbegin[i] == '0') ClrBit(i); // else if ASCII 1 else if (pbegin[i] == '1') SetBit(i); else // PIERCE THROW throw ParameterException("Invalid string form for BIT STRING", STACK_ENTRY); } nblFlag = true; return *this; } // soloBitCheck() // // determines if the only bit set is 'b'. This is used to determine whether a // BIT STRING contains only the default bit set. If it does then it is not encoded. // bool AsnBits::soloBitCheck(size_t b) { bool result = false; if (GetBit(b)) { // Clear bit b and check if bit string is empty ClrBit(b); if (IsEmpty()) { result = true; } SetBit(b); } return result; } #if META const AsnBitsTypeDesc AsnBits::_desc (NULL, NULL, false, AsnTypeDesc::BIT_STRING, NULL, NULL); const AsnTypeDesc *AsnBits::_getdesc() const { return &_desc; } #if TCL int AsnBits::TclGetVal (Tcl_Interp *interp) const { Tcl_ResetResult(interp); for (int i=0; igetmodule()->name, ".", _getdesc()->getname(), NULL); Tcl_SetErrorCode (interp, "SNACC", "ILLBIT", NULL); return TCL_ERROR; } ReSet (i); for (i=0, p=valstr; i _BEGIN_SNACC_NAMESPACE AsnLen AsnBool::PEnc (AsnBufBits &b) const { AsnLen len = 1; unsigned char c = 0x80; unsigned char * cBool; if(value) { cBool = &c; } else { c = 0x00; cBool = &c; } b.PutBits(cBool, 1); return len; } void AsnBool::PDec(AsnBufBits &b, AsnLen &bitsDecoded) { unsigned char* cBool; cBool = b.GetBits(1); if( (cBool[0] & 0x80) == 0x80 ) { value = true; } else { value = false; } bitsDecoded += 1; delete [] cBool; } AsnLen AsnBool::BEnc (AsnBuf &b) const { AsnLen l; l = BEncContent (b); BEncDefLenTo127 (b, l); l++; l += BEncTag1 (b, UNIV, PRIM, BOOLEAN_TAG_CODE); return l; } void AsnBool::BDec (const AsnBuf &b, AsnLen &bytesDecoded) { FUNC("AsnBool::BDec()"); AsnLen elmtLen; AsnTag tagId; tagId = BDecTag (b, bytesDecoded); if (tagId != MAKE_TAG_ID (UNIV, PRIM, BOOLEAN_TAG_CODE)) { throw InvalidTagException(typeName(), tagId, STACK_ENTRY); } elmtLen = BDecLen (b, bytesDecoded); BDecContent (b, MAKE_TAG_ID (UNIV, PRIM, BOOLEAN_TAG_CODE), elmtLen, bytesDecoded); } // Decodes the content of a BOOLEAN and sets this object's value // to the decoded value. Flags an error if the length is wrong // or a read error occurs. void AsnBool::BDecContent (const AsnBuf &b, AsnTag /*tagId*/, AsnLen elmtLen, AsnLen &bytesDecoded) { FUNC("AsnBool::BDecContent"); if (elmtLen != 1) { throw BoundsException("AsnBool max length exceeded", STACK_ENTRY); } value = (b.GetByte() != 0); bytesDecoded++; // if (b.ReadError()) // { // throw SNACC_EXCEPT("decoded past end of data "); // } } AsnLen AsnBool::BEncContent (AsnBuf &b) const { b.PutByteRvs ((unsigned char)(value ? 0xFF : 0)); return 1; } // print the BOOLEAN's value in ASN.1 value notation to the given ostream void AsnBool::Print (std::ostream& os, unsigned short /*indent*/) const { os << (value ? "TRUE" : "FALSE"); } void AsnBool::PrintXML (std::ostream &os, const char *lpszTitle) const { os << ""; if (lpszTitle) os << lpszTitle; os << "-"; Print(os); os << "\n"; } char* AsnBool::checkBoolSingleVal(const bool m_SingleVal) const { bool ltemp; char* pError=NULL; char cTmperr[200]; ltemp=value; if(ltemp==m_SingleVal) { return pError; } else { sprintf(cTmperr, "_______\nBOOLEAN--SingleValue Constraints:\n_______\nError: --Values must match--\nValue: %d is not equal to the Constraint Single Value: %d \n", ltemp, m_SingleVal); pError = strdup(cTmperr); return pError; } return pError; } #if META const AsnTypeDesc AsnBool::_desc (NULL, NULL, false, AsnTypeDesc::BOOLEAN, NULL); const AsnTypeDesc *AsnBool::_getdesc() const { return &_desc; } #if TCL int AsnBool::TclGetVal (Tcl_Interp *interp) const { Tcl_SetResult (interp, value ? "TRUE" : "FALSE", TCL_STATIC); return TCL_OK; } int AsnBool::TclSetVal (Tcl_Interp *interp, const char *valstr) { int valval; if (Tcl_GetBoolean (interp, (char*) valstr, &valval) != TCL_OK) return TCL_ERROR; value = valval; return TCL_OK; } #endif /* TCL */ #endif /* META */ _END_SNACC_NAMESPACE esnacc-ng-1.8.1/cxx-lib/src/asn-buf.cpp000066400000000000000000000414021302010526100175420ustar00rootroot00000000000000 #include "asn-incl.h" #ifdef _MSC_VER #pragma warning(disable: 4189) // Disable local variable not referenced warning #endif using namespace SNACC; // AsnBuf.cpp AsnBuf::AsnBuf() { m_card = m_deck.begin(); //m_card = m_deck.insert(m_deck.begin(), new Card()); } AsnBuf::AsnBuf(const char *seg, size_t segLen) { m_card = m_deck.insert(m_deck.begin(), new Card(new AsnRvsBuf(seg, segLen))); } AsnBuf::AsnBuf(const std::stringstream &ss) { m_card = m_deck.insert(m_deck.begin(), new Card(ss)); } AsnBuf::AsnBuf(std::streambuf *sb) { m_card = m_deck.insert(m_deck.begin(), new Card(sb)); } // Copy constructor AsnBuf::AsnBuf(const AsnBuf &o) { operator=(o); } void AsnBuf::insert(const AsnBuf &that) { if (!m_deck.empty() && m_card != m_deck.end() && (*m_card)->length() == 0) { delete *m_card; m_card = m_deck.erase(m_card); } AsnRvsBuf *rvsBuf = new AsnRvsBuf(that); m_card = m_deck.insert(m_deck.begin(), new Card(rvsBuf)); } AsnBuf & AsnBuf::operator=(const AsnBuf &o) { if (this != &o) { clear(); insert(o); } return *this; } AsnBuf::AsnBuf(const char *pFilename) { m_card = m_deck.insert(m_deck.begin(), new Card(new AsnFileSeg(pFilename))); } void AsnBuf::clear() { for (m_card = m_deck.begin(); m_card != m_deck.end(); m_card++) { delete *m_card; } m_deck.clear(); } void AsnBuf::PutByteRvs(char byte) { // if empty add an AsnRvsBuf card // if (m_deck.empty()) { m_card = m_deck.insert(m_deck.begin(), new Card(new AsnRvsBuf)); } if ((*m_card)->rdbuf()->sputc(byte) == EOF) { m_card = m_deck.insert(m_deck.begin(), new Card(new AsnRvsBuf)); (*m_card)->rdbuf()->sputc(byte); } } void AsnBuf::PutSegRvs(const char *seg, size_t segLen) { // if empty add an AsnRvsBuf card // if (m_deck.empty()) { m_card = m_deck.insert(m_deck.begin(), new Card(new AsnRvsBuf)); } while (segLen > 0) { segLen -= (*m_card)->rdbuf()->sputn(seg, segLen); if (segLen > 0) { // reuse any existing card(s) if (m_card == m_deck.begin()) m_card = m_deck.insert(m_deck.begin(), new Card(new AsnRvsBuf)); else --m_card; } } } //#ifdef WIN32 //void AsnBuf::ResetMode(std::ios_base::open_mode mode) const //#else void AsnBuf::ResetMode(std::ios_base::openmode mode) const //#endif { AsnRvsBuf tmp; Deck::iterator i; i = m_deck.begin(); while (i != m_deck.end()) { if (mode & std::ios_base::out) { // dump all cards that are not AsnRvsBuf's because // those are the only cards that can be encoded into. // if ((*i)->bufType() != RVS_BUF_TYPE) { delete *i; i = m_deck.erase(i); continue; } } (*i)->rdbuf()->pubseekpos(0, mode); i++; } if (mode == std::ios_base::in) m_card = m_deck.begin(); else { m_card = m_deck.end(); if ( ! m_deck.empty()) --m_card; } } // GetFileSeg() // // Create a AsnFileSeg object from the current card in the deck // for the length "segLen". // AsnFileSeg * AsnBuf::GetFileSeg(long segLen) const { FUNC("AsnBuf::GetFileSeg()"); // If the bufType == FILE_TYPE then the card is a AsnFileSeg // cast it and pass it to the AsnFileSeg constructor // if ((*m_card)->bufType() == FILE_TYPE) return (new AsnFileSeg((AsnFileSeg *)(*m_card)->rdbuf(), segLen)); else throw BufferException("GetFileSeg called with non file card", STACK_ENTRY); } // PutFileSeg() // // Copy AsnFileSeg pointer into this AsnBuf's deck. AsnBuf assumes // responsibility of cleanup for it. // void AsnBuf::PutFileSeg(AsnFileSeg *pFs) { m_card = m_deck.insert(m_deck.begin(), new Card(pFs)); } char * AsnBuf::GetSeg(long segLen) const { char *seg = new (std::nothrow) char[segLen]; if (!seg) return NULL; try { GetSeg(seg, segLen); } catch (BufferException) { delete [] seg; seg = NULL; } return seg; } //unsigned long AsnBuf::GetSeg(char *seg, long segLen) const void AsnBuf::GetSeg(char *seg, long segLen) const { FUNC("AsnBuf::GetSeg()"); long bytesRead = 0; long lTmp; while (segLen > 0 && m_card != m_deck.end() ) { lTmp = (*m_card)->rdbuf()->sgetn(&seg[bytesRead], segLen); bytesRead += lTmp; if (lTmp != segLen) m_card++; segLen -= lTmp; } if (segLen > 0) throw BufferException("Read past end of data", STACK_ENTRY); //return bytesRead; } // FUNCTION: GetSeg() // PURPOSE: Retrieve the contents of the AsnBuf into a std::string. // segLen is defaulted 0. If defaulted to 0 then the entire // buffer is returned. // void AsnBuf::GetSeg(std::string &seg, long segLen) const { long i; FUNC("AsnBuf::GetSeg(std::string &seg, long segLen)"); if (segLen == 0) segLen = length(); if ((unsigned long)segLen > this->length()) //RWC; TOO MUCH DATA requested... { throw BufferException("GetSeg attempt to read past end of data", STACK_ENTRY); } seg.resize(segLen); for (i = 0; i < segLen; i++) { seg[i] = GetByte(); } } bool AsnBuf::operator<(const AsnBuf &rhs) const { bool lessThan = true; bool firstTime = true; ResetMode(); rhs.ResetMode(); std::streambuf::int_type ch1; std::streambuf::int_type ch2; while ( lessThan ) { try { ch1 = GetUByte(); } catch (BufferException &) { ch1 = EOF; } try { ch2 = rhs.GetUByte(); } catch (BufferException &) { ch2 = EOF; } if ((ch1 == EOF) && (ch2 == EOF)) { if (firstTime) lessThan = false; break; } else if (ch2 == EOF) { lessThan = false; break; } else if (ch1 == EOF) { break; } if (ch1 > ch2) lessThan = false; else if (ch1 < ch2) break; firstTime = false; } ResetMode(); rhs.ResetMode(); return lessThan; } // FUNCTION: length() // PURPOSE; Traverse all REMAINING cards in deck and calculate the overall length // of the AsnBuf. // unsigned long AsnBuf::length() const { unsigned long bytesRemaining = 0; Deck::iterator tmpCard = m_card; int currPos, endPos; if (! m_deck.empty()) { //AsnBufLoc readLoc = GetReadLoc(); // ResetMode(); //RWC; while (tmpCard != m_deck.end()) { //(*tmpCard)->rdbuf()->sgetc(); currPos = (*tmpCard)->rdbuf()->pubseekoff(0, std::ios_base::cur, std::ios_base::in); if (currPos == -1) currPos = 0; endPos = (*tmpCard)->rdbuf()->pubseekoff(0, std::ios_base::end, std::ios_base::in); (*tmpCard)->rdbuf()->pubseekpos(currPos, std::ios_base::in); bytesRemaining += endPos - currPos; tmpCard++; } //SetReadLoc(readLoc); } return bytesRemaining; } /* JKG -- added 03/03/04 for support of unkown any's in extension additions */ /* For unkown any's we need to unget the tag and length bytes to be able to properly decode */ /* unkown any's in extension additions, but outside the extension addition root list */ void AsnBuf::UnGetBytes(long lBytesToPutBack) const { FUNC("AsnBuf::UnGetByte()"); while( lBytesToPutBack ) { if( ((*m_card)->rdbuf()->sungetc()) == EOF ) { if( m_card != m_deck.begin() ) { m_card--; } else { throw BufferException("Failed putting bytes back", STACK_ENTRY); } } else { lBytesToPutBack--; } } } char AsnBuf::GetByte() const { FUNC("AsnBuf::GetByte()"); std::streambuf::int_type ch; if (m_card != m_deck.end()) { #ifdef _DEBUG Card *tmpCard = *m_card; #endif while ((ch = (*m_card)->rdbuf()->sbumpc()) == EOF) { m_card++; if ((m_card == m_deck.end())) { throw BufferException("Read past end of data", STACK_ENTRY); } } } else throw BufferException("Read past end of data", STACK_ENTRY); return (char)ch; } // FUNCTION: GrabAny() // PURPOSE : copy the current sequence of bytes (i.e. Tag Length and associated data) // into AsnBuf that was passed in. This is useful for copying the raw encoding // of any ANY out of an AsnBuf. // void AsnBuf::GrabAny(AsnBuf &anyBuf, AsnLen &bytesDecoded) const { FUNC("AsnBuf::GrabAny"); AsnLen len; AsnLen tmpLen = bytesDecoded; AsnBufLoc readLoc = GetReadLoc(); AsnLen lTmpbytesDecoded=0; // Decode tag of the ANY. This will be encoded into AnyBuf after the length // // @todo: decode the tag using an ASN.1 TagId structure, and check // validity // (void)BDecTag(*this, bytesDecoded); // Decode length of the ANY. This will be encoded into anyBuf after the data. len = BDecLen(*this, bytesDecoded); if (len == INDEFINITE_LEN) { ConsStringDeck deck(0); try { deck.Fill(*this, len, lTmpbytesDecoded); } catch (... /*std::exception &e*/) { throw BufferException("deck.Fill(...) failed, unexpected exception (STACK?)", STACK_ENTRY); } len = lTmpbytesDecoded; } else if (len > this->length()) { throw BufferException("len error from BDecLen call", STACK_ENTRY); } SetReadLoc(readLoc); // length is greater than the magic size and // the m_card contains a file then store a // AsnFileSeg object in output buf. // tmpLen = (bytesDecoded - tmpLen) + len; /** PIERCE: Commented out until further testing is done if (tmpLen > _MAGIC_SIZE && card().bufType() == FILE_TYPE) { anyBuf.PutFileSeg(GetFileSeg(tmpLen)); } else { AsnRvsBuf *pRvsBuf = new AsnRvsBuf(tmpLen); GetSeg(pRvsBuf->m_buf, tmpLen); pRvsBuf->m_pStart = pRvsBuf->m_buf; anyBuf.m_card = anyBuf.m_deck.insert(anyBuf.m_deck.begin(), new Card(pRvsBuf)); } **/ AsnRvsBuf *pRvsBuf = new AsnRvsBuf(tmpLen); GetSeg(pRvsBuf->m_buf, tmpLen); pRvsBuf->m_pStart = pRvsBuf->m_buf; anyBuf.m_card = anyBuf.m_deck.insert(anyBuf.m_deck.begin(), new Card(pRvsBuf)); bytesDecoded += len; #ifdef _DEBUG if (! anyBuf.m_deck.empty()) Card *tmpCard = *(anyBuf.m_deck.begin()); #endif // _DEBUG } char AsnBuf::PeekByte() const { FUNC("AsnBuf::PeekByte()"); std::streambuf::int_type ch; if (m_card != m_deck.end()) { if ( (ch = (*m_card)->rdbuf()->sgetc()) == EOF ) { m_card++; if ( (m_card == m_deck.end()) || (ch = (*m_card)->rdbuf()->sgetc()) == EOF) throw BufferException("Read past end of data", STACK_ENTRY); } } else throw BufferException("Read past end of data", STACK_ENTRY); return (unsigned char) ch; } AsnBufLoc AsnBuf::GetReadLoc() const { AsnBufLoc bl; bl.m_card = m_card; bl.m_offset = (*m_card)->rdbuf()->pubseekoff(0, std::ios_base::cur, std::ios_base::in); #ifdef _DEBUG Card *pCard=*m_card; #endif if (bl.m_offset == -1) bl.m_offset = 0; return bl; } void AsnBuf::SetReadLoc(const AsnBufLoc &bl) const { FUNC("AsnBuf::setReadLoc()"); Deck::iterator i = m_deck.begin(); // first make sure interator bl.m_card is between current card // start of the deck. // while (i != bl.m_card && i != m_deck.end()) { i++; } if ( i == bl.m_card ) { ResetMode(); m_card = bl.m_card; (*m_card)->rdbuf()->pubseekpos(bl.m_offset, std::ios_base::in); } else { throw BufferException("Invalid AsnBufLoc", STACK_ENTRY); } } // skip() // // skips ahead by the number of "skipBytes" // void AsnBuf::skip(size_t skipBytes) { FUNC("AsnBuf::skip()"); size_t nCardLen; while (skipBytes > 0 && m_card != m_deck.end() ) { nCardLen = (*m_card)->length(); if (skipBytes > nCardLen) { skipBytes -= nCardLen; (*m_card)->rdbuf()->pubseekoff(0, std::ios_base::end, std::ios_base::in); m_card++; } else { (*m_card)->rdbuf()->pubseekoff(skipBytes, std::ios_base::cur, std::ios_base::in); skipBytes = 0; } } if (skipBytes > 0) { throw BufferException("Skipped past end of buffer", STACK_ENTRY); } } // insert() // // insert cards from b into this AsnBuf // // TBD: is it necessary to return the length? // long AsnBuf::splice(AsnBuf &b) { if (m_card != m_deck.end() && ((*m_card == NULL) || (*m_card)->length() == 0)) { delete *m_card; m_card = m_deck.erase(m_card); } long length = b.length(); Deck::reverse_iterator ib; for (ib = b.m_deck.rbegin(); ib != b.m_deck.rend(); ++ib) { m_card = m_deck.insert(m_deck.begin(), *ib); } b.m_deck.clear(); return length; } void BDEC_2ND_EOC_OCTET(const SNACC::AsnBuf &b, SNACC::AsnLen &bytesDecoded) { FUNC("BDEC_2ND_EOC_OCTET"); if ((b.GetByte() != 0)) throw EXCEPT("second octet of EOC not zero", DECODE_ERROR); bytesDecoded++; } // Sort by encoding included tag, length, and data // bool asnbuf_greater(const SNACC::AsnBuf &x, const SNACC::AsnBuf &y) { AsnLen len(0); AsnTag xTag = (BDecTag(x, len) & 0xDFFFFFFF); AsnTag yTag = (BDecTag(y, len) & 0xDFFFFFFF); x.ResetMode(); y.ResetMode(); return (xTag > yTag); } void sortSet(std::list &bufList) { for (std::list::iterator j = bufList.begin(); j != bufList.end(); ++j) j->ResetMode(); bufList.sort(asnbuf_greater); } #define ASN_UNIVERSAL 0x00 #define ASN_APPLICATION 0x40 #define ASN_CONTEXT 0x80 #define ASN_PRIVATE 0xC0 bool AsnBuf::operator == (const AsnBuf &b) const { bool equal = true; ResetMode(); b.ResetMode(); std::streambuf::int_type ch1; std::streambuf::int_type ch2; while ( equal ) { try { ch1 = GetUByte(); } catch (BufferException &) { ch1 = EOF; } try { ch2 = b.GetUByte(); } catch (BufferException &) { ch2 = EOF; } if ((ch1 == EOF) && (ch1 == EOF)) break; if (ch1 != ch2) equal = false; } ResetMode(); b.ResetMode(); return equal; } void AsnBuf::hexDump(std::ostream &os) const { bool done = false; int ch; ResetMode(); std::hex(os); while (! done) { try { ch = GetUByte(); os << "0x"; os << ch; os << " "; } catch (...) { os.unsetf(std::ios_base::hex); os.unsetf(std::ios_base::hex); done = true; } } } std::ostream & operator<<(std::ostream &os, const SNACC::AsnBuf &b) { SNACC::Deck::const_iterator card = b.deck().begin(); while (card != b.deck().end()) { if ((*card)->length() > 0) os << (*card)->rdbuf(); card++; } os.flush(); return os; } long Card::size() { long currPos, endPos; currPos = first->pubseekoff(0, std::ios_base::cur, std::ios_base::in); endPos = first->pubseekoff(0, std::ios_base::end, std::ios_base::in); if (currPos != -1) first->pubseekpos(currPos, std::ios_base::in); if (endPos == -1) endPos = 0; return endPos; } long Card::length() { long currPos, endPos; currPos = first->pubseekoff(0, std::ios_base::cur, std::ios_base::in); if (currPos == -1) currPos = 0; endPos = first->pubseekoff(0, std::ios_base::end, std::ios_base::in); first->pubseekpos(currPos, std::ios_base::in); if (endPos == -1) endPos = 0; return endPos - currPos; } #ifdef _DEBUG void AsnBuf::status(std::ostream &os) { std::cout << "**** AsnBuf Status ****\n"; std::cout << "Card Written Bytes TBR Type Max Size\n"; std::cout << "----------------------------------------------------------------------\n"; Deck::iterator i; int j; for (j=0,i = m_deck.begin(); i != m_deck.end(); i++,j++) { std::cout << j << "\t" << (*i)->size() << "\t" << (*i)->length() << "\t" << (*i)->bufTypeStr() << "\t"; if ((*i)->bufType() == RVS_BUF_TYPE) { const AsnRvsBuf *pRvsBuf = (const AsnRvsBuf *)(*i)->rdbuf(); std::cout << pRvsBuf->max_size() << "\n"; } else std::cout << "?\n"; } std::cout << "**** AsnBuf Status ****\n"; } // AsnBufType { FILE_TYPE=0, RVS_BUF_TYPE, IN_MEM_TYPE, EXT_MEM_TYPE} ; const char * Card::bufTypeStr() { switch (this->bufType()) { case RVS_BUF_TYPE: return "ASN_RVS_BUF"; case FILE_TYPE: return "FILE_TYPE"; case IN_MEM_TYPE: return "IN_MEM_TYPE"; case EXT_MEM_TYPE: return "EXT_MEM_TYPE"; } return NULL; } #endif esnacc-ng-1.8.1/cxx-lib/src/asn-bufbits.cpp000066400000000000000000000371341302010526100204330ustar00rootroot00000000000000#include "asn-incl.h" #include #include using namespace SNACC; #define _MAGIC_SIZE 99999999 //RWC;This class was created to allow a reset of the protected inherited elements //RWC; for a non-destructive read of the contents. It is used in several //RWC; places in this source file. class VDAstreambuf: public std::streambuf { public: //char* pptr() const (return std::streambuf::pptr()); char* Vgptr() const { return (this->gptr()); } char* Vegptr() const { return this->egptr(); } void Vsetg( char* peb, char* pg, char* peg ) { this->setg(peb, pg, peg); } char* Veback() const { return this->eback(); } //std::streambuf & operator = ( const std::streambuf &A) //{ (std::streambuf &) *this = A; return *this; } }; AsnBufBits::AsnBufBits(const AsnBufBits& buf) { m_isInternalBuf = false; m_pbuf = NULL; operator=(buf); } AsnBufBits& AsnBufBits::operator=(const AsnBufBits& buf) { // Destroy the existing buffer if (m_isInternalBuf && (m_pbuf != NULL)) delete m_pbuf; if (buf.m_isInternalBuf) { m_pbuf = new std::stringbuf; // Save current read position std::streambuf::pos_type origPos = buf.m_pbuf->pubseekoff(0, std::ios_base::cur, std::ios_base::in); // Copy each byte from buf to this new streambuf std::streambuf::int_type ch; while((ch = buf.m_pbuf->sbumpc()) != EOF) { m_pbuf->sputc((char)ch); } // Reset read position to original value buf.m_pbuf->pubseekpos(origPos, std::ios_base::in); //m_pbuf = new std::stringbuf(buf.pbuf_str(), buf.pbuf_length()); // VDAstreambuf *pVDAbufref = (VDAstreambuf *)buf.m_pbuf; // char* pg=pVDAbufref->Vgptr(); // char* peg=pVDAbufref->Vegptr(); // char* peb=pVDAbufref->Veback(); // pVDAbufref->Vsetg( peb, pg, peg ); } else { m_pbuf = buf.m_pbuf; } m_isInternalBuf = buf.m_isInternalBuf; m_ucWriteCharBuf[0] = buf.m_ucWriteCharBuf[0]; m_iWriteBitPos = buf.m_iWriteBitPos; m_ucReadCharBuf[0] = buf.m_ucReadCharBuf[0]; m_iReadBitPos = buf.m_iReadBitPos; m_ulNumBits = buf.m_ulNumBits; m_ulBitsLeft = buf.m_ulBitsLeft; bAlign = buf.bAlign; return *this; } /* AsnBufBits& AsnBufBits::operator=(const AsnBufBits& buf) { if (this != &buf) { m_pbuf = buf.m_pbuf; m_ucWriteCharBuf[0] = buf.m_ucWriteCharBuf[0]; m_iWriteBitPos = buf.m_iWriteBitPos; m_ucReadCharBuf[0] = buf.m_ucReadCharBuf[0]; m_iReadBitPos = buf.m_iReadBitPos; m_ulNumBits = buf.m_ulNumBits; m_ulBitsLeft = buf.m_ulBitsLeft; } return *this; } */ // // void AsnBufBits::hexDump(std::ostream &os) { FUNC("AsnBufBits::hexDump()"); // Check that the buffer is present if (m_pbuf == NULL) throw BufferException("NULL internal m_pbuf pointer", STACK_ENTRY); ; /* bool done = false; int ch; unsigned char* c = NULL; if (m_pbuf == NULL) m_pbuf = new std::stringbuf; // DELETED in this class. AsnBufBits tmpBuf(*this); VDAstreambuf *pVDAbufref = (VDAstreambuf *)tmpBuf.m_pbuf; char* pg=pVDAbufref->Vgptr(); char* peg=pVDAbufref->Vegptr(); char* peb=pVDAbufref->Veback(); */ AsnBufBits tmpbuf = *this; int ch; std::hex(os); os << "0x"; bool done = false; unsigned int i = 1; while (!done) { ch = tmpbuf.m_pbuf->sbumpc(); //std::streambuf::int_type ch = tmpbuf.m_pbuf->sbumpc(); if (ch == EOF) done = true; else os << ch; if ((i % 8) == 0) os << " "; else if ((i % 16) == 0) os << std::endl; i++; } if(tmpbuf.m_iWriteBitPos < 8) { ch = tmpbuf.m_ucWriteCharBuf[0]; os << ch; } os << std::endl; os.unsetf(std::ios_base::hex); //m_pbuf->pubseekpos(0 /* REN -- 12/30/03, ios_base::in */); /* while (! done) { try { ch = tmpBuf.ReadByte(); os << "0x"; os << ch; os << " "; } catch (...) { os.unsetf(std::ios_base::hex); done = true; } } pVDAbufref->Vsetg( peb, pg, peg ); //RE-SET referenced shared stream pointer. tmpBuf.m_pbuf = NULL; //Be sure not to delete original buffer on a delete */ } // END AsnBufBits::hexDump(...) // // void AsnBufBits::AppendTo(AsnBufBits &bufBitsOut) { FUNC("AsnBufBits::AppendTo()"); // Check that buffer is valid if (m_pbuf == NULL) throw BufferException("NULL internal m_pbuf pointer", STACK_ENTRY); unsigned char ch = 0, *p_ch; AsnBufBits tmpBuf(*this); VDAstreambuf *pVDAbufref = (VDAstreambuf *)m_pbuf; char* pg=pVDAbufref->Vgptr(); char* peg=pVDAbufref->Vegptr(); char* peb=pVDAbufref->Veback(); int iThisCount=length(); int iLeft; try { for (int ii=0; ii < iThisCount/8; ii++) { ch = ReadByte(); bufBitsOut.PutBits(&ch, 8); } iLeft = iThisCount - 8*(iThisCount/8); if (iLeft) { p_ch = this->GetBits(iLeft); if (p_ch) { bufBitsOut.PutBits(&ch, iLeft); delete [] p_ch; } // END IF p_ch } // END IF iLeft } // END try catch (...) { // @todo: really handle this properly. } pVDAbufref->Vsetg( peb, pg, peg ); //RE-SET referenced shared stream pointer. } // END Append(...) /*****RWC;PAINFUL DANG THING... AsnBufBits::operator AsnBuf *() { AsnBuf *pResultBuf=NULL; bool done = false; unsigned char* c = NULL; AsnBufBits tmpBuf(*this); VDAstreambuf *pVDAbufref = (VDAstreambuf *)&tmpBuf.m_buf; char* pg=pVDAbufref->Vgptr(); char* peg=pVDAbufref->Vegptr(); char* peb=pVDAbufref->Veback(); int iBufLength, iBufLength2; char *pch; FUNC("AsnBufBits::operator AsnBuf *()"); try { //tmpBuf. //int sgetn( char* pch, int nCount ); iBufLength = pVDAbufref->Vblen();//in_avail(); if (iBufLength) { pch = (char *)calloc(1, iBufLength); iBufLength2 = pVDAbufref->sgetn(pch, iBufLength); if (iBufLength2 != iBufLength) throw BufferException("NOT ENOUGH chars from buffer", STACK_ENTRY); pResultBuf = new AsnBuf(pch, iBufLength); free(pch); } // END IF iBufLength //RWC;NOT DEFINED YET;pResultBuf->PutStream(pVDAbufref); } catch (...) { if (pResultBuf) delete pResultBuf; pResultBuf = NULL; done = true; } pVDAbufref->Vsetg( peb, pg, peg ); //RE-SET referenced shared stream pointer. return pResultBuf; } // END AsnBufBits::operator *AsnBuf() ***/ // // int AsnBufBits::OctetAlignWrite() { FUNC("AsnBufBits::OctetAlignWrite()"); int returnVal = 0; if(bAlign) { if(m_iWriteBitPos < 8) { if( m_pbuf->sputc( m_ucWriteCharBuf[0] ) == EOF ) throw BufferException("Ran out of room in the designated buffer", STACK_ENTRY); returnVal = m_iWriteBitPos; m_ulNumBits += m_iWriteBitPos; m_ulBitsLeft += m_iWriteBitPos; m_ucWriteCharBuf[0] = 0x00; m_iWriteBitPos = 8; } } return returnVal; } int AsnBufBits::OctetAlignRead() { int returnVal = 0; if(bAlign) { returnVal = (8 - m_iReadBitPos); m_ulBitsLeft -= returnVal; m_iReadBitPos = 8; m_ucReadCharBuf[0] = 0x00; } return returnVal; } unsigned char AsnBufBits::ReadByte() { FUNC("AsnBufBits::ReadByte()"); // Check that buffer is valid if (m_pbuf == NULL) throw BufferException("NULL internal m_pbuf pointer", STACK_ENTRY); std::streambuf::int_type ch = m_pbuf->sbumpc(); if (ch == EOF) { if (m_iWriteBitPos < 8) { ch = m_ucWriteCharBuf[0]; m_iWriteBitPos = 8; m_ucWriteCharBuf[0] = 0x00; } else if (m_ulBitsLeft > 0) { ch = m_ucReadCharBuf[0]; m_ulBitsLeft = 0; } else throw BufferException("Read Past End of Buffer", STACK_ENTRY); } return (unsigned char)ch; } unsigned char* AsnBufBits::GetBits(unsigned long numBits) { FUNC("AsnBufBits::GetBits()"); unsigned char* seg = NULL; unsigned long count = 0; unsigned long ulNumBytes = (numBits / 8); int iExtraBits = (numBits % 8); unsigned char ucTempChar = 0x00; // Check that buffer is valid and contains enough bits if (m_pbuf == NULL) throw BufferException("NULL internal m_pbuf pointer", STACK_ENTRY); if (m_ulBitsLeft < numBits) { throw BufferException("Trying to retrieve more bits than in the buffer", STACK_ENTRY); } if(iExtraBits) { seg = new unsigned char[ulNumBytes + 2]; } else { seg = new unsigned char[ulNumBytes + 1]; } while(count < ulNumBytes) { if( m_iReadBitPos == 8) { seg[count] = ReadByte(); } else { m_ucReadCharBuf[1] = ReadByte(); ucTempChar = m_ucReadCharBuf[1]; m_ucReadCharBuf[1] = MaskBits(m_ucReadCharBuf[1], (m_iReadBitPos)); m_ucReadCharBuf[1] >>= (8 - m_iReadBitPos); seg[count] = m_ucReadCharBuf[0] |= m_ucReadCharBuf[1]; m_ucReadCharBuf[0] = (unsigned char)(ucTempChar << (m_iReadBitPos) ); } count++; } if(iExtraBits > 0 ) { if(iExtraBits <= (8 - m_iReadBitPos)) { seg[count] = MaskBits(m_ucReadCharBuf[0], iExtraBits); m_ucReadCharBuf[0] <<= iExtraBits; m_iReadBitPos += iExtraBits; } else { m_ucReadCharBuf[1] = ReadByte(); ucTempChar = m_ucReadCharBuf[1]; ucTempChar = MaskBits(ucTempChar, (iExtraBits - (8 - m_iReadBitPos)) ); if(m_iReadBitPos != 8) { ucTempChar >>= (8 - m_iReadBitPos); } seg[count] = m_ucReadCharBuf[0] |= ucTempChar; m_ucReadCharBuf[0] = (unsigned char)(m_ucReadCharBuf[1] << (iExtraBits - (8 - m_iReadBitPos)) ); m_iReadBitPos = (iExtraBits - (8 - m_iReadBitPos)); } count++; } seg[count] = 0x00; m_ulBitsLeft -= numBits; return seg; } bool AsnBufBits::GetBit() { FUNC("AsnBufBits::GetBit()"); // Check that the buffer is valid and contains at least one bit if (m_pbuf == NULL) throw BufferException("NULL internal m_pbuf pointer", STACK_ENTRY); if (m_ulBitsLeft == 0) throw BufferException("No more bits in the buffer", STACK_ENTRY); // Read another byte from the stream if necessary if (m_iReadBitPos == 8) { m_ucReadCharBuf[0] = ReadByte(); m_iReadBitPos = 0; } // Calculate the return value bool bitRead = (m_ucReadCharBuf[0] & 0x80); // Update the read position and read buffer and decrement the bits left m_iReadBitPos++; m_ucReadCharBuf[0] <<= 1; --m_ulBitsLeft; // Return the bit read return bitRead; } unsigned char AsnBufBits::GetByte() { FUNC("AsnBufBits::GetByte()"); // Check that the buffer is valid and contains at least eight bits if (m_pbuf == NULL) throw BufferException("NULL internal m_pbuf pointer", STACK_ENTRY); if (m_ulBitsLeft < 8) { throw BufferException("Trying to retrieve more bits than in the buffer", STACK_ENTRY); } // If the read buffer is empty, just read the next byte in the stream unsigned char byte; if (m_iReadBitPos == 8) byte = ReadByte(); else { // Set the resulting byte to the remaining bits in the read buffer byte = m_ucReadCharBuf[0]; // Read the next byte from the buffer m_ucReadCharBuf[0] = ReadByte(); // Mask out the unneeded bits from the next byte unsigned char nextBits = m_ucReadCharBuf[0]; nextBits >>= 8 - m_iReadBitPos; // Combine the byte with the bits from the next byte in the stream byte |= nextBits; // Update the read buffer m_ucReadCharBuf[0] <<= m_iReadBitPos; } // Decrement the number of bits left m_ulBitsLeft -= 8; // Return the byte return byte; } unsigned long AsnBufBits::GetBits(AsnBits& bits, unsigned long numBits) { FUNC("AsnBufBits::GetBits()"); // Check that the buffer contains the required number of bits if (m_ulBitsLeft < numBits) { throw BufferException("Trying to retrieve more bits than in the buffer", STACK_ENTRY); } // Set the size of the bitstring bits.Set(numBits); // Read each bit from the buffer for (unsigned long i = 0; i < numBits; ++i) { if (GetBit()) bits.SetBit(i); } return numBits; } // end of AsnBufBits::GetBits() unsigned long AsnBufBits::PutBits(const unsigned char* seg, unsigned long numBits) { FUNC("AsnBufBits::PutBits()"); unsigned long totalBitsWrote = numBits; unsigned long ulBitsWrote = 0; unsigned long ulNumBytes = 0; int iExtraBits = 0; unsigned long count = 0; // Check that buffer is valid if (m_pbuf == NULL) throw BufferException("NULL internal m_pbuf pointer", STACK_ENTRY); iExtraBits = numBits % 8; ulNumBytes = numBits / 8; while( count < ulNumBytes ) { m_ucWriteCharBuf[1] = seg[count]; m_ucWriteCharBuf[1] = MaskBits(m_ucWriteCharBuf[1], m_iWriteBitPos); m_ucWriteCharBuf[1] >>= ( 8 - m_iWriteBitPos ); m_ucWriteCharBuf[0] |= m_ucWriteCharBuf[1]; if( m_pbuf->sputc( m_ucWriteCharBuf[0] ) == EOF ) throw BufferException("Ran out of room in the designated buffer", STACK_ENTRY); m_ucWriteCharBuf[0] = seg[count]; m_ucWriteCharBuf[0] <<= m_iWriteBitPos; m_ulBitsLeft += 8; m_ulNumBits += 8; ulBitsWrote += 8; count++; } if( iExtraBits ) { m_ulBitsLeft += iExtraBits; m_ulNumBits += iExtraBits; m_ucWriteCharBuf[1] = seg[count]; m_ucWriteCharBuf[1] >>= (8 - m_iWriteBitPos); m_ucWriteCharBuf[0] |= m_ucWriteCharBuf[1]; if(iExtraBits == m_iWriteBitPos) { if( m_pbuf->sputc( m_ucWriteCharBuf[0] ) == EOF ) throw BufferException("Ran out of room in the designated buffer", STACK_ENTRY); m_iWriteBitPos = 8; m_ucWriteCharBuf[0] = 0x00; } else if(iExtraBits < m_iWriteBitPos) { m_iWriteBitPos -= iExtraBits; m_ucWriteCharBuf[0] = MaskBits(m_ucWriteCharBuf[0], 8 - m_iWriteBitPos); } else if(iExtraBits > m_iWriteBitPos) { if( m_pbuf->sputc( m_ucWriteCharBuf[0] ) == EOF ) throw BufferException("Ran out of room in the designated buffer", STACK_ENTRY); m_ucWriteCharBuf[0] = seg[count]; m_ucWriteCharBuf[0] >>= ( 8 - iExtraBits ); iExtraBits -= m_iWriteBitPos; m_iWriteBitPos = ( 8 - iExtraBits ); m_ucWriteCharBuf[0] <<= m_iWriteBitPos; } } return totalBitsWrote; } unsigned char AsnBufBits::MaskBits(unsigned char cCharToMask, int iBitsToMask) { unsigned char cReturnChar = 0x00; cReturnChar = cCharToMask; if(iBitsToMask < 8 && iBitsToMask > 0) { cReturnChar >>= 8 - iBitsToMask; cReturnChar <<= 8 - iBitsToMask; } return cReturnChar; } //RWC;TBD; FIX THIS TO WORK PROPERLY..... bool AsnBufBits::operator<(AsnBufBits &rhs) { FUNC("AsnBufBits::operator<()"); bool lessThan = true; bool firstTime = true; //ResetMode(); //rhs.ResetMode(); // Check that both buffers are valid if ((m_pbuf == NULL) || (rhs.m_pbuf == NULL)) throw BufferException("NULL internal m_pbuf pointer", STACK_ENTRY); AsnBufBits tmpBuf1(*this); VDAstreambuf *pVDAbufref1 = (VDAstreambuf *)tmpBuf1.m_pbuf; char* pg1=pVDAbufref1->Vgptr(); char* peg1=pVDAbufref1->Vegptr(); char* peb1=pVDAbufref1->Veback(); AsnBufBits tmpBuf2(rhs); VDAstreambuf *pVDAbufref2 = (VDAstreambuf *)rhs.m_pbuf; char* pg2=pVDAbufref2->Vgptr(); char* peg2=pVDAbufref2->Vegptr(); char* peb2=pVDAbufref2->Veback(); std::streambuf::int_type ch1; std::streambuf::int_type ch2; while ( lessThan ) { try { ch1 = tmpBuf1.ReadByte(); } catch (BufferException &) { ch1 = EOF; } try { ch2 = tmpBuf2.ReadByte(); } catch (BufferException &) { ch2 = EOF; } if ((ch1 == EOF) && (ch2 == EOF)) { if (firstTime) lessThan = false; break; } else if (ch2 == EOF) { lessThan = false; break; } else if (ch1 == EOF) { break; } if (ch1 > ch2) lessThan = false; else if (ch1 < ch2) break; firstTime = false; } //ResetMode(); //rhs.ResetMode(); pVDAbufref1->Vsetg( peb1, pg1, peg1); pVDAbufref2->Vsetg( peb2, pg2, peg2 ); //RE-SET referenced shared stream pointer. return lessThan; } // END AsnBufBits::operator<(AsnBufBits &rhs) esnacc-ng-1.8.1/cxx-lib/src/asn-enum.cpp000066400000000000000000000163531302010526100177410ustar00rootroot00000000000000// file: .../c++-lib/src/asn-enum.C - methods for AsnEnum (ASN.1 ENUMERATED) class // // MS 92/06/16 // Copyright (C) 1992 Michael Sample and the University of British Columbia // // This library is free software; you can redistribute it and/or // modify it provided that this copyright/license information is retained // in original form. // // If you modify this file, you must clearly indicate your changes. // // This source code is distributed in the hope that it will be // useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // // $Header: /baseline/SNACC/c++-lib/src/asn-enum.cpp,v 1.13 2003/12/17 19:05:03 gronej Exp $ // $Log: asn-enum.cpp,v $ // Revision 1.13 2003/12/17 19:05:03 gronej // SNACC baseline merged with PER v1_7 tag // // Revision 1.12.2.3 2003/12/02 18:33:43 gronej // Updated and debugged PER constraint logic for primitives // // Revision 1.12.2.2 2003/10/22 12:45:58 gronej // Updating PER compiler // // Revision 1.12.2.1 2003/10/02 17:15:24 gronej // Updating PER compiler // // Revision 1.12 2003/01/06 16:20:07 leonberp // Changed BDec() and BDecContent() to use const AsnBufs // // Revision 1.11 2002/12/17 20:27:40 leonberp // made BEnc() and BEncContent() const // // Revision 1.10 2002/10/23 21:02:48 leonberp // fixed AsnBuf references and fixed clock skew problem // // Revision 1.9 2002/10/23 10:51:10 mcphersc // Changed BUF_TYPE to AsnBuf // // Revision 1.8 2002/05/10 16:39:34 leonberp // latest changes for release 2.2 // includes integrating asn-useful into C & C++ runtime library, the compiler changes that go along with that, SnaccException changes for C++ runtime and compiler // // Revision 1.7 2001/08/29 22:04:18 leonberp // enchanced Clone() to allocate a new pointe AND COPY the object // // Revision 1.6 2001/07/12 19:33:37 leonberp // Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. // // Revision 1.5 2001/06/28 15:29:47 rwc // ADDED "SNACCASN" namespace definition to all SNACC data structures. // This should not affect most applications since we do not have any name // conflicts. // ALSO, combined all ASN primitive data type includes into asn-incl.h. // // Revision 1.4 2001/06/26 15:03:48 mcphersc // Tex - Added logic to accept a clone of the enum. // // Revision 1.3 2001/06/18 17:47:43 rwc // Updated to reflect newly added C++ Exception error handling, instead of "C" longjmp and setjmp calls. // Changes made to both the compiler and the SNACC C++ run-time library. // // Revision 1.2 2000/10/24 14:54:40 rwc // Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. // SOME warnings persist due to difficulty in modifying the SNACC compiler to // properly build clean source; also some files are built by Lex/Yacc. // // Revision 1.1.1.1 2000/08/21 20:36:08 leonberp // First CVS Version of SNACC. // // Revision 1.5 1997/02/28 13:39:44 wan // Modifications collected for new version 1.3: Bug fixes, tk4.2. // // Revision 1.4 1995/08/17 15:19:52 rj // AsnEnumTypeDesc gets its own TclGetVal and TclSetVal functions. // // Revision 1.3 1995/07/24 20:14:49 rj // Clone() added, or else the _desc would be wrong (and the wrong BEnc etc... would get called) for Clone-d objects. // // call constructor with additional pdu and create arguments. // // changed `_' to `-' in file names. // // Revision 1.2 1994/10/08 05:26:37 rj // comment leader fixed. // // Revision 1.1 1994/10/08 05:24:03 rj // functions extracted from ../inc/asn_enum.h #include "asn-incl.h" _BEGIN_SNACC_NAMESPACE AsnLen AsnEnum::BEnc (AsnBuf &b) const { AsnLen l; l = BEncContent (b); BEncDefLenTo127 (b, l); l++; l += BEncTag1 (b, UNIV, PRIM, ENUM_TAG_CODE); return l; } /*Takes the enumerated list, sorts them, and returns the index of the */ /*number that matches the value */ long AsnEnum::IndexedVal(long *penumList, long numVals)const { FUNC("AsnEnum::IndexedVal"); long * indexedList = penumList; long temp = 0; long count1 = 0; long count2 = 0; bool bValueNotInList = true; if(m_len > 4) throw EXCEPT("enumerated value is too big", INTEGER_ERROR); for(count1 = 0; count1 < numVals; count1++) { for(count2 = 0; count2 < numVals; count2++) { if(indexedList[count2] < indexedList[count1]) { temp = indexedList[count2]; indexedList[count2] = indexedList[count1]; indexedList[count1] = temp; } } } temp = (long)*this; for(count1 = 0; count1 < numVals; count1++) { if(temp == indexedList[count1]) { temp = count1; count1 = numVals; bValueNotInList = false; } } if(bValueNotInList) throw EXCEPT("value is not in enumerated List", INTEGER_ERROR); return temp; } /*sorts the enumerated list and matches the decoded number with */ /*the associated indexed number in the list */ void AsnEnum::SetIndex(long *penumList, long numVals, long index) { long * indexedList = penumList; long temp = 0; long count1 = 0; long count2 = 0; for(count1 = 0; count1 < numVals; count1++) { for(count2 = 0; count2 < numVals; count2++) { if(indexedList[count2] < indexedList[count1]) { temp = indexedList[count2]; indexedList[count2] = indexedList[count1]; indexedList[count1] = temp; } } } Set(indexedList[index]); } void AsnEnum::BDec (const AsnBuf &b, AsnLen &bytesDecoded) { FUNC("AsnEnum::BDec"); AsnLen elmtLen; AsnTag tagId; tagId = BDecTag (b, bytesDecoded); if (tagId != MAKE_TAG_ID (UNIV, PRIM, ENUM_TAG_CODE)) { throw InvalidTagException(typeName(), tagId, STACK_ENTRY); } elmtLen = BDecLen (b, bytesDecoded); BDecContent (b, MAKE_TAG_ID (UNIV, PRIM, ENUM_TAG_CODE), elmtLen, bytesDecoded); } #if META const AsnEnumTypeDesc AsnEnum::_desc (NULL, NULL, false, AsnTypeDesc::ENUMERATED, NULL, NULL); const AsnTypeDesc *AsnEnum::_getdesc() const { return &_desc; } #if TCL int AsnEnum::TclGetVal (Tcl_Interp *interp) const { const AsnNameDesc *n = _getdesc()->getnames(); if (n) { for (; n->name; n++) if (n->value == value) { Tcl_SetResult (interp, (char*)n->name, TCL_STATIC); return TCL_OK; } } char valstr[80]; sprintf (valstr, "%d", value); Tcl_AppendResult (interp, "illegal numeric enumeration value ", valstr, " for type ", _getdesc()->getmodule()->name, ".", _getdesc()->getname(), NULL); Tcl_SetErrorCode (interp, "SNACC", "ILLENUM", NULL); return TCL_ERROR; } int AsnEnum::TclSetVal (Tcl_Interp *interp, const char *valstr) { const AsnNameDesc *n = _getdesc()->getnames(); if (n) { for (; n->name; n++) if (!strcmp (n->name, valstr)) { value = n->value; return TCL_OK; } } Tcl_SetErrorCode (interp, "SNACC", "ILLENUM", NULL); Tcl_AppendResult (interp, "illegal symbolic enumeration value \"", valstr, "\" for type ", _getdesc()->getmodule()->name, ".", _getdesc()->getname(), NULL); return TCL_ERROR; } #endif /* TCL */ #endif /* META */ _END_SNACC_NAMESPACE esnacc-ng-1.8.1/cxx-lib/src/asn-extension.cpp000066400000000000000000000013241302010526100210010ustar00rootroot00000000000000 #include "asn-incl.h" _BEGIN_SNACC_NAMESPACE AsnLen AsnExtension::BEnc(AsnBuf& b) const { AsnLen l = 0; std::list::const_reverse_iterator i; for (i = extList.rbegin(); i != extList.rend(); ++i) l += i->BEnc(b); return l; } AsnLen AsnExtension::PEnc(AsnBufBits& b) const { AsnLen l = 0; std::list::const_iterator i; for (i = extList.begin(); i != extList.end(); ++i) l += i->PEnc(b); return l; } void AsnExtension::Print(std::ostream& os, unsigned short indent) const { std::list::const_iterator i; for (i = extList.begin(); i != extList.end(); ++i) { i->Print(os, indent); os<<"\n"; Indent(os, indent); } } _END_SNACC_NAMESPACE esnacc-ng-1.8.1/cxx-lib/src/asn-fileseg.cpp000066400000000000000000000060321302010526100204040ustar00rootroot00000000000000#include "asn-buf.h" #include "snaccexcept.h" #include #include using namespace SNACC; AsnFileSeg::AsnFileSeg(const char *pFilename) { FUNC("AsnFileSeg::AsnFileSeg()"); m_filename = strdup(pFilename); m_fb = new std::filebuf; if (m_fb->open(m_filename, std::ios_base::in | std::ios_base::binary) == NULL) throw FileException(m_filename, FileException::OPEN, STACK_ENTRY); m_offset = 0; m_segSize = m_fb->pubseekoff(0, std::ios_base::end, std::ios_base::in); if (m_segSize == -1) { throw FileException(m_filename, FileException::READ, STACK_ENTRY); } m_fb->pubseekpos(0, std::ios_base::in); } AsnFileSeg::AsnFileSeg(AsnFileSeg *afs, unsigned long segLen) { FUNC("AsnFileSeg::CopyConstructor()"); m_offset = afs->pubseekoff(0, std::ios_base::cur, std::ios_base::in); m_segSize = segLen; m_filename = strdup(afs->m_filename); m_fb = new std::filebuf; if (m_fb->open(m_filename, std::ios_base::in | std::ios_base::binary) == NULL) throw FileException(m_filename, FileException::OPEN, STACK_ENTRY); } // Copy constructor // // assign offset and segSize from o and copy filename, and construct new // std::filebuf from that filename // AsnFileSeg::AsnFileSeg(const AsnFileSeg &o) : std::basic_streambuf() { FUNC("AsnFileSeg::CopyConstructor()"); m_offset = o.m_offset; m_segSize = o.m_segSize; m_filename = strdup(o.m_filename); m_fb = new std::filebuf; if (m_fb->open(m_filename, std::ios_base::in | std::ios_base::binary) == NULL) throw FileException(m_filename, FileException::OPEN, STACK_ENTRY); } // Destructor // AsnFileSeg::~AsnFileSeg() { free(m_filename); delete m_fb; } std::streambuf::int_type AsnFileSeg::underflow() { // check current position to determine if we've read segSize yet // long currPos = m_fb->pubseekoff(0, std::ios_base::cur); if ( (currPos - m_offset) < (long) m_segSize) { return m_fb->sgetc(); } else return EOF; } std::streambuf::int_type AsnFileSeg::uflow() { // check current position to determine if we've read segSize yet // long currPos = m_fb->pubseekoff(0, std::ios_base::cur); if ( (currPos - m_offset) < (long) m_segSize) { return m_fb->sbumpc(); } else return EOF; } std::streamsize AsnFileSeg::xsgetn(char *s, std::streamsize n) { long currPos = m_fb->pubseekoff(0, std::ios_base::cur); // if the file segment contains the number of bytes requested // then grab it. if (n <= (m_segSize - (currPos - m_offset)) ) { return m_fb->sgetn(s, n); } else { return EOF; } } std::streambuf::pos_type AsnFileSeg::seekoff(off_type off, std::ios_base::seekdir way, std::ios_base::openmode which) { return (m_fb->pubseekoff((m_offset + off), way, which)); } std::streambuf::pos_type AsnFileSeg::seekpos(std::streambuf::pos_type sp, std::ios_base::openmode which) { return (seekoff(sp, std::ios_base::beg, which)); } esnacc-ng-1.8.1/cxx-lib/src/asn-int.cpp000066400000000000000000001077001302010526100175640ustar00rootroot00000000000000// File: .../c++-lib/src/asn-int.C - methods for AsnInt (ASN.1 INTEGER) class // // MS 92/06/16 // Copyright (C) 1992 Michael Sample and the University of British Columbia // // This library is free software; you can redistribute it and/or // modify it provided that this copyright/license information is retained // in original form. // // If you modify this file, you must clearly indicate your changes. // // This source code is distributed in the hope that it will be // useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // // $Log: asn-int.cpp,v $ // Revision 1.66 2004/03/25 19:20:16 gronej // fixed some linux warnings // // Revision 1.65 2004/03/22 19:38:13 leonberp // changed ConstraintErrorStringList to be const to avoid possible memory corruption // // Revision 1.64 2004/03/09 16:48:45 gronej // Updated c++ constraint checking capability and constraint error handling // // Revision 1.63 2004/03/01 15:50:45 gronej // Took out SetConstraints() and member variables for constraints, replaced with functions that return constraint lists // // Revision 1.62 2004/02/12 18:55:09 gronej // Stable SNACC // non optional choices, sets and sequences are now not pointers // merged with list code // all memory leaks within SNACC fixed // // Revision 1.61 2004/02/11 19:08:48 nicholar // Updated Print() function so no longer uses global indent // // Revision 1.60 2004/02/06 00:39:13 nicholar // Changed AsnList to use std::list instead of List // // Revision 1.59 2004/02/04 14:59:27 gronej // Fixed a TON of memory leaks // // Revision 1.58 2004/02/03 14:44:32 gronej // made all constraint lists static to avoid memory issues // // Revision 1.57 2003/12/17 19:05:03 gronej // SNACC baseline merged with PER v1_7 tag // // Revision 1.54.2.14 2003/12/15 18:43:50 gronej // EKMS PER Beta Release Files // // Revision 1.54.2.13 2003/12/09 21:20:50 gronej // Updated to pull working EKMS test space // // Revision 1.54.2.12 2003/12/04 20:47:10 gronej // Moved bAlign out of all PEnc calls and into AsnBufBits as a member // An AsnBufBits is now invoked with a bAlign parameter defaulted to false // // Revision 1.54.2.11 2003/12/03 19:48:08 gronej // Fixed bitsDecoded to return correct value on decode operations // // Revision 1.54.2.10 2003/12/02 18:33:43 gronej // Updated and debugged PER constraint logic for primitives // // Revision 1.54.2.9 2003/12/02 17:00:09 colestor // Fixed unsetf(...) of HEX setting when printing. // // Revision 1.54.2.8 2003/11/26 14:23:17 colestor // Fixed AsnInt initialization. // // Revision 1.54.2.7 2003/11/06 20:23:25 gronej // Updated PER compiler with working Interpret() and Deterpret() functionality for AsnInt and String Types // // Revision 1.54.2.6 2003/11/05 14:58:54 gronej // working PER code merged with esnacc_1_6 // // Revision 1.54.2.5 2003/11/04 18:04:08 gronej // Update PER compiler with some PERGeneral functionality 11/04/03 // // Revision 1.54.2.4 2003/11/04 14:21:21 gronej // Update PER compiler with some PERGeneral functionality 11/04/03 // // Revision 1.54.2.3 2003/10/22 12:45:58 gronej // Updating PER compiler // // Revision 1.54.2.2 2003/10/02 17:15:24 gronej // Updating PER compiler // // Revision 1.54.2.1 2003/08/12 20:04:38 gronej // no message // // Revision 1.54 2003/03/28 14:10:16 leonberp // added pragmas to get rid of warnings // // Revision 1.53 2003/03/17 17:35:16 leonberp // fixed compile errors for HPUX // // Revision 1.52 2003/01/28 17:30:44 leonberp // added AsnInt copy constructor and operator= // // Revision 1.51 2003/01/28 14:23:22 leonberp // replaced memmove with memcpy // // Revision 1.50 2003/01/28 14:10:13 leonberp // Added AsnInt destructor // // Revision 1.49 2003/01/27 20:58:06 leonberp // enhanced to use dynamically allocated unsigned char[] and length instead of basic_string<> for performance reasons also removed obsolete code // // Revision 1.48 2003/01/06 16:20:07 leonberp // Changed BDec() and BDecContent() to use const AsnBufs // // Revision 1.47 2002/12/22 01:20:52 colestor // (RWC)Updated PrintXML(...) details to better match specification for SEQUENCE OF and SET OF logic. // // Revision 1.46 2002/12/19 18:17:54 colestor // (RWC)Updated to allow integer output as ASCII. // // Revision 1.45 2002/12/17 20:27:40 leonberp // made BEnc() and BEncContent() const // // Revision 1.44 2002/11/25 20:21:19 leonberp // added AsnBuf copy constructor // // Revision 1.43 2002/10/23 21:02:48 leonberp // fixed AsnBuf references and fixed clock skew problem // // Revision 1.42 2002/10/23 10:51:10 mcphersc // Changed BUF_TYPE to AsnBuf // // Revision 1.41 2002/10/21 19:49:50 leonberp // changes for Linux and GCC 3.2 // // Revision 1.40 2002/10/01 19:43:06 vracarl // now using c_ustr // // Revision 1.39 2002/09/25 13:54:54 vracarl // made asn_buf fixes // // Revision 1.38 2002/09/16 20:06:47 vracarl // new asn-octs changes // // Revision 1.37 2002/08/21 16:48:07 vracarl // added a FUNC and throw and checks to make sure the decimal number isn't too large // // Revision 1.36 2002/08/19 18:14:43 vracarl // added code to construct an int from decimal format // // Revision 1.35 2002/07/17 17:30:09 leonberp // fixed for unix // // Revision 1.34 2002/07/17 14:29:47 vracarl // removed #include // // Revision 1.33 2002/07/15 17:04:14 vracarl // moved an indefinite len check // // Revision 1.32 2002/07/12 19:59:21 nicholar // Fixed bug in AsnInt:storeDERInteger. // Enhanced AsnInt::operator==(AsnIntType i) function. // // Revision 1.31 2002/06/17 18:42:14 leonberp // yet another bug fix // // Revision 1.30 2002/06/17 18:25:50 leonberp // fixed bug again // // Revision 1.29 2002/06/17 17:20:46 leonberp // fixed AsnInt bug // // Revision 1.28 2002/06/17 16:37:58 leonberp // fixed AsnInt conversion operator code // // Revision 1.27 2002/06/13 15:47:03 leonberp // added c_str() and length() dumped get() // // Revision 1.26 2002/06/13 15:06:26 leonberp // added get() to AsnInt // // Revision 1.25 2002/06/12 21:29:56 leonberp // fixed Linux compile error // // Revision 1.24 2002/06/12 20:43:26 leonberp // new AsnInt class // // Revision 1.23 2002/05/21 14:07:02 nicholar // Removed warnings // // Revision 1.22 2002/05/10 16:39:35 leonberp // latest changes for release 2.2 // includes integrating asn-useful into C & C++ runtime library, the compiler changes that go along with that, SnaccException changes for C++ runtime and compiler // // Revision 1.21 2002/03/25 19:32:16 vracarl // added an AsnInt constructor to handle str to hex conversions - still need to add binary // // Revision 1.20 2002/03/01 14:07:40 vracarl // typo // // Revision 1.19 2002/02/28 21:47:27 vracarl // added an INDEFINATE_LEN check on the primitive // // Revision 1.18 2002/02/12 14:42:34 rwc // Updates to fix the BigInteger Get Signed call to properly pre-load 0xff. (Thank you james.bishop@jrc.it). // Also some Linux/Unix fixes. // // Revision 1.17 2002/02/11 15:54:04 leonberp // changed the conversion and comparison operators so that they'll work with const objects // // Revision 1.16 2001/11/14 22:39:21 sfl // Updated logic to accept BigIntegerStr with 1 in upper-most bit on decode. // This allows our lib to be more forgiving on older messages, not throw // an exception when all else would succeed.. // // Revision 1.15 2001/10/29 12:04:56 nicholar // Replaced memcpy with memmove where needed // // Revision 1.14 2001/10/09 13:52:30 rwc // Memory leak testing updates. // // Revision 1.13 2001/09/21 20:16:20 rwc // Partial updates to start integration of Sign/Encrypt/Sign message processing. // // Revision 1.12 2001/09/21 18:01:08 rwc // Updated to properly return BigIntegerString processed buffer if count matches // precisely to expected value. Previously, it simply returned, without copying // the input to the output as expected. // // Revision 1.11 2001/08/29 22:04:18 leonberp // enchanced Clone() to allocate a new pointe AND COPY the object // // Revision 1.10 2001/08/27 21:25:41 leonberp // I 'const' enchanced CSM_Buffer and update all code that references it // // Revision 1.9 2001/08/24 15:39:24 leonberp // Enchanced Print() and PrintXML() #if'd out PrintXMLSupport() // // Revision 1.8 2001/07/19 16:02:51 sfl // Yet more string.h updates. // // Revision 1.7 2001/07/12 19:33:37 leonberp // Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. // // Revision 1.6 2001/06/28 21:38:28 rwc // Updated to remove referneces to vdacerr, which originally replaced the cerr standard error output. // Updated all references in macros and source that printed to vdacerr. All code now performs an // ASN_THROW(...) exception. // // Revision 1.5 2001/06/28 15:29:47 rwc // ADDED "SNACCASN" namespace definition to all SNACC data structures. // This should not affect most applications since we do not have any name // conflicts. // ALSO, combined all ASN primitive data type includes into asn-incl.h. // // Revision 1.4 2001/06/18 17:47:43 rwc // Updated to reflect newly added C++ Exception error handling, instead of "C" longjmp and setjmp calls. // Changes made to both the compiler and the SNACC C++ run-time library. // // Revision 1.3 2001/06/12 14:40:57 rwc // Updates to add the SFL CSM_BigIntegerStr multi-byte integer logic to // AsnInt for SNACC primitive support. The code has been tested for full // backward compatibility for integer assign/compare, etc. // // Revision 1.2 2000/10/16 18:10:37 rwc // removed most warnings from C++-lib, some C-lib. // // Revision 1.1.1.1 2000/08/21 20:36:08 leonberp // First CVS Version of SNACC. // // Revision 1.7 1997/02/28 13:39:45 wan // Modifications collected for new version 1.3: Bug fixes, tk4.2. // // Revision 1.6 1995/09/07 18:55:50 rj // (unsigned) long int replaced by newly introduced Asn(U)IntType at a lot of places. // they shall provide 32 bit integer types on all platforms. // // Revision 1.5 1995/07/24 20:17:32 rj // #if TCL ... #endif wrapped into #if META ... #endif // // call constructor with additional pdu and create arguments. // // changed `_' to `-' in file names. // // Revision 1.4 1995/02/18 16:48:05 rj // denote a long if we want a long // // Revision 1.3 1994/10/08 04:18:23 rj // code for meta structures added (provides information about the generated code itself). // // code for Tcl interface added (makes use of the above mentioned meta code). // // virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included. // // made Print() const (and some other, mainly comparison functions). // // several `unsigned long int' turned into `size_t'. // // Revision 1.2 1994/08/28 10:01:12 rj // comment leader fixed. // // Revision 1.1 1994/08/28 09:20:59 rj // first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. // Revision 2.0 6/4/01 RWC; VDA // Added logic to accommodate real ASN.1 multi-byte integers, not just 4 byte. #include "asn-incl.h" #ifdef WIN32 #if defined(_MSC_VER) #pragma warning(disable: 4100 4710 4251 4018) #pragma warning(push,3) #endif #include #if defined(_MSC_VER) #pragma warning(pop) #endif #else #include #endif #include _BEGIN_SNACC_NAMESPACE #if META const AsnIntTypeDesc AsnInt::_desc (NULL, NULL, false, AsnTypeDesc::INTEGER, NULL, NULL); const AsnTypeDesc *AsnInt::_getdesc() const { return &_desc; } #if TCL #define RETURN_NAME_INSTEAD_OF_VALUE 0 int AsnInt::TclGetVal (Tcl_Interp *interp) const { #if RETURN_NAME_INSTEAD_OF_VALUE const AsnNameDesc *n = _getdesc()->getnames(); if (n) for (; n->name; n++) if (n->value == value) { Tcl_SetResult (interp, n->name, TCL_STATIC); return TCL_OK; } #endif char buf[32]; sprintf (buf, "%d", value); Tcl_SetResult (interp, buf, TCL_VOLATILE); return TCL_OK; } int AsnInt::TclSetVal (Tcl_Interp *interp, const char *valstr) { const AsnNameDesc *n = _getdesc()->getnames(); if (n) for (; n->name; n++) if (!strcmp (n->name, valstr)) { value = n->value; return TCL_OK; } int valval; if (Tcl_GetInt (interp, (char*)valstr, &valval) != TCL_OK) return TCL_ERROR; value = valval; return TCL_OK; } #endif /* TCL */ #endif /* META */ //RWC;6/4/01; newly added functionality (along with changes above). //------------------------------------------------------------------------------ // class member definitions: // // AsnLen AsnInt::BEnc (AsnBuf &b) const { FUNC("AsnInt::BEnc"); if( checkConstraints(NULL) != 0 ) throw ConstraintException("Integer not within constraints", STACK_ENTRY); AsnLen l=0; l = BEncContent (b); l += BEncDefLen (b, l); l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE); return l; } // // void AsnInt::BDec (const AsnBuf &b, AsnLen &bytesDecoded) { FUNC("AsnInt::BDec"); AsnTag tag; AsnLen elmtLen1; if (((tag = BDecTag (b, bytesDecoded)) != MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)) && (tag != MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE))) { throw InvalidTagException(typeName(), tag, STACK_ENTRY); } elmtLen1 = BDecLen (b, bytesDecoded); BDecContent (b, tag, elmtLen1, bytesDecoded); } AsnLen AsnInt::BEncContent (AsnBuf &b) const { b.PutSegRvs((char *)m_bytes, m_len); return m_len; } void AsnInt::BDecContent (const AsnBuf &b, AsnTag, AsnLen elmtLen, AsnLen &bytesDecoded) { FUNC("AsnInt::BDecContent()"); if (elmtLen == INDEFINITE_LEN) throw EXCEPT("indefinite length on primitive", DECODE_ERROR); delete[] m_bytes; m_bytes = new unsigned char[elmtLen + 1]; m_len = elmtLen; b.GetSeg((char *)m_bytes, elmtLen); bytesDecoded += elmtLen; } AsnInt::AsnInt (const AsnInt &that) { m_len = 0; m_bytes = NULL; operator=(that); } AsnInt::AsnInt(const char *str, const size_t len, bool unsignedFlag) { m_len = 0; m_bytes = NULL; storeDERInteger((const unsigned char *)str, len, unsignedFlag); } AsnInt::AsnInt(const AsnOcts &o, bool unsignedFlag) { m_len = 0; m_bytes = NULL; storeDERInteger(o.c_ustr(), o.Len(), unsignedFlag); } // Construct an AsnInt from an integer value // AsnInt::AsnInt (AsnIntType val) { if (val == 0) { m_len = 1; m_bytes = new unsigned char[1]; *m_bytes = 0; } else { m_len = 0; m_bytes = NULL; Set(val); } } // Construct an AsnInt from a null terminated character string. // The string can be in either HEX or decimal format. // // HEX format accepted: // 0xFFFFF // 'FFFFF'H // AsnInt::AsnInt(const char *str, bool unsignedFlag) { char radix=0; unsigned length = strlen(str); unsigned i = 0; //std::basic_string localBytes; std::vector localBytes; AsnIntType l = 0; FUNC("AsnInt::AsnInt"); m_len = 0; m_bytes = NULL; if (length == 0) return; switch (str[length-1]) { case 'h': case 'H': radix=16; break; } if (radix == 16) { if (str[0] != '\'' && str[length-2] != '\'') return; length -= 2; i = 1; } else { if (strncmp("0x", str, 2) == 0) { radix = 16; i = 2; } else // assume it's a decimal { // make sure the number isn't out of range if (((strlen(str) >= 11) && (str[0] != '-')) || ((strlen(str) == 11) && (str[0] == '-') && (str[1] >= '2')&& (str[2] >= '1')) || ((strlen(str) == 10) && (str[0] >= '2') && (str[1] >= '1'))) { throw EXCEPT("decimal string is too big to convert to an integer", INTEGER_ERROR); } l = atol(str); Set(l); } } if (radix == 16) { bool flag = false; unsigned char prevDigit = 0; for (; i= '0' && str[i] <= '9') digit = (unsigned char)(str[i] - '0'); else if (str[i] >= 'A' && str[i] <= 'F') digit = (unsigned char)(str[i] - 'A' + 10); else if (str[i] >= 'a' && str[i] <= 'f') digit = (unsigned char)(str[i] - 'a' + 10); else return; if (!flag) { prevDigit = digit; flag = true; } else { prevDigit <<= 4; prevDigit |= digit; //localBytes += prevDigit; localBytes.push_back(prevDigit); flag = false; } } storeDERInteger(&localBytes[0], localBytes.size(), unsignedFlag); } } AsnInt::~AsnInt() { if(m_bytes) delete[] m_bytes; } void AsnInt::storeDERInteger(const unsigned char *pData, long dataLen, bool unsignedFlag) { m_len = 0; delete[] m_bytes; /* IF the application generates an r,s,p,q,g or y value in which the * first 9 bits are all set to 0, then the encoding software deletes the * first octet from the octets to be encoded. This rule is applied * repeatedly to the remaining octets until the first 9 bits are not all * set to 0. */ if (unsignedFlag) { // Check for leading nine bits all zero if (dataLen > 1) { while (dataLen > 1 && !( (pData[0] & 0xFF) || (pData[1] & 0x80)) ) { ++pData; --dataLen; } } m_bytes = new unsigned char[dataLen + 1]; m_len = dataLen; /* If the application generates a r,s,p,q,g, or y value in which the * MSB is set to 1, THEN the software prepends a single octet in which * all bits are set to 0. */ if (*pData & 0x80) { // Prepend a leading octet memcpy(m_bytes + 1, pData, dataLen); *m_bytes = '\0'; m_len++; } else memcpy(m_bytes, pData, dataLen); } /* * ASN.1 rules state that the first 9 bits of an integer encoding can * not be all ones or all zeros. */ else if (dataLen > 1 ) { /* check for first first 9 bits all ones */ while ((dataLen > 1) && (pData[0] == 0xFF) && (pData[1] & 0x80)) { ++pData; --dataLen; } /* check for first 9 bits all zeros */ while ((dataLen > 1) && (pData[0] == 0) && ((pData[1] & 0x80) == 0)) { ++pData; --dataLen; } m_bytes = new unsigned char[dataLen + 1]; m_len = dataLen; memcpy(m_bytes, pData, dataLen); } } AsnInt & AsnInt::operator =(const AsnInt &that) { if (this != &that) { m_len = that.m_len; delete[] m_bytes; m_bytes = new unsigned char[m_len]; memcpy(m_bytes, that.m_bytes, m_len); } return *this; } // Conversion operator for converting an AsnInt to an AsnIntType // AsnInt::operator AsnIntType() const { FUNC("AsnInt::operator AsnIntType"); AsnIntType iResult=0; if (m_len > sizeof(AsnIntType)) { throw EXCEPT("integer is too big for conversion to AsnIntType", INTEGER_ERROR); } // If big int is negative initialize result to -1 // if ( (m_bytes[0] >> 7 == 1) ) { iResult = -1; } if (m_len > 0) { /* * write from buffer into AsnIntType */ for (unsigned int i = 0; i < m_len; i++) iResult = (iResult << 8) | (AsnUIntType)(m_bytes[i]); } else { iResult = 0; } return iResult; } // Set AsnInt from a buffer. Buffer is assumed to be a proper // ASN.1 integer. // void AsnInt::Set (const unsigned char *pData, size_t len, bool unsignedFlag) { storeDERInteger(pData, len, unsignedFlag); } // Set AsnInt from a AsnIntType // void AsnInt::Set(AsnIntType iIn) { AsnIntType iTmp; unsigned char cTmp[sizeof(iIn)]; iTmp = iIn; for (unsigned long i=0; i < sizeof(iIn); i++) cTmp[3-i] = (unsigned char)((iTmp >> (8*i)) & 0xff); storeDERInteger(cTmp, sizeof(iIn), (iIn >= 0)); } void AsnInt::getPadded(unsigned char *&bigIntDataOut, size_t &bigIntLen, const size_t padToSize) const { FUNC("AsnInt::GetUnSignedBitExtendedData()"); bigIntLen = m_len; const unsigned char *bigIntData = m_bytes; /* This is fix to determine if the r,s,p,q,g, or y value is of the correct * length. */ if (padToSize > 0) { /* if bigint length is less than the expected number of octets * the decoding software ensures that the MSB is 0 and, if so, it * prepends the appropriate number of octets in which every bit is * set to 0 to the decoded value to obtain the value supplied to * Fortezza Card. */ if ( bigIntLen < padToSize ) { long prepend = 0; unsigned char *tmpInt; prepend = padToSize - bigIntLen; tmpInt = (unsigned char *) calloc(1, bigIntLen + prepend); memset( tmpInt, 0, prepend); memcpy( &tmpInt[prepend], bigIntData , bigIntLen); bigIntDataOut = tmpInt; bigIntLen += prepend; } /* If the encoded values includes an "extra" octet THEN the * decoding software ensures that every bit in the initial octets is * set to 0 and, if so, deletes the initial octet from the decoded value * to obtain the value to be supplied to the Fortezza Card. If the * extra octet contains a bit set to 1, then an error is reported. */ else if (bigIntLen > padToSize) { if (bigIntData[0] != 0) { throw EXCEPT("Extra octet is not zero.", INTEGER_ERROR); } bigIntLen--; bigIntDataOut = (unsigned char *) calloc(1, bigIntLen); memcpy( &bigIntDataOut[0], &bigIntData[1], bigIntLen); } else // Exact length. { bigIntDataOut = (unsigned char *) calloc(1, bigIntLen); memcpy( &bigIntDataOut[0], &bigIntData[0], bigIntLen); } } // bigIntData AND bigIntLen contain the results. } bool AsnInt::operator == (const AsnInt &o) const { if (m_len == o.m_len) return (memcmp(m_bytes, o.m_bytes, m_len) == 0); else return false; } bool AsnInt::operator != (const AsnInt &o) const { return (!(*this == o)); } bool AsnInt::operator==(AsnIntType o) const { if (m_len > sizeof(AsnIntType)) return false; // Convert this AsnInt to a normal integer AsnIntType result = 0; if (m_len > 0) { // If the AsnInt is negative initialize the result to -1 if ((m_bytes[0] & 0x80) != 0) result = -1; for (unsigned int i = 0; i < m_len; ++i) { result <<= 8; result |= (unsigned char)m_bytes[i]; } } return (result == o); } bool AsnInt::operator<(const AsnInt &o) const { if (m_len < o.m_len) return true; else if (m_len > o.m_len) return false; if (memcmp(m_bytes, o.m_bytes, m_len) < 0) return true; else return false; } void AsnInt::Print(std::ostream& os, unsigned short /*indent*/) const { os << "'"; os.setf(std::ios::hex); char buf[3]; buf[2] = '\0'; for (unsigned long i = 0; i < m_len; i++) { sprintf(buf, "%2.2x", (int)m_bytes[i]); os << buf; } //END for all data. os << "'H -- \n"; os.unsetf(std::ios::hex); } void AsnInt::PrintXML(std::ostream &os, const char *lpszTitle) const { if (lpszTitle) { os << "<" << lpszTitle; os << " type=\"INTEGER\">\n"; } else { os << "\n"; } //RWC:os << "-"; Print(os); if (lpszTitle) os << "\n"; else os << "\n"; } int AsnInt::checkConstraints (ConstraintFailList* pConstraintFails)const { FUNC("AsnInt::checkConstraints"); int numValueRanges; const ValueRange* valueRanges = ValueRanges(numValueRanges); int count = 0; int failed = 1; std::string ptr; long ltemp= 0; const char* tmpptr = NULL; if (m_len > sizeof(AsnIntType) && (numValueRanges > 0) ) { throw EXCEPT("Integer is out of constraint range", CONSTRAINT_ERROR); } if(valueRanges) { ltemp = *this; for(count = 0; count< numValueRanges; count++) { tmpptr = NULL; if(valueRanges[count].upperBoundExists == 1) { if( ( ltemp < valueRanges[count].lowerBound ) || ( ltemp > valueRanges[count].upperBound ) ) { tmpptr = ConstraintErrorStringList[ INTEGER_VALUE_RANGE ]; } } else if(valueRanges[count].upperBoundExists == 2) { if( ltemp != valueRanges[count].lowerBound ) { tmpptr = ConstraintErrorStringList[ INTEGER_SINGLE_VALUE ]; } } else if(valueRanges[count].upperBoundExists == 0) { if( ltemp < valueRanges[count].lowerBound ) { tmpptr = ConstraintErrorStringList[ INTEGER_VALUE_RANGE ]; } } if(tmpptr) { ptr += tmpptr; } else { failed = 0; } } } else { failed = 0; } if(failed) { if(pConstraintFails!=NULL) pConstraintFails->push_back(ptr); } return failed; } void AsnInt::putByte(long offset, unsigned char cByte) { m_bytes[offset] = cByte; } void AsnInt::Allocate(long size) { unsigned char* temp = new unsigned char[m_len + size]; if (m_len) // RWC; { // RWC; memcpy(temp, m_bytes, m_len); size += m_len; } //RWC; Clear(); m_len = size; m_bytes = new unsigned char[m_len]; if( m_len ) memcpy(m_bytes, temp, m_len); delete [] temp; } void AsnInt::PDec(AsnBufBits &b, AsnLen &bitsDecoded) { int numValueRanges; const ValueRange* valueRanges = ValueRanges(numValueRanges); int x = 0; int upperBoundFound = 0; int lowerBound = 0; int upperBound = 0; Clear(); if(numValueRanges <= 0) { DecodeGeneral(b, bitsDecoded); } else { lowerBound = valueRanges[x].lowerBound; upperBound = lowerBound; upperBoundFound = valueRanges[x].upperBoundExists; for(x = 0; x < numValueRanges; x++) { if(lowerBound > valueRanges[x].lowerBound) { lowerBound = valueRanges[x].lowerBound; } if(upperBound < valueRanges[x].lowerBound) { upperBound = valueRanges[x].lowerBound; } if(valueRanges[x].upperBoundExists == 1) { upperBoundFound = 1; if(upperBound < valueRanges[x].upperBound) { upperBound = valueRanges[x].upperBound; } } } if(upperBound > lowerBound) upperBoundFound = 1; if(upperBoundFound == 1) { if(lowerBound != upperBound) PDecFullyConstrained(b, lowerBound, upperBound, bitsDecoded); } else { if(numValueRanges == 1 && valueRanges[0].upperBoundExists == 2 ) { Set(lowerBound); } else { PDecSemiConstrained(b, lowerBound, bitsDecoded); } } } } void AsnInt::PDecSemiConstrained (AsnBufBits &b, long lowerBound, AsnLen &bitsDecoded) { FUNC("AsnInt::PDec(...Semi-Constrained Int...)"); unsigned char* seg; long l_intval; m_len = 0; seg = (unsigned char*)b.GetBits(8); bitsDecoded += 8; m_len = (long)seg[0]; if(m_len > 4) { throw EXCEPT("integer is too big for decoding from offset", INTEGER_ERROR); } delete [] seg; seg = (unsigned char*)b.GetBits(m_len * 8); bitsDecoded += (m_len * 8); Set(seg, m_len); l_intval = *this; l_intval += lowerBound; Set(l_intval); delete [] seg; } void AsnInt::PDecFullyConstrained (AsnBufBits &b, long lowerBound, long upperBound, AsnLen &bitsDecoded) { FUNC("AsnInt::PDec(...Fully-Constrained Int...)"); unsigned char* seg = NULL; long l_intval = 0; int oddBits = 0; unsigned long range = (upperBound - lowerBound) + 1; long tempRange = range; long minBitsNeeded = 0; long numBytes = 0; long count = 0; unsigned char pChar[] = {0x00, 0x00}; Clear(); m_len = 0; if(range != 1) { tempRange -= 1; while(tempRange > 0) { tempRange -= (long)(1 << minBitsNeeded); minBitsNeeded += 1; } if(b.IsAligned()) { if(range <= 255) { seg = b.GetBits(minBitsNeeded); bitsDecoded += minBitsNeeded; seg[0] >>= (8 - minBitsNeeded); l_intval = (long)seg[0]; } else if(range == 256) { bitsDecoded += b.OctetAlignRead(); seg = b.GetBits(8); bitsDecoded += 8; l_intval = (long)seg[0]; } else if(range > 256 && range < 65536) { bitsDecoded += b.OctetAlignRead(); seg = b.GetBits(16); bitsDecoded += 16; l_intval = (long)seg[0]; l_intval <<= 8; l_intval |= (long)seg[1]; } else if(range >= 65536) { minBitsNeeded /= 8; if( (minBitsNeeded % 8) != 0 ) { minBitsNeeded += 1; } minBitsNeeded -= 1; seg = b.GetBits(minBitsNeeded); bitsDecoded += minBitsNeeded; seg[0] >>= 8 - (minBitsNeeded % 8); numBytes = (long)seg[0]; numBytes += 1; delete [] seg; if(numBytes > 4) throw EXCEPT("integer is too big for decoded", INTEGER_ERROR); seg = b.GetBits(numBytes * 8); bitsDecoded += (numBytes * 8); l_intval = seg[0]; count = 1; while(count < numBytes) { l_intval <<= 8; l_intval |= (long)seg[count]; count++; } } } else { seg = b.GetBits(minBitsNeeded); bitsDecoded += minBitsNeeded; numBytes = minBitsNeeded / 8; oddBits = (minBitsNeeded % 8); if( oddBits == 0) { l_intval = (long)seg[0]; count = 1; while(count < numBytes) { l_intval <<= 8; l_intval |= (long)seg[count]; count++; } } else { m_len = numBytes + 2; m_bytes = new unsigned char[m_len]; count = numBytes; while(count > 0) { seg[count] >>= (8 - oddBits); pChar[0] = seg[count - 1]; pChar[0] <<= oddBits; seg[count] |= pChar[0]; count--; } seg[count] >>= (8 - oddBits); l_intval = (long)seg[0]; count = 1; while(count < numBytes + 1) { l_intval <<= 8; l_intval |= (long)seg[count]; count++; } } } } l_intval += lowerBound; Set(l_intval); delete [] seg; } AsnLen AsnInt::Interpret(AsnBufBits &b, long offset)const { AsnLen len = 8; unsigned char* pEncodedVal = NULL; unsigned char c; c = getByte(offset); pEncodedVal = &c; b.PutBits(pEncodedVal, len); return len; } void AsnInt::Deterpret(AsnBufBits &b, AsnLen &bitsDecoded, long offset) { unsigned char* seg; seg = b.GetBits(8); bitsDecoded += 8; putByte(offset, seg[0]); delete [] seg; } AsnLen AsnInt::PEnc(AsnBufBits &b)const { FUNC("AsnInt::PEnc"); int numValueRanges; const ValueRange* valueRanges = ValueRanges(numValueRanges); AsnLen len = 0; int x = 0; int upperBoundFound = 0; int lowerBound = 0; int upperBound = 0; if( checkConstraints(NULL) != 0 ) throw ConstraintException("Integer not within constraints", STACK_ENTRY); if(numValueRanges <= 0) { len = EncodeGeneral(b); } else { lowerBound = valueRanges[x].lowerBound; upperBound = lowerBound; upperBoundFound = valueRanges[x].upperBoundExists; for(x = 0; x < numValueRanges; x++) { if(lowerBound > valueRanges[x].lowerBound) { lowerBound = valueRanges[x].lowerBound; } if(upperBound < valueRanges[x].lowerBound) { upperBound = valueRanges[x].lowerBound; } if(valueRanges[x].upperBoundExists == 1) { upperBoundFound = 1; if(upperBound < valueRanges[x].upperBound) { upperBound = valueRanges[x].upperBound; } } } if(upperBound > lowerBound) upperBoundFound = 1; if(upperBoundFound == 1) { if(lowerBound != upperBound) len = PEncFullyConstrained(b, lowerBound, upperBound); } else { if(numValueRanges == 1 && valueRanges[0].upperBoundExists == 2 ) { if((long)*this != lowerBound) { throw EXCEPT("integer does not match singlevalue size constraint", INTEGER_ERROR); } } else { len = PEncSemiConstrained(b, lowerBound); } } } return len; } /*PER encoding of an semi-constrained integer*/ AsnLen AsnInt::PEncSemiConstrained (AsnBufBits &b, long lowerBound)const { FUNC("AsnInt::PEnc(...Semi-Constrained Int...)"); AsnLen len = 0; long tempval; AsnInt tempInt = AsnInt(); if(m_len>4) { throw EXCEPT("integer is too big for encoding from offset", INTEGER_ERROR); } tempval = *this; tempval -= lowerBound; tempInt = tempval; if((tempInt.m_len) > 1 && (tempInt.m_bytes[0]) == 0x00) { memmove(tempInt.m_bytes, tempInt.m_bytes + 1, tempInt.m_len - 1); tempInt.m_len--; } if(tempInt.m_len > 4) { throw EXCEPT("offset from lower bound too large to be encoded", INTEGER_ERROR); } len = tempInt.EncodeGeneral(b); return len; } /*PER encoding of constrained integer types*/ AsnLen AsnInt::PEncFullyConstrained(AsnBufBits &b, long lowerBound, long upperBound)const { FUNC("AsnInt::PEnc(...Constrained Int...)"); unsigned long range = ((upperBound - lowerBound) + 1); AsnLen len = 0; long tempval; AsnInt tempInt; AsnInt tempInt2; int minBitsNeeded = 0; long tempRange = range; int oddBits = 0; unsigned char pChar[] = {0x00, 0x00, 0x00, 0x00}; if(m_len>4) { throw EXCEPT("decimal string is too big to convert to an integer", INTEGER_ERROR); } tempval = *this; if( tempval < lowerBound || tempval > upperBound ) { throw EXCEPT("Integer is out of range", INTEGER_ERROR); } tempval -= lowerBound; tempInt.Set(tempval); if((tempInt.m_len) > 1 && (tempInt.m_bytes[0]) == 0x00) { memmove(tempInt.m_bytes, tempInt.m_bytes + 1, tempInt.m_len - 1); tempInt.m_len--; } if( range <= 0 ) { throw EXCEPT("upperBound cannot be smaller than lowerBound", INTEGER_ERROR); } if(tempInt.m_len > 4) { throw EXCEPT("offset from lower bound too large to be encoded", INTEGER_ERROR); } if(range != 1) { tempRange -= 1; while(tempRange > 0) { tempRange -= (long)(1 << minBitsNeeded); minBitsNeeded += 1; } if(b.IsAligned()) { if(range <= 255) { pChar[0] = tempInt.m_bytes[0]; pChar[0] <<= 8 - minBitsNeeded; len += b.PutBits(pChar, minBitsNeeded); } else if(range == 256) { len += b.OctetAlignWrite(); pChar[0] = tempInt.m_bytes[0]; len += b.PutBits(pChar, 8); } else if(range > 256 && range < 65536) { len += b.OctetAlignWrite(); if(tempInt.m_len < 2) { pChar[0] = 0x00; len += b.PutBits(pChar, 8); } len += b.PutBits(tempInt.m_bytes, tempInt.m_len * 8); } else if(range >= 65536) { minBitsNeeded /= 8; if( (minBitsNeeded % 8) != 0 ) { minBitsNeeded += 1; } minBitsNeeded -= 1; tempval = tempInt.m_len - 1; tempInt2.Set(tempval); if((tempInt2.m_len) > 1 && (tempInt2.m_bytes[0]) == 0x00) { memmove(tempInt2.m_bytes, tempInt2.m_bytes + 1, tempInt2.m_len - 1); tempInt2.m_len--; } if((unsigned)minBitsNeeded > (tempInt2.m_len * 8)) { len += b.PutBits(pChar, minBitsNeeded - (tempInt2.m_len * 8)); minBitsNeeded -= (minBitsNeeded - (tempInt2.m_len * 8)); } //TBD, NOT SURE IF THIS LOGIC WORKS CORRECTLY oddBits = (minBitsNeeded % 8); if( oddBits== 0) { len += b.PutBits(tempInt2.m_bytes, tempInt2.m_len * 8); } else { pChar[0] = tempInt2.m_bytes[0]; pChar[0] <<= 8 - oddBits; len += b.PutBits(pChar, oddBits); if(tempInt2.m_len > 1) { len += b.PutBits(&tempInt2.m_bytes[1], (tempInt2.m_len - 1) * 8); } } len += b.PutBits(tempInt.m_bytes, tempInt.m_len * 8); } } else { if((unsigned)minBitsNeeded > (tempInt.m_len * 8)) { len += b.PutBits(pChar, minBitsNeeded - (tempInt.m_len * 8)); minBitsNeeded -= (minBitsNeeded - (tempInt.m_len * 8)); } oddBits = (minBitsNeeded % 8); if( oddBits== 0) { len += b.PutBits(tempInt.m_bytes, tempInt.m_len * 8); } else { pChar[0] = tempInt.m_bytes[0]; pChar[0] <<= 8 - oddBits; len += b.PutBits(pChar, oddBits); if(tempInt.m_len > 1) { len += b.PutBits(&tempInt.m_bytes[1], (tempInt.m_len - 1) * 8); } } } } return len; } _END_SNACC_NAMESPACE esnacc-ng-1.8.1/cxx-lib/src/asn-len.cpp000066400000000000000000000210031302010526100175370ustar00rootroot00000000000000// file: .../c++-lib/src/asn-len.C - ASN.1 Length manipluation routines // // MS 92/06/18 // Copyright (C) 1992 Michael Sample and the University of British Columbia // // This library is free software; you can redistribute it and/or // modify it provided that this copyright/license information is retained // in original form. // // If you modify this file, you must clearly indicate your changes. // // This source code is distributed in the hope that it will be // useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // // $Header: /baseline/SNACC/c++-lib/src/asn-len.cpp,v 1.18 2004/03/03 20:19:01 gronej Exp $ // $Log: asn-len.cpp,v $ // Revision 1.18 2004/03/03 20:19:01 gronej // took out readLoc from choice's BDecContent generation, and made new // put-back logic to put back a tag and a length so you can properly decode // an unkown any // // Revision 1.17 2004/02/09 20:38:50 nicholar // Updated AsnOid and AsnRelativeOid classes // // Revision 1.16 2003/12/17 19:05:03 gronej // SNACC baseline merged with PER v1_7 tag // // Revision 1.15.2.2 2003/11/04 14:21:21 gronej // Update PER compiler with some PERGeneral functionality 11/04/03 // // Revision 1.15.2.1 2003/10/22 12:45:58 gronej // Updating PER compiler // // Revision 1.15 2003/01/17 01:16:04 leonberp // FIXED A TON of warnings // // Revision 1.14 2003/01/06 16:20:07 leonberp // Changed BDec() and BDecContent() to use const AsnBufs // // Revision 1.13 2002/11/27 14:29:35 leonberp // changed to use GetUByte() // // Revision 1.12 2002/10/24 14:04:22 leonberp // fixing support for OCTET STRING CONTAINING // // Revision 1.11 2002/10/23 21:02:48 leonberp // fixed AsnBuf references and fixed clock skew problem // // Revision 1.10 2002/10/23 10:51:10 mcphersc // Changed BUF_TYPE to AsnBuf // // Revision 1.9 2002/10/09 19:37:55 leonberp // new AsnBuf integration // // Revision 1.8 2002/10/01 13:43:57 leonberp // fixed to use new AsnBuf // // Revision 1.7 2002/05/10 16:39:35 leonberp // latest changes for release 2.2 // includes integrating asn-useful into C & C++ runtime library, the compiler changes that go along with that, SnaccException changes for C++ runtime and compiler // // Revision 1.6 2002/03/01 14:13:22 vracarl // fixed incorrect ASN_THROW message text // // Revision 1.5 2001/07/12 19:33:37 leonberp // Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. // // Revision 1.4 2001/06/28 15:29:47 rwc // ADDED "SNACCASN" namespace definition to all SNACC data structures. // This should not affect most applications since we do not have any name // conflicts. // ALSO, combined all ASN primitive data type includes into asn-incl.h. // // Revision 1.3 2001/06/18 17:47:43 rwc // Updated to reflect newly added C++ Exception error handling, instead of "C" longjmp and setjmp calls. // Changes made to both the compiler and the SNACC C++ run-time library. // // Revision 1.2 2000/10/16 18:10:37 rwc // removed most warnings from C++-lib, some C-lib. // // Revision 1.1.1.1 2000/08/21 20:36:08 leonberp // First CVS Version of SNACC. // // Revision 1.5 1997/02/16 20:26:04 rj // check-in of a few cosmetic changes // // Revision 1.4 1995/07/24 20:33:15 rj // changed `_' to `-' in file names. // // Revision 1.3 1994/10/08 04:18:24 rj // code for meta structures added (provides information about the generated code itself). // // code for Tcl interface added (makes use of the above mentioned meta code). // // virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included. // // made Print() const (and some other, mainly comparison functions). // // several `unsigned long int' turned into `size_t'. // // Revision 1.2 1994/08/28 10:01:13 rj // comment leader fixed. // // Revision 1.1 1994/08/28 09:21:00 rj // first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. #include "asn-incl.h" /*#include "asn-config.h" #include "asn-len.h"*/ _BEGIN_SNACC_NAMESPACE /*returns the number of bytes in the encoded length passed in*/ long BytesInLen(AsnLen len) { if (len < 128) { return 1; } else if (len < 256) { return 2; } else if (len < 65536) { return 3; } else if (len < 16777126) { return 4; } else { return 5; } } /* * Encodes the given length to the given buffer. * returns the number of octets written to the buffer. */ AsnLen BEncDefLen (AsnBuf &b, AsnLen len) { /* * unrolled for efficiency * (check each possibitlity of the 4 byte integer) */ if (len < 128) { b.PutByteRvs ((unsigned char)len); return 1; } else if (len < 256) { b.PutByteRvs ((unsigned char)len); b.PutByteRvs ((unsigned char)0x81); return 2; } else if (len < 65536) { b.PutByteRvs ((unsigned char)len); b.PutByteRvs ((unsigned char)(len >> 8)); b.PutByteRvs ((unsigned char) 0x82); return 3; } else if (len < 16777126) { b.PutByteRvs ((unsigned char)len); b.PutByteRvs ((unsigned char)(len >> 8)); b.PutByteRvs ((unsigned char)(len >> 16)); b.PutByteRvs ((unsigned char)0x83); return 4; } else { b.PutByteRvs ((unsigned char)len); b.PutByteRvs ((unsigned char)(len >> 8)); b.PutByteRvs ((unsigned char)(len >> 16)); b.PutByteRvs ((unsigned char)(len >> 24)); b.PutByteRvs ((unsigned char)0x84); return 5; } } /* EncodeDefLen */ /* * Decode a BER length from the given buffer. Increments bytesDecoded * by the number of octets of the encoded length. Flags an * error if the length is too large or a read error occurs */ AsnLen BDecLen (const AsnBuf &b, AsnLen &bytesDecoded) { FUNC("BDecLen()"); AsnLen len; unsigned char byte; unsigned long lenBytes; byte = b.GetUByte(); bytesDecoded++; if (byte < 128) /* short length */ return byte; else if (byte == (unsigned char) 0x080) /* indef len indicator */ return INDEFINITE_LEN; else /* long len form */ { /* * strip high bit to get # bytes left in len */ lenBytes = byte & (unsigned char) 0x7f; if (lenBytes > sizeof (long)) { throw BoundsException("length overflow", STACK_ENTRY); } bytesDecoded += lenBytes; for (len = 0; lenBytes > 0; lenBytes--) len = (len << 8) | (unsigned long int) b.GetUByte(); return len; } /* not reached */ } /* * Encodes an End of Contents (EOC) to the given buffer. * Returns the encoded length. */ AsnLen BEncEoc (AsnBuf &b) { b.PutByteRvs (0); b.PutByteRvs (0); return 2; } /* BEncEoc */ /* * Decodes an EOC from the given buffer. Flags an error if the * octets are non-zero or if read error occured. */ void BDecEoc (const AsnBuf &b, AsnLen &bytesDecoded) { FUNC("BDecEoc()"); if ((b.GetUByte() != 0) || (b.GetUByte() != 0)) { throw EXCEPT("non zero byte in EOC or end of data reached" , DECODE_ERROR); } bytesDecoded += 2; } /* BDecEoc */ /* PER encoding of the length determinant for lengths */ /* zero to 127 inclusive */ /* Length will encode in one byte with bit 8 = 0 */ AsnLen PEncDefLenTo127(AsnBufBits &b, int len) { unsigned char cLen = (unsigned char)len; b.PutBits(&cLen, 8); return 8; } /* PER encoding of the length determinant for lengths */ /* in 16k fragments */ /* Length will encode in one byte, bit 7 and 8 = 1 */ /* lower bits (1-4) are multiplied by 16k to give */ /* length determinant */ AsnLen PEncLen_16kFragment(AsnBufBits &b, int len) { AsnLen l= 8; unsigned char cLen = 0xC0; cLen |= ((unsigned char)len); unsigned char *c = &cLen; b.PutBits(c, l); return l; } /* PER encoding of the length determinant for lengths */ /* between 127 and 16k non-inclusive */ AsnLen PEncLen_1to16k(AsnBufBits &b, int len) { AsnLen l = 16; int templen = len; unsigned char cLen = ((unsigned char)len); unsigned char *c = &cLen; len >>= 8; cLen = ((unsigned char)len); cLen |= 0x80; c = &cLen; b.PutBits(c, 8); cLen = (unsigned char)templen; c = &cLen; b.PutBits(c, 8); return l; } _END_SNACC_NAMESPACE esnacc-ng-1.8.1/cxx-lib/src/asn-null.cpp000066400000000000000000000135561302010526100177510ustar00rootroot00000000000000// file: .../c++-lib/src/asn-null.C // // MS 92 // Copyright (C) 1992 Michael Sample and the University of British Columbia // // This library is free software; you can redistribute it and/or // modify it provided that this copyright/license information is retained // in original form. // // If you modify this file, you must clearly indicate your changes. // // This source code is distributed in the hope that it will be // useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // // $Header: /baseline/SNACC/c++-lib/src/asn-null.cpp,v 1.13 2004/02/11 19:08:48 nicholar Exp $ // $Log: asn-null.cpp,v $ // Revision 1.13 2004/02/11 19:08:48 nicholar // Updated Print() function so no longer uses global indent // // Revision 1.12 2003/12/17 19:05:03 gronej // SNACC baseline merged with PER v1_7 tag // // Revision 1.11.2.4 2003/12/04 20:47:10 gronej // Moved bAlign out of all PEnc calls and into AsnBufBits as a member // An AsnBufBits is now invoked with a bAlign parameter defaulted to false // // Revision 1.11.2.3 2003/11/04 14:21:21 gronej // Update PER compiler with some PERGeneral functionality 11/04/03 // // Revision 1.11.2.2 2003/10/22 12:45:58 gronej // Updating PER compiler // // Revision 1.11.2.1 2003/10/02 17:15:24 gronej // Updating PER compiler // // Revision 1.11 2003/01/06 16:20:07 leonberp // Changed BDec() and BDecContent() to use const AsnBufs // // Revision 1.10 2002/12/17 20:27:40 leonberp // made BEnc() and BEncContent() const // // Revision 1.9 2002/10/23 21:02:48 leonberp // fixed AsnBuf references and fixed clock skew problem // // Revision 1.8 2002/10/23 10:51:10 mcphersc // Changed BUF_TYPE to AsnBuf // // Revision 1.7 2002/05/10 16:39:35 leonberp // latest changes for release 2.2 // includes integrating asn-useful into C & C++ runtime library, the compiler changes that go along with that, SnaccException changes for C++ runtime and compiler // // Revision 1.6 2001/08/29 22:04:18 leonberp // enchanced Clone() to allocate a new pointe AND COPY the object // // Revision 1.5 2001/07/12 19:33:38 leonberp // Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. // // Revision 1.4 2001/06/28 15:29:47 rwc // ADDED "SNACCASN" namespace definition to all SNACC data structures. // This should not affect most applications since we do not have any name // conflicts. // ALSO, combined all ASN primitive data type includes into asn-incl.h. // // Revision 1.3 2001/06/18 17:47:43 rwc // Updated to reflect newly added C++ Exception error handling, instead of "C" longjmp and setjmp calls. // Changes made to both the compiler and the SNACC C++ run-time library. // // Revision 1.2 2000/10/16 18:10:37 rwc // removed most warnings from C++-lib, some C-lib. // // Revision 1.1.1.1 2000/08/21 20:36:08 leonberp // First CVS Version of SNACC. // // Revision 1.5 1995/08/17 15:38:19 rj // set Tcl's errorCode variable // // Revision 1.4 1995/07/24 20:18:27 rj // #if TCL ... #endif wrapped into #if META ... #endif // // call constructor with additional pdu and create arguments. // // changed `_' to `-' in file names. // // Revision 1.3 1994/10/08 04:18:26 rj // code for meta structures added (provides information about the generated code itself). // // code for Tcl interface added (makes use of the above mentioned meta code). // // virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included. // // made Print() const (and some other, mainly comparison functions). // // several `unsigned long int' turned into `size_t'. // // Revision 1.2 1994/08/28 10:01:15 rj // comment leader fixed. // // Revision 1.1 1994/08/28 09:21:04 rj // first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. #include "asn-incl.h" _BEGIN_SNACC_NAMESPACE void AsnNull::BDecContent (const AsnBuf &/*b*/, AsnTag /*tagId*/, AsnLen elmtLen, AsnLen &/*bytesDecoded*/) { FUNC("AsnNull::BDecContent()"); if (elmtLen != 0) { throw BoundsException("AsnNull has non-zero length", STACK_ENTRY); } } /* AsnNull::BDecContent */ AsnLen AsnNull::PEnc (AsnBufBits &) const { return AsnLen(0); } void AsnNull::PDec (AsnBufBits &, AsnLen &) { } AsnLen AsnNull::BEnc (AsnBuf &b) const { AsnLen l; l = BEncContent (b); BEncDefLenTo127 (b, l); l++; l += BEncTag1 (b, UNIV, PRIM, NULLTYPE_TAG_CODE); return l; } void AsnNull::BDec (const AsnBuf &b, AsnLen &bytesDecoded) { FUNC("AsnNull::BDec()"); AsnLen elmtLen; AsnTag tagId; tagId = BDecTag (b, bytesDecoded); if (tagId != MAKE_TAG_ID (UNIV, PRIM, NULLTYPE_TAG_CODE)) { throw InvalidTagException(typeName(), tagId, STACK_ENTRY); } elmtLen = BDecLen (b, bytesDecoded); BDecContent (b, MAKE_TAG_ID (UNIV, PRIM, NULLTYPE_TAG_CODE), elmtLen, bytesDecoded); } void AsnNull::Print(std::ostream& os, unsigned short /*indent*/) const { os << "NULL"; } void AsnNull::PrintXML (std::ostream &os, const char *lpszTitle) const { os << ""; if (lpszTitle) os << lpszTitle; os << "-"; Print(os); os << "\n"; } #if META const AsnNullTypeDesc AsnNull::_desc (NULL, NULL, false, AsnTypeDesc::NUL_, NULL); const AsnTypeDesc *AsnNull::_getdesc() const { return &_desc; } #if TCL int AsnNull::TclGetVal (Tcl_Interp *interp) const { return TCL_OK; } int AsnNull::TclSetVal (Tcl_Interp *interp, const char *valstr) { if (*valstr) { Tcl_AppendResult (interp, "illegal non-null value `", valstr, "' for type ", _getdesc()->getmodule()->name, ".", _getdesc()->getname(), NULL); Tcl_SetErrorCode (interp, "SNACC", "ILLNULL", NULL); return TCL_ERROR; } return TCL_OK; } #endif /* TCL */ #endif /* META */ _END_SNACC_NAMESPACE esnacc-ng-1.8.1/cxx-lib/src/asn-octs.cpp000066400000000000000000000431621302010526100177430ustar00rootroot00000000000000/*#include */ #include "asn-incl.h" #include _BEGIN_SNACC_NAMESPACE // Copy Constructor // // copy m_str and pFileSeg AsnOcts::AsnOcts(const AsnOcts &o) { m_str = o.m_str; if (o.m_pFileSeg != NULL) m_pFileSeg = new AsnFileSeg(*o.m_pFileSeg); else m_pFileSeg = NULL; } AsnOcts::~AsnOcts() { if (m_pFileSeg != NULL) delete m_pFileSeg; } // Returns the length of the AsnOcts. size_t AsnOcts::Len() const { size_t result = 0; result = m_str.length(); if (m_pFileSeg != NULL) result = m_pFileSeg->size(); return result; } // Returns the data const std::string & AsnOcts::data() const { char ch; // IF the octet string is not in an AsnFileSeg just return the string // if (m_pFileSeg == NULL) { return m_str; } // ELSE if the octet string is in an AsnFileSeg read it into the // string then return it. Destroy the AsnFileSeg in the process. // else { m_pFileSeg->pubseekoff(0, std::ios_base::beg, std::ios_base::in); while ((ch = (char)m_pFileSeg->snextc()) != EOF) { m_str += ch; ch = (char)m_pFileSeg->snextc(); } delete m_pFileSeg; m_pFileSeg = NULL; return m_str; } } // Returns the data const char * AsnOcts::c_str() const { return data().c_str(); } const unsigned char* AsnOcts::c_ustr() const { return (unsigned char *) data().data(); } // Initialize the AsnOcts with a char * and length. // copies the string str. void AsnOcts::Set (const char *str, size_t len) { m_str.assign(str, len); } // Prints the AsnOcts to the given ostream in Value Notation. void AsnOcts::PrintXML (std::ostream &os, const char *lpszTitle, const char *lpszType) const { if (lpszType) os << "<" << lpszType << ">"; else os << ""; if (lpszTitle) os << lpszTitle; os << "-"; Print(os); //PrintXMLSupport(&os, ((AsnOcts *)this)->Access(), octetLen); if (lpszType) os << "\n"; else os << "\n"; } // Prints the AsnOcts to the given ostream in Value Notation. void AsnOcts::Print(std::ostream& os, unsigned short /*indent*/) const { int i; os << "'"; for (i = 0; i < (int)Len(); i++) os << TO_HEX (c_ustr()[i] >> 4) << (TO_HEX (c_ustr()[i])); os << "'H -- \""; /* put printable parts in ASN.1 comment */ for (i = 0; i < (int)Len(); i++) { if (isspace ((unsigned char)c_ustr()[i]) || ! isprint(c_ustr()[i])) os << "."; /* newlines->space (so don't screw up ASN.1 comment) */ else os << c_ustr()[i]; } os << "\" --"; } /* AsnOcts::Print */ AsnLen AsnOcts::BEncContent (AsnBuf &b) const { if (m_pFileSeg != NULL) b.PutFileSeg(m_pFileSeg); else b.PutSegRvs(m_str.data(), m_str.length()); return Len(); } // Decodes a BER OCTET STRING value and puts it in this object. // Constructed OCTET STRINGs are always concatenated into primitive ones. void AsnOcts::BDecContent (const AsnBuf &b, AsnTag tagId, AsnLen elmtLen, AsnLen &bytesDecoded) { FUNC("AsnOcts::BDecContent()"); if (elmtLen != 0) { /* * tagId is encoded tag shifted into long int. * if CONS bit is set then constructed octet string */ if (tagId & 0x20000000) { BDecConsOcts (b, elmtLen, bytesDecoded); } else /* primitive octet string */ { if (elmtLen == INDEFINITE_LEN) throw BoundsException("indefinite length on primitive", STACK_ENTRY); /** PIERCE: commented out until further testing is done else if (elmtLen > MAX_OCTS) // use a filebuf instead of memory { m_pFileSeg = b.GetFileSeg(elmtLen); } else // use memory { b.GetSeg(m_str, elmtLen); } **/ b.GetSeg(m_str,elmtLen); bytesDecoded += elmtLen; } } } /* AsnOcts::BDecContent */ AsnLen AsnOcts::EncodeWithSizeConstraint(AsnBufBits &b)const { FUNC("AsnOcts::EncodeWithSizeConstraint"); int numSizeConstraints; const SizeConstraint* sizeConstraints = SizeConstraints(numSizeConstraints); AsnLen len = 0; int iSCLowerBound = sizeConstraints[0].lowerBound; int iSCUpperBound = iSCLowerBound; int minBitsNeeded = 0; int minBytesNeeded = 0; long Range = FindSizeConstraintBounds(iSCLowerBound, iSCUpperBound); long tempRange = Range - 1; long size = length(); unsigned char* pStr = new unsigned char[1]; while(tempRange > 0) { tempRange -= (long)(1 << minBitsNeeded); minBitsNeeded += 1; } if(size < iSCLowerBound || size > iSCUpperBound) { delete [] pStr; throw EXCEPT("AsnOcts size not withing restricted bounds", RESTRICTED_TYPE_ERROR); } if(Range > 1) { if( (iSCUpperBound <= 2) && b.IsAligned()) { len += b.OctetAlignWrite(); } minBytesNeeded = minBitsNeeded / 8; minBitsNeeded = minBitsNeeded % 8; size -= iSCLowerBound; if(minBytesNeeded > 0) { pStr[0] = (unsigned char)(size >> minBitsNeeded); len += b.PutBits(pStr, 8); } pStr[0] = (unsigned char)size; pStr[0] <<= 8 - minBitsNeeded; len += b.PutBits(pStr, minBitsNeeded); } if(iSCUpperBound > 0) { if( (iSCUpperBound <= 2) && b.IsAligned()) { len += b.OctetAlignWrite(); } len += b.PutBits((unsigned char*)c_ustr(), (length() * 8) ); } delete [] pStr; return len; } void AsnOcts::DecodeWithSizeConstraint(AsnBufBits &b, AsnLen &bitsDecoded) { FUNC("AsnString::DecodeWithSizeConstraint"); int numSizeConstraints; const SizeConstraint* sizeConstraints = SizeConstraints(numSizeConstraints); int iSCLowerBound = sizeConstraints[0].lowerBound; int iSCUpperBound = iSCLowerBound; int minBitsNeeded = 0; int minBytesNeeded = 0; long Range = FindSizeConstraintBounds(iSCLowerBound, iSCUpperBound); long tempRange = Range - 1; long decodeSize = 0; unsigned char* seg; unsigned char* pStr = new unsigned char[1]; clear(); while(tempRange > 0) { tempRange -= (long)(1 << minBitsNeeded); minBitsNeeded += 1; } if(Range > 1) { if( (iSCUpperBound <= 2) && b.IsAligned()) { bitsDecoded += b.OctetAlignRead(); } minBytesNeeded = minBitsNeeded / 8; minBitsNeeded = minBitsNeeded % 8; if(minBytesNeeded > 0) { delete [] pStr; pStr = b.GetBits(8); bitsDecoded += 8; decodeSize <<= 8; decodeSize |= (long)pStr[0]; } delete [] pStr; pStr = b.GetBits(minBitsNeeded); bitsDecoded += minBitsNeeded; if(minBitsNeeded > 0) { decodeSize <<= minBitsNeeded; pStr[0] >>= (8 - minBitsNeeded); decodeSize |= (long)pStr[0]; } } decodeSize += iSCLowerBound; if(decodeSize > iSCUpperBound) { delete [] pStr; throw EXCEPT("String size not withing restricted bounds", RESTRICTED_TYPE_ERROR); } if(iSCUpperBound > 0) { if( (iSCUpperBound <= 2) && b.IsAligned()) { bitsDecoded += b.OctetAlignRead(); } seg = b.GetBits(decodeSize * 8); m_str.append((const char*)seg, decodeSize); bitsDecoded += (decodeSize * 8); delete [] seg; } delete [] pStr; } long AsnOcts::FindSizeConstraintBounds(int &iSCLowerBound, int &iSCUpperBound)const { int count = 0; int numSizeConstraints; const SizeConstraint* sizeConstraints = SizeConstraints(numSizeConstraints); while(count < numSizeConstraints) { if((unsigned)iSCUpperBound < sizeConstraints[count].lowerBound) { iSCUpperBound = sizeConstraints[count].lowerBound; } if( sizeConstraints[count].upperBoundExists == 1 && (unsigned)iSCUpperBound < sizeConstraints[count].upperBound) { iSCUpperBound = sizeConstraints[count].upperBound; } if( (unsigned)iSCLowerBound > sizeConstraints[count].lowerBound ) { iSCLowerBound = sizeConstraints[count].lowerBound; } count++; } return ( (iSCUpperBound - iSCLowerBound) + 1); } AsnLen AsnOcts::EncodeGeneral(AsnBufBits &b)const { AsnLen len = 0; unsigned long l_64kFrag = l_16k * 4; unsigned long count = 0; unsigned long x = 0; unsigned long tempLen = length(); unsigned char ch = 0x00; unsigned char *c = NULL; long offset = 0; if(tempLen >= l_16k) { /*there is more than 16k bytes of data*/ count = (tempLen / l_64kFrag); for(x=0; x < count; x++) { len += b.OctetAlignWrite(); len += PEncLen_16kFragment(b, 4); len += b.OctetAlignWrite(); len += b.PutBits((unsigned char*)&m_str[offset], (l_64kFrag * 8) ); offset += l_64kFrag; } tempLen -= count * l_64kFrag; count = tempLen / l_16k; if(count != 0) { len += b.OctetAlignWrite(); len += PEncLen_16kFragment(b, count); len += b.OctetAlignWrite(); len += b.PutBits((unsigned char*)&m_str[offset], (count * l_16k * 8) ); offset += (count * l_16k); } tempLen -= (l_16k * count); if(tempLen == 0) { ch = 0x00; c = &ch; len += b.OctetAlignWrite(); len += b.PutBits(c, 8); return len; } } /*if there are less than 128 bytes of data*/ if(tempLen < 128) { len += b.OctetAlignWrite(); len += PEncDefLenTo127(b, tempLen); len += b.OctetAlignWrite(); len += b.PutBits((unsigned char*)&m_str[offset], (tempLen * 8) ); offset += tempLen; } else if(tempLen >= 128 && tempLen < l_16k) { len += b.OctetAlignWrite(); /*if there is less than 16k bytes of data*/ /*and more than 127 bytes of data*/ len += PEncLen_1to16k(b, tempLen); len += b.OctetAlignWrite(); len += b.PutBits((unsigned char*)&m_str[offset], (tempLen * 8) ); offset += tempLen; } return len; } void AsnOcts::DecodeGeneral(AsnBufBits &b, AsnLen &bitsDecoded) { unsigned char* seg; unsigned long templen = 0; clear(); bitsDecoded += b.OctetAlignRead(); seg = (unsigned char*)b.GetBits(8); bitsDecoded += 8; while((seg[0] & 0xC0) == 0xC0) { seg[0] &= 0x3F; templen = (unsigned long)seg[0]; templen *= l_16k; b.OctetAlignRead(); const char *pseg = (const char *)b.GetBits(templen * 8); m_str.append(pseg, templen); bitsDecoded += (templen * 8); bitsDecoded += b.OctetAlignRead(); delete [] pseg; delete [] seg; seg = (unsigned char*)b.GetBits(8); bitsDecoded += 8; } if((seg[0] & 0xC0) == 0x80) { seg[0] &= 0x3F; templen = (unsigned long)seg[0]; templen <<= 8; delete [] seg; seg = (unsigned char*)b.GetBits(8); bitsDecoded += 8; templen |= (unsigned long)seg[0]; bitsDecoded += b.OctetAlignRead(); delete [] seg; seg = b.GetBits(templen * 8); m_str.append((const char*)seg, templen); delete [] seg; bitsDecoded += (templen * 8); } else if((seg[0] & 0x80) == 0x00) { seg[0] &= 0x7F; templen = (unsigned long)seg[0]; bitsDecoded += b.OctetAlignRead(); delete [] seg; seg = b.GetBits(templen * 8); m_str.append((const char*)seg, templen); delete [] seg; bitsDecoded += (templen * 8); } } AsnLen AsnOcts::PEnc(AsnBufBits &b) const { /*if there are no constraints, a default lower bound of zero is set */ AsnLen len=0; int numSizeConstraints; const SizeConstraint* sizeConstraints = SizeConstraints(numSizeConstraints); if(sizeConstraints == NULL && numSizeConstraints == 0) { len = EncodeGeneral(b); } else { len = EncodeWithSizeConstraint(b); } return len; } void AsnOcts::PDec (AsnBufBits &b, AsnLen &bitsDecoded) { int numSizeConstraints; const SizeConstraint* sizeConstraints = SizeConstraints(numSizeConstraints); if(sizeConstraints == NULL && numSizeConstraints == 0) { DecodeGeneral(b, bitsDecoded); } else { DecodeWithSizeConstraint(b, bitsDecoded); } } AsnLen AsnOcts::BEnc (AsnBuf &b) const { AsnLen l; l = BEncContent (b); l += BEncDefLen (b, l); l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE); return l; } void AsnOcts::BDec (const AsnBuf &b, AsnLen &bytesDecoded) { FUNC("AsnOcts::BDec()"); AsnLen elmtLen; AsnTag tag; tag = BDecTag (b, bytesDecoded); if ((tag != MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE)) && (tag != MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE))) { throw InvalidTagException(typeName(), tag, STACK_ENTRY); } elmtLen = BDecLen (b, bytesDecoded); BDecContent (b, tag, elmtLen, bytesDecoded); } /* * decodes a seq of universally tagged octets until either EOC is * encountered or the given len decoded. Return them in a * single concatenated octet string */ void AsnOcts::BDecConsOcts (const AsnBuf &b, AsnLen elmtLen, AsnLen &bytesDecoded) { ConsStringDeck strDeck; strDeck.Fill(b, elmtLen, bytesDecoded); strDeck.Collapse( m_str ); } /* BDecConsOcts */ class RefNode { public: ~RefNode() { /***RWC;TBD; ***/ } AsnLen length; AsnLen count; RefNode(){length = (unsigned long)-1; count = (unsigned long)-1; } RefNode(AsnLen l, AsnLen c ) {length = l; count = c; } }; void ConsStringDeck::Fill(const AsnBuf &b, AsnLen elmtLen, AsnLen &bytesDecoded) { FUNC("ConsStringDeck::Fill()"); AsnLen totalElmtsLen1 = 0; std::list refList; refList.insert (refList.begin(), RefNode(elmtLen, totalElmtsLen1)); std::list::iterator curr = refList.begin(); bool done = false; unsigned char *strPtr; unsigned long tagId1; while ( !done ) { for (; (curr != refList.end()) && ((curr->count < curr->length) || (curr->length == INDEFINITE_LEN));) { tagId1 = BDecTag (b, curr->count); if (tagId1 == EOC_TAG_ID && curr->length == INDEFINITE_LEN) { // We may have found a EOC TAG // if next byte is a 0 then is an EOC tag if (b.GetByte() == 0) { ++curr->count; break; } else { throw EXCEPT("Partial EOC tag found", DECODE_ERROR); } } else if (tagId1 == MAKE_TAG_ID (UNIV, PRIM, m_baseTag)) { /* * primitive part of string, put references to piece (s) in * str stack */ totalElmtsLen1 = BDecLen (b, curr->count); if(totalElmtsLen1 == INDEFINITE_LEN) { throw InvalidTagException("Primitive String can not have INDEFINITE_LEN", tagId1, STACK_ENTRY); } strPtr = (unsigned char *)b.GetSeg(totalElmtsLen1); push_back( StringPair(strPtr, totalElmtsLen1) ); curr->count += totalElmtsLen1; } else if (tagId1 == MAKE_TAG_ID (UNIV, CONS, m_baseTag)) { /* * primitive part of string, put references to piece (s) in * str stack */ totalElmtsLen1 = BDecLen(b, curr->count); if ((totalElmtsLen1 != INDEFINITE_LEN) && (totalElmtsLen1 + curr->count) > curr->length/*elmtLen*/) { throw BoundsException("Invalid constructed object", STACK_ENTRY); } curr = refList.insert (refList.end(), RefNode(totalElmtsLen1, 0)); //curr = curr->next; //Fill(b, curr->length, curr->count); } else if (m_baseTag == 0 && TAG_IS_CONS(tagId1)) { /* Handle set and sequence */ totalElmtsLen1 = BDecLen(b, curr->count); if ((totalElmtsLen1 != INDEFINITE_LEN) && (totalElmtsLen1 + curr->count) > curr->length/*elmtLen*/) { throw BoundsException("Invalid constructed object", STACK_ENTRY); } curr = refList.insert (refList.end(), RefNode(totalElmtsLen1, 0) ); //Fill(b, curr->length, curr->count); } else if (m_baseTag == 0) { totalElmtsLen1 = BDecLen (b, curr->count); if (totalElmtsLen1 == INDEFINITE_LEN) { throw InvalidTagException("Primitive String can not have INDEFINITE_LEN", tagId1, STACK_ENTRY); } if(totalElmtsLen1 > b.length()) { throw InvalidTagException("Primitive String, length", tagId1, STACK_ENTRY); } strPtr = (unsigned char *)b.GetSeg(totalElmtsLen1); push_back( StringPair(strPtr, totalElmtsLen1) ); curr->count += totalElmtsLen1; } else { throw InvalidTagException("Constructed String", tagId1, STACK_ENTRY); } } /* end of for */ if( curr != refList.begin() && curr != refList.end() ) { int iTmpCount = curr->count; curr = refList.erase(curr); if( curr != refList.end() ) curr->count += iTmpCount; else done = true; } else { done = true; } } bytesDecoded += refList.begin()->count; } void ConsStringDeck::Collapse(std::string &str) { iterator i; i = begin(); for (; i != end(); i++) { str.append((char *)i->first, i->second); } } ConsStringDeck::~ConsStringDeck() { iterator i; i = begin(); for (; i != end(); i++) { delete[] i->first; i->first = NULL; } } bool AsnOcts::operator == (const AsnOcts &o) const { if ( (o.Len() == Len()) && (memcmp(o.c_ustr(), c_ustr(), Len()) == 0) ) return true; return false; } bool AsnOcts::operator != (const AsnOcts &o) const { return !operator ==(o); } _END_SNACC_NAMESPACE esnacc-ng-1.8.1/cxx-lib/src/asn-oid.cpp000066400000000000000000000034141302010526100175420ustar00rootroot00000000000000// file: .../c++-lib/src/asn-oid.C - OBJECT IDENTIFIER // // Mike Sample // 92/07/02 // Copyright (C) 1992 Michael Sample and the University of British Columbia // // This library is free software; you can redistribute it and/or // modify it provided that this copyright/license information is retained // in original form. // // If you modify this file, you must clearly indicate your changes. // // This source code is distributed in the hope that it will be // useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // // $Header: /baseline/SNACC/c++-lib/src/asn-oid.cpp,v 1.59 2004/02/09 20:38:50 nicholar Exp $ // #include "asn-incl.h" _BEGIN_SNACC_NAMESPACE AsnOid::AsnOid() : AsnRelativeOid() { m_isRelative = false; Set("0.0"); } AsnOid::AsnOid(const char* pszOID) : AsnRelativeOid() { m_isRelative = false; Set(pszOID); } AsnOid AsnOid::operator+(const AsnRelativeOid& ro) const { AsnOid tempOid(*this); tempOid += ro; return tempOid; } AsnOid& AsnOid::operator+=(const AsnRelativeOid& ro) { FUNC("AsnOid::operator+=()"); // Create a temporary encoded OID and concatenate the RelativeOID to it char *tmp = new char[octetLen + ro.Len()]; if (tmp == NULL) throw SNACC_MEMORY_EXCEPT(octetLen + ro.Len(), "tmp"); memcpy(tmp, oid, octetLen); memcpy(&tmp[octetLen], ro.Str(), ro.Len()); // Delete existing members delete[] oid; delete[] m_lpszOidString; m_lpszOidString = NULL; // Set this OID's encoded value to the temporary one octetLen += ro.Len(); oid = tmp; return *this; } #if META const AsnOidTypeDesc AsnOid::_desc (NULL, NULL, false, AsnTypeDesc::OBJECT_IDENTIFIER, NULL); const AsnTypeDesc *AsnOid::_getdesc() const { return &_desc; } #endif /* META */ _END_SNACC_NAMESPACE esnacc-ng-1.8.1/cxx-lib/src/asn-real.cpp000066400000000000000000000737121302010526100177220ustar00rootroot00000000000000// file: .../c++-lib/src/asn-real.C - AsnReal (ASN.1 REAL) type // // Mike Sample // 92/07/02 // Copyright (C) 1992 Michael Sample and the University of British Columbia // // This library is free software; you can redistribute it and/or // modify it provided that this copyright/license information is retained // in original form. // // If you modify this file, you must clearly indicate your changes. // // This source code is distributed in the hope that it will be // useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // // $Log: asn-real.cpp,v $ // Revision 1.21 2004/03/22 20:04:18 gronej // took IBM references out of the code (to the best of our knowledge, we don't use any of it anymore) // // Revision 1.20 2004/02/11 19:08:48 nicholar // Updated Print() function so no longer uses global indent // // Revision 1.19 2004/02/06 00:39:13 nicholar // Changed AsnList to use std::list instead of List // // Revision 1.18 2004/02/04 14:59:27 gronej // Fixed a TON of memory leaks // // Revision 1.17 2004/02/03 14:44:32 gronej // made all constraint lists static to avoid memory issues // // Revision 1.16 2003/12/17 19:05:03 gronej // SNACC baseline merged with PER v1_7 tag // // Revision 1.14.2.5 2003/12/04 20:47:11 gronej // Moved bAlign out of all PEnc calls and into AsnBufBits as a member // An AsnBufBits is now invoked with a bAlign parameter defaulted to false // // Revision 1.14.2.4 2003/12/03 19:48:08 gronej // Fixed bitsDecoded to return correct value on decode operations // // Revision 1.14.2.3 2003/11/04 14:21:21 gronej // Update PER compiler with some PERGeneral functionality 11/04/03 // // Revision 1.14.2.2 2003/10/22 12:45:58 gronej // Updating PER compiler // // Revision 1.14.2.1 2003/10/02 17:15:24 gronej // Updating PER compiler // // Revision 1.14 2003/01/17 01:16:04 leonberp // FIXED A TON of warnings // // Revision 1.13 2003/01/06 16:20:07 leonberp // Changed BDec() and BDecContent() to use const AsnBufs // // Revision 1.12 2002/12/17 20:27:40 leonberp // made BEnc() and BEncContent() const // // Revision 1.11 2002/10/23 21:02:48 leonberp // fixed AsnBuf references and fixed clock skew problem // // Revision 1.10 2002/10/23 10:51:10 mcphersc // Changed BUF_TYPE to AsnBuf // // Revision 1.9 2002/05/10 16:39:36 leonberp // latest changes for release 2.2 // includes integrating asn-useful into C & C++ runtime library, the compiler changes that go along with that, SnaccException changes for C++ runtime and compiler // // Revision 1.8 2002/03/01 14:03:37 vracarl // added an INDEFINATE_LEN check on the primitive // // Revision 1.7 2001/08/29 22:04:19 leonberp // enchanced Clone() to allocate a new pointe AND COPY the object // // Revision 1.6 2001/07/12 19:33:39 leonberp // Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. // // Revision 1.5 2001/06/28 15:43:32 rwc // ADDED "SNACCASN" namespace definition to all SNACC data structures. // This should not affect most applications since we do not have any name // conflicts. // ALSO, combined all ASN primitive data type includes into asn-incl.h. // // Revision 1.4 2001/06/19 15:19:47 grafb // Re-ordered includes and removed redundant includes for g++ 3.0 compile // Also ifdef-ed out two macro definitions in asn-real.cpp due to conflict // with this compiler version. // // Revision 1.3 2001/06/18 17:47:44 rwc // Updated to reflect newly added C++ Exception error handling, instead of "C" longjmp and setjmp calls. // Changes made to both the compiler and the SNACC C++ run-time library. // // Revision 1.2 2000/10/16 18:10:37 rwc // removed most warnings from C++-lib, some C-lib. // // Revision 1.1.1.1 2000/08/21 20:36:09 leonberp // First CVS Version of SNACC. // // Revision 1.7 1997/02/28 13:39:46 wan // Modifications collected for new version 1.3: Bug fixes, tk4.2. // // Revision 1.6 1995/08/17 15:27:19 rj // recognize and return "±inf" for PLUS-INFINITY/MINUS-INFINITY. // // Revision 1.5 1995/07/24 20:29:24 rj // #if TCL ... #endif wrapped into #if META ... #endif // // call constructor with additional pdu and create arguments. // // changed `_' to `-' in file names. // // Revision 1.4 1995/02/18 17:01:49 rj // denote a long if we want a long. // make the code work on little endian CPUs. // ported to work with CPU/compiler combinations providing 64 bit longs. // // Revision 1.3 1994/10/08 04:18:29 rj // code for meta structures added (provides information about the generated code itself). // // code for Tcl interface added (makes use of the above mentioned meta code). // // virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included. // // made Print() const (and some other, mainly comparison functions). // // several `unsigned long int' turned into `size_t'. // // Revision 1.2 1994/08/28 10:01:18 rj // comment leader fixed. // // Revision 1.1 1994/08/28 09:21:07 rj // first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. #include "asn-incl.h" #include "math.h" #include _BEGIN_SNACC_NAMESPACE #ifndef IEEE_REAL_LIB /* ieee functions (in case not in math.h)*/ extern "C" { extern int iszero (double); #ifdef VDAIEEE_NOT_GPP_30 extern int isinf (double); extern int signbit (double); #endif extern int ilogb (double); extern double scalbn (double, int); } #endif double AsnPlusInfinity(); double AsnMinusInfinity(); /* * Declare and init the PLUS and MINUS INFINITY values. * */ const AsnReal PLUS_INFINITY (AsnPlusInfinity()); const AsnReal MINUS_INFINITY (AsnMinusInfinity()); #define ENC_PLUS_INFINITY 0x40 #define ENC_MINUS_INFINITY 0x41 #define REAL_BINARY 0x80 #define REAL_SIGN 0x40 #define REAL_EXPLEN_MASK 0x03 #define REAL_EXPLEN_1 0x00 #define REAL_EXPLEN_2 0x01 #define REAL_EXPLEN_3 0x02 #define REAL_EXPLEN_LONG 0x03 #define REAL_FACTOR_MASK 0x0c #define REAL_BASE_MASK 0x30 #define REAL_BASE_2 0x00 #define REAL_BASE_8 0x10 #define REAL_BASE_16 0x20 // Returns the smallest octet length needed to hold the given long int value unsigned int SignedIntOctetLen (long int val) { unsigned long int mask = (0x7f80L << ((sizeof (long int) - 2) * 8)); unsigned int retVal = sizeof (long int); if (val < 0) val = val ^ (~0L); /* XOR val with all 1's */ while ((retVal > 1) && ((val & mask) == 0)) { mask >>= 8; retVal--; } return retVal; } /* SignedIntOctetLen */ #ifdef IEEE_REAL_FMT // Returns the PLUS INFINITY in double format // This assumes that a C++ double is an IEEE double. // The bits for IEEE double PLUS INFINITY are // 0x7ff0000000000000 double AsnPlusInfinity() { double d; unsigned char *c = (unsigned char *)&d; #if WORDS_BIGENDIAN c[0] = 0x7f; c[1] = 0xf0; c[2] = 0x0; c[3] = 0x0; c[4] = 0x0; c[5] = 0x0; c[6] = 0x0; c[7] = 0x0; #else c[7] = 0x7f; c[6] = 0xf0; c[5] = 0x0; c[4] = 0x0; c[3] = 0x0; c[2] = 0x0; c[1] = 0x0; c[0] = 0x0; #endif return d; } /* AsnPlusInfinity */ double AsnMinusInfinity() { return -AsnPlusInfinity(); } #if SIZEOF_DOUBLE != 8 #error oops: doubles are expected to be 8 bytes in size! #endif /* * Use this routine if you system/compiler represents doubles in the IEEE format. */ AsnLen AsnReal::BEncContent (AsnBuf &b) const { int exponent; int isNeg; #if SIZEOF_LONG == 8 unsigned long mantissa, val, *p; int i; #elif SIZEOF_LONG == 4 unsigned char *dbl; unsigned long int *first4; unsigned long int *second4; #else #error long neither 8 nor 4 bytes in size? #endif /* no contents for 0.0 reals */ if (value == 0.0) /* all bits zero, disregarding top/sign bit */ return 0; #if SIZEOF_LONG == 8 /* * this part assumes that sizeof (long) == sizeof (double) == 8 * It shouldn't be endian-dependent but I haven't verified that */ p = (unsigned long*) &value; val = *p; isNeg = (val >> 63) & 1; /* special real values for +/- oo */ if (!finite (value)) { if (isNeg) { b.PutByteRvs(ENC_MINUS_INFINITY); } else { b.PutByteRvs(ENC_PLUS_INFINITY); } return 1; } else /* encode a binary real value */ { exponent = (val >> 52) & 0x7ff; mantissa = (val & 0xfffffffffffffL) | 0x10000000000000L; for (i = 0; i < 7; i++) { b.PutByteRvs(mantissa & 0xff); mantissa >>= 8; } exponent -= (1023 + 52); #elif SIZEOF_LONG == 4 /* * this part assumes that sizeof (long) == 4 and * that sizeof (double) == 8 * * sign exponent * b 2-12 incl * Sv-----------v----- rest is mantissa * ------------------------------------------- * | | * ------------------------------------------- * 123456878 1234 * * sign bit is 1 if real is < 0 * exponent is an 11 bit unsigned value (subtract 1023 to get correct exp value) * decimal pt implied before mantissa (ie mantissa is all fractional) * and implicit 1 bit to left of decimal * * when given NaN (not a number - ie oo/oo) it encodes the wrong value * instead of checking for the error. If you want to check for it, * a NaN is any sign bit with a max exponent (all bits a 1) followed * by any non-zero mantissa. (a zero mantissa is used for infinity) * */ first4 = (unsigned long int*) (dbl = (unsigned char*) &value); second4 = (unsigned long int *) (dbl + sizeof (long int)); /* no contents for 0.0 reals */ if (value == 0.0) /* all bits zero, disregarding top/sign bit */ return 0; isNeg = dbl[0] & 0x80; /* special real values for +/- oo */ if (((*first4 & 0x7fffffff) == 0x7ff00000) && (*second4 == 0)) { if (isNeg) b.PutByteRvs (ENC_MINUS_INFINITY); else b.PutByteRvs (ENC_PLUS_INFINITY); return 1; } else /* encode a binary real value */ { exponent = (((*first4) >> 20) & 0x07ff); /* write the mantissa (N value) */ b.PutSegRvs ((char*)(dbl+2), sizeof (double)-2); /* * The rightmost 4 bits of a double 2nd octet are the * most sig bits of the mantissa. * write the most signficant byte of the asn1 real manitssa, * adding implicit bit to 'left of decimal' if not de-normalized * (de normalized if exponent == 0) * * if the double is not in de-normalized form subtract 1023 * from the exponent to get proper signed exponent. * * for both the normalized and de-norm forms * correct the exponent by subtracting 52 since: * 1. mantissa is 52 bits in the double (56 in ASN.1 REAL form) * 2. implicit decimal at the beginning of double's mantissa * 3. ASN.1 REAL's implicit decimal is after its mantissa * so converting the double mantissa to the ASN.1 form has the * effect of multiplying it by 2^52. Subtracting 52 from the * exponent corrects this. */ if (exponent == 0) /* de-normalized - no implicit 1 to left of dec.*/ { b.PutByteRvs (dbl[1] & 0x0f); exponent -= 52; } else { b.PutByteRvs ((dbl[1] & 0x0f) | 0x10); /* 0x10 adds implicit bit */ exponent -= (1023 + 52); } #else #error long neither 8 nor 4 bytes in size? #endif /* write the exponent */ b.PutByteRvs (exponent & 0xff); b.PutByteRvs (exponent >> 8); /* write format octet */ /* bb is 00 since base is 2 so do nothing */ /* ff is 00 since no other shifting is nec */ if (isNeg) b.PutByteRvs (REAL_BINARY | REAL_EXPLEN_2 | REAL_SIGN); else b.PutByteRvs (REAL_BINARY | REAL_EXPLEN_2); return sizeof (double) + 2; } /* not reached */ } /* AsnReal::BEncContent */ #else /* IEEE_REAL_FMT not def */ #ifdef IEEE_REAL_LIB // Returns the PLUS INFINITY in double format // this assumes you have the IEEE functions in // the math lib double AsnPlusInfinity() { return infinity(); } /* AsnPlusInfinity */ double AsnMinusInfinity() { return -AsnPlusInfinity(); } // This routine uses the ieee library routines to encode // this AsnReal's double value AsnLen AsnReal::BEncContent (AsnBuf &b) const { AsnLen encLen; double mantissa; double tmpMantissa; unsigned int truncatedMantissa; int exponent; unsigned int expLen; int sign; unsigned char buf[sizeof (double)]; int i, mantissaLen; unsigned char firstOctet; /* no contents for 0.0 reals */ if (iszero (value)) return 0; /* special real values for +/- oo */ if (isinf (value)) { if (signbit (value)) /* neg */ b.PutByteRvs (ENC_MINUS_INFINITY); else b.PutByteRvs (ENC_PLUS_INFINITY); encLen = 1; } else /* encode a binary real value */ { if (signbit (value)) sign = -1; else sign = 1; exponent = ilogb (value); /* get the absolute value of the mantissa (subtract 1 to make < 1) */ mantissa = scalbn (fabs (value), -exponent-1); tmpMantissa = mantissa; /* convert mantissa into an unsigned integer */ for (i = 0; i < sizeof (double); i++) { /* normalizied so shift 8 bits worth to the left of the decimal */ tmpMantissa *= (1<<8); /* grab only (octet sized) the integer part */ truncatedMantissa = (unsigned int) tmpMantissa; /* remove part to left of decimal now for next iteration */ tmpMantissa -= truncatedMantissa; /* write into tmp buffer */ buf[i] = truncatedMantissa; /* keep track of last non zero octet so can zap trailing zeros */ if (truncatedMantissa) mantissaLen = i+1; } /* * write format octet (first octet of content) * field 1 S bb ff ee * bit# 8 7 65 43 21 * * 1 in bit#1 means binary rep * 1 in bit#2 means the mantissa is neg, 0 pos * bb is the base: 65 base * 00 2 * 01 8 * 10 16 * 11 future ext. * * ff is the Value of F where Mantissa = sign x N x 2^F * FF can be one of 0 to 3 inclusive. (used to save re-alignment) * * ee is the length of the exponent: 21 length * 00 1 * 01 2 * 10 3 * 11 long form * * * encoded binary real value looks like * * fmt oct * -------------------------------------------------------- * |1Sbbffee| exponent (2's comp) | N (unsigned int) | * -------------------------------------------------------- * 87654321 */ firstOctet = REAL_BINARY; if (signbit (value)) firstOctet |= REAL_SIGN; /* bb is 00 since base is 2 so do nothing */ /* ff is 00 since no other shifting is nec */ /* * get exponent calculate its encoded length * Note that the process of converting the mantissa * double to an int shifted the decimal mantissaLen * 8 * to the right - so correct that here */ exponent++; /* compensate for trick to put mantissa < 1 */ exponent -= (mantissaLen * 8); expLen = SignedIntOctetLen (exponent); switch (expLen) { case 1: firstOctet |= REAL_EXPLEN_1; break; case 2: firstOctet |= REAL_EXPLEN_2; break; case 3: firstOctet |= REAL_EXPLEN_3; break; default: firstOctet |= REAL_EXPLEN_LONG; break; } encLen = mantissaLen + expLen + 1; /* write the mantissa (N value) */ b.PutSegRvs ((char*)buf, mantissaLen); /* write the exponent */ for (i = expLen; i > 0; i--) { b.PutByteRvs (exponent); exponent >> 8; } /* write the exponents length if nec */ if (expLen > 3) { encLen++; b.PutByteRvs (expLen); } /* write the format octet */ b.PutByteRvs (firstOctet); } return encLen; } /* AsnReal::BEncContent */ #else /* neither IEEE_REAL_FMT or IEEE_REAL_LIB are def */ // Returns the PLUS INFINITY in double format // This assumes that a C++ double is an IEEE double. // The bits for IEEE double PLUS INFINITY are // 0x7ff0000000000000 // NOTE: this is a guess - you should set this up for // your architecture double AsnPlusInfinity() { double d; unsigned char *c; unsigned long i; c = (unsigned char*)&d; c[0] = 0x7f; c[1] = 0xf0; for (i = 2; i < sizeof (double); i++) c[i] = 0; return d; } /* AsnPlusInfinity */ double AsnMinusInfinity() { return -AsnPlusInfinity(); } /* * Encodes the content of an ASN.1 REAL value to the given buffer. * This version of the routine does not assume an IEEE double rep. * or the existence of the IEEE library routines. Uses old style * UNIX frexp etc. */ AsnLen AsnReal::BEncContent (AsnBuf &b) const { unsigned long int encLen; double mantissa; double tmpMantissa; unsigned int truncatedMantissa; int exponent; unsigned int expLen; int sign; unsigned char buf[sizeof (double)]; unsigned int i, mantissaLen=0; unsigned char firstOctet; /* no contents for 0.0 reals */ if (value == 0.0) return 0; /* special real values for +/- oo */ if (value == MINUS_INFINITY) { b.PutByteRvs (ENC_MINUS_INFINITY); encLen = 1; } else if (value == PLUS_INFINITY) { b.PutByteRvs (ENC_PLUS_INFINITY); encLen = 1; } else /* encode a binary real value */ { /* * this is what frexp gets from value * value == mantissa * 2^exponent * where 0.5 <= |manitissa| < 1.0 */ mantissa = frexp (value, &exponent); /* set sign and make mantissa = | mantissa | */ if (mantissa < 0.0) { sign = -1; mantissa *= -1; } else sign = 1; tmpMantissa = mantissa; /* convert mantissa into an unsigned integer */ for (i = 0; i < sizeof (double); i++) { /* normalizied so shift 8 bits worth to the left of the decimal */ tmpMantissa *= (1<<8); /* grab only (octet sized) the integer part */ truncatedMantissa = (unsigned int) tmpMantissa; /* remove part to left of decimal now for next iteration */ tmpMantissa -= truncatedMantissa; /* write into tmp buffer */ buf[i] = (unsigned char)truncatedMantissa; /* keep track of last non zero octet so can zap trailing zeros */ if (truncatedMantissa) mantissaLen = i+1; } /* * write format octet (first octet of content) * field 1 S bb ff ee * bit# 8 7 65 43 21 * * 1 in bit#1 means binary rep * 1 in bit#2 means the mantissa is neg, 0 pos * bb is the base: 65 base * 00 2 * 01 8 * 10 16 * 11 future ext. * * ff is the Value of F where Mantissa = sign x N x 2^F * FF can be one of 0 to 3 inclusive. (used to save re-alignment) * * ee is the length of the exponent: 21 length * 00 1 * 01 2 * 10 3 * 11 long form * * * encoded binary real value looks like * * fmt oct * -------------------------------------------------------- * |1Sbbffee| exponent (2's comp) | N (unsigned int) | * -------------------------------------------------------- * 87654321 */ firstOctet = REAL_BINARY; if (sign == -1) firstOctet |= REAL_SIGN; /* bb is 00 since base is 2 so do nothing */ /* ff is 00 since no other shifting is nec */ /* * get exponent calculate its encoded length * Note that the process of converting the mantissa * double to an int shifted the decimal mantissaLen * 8 * to the right - so correct that here */ //exponent -= (mantissaLen * 8); expLen = SignedIntOctetLen (exponent); switch (expLen) { case 1: firstOctet |= REAL_EXPLEN_1; break; case 2: firstOctet |= REAL_EXPLEN_2; break; case 3: firstOctet |= REAL_EXPLEN_3; break; default: firstOctet |= REAL_EXPLEN_LONG; break; } encLen = mantissaLen + expLen + 1; /* write the mantissa (N value) */ b.PutSegRvs ((char*)buf, mantissaLen); /* write the exponent */ for (i = expLen; i > 0; i--) { b.PutByteRvs ((unsigned char)exponent); //RWC;10/10/00;I suspect we need this for multi-byte exponents... exponent = exponent >> 8; } /* write the exponents length if nec */ if (expLen > 3) { encLen++; b.PutByteRvs ((unsigned char)expLen); } /* write the format octet */ b.PutByteRvs (firstOctet); } return encLen; } /* AsnReal::BEncContent */ #endif #endif static double domainExp(double i, int j) { double exp = 1.0; while(j--) { exp *= 2.0; } return i * exp; } // Decode a REAL value's content from the given buffer. // places the result in this object. void AsnReal::BDecContent (const AsnBuf &b, AsnTag /* tagId */, AsnLen elmtLen, AsnLen &bytesDecoded) { FUNC("AsnReal::BDecContent()"); unsigned char firstOctet; unsigned char firstExpOctet; int i; unsigned int expLen; double mantissa; unsigned int baseF; int exponent = 0; if (elmtLen == 0) { value = 0.0; return; } else if (elmtLen == INDEFINITE_LEN) throw EXCEPT("indefinite length on primitive", DECODE_ERROR); firstOctet = b.GetByte(); if (elmtLen == 1) { bytesDecoded += 1; if (firstOctet == ENC_PLUS_INFINITY) value = PLUS_INFINITY; else if (firstOctet == ENC_MINUS_INFINITY) value = MINUS_INFINITY; else { throw EXCEPT("unrecognized 1 octet length real number", DECODE_ERROR); } } else { if (firstOctet & REAL_BINARY) { firstExpOctet = b.GetByte(); if (firstExpOctet & 0x80) exponent = -1; switch (firstOctet & REAL_EXPLEN_MASK) { case REAL_EXPLEN_1: expLen = 1; exponent = (exponent << 8) | firstExpOctet; break; case REAL_EXPLEN_2: expLen = 2; exponent = (exponent << 16) | (((unsigned long int) firstExpOctet) << 8) | b.GetByte(); break; case REAL_EXPLEN_3: expLen = 3; exponent = (exponent << 16) | (((unsigned long int) firstExpOctet) << 8) | b.GetByte(); exponent = (exponent << 8) | b.GetByte(); break; default: /* long form */ expLen = firstExpOctet +1; i = firstExpOctet-1; firstExpOctet = b.GetByte(); if (firstExpOctet & 0x80) exponent = (-1 <<8) | firstExpOctet; else exponent = firstExpOctet; for (;i > 0; firstExpOctet--, i--) exponent = (exponent << 8) | b.GetByte(); break; } unsigned char cValue; mantissa = 0.0; for (i = 1 + expLen; i < (int)elmtLen; i++) { cValue = b.GetByte(); mantissa = domainExp(mantissa, 8) + cValue; } switch (firstOctet & REAL_BASE_MASK) { case REAL_BASE_2: baseF = 1; break; case REAL_BASE_8: baseF = 3; break; case REAL_BASE_16: baseF = 4; break; default: throw EXCEPT("unsupported base for a binary real number.", DECODE_ERROR); break; } unsigned int scaleF = 1<<((firstOctet & REAL_FACTOR_MASK) >> 2); //std::cout << "( " << pow(2,baseF) << "," << mantissa << "," << exponent << ") * " << double(scaleF) << " * " << ((firstOctet & REAL_SIGN) ? "-1.0" : "1.0") << std::endl; value = mantissa * pow(double(2.0), double(baseF) * double(exponent)); value *= scaleF; if (firstOctet & REAL_SIGN) value = -value; bytesDecoded += elmtLen; } else /* decimal version */ { throw EXCEPT("decimal REAL form is not currently supported" , DECODE_ERROR); } } } /* AsnInt::BDecContent */ AsnLen AsnReal::PEnc (AsnBufBits &b) const { AsnLen len=0; long templen = 0; AsnBuf tempBuf; char* seg = NULL; templen += BEncContent(tempBuf); seg = new char[templen + 1]; tempBuf.GetSeg(seg, templen); len += PEncDefLenTo127(b, templen); if(templen > 0) { templen *= 8; len += b.OctetAlignWrite(); len += b.PutBits((unsigned char*) seg, templen); } delete[] seg; return len; } void AsnReal::PDec (AsnBufBits &b, AsnLen &bitsDecoded) { AsnBuf tempBuf; AsnLen bytesDecoded = 0; unsigned char* seg; unsigned long lseg; seg = b.GetBits(8); lseg = (unsigned long)seg[0]; bitsDecoded += 8; bitsDecoded += b.OctetAlignRead(); delete [] seg; seg = b.GetBits(lseg * 8); tempBuf.PutSegRvs((char*)seg, lseg); BDecContent (tempBuf, MAKE_TAG_ID (UNIV, PRIM, REAL_TAG_CODE), lseg, bytesDecoded); bitsDecoded += (bytesDecoded * 8); delete [] seg; } AsnLen AsnReal::BEnc (AsnBuf &b) const { AsnLen l; l = BEncContent (b); l += BEncDefLen (b, l); l += BEncTag1 (b, UNIV, PRIM, REAL_TAG_CODE); return l; } void AsnReal::BDec (const AsnBuf &b, AsnLen &bytesDecoded) { FUNC("AsnReal::BDec()"); AsnLen elmtLen; AsnTag tagId; tagId = BDecTag (b, bytesDecoded); if (tagId != MAKE_TAG_ID (UNIV, PRIM, REAL_TAG_CODE)) { throw InvalidTagException(typeName(), tagId, STACK_ENTRY); } elmtLen = BDecLen (b, bytesDecoded); BDecContent (b, MAKE_TAG_ID (UNIV, PRIM, REAL_TAG_CODE), elmtLen, bytesDecoded); } void AsnReal::Print(std::ostream& os, unsigned short /*indent*/) const { os << value; } void AsnReal::PrintXML (std::ostream &os, const char *lpszTitle) const { os << ""; if (lpszTitle) os << lpszTitle; os << "-"; Print(os); os << "\n"; } char* AsnReal::checkRealValRange(const double m_Lower, const double m_Upper) const { double ltemp; char* pError=NULL; char cTmperr[200]; ltemp=value; if(ltemp<=m_Upper && ltemp >= m_Lower) { return pError; } else { if(ltemp>m_Upper) { sprintf(cTmperr, "_______\nREAL--Valuerange Constraints:\n_______\nError: --Value out of range--\nValue: %.5f is above the Upper Limit: %.5f \n", ltemp, m_Upper); pError = strdup(cTmperr); return pError; } else if(ltempresult, "+inf"); else if (value == MINUS_INFINITY) strcpy (interp->result, "-inf"); else sprintf (interp->result, "%g", value); return TCL_OK; } int AsnReal::TclSetVal (Tcl_Interp *interp, const char *valstr) { double valval; if (!strcmp (valstr, "+inf")) valval = PLUS_INFINITY; else if (!strcmp (valstr, "-inf")) valval = MINUS_INFINITY; else if (Tcl_GetDouble (interp, (char*)valstr, &valval) != TCL_OK) return TCL_ERROR; value = valval; return TCL_OK; } #endif /* TCL */ #endif /* META */ _END_SNACC_NAMESPACE esnacc-ng-1.8.1/cxx-lib/src/asn-rvsbuf.cpp000066400000000000000000000061371302010526100203030ustar00rootroot00000000000000#include "asn-buf.h" #include using namespace SNACC; AsnRvsBuf::AsnRvsBuf(char *preFilled, size_t segSize) { m_segSize = segSize; m_buf = preFilled; m_bDeleteable = false; m_pReadLoc = m_buf; m_pStart = m_buf; } AsnRvsBuf::AsnRvsBuf(const char *seg, size_t segSize) { m_segSize = segSize; m_buf = new char[segSize]; m_bDeleteable = true; memcpy(m_buf, seg, segSize); m_pReadLoc = m_buf; m_pStart = m_buf; } AsnRvsBuf::AsnRvsBuf(const AsnBuf& otherBuf) { otherBuf.ResetMode(); size_t len = otherBuf.length(); if (len > 0) m_segSize = len; else m_segSize = _SEG_SIZE; m_buf = new char[m_segSize]; m_bDeleteable = true; m_pReadLoc = NULL; m_pStart = (m_buf + m_segSize); if (len > 0) { otherBuf.GetSeg(m_buf, len); otherBuf.ResetMode(); m_pReadLoc = m_buf; m_pStart = m_buf; } } AsnRvsBuf::AsnRvsBuf(long segSize) { m_segSize = segSize; m_buf = new char[segSize]; m_bDeleteable = true; m_pReadLoc = NULL; m_pStart = (m_buf + segSize); } AsnRvsBuf::~AsnRvsBuf() { if (m_bDeleteable) delete[] m_buf; } std::streambuf::int_type AsnRvsBuf::underflow() { if (eback() == m_pStart) return EOF; setg(m_pStart, m_pStart, &m_buf[m_segSize]); return (int_type) (unsigned char) *m_pStart; } std::streambuf::int_type AsnRvsBuf::overflow(int c) { if (m_pStart > m_buf && c <= 255 && c >= 0) { *(--m_pStart) = (char)c; } else return EOF; return c; } std::streamsize AsnRvsBuf::xsputn(const char *s, std::streamsize n) { std::streamsize written; if (n <= (m_pStart - m_buf)) { m_pStart -= n; memcpy(m_pStart, s, n); written = n; } else { written = m_pStart - m_buf; memcpy(m_buf, &s[n - written], written); m_pStart = m_buf; } return written; } std::streambuf::pos_type AsnRvsBuf::seekoff(std::streambuf::off_type off, std::ios_base::seekdir way, std::ios_base::openmode which) { char *pNext = NULL; if (which & std::ios_base::out) { m_pStart = &m_buf[m_segSize]; setg(0,0,0); } if (which & std::ios_base::in) { switch (way) { case std::ios_base::beg: pNext = m_pStart + off; break; case std::ios_base::end: pNext = m_buf + m_segSize + off; break; case std::ios_base::cur: if (gptr() == NULL) { pNext = m_pStart; } else pNext = gptr() + off; break; default: break; } if ((pNext <= &m_buf[m_segSize]) && (pNext >= m_pStart)) { setg(m_pStart, pNext, &m_buf[m_segSize]); return (pNext - m_pStart); } else return (-1); } return (-1); } std::streambuf::pos_type AsnRvsBuf::seekpos(std::streambuf::pos_type sp, std::ios_base::openmode which) { #ifdef _MSVC_6 return (seekoff(sp, std::ios_base::seekdir::beg, which)); #else return (seekoff(sp, std::ios_base::beg, which)); #endif } esnacc-ng-1.8.1/cxx-lib/src/asn-stringtype.cpp000066400000000000000000001047071302010526100212060ustar00rootroot00000000000000// // asn-stringType.cpp // #include "asn-incl.h" #if defined(HPUX) || defined(HPUX32) /* for some strange reason GCC 3.2.1 on HPUX has trouble specializing the * basic_string<> template for wchar_t. Do the following is necessary on HPUX * until GCC is fixed or we figure out another work around. */ namespace std { const basic_string::size_type basic_string::_Rep::_S_max_size = (((npos - sizeof(_Rep))/sizeof(wchar_t)) - 1) / 4; const wchar_t basic_string::_Rep::_S_terminal = wchar_t(); } #endif // HPUX #ifdef _MSC_VER #pragma warning(disable: 4127) // Disable conditional expression is constant #endif #include using namespace SNACC; #define MAX_UTF8_OCTS_PER_CHAR 6 typedef struct { unsigned char mask; unsigned char value; unsigned short bits; unsigned long maxCharValue; } MaskValue; const MaskValue gUTF8Masks[6] = { { 0x80, 0x00, 1, 0x0000007F }, // one-byte encoding { 0xE0, 0xC0, 3, 0x000007FF }, // two-byte encoding { 0xF0, 0xE0, 4, 0x0000FFFF }, // three-byte encoding { 0xF8, 0xF0, 5, 0x0001FFFF }, // four-byte encoding { 0xFC, 0xF8, 6, 0x03FFFFFF }, // five-byte encoding { 0xFE, 0xFC, 7, 0x07FFFFFF } // six-byte encoding }; char* AsnString::getChar(long offset)const { return (char*)&(*this)[offset]; } const char* AsnString::PermittedAlphabet(int &sizeAlpha) const { sizeAlpha = 256; static const unsigned char baseAlpha[]= { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, }; return (char*)baseAlpha; } int AsnString::findB2(int B)const { int power = 0; int B2 = 0; int B2NotFound = 1; while(B2NotFound == 1) { B2 = (int)(1 << power); if(B <= B2) { B2NotFound = 0; } power++; } return B2; } int AsnString::numBits()const { int B = 0; int N; PermittedAlphabet(N); N -= 1; while(N > 0) { N -= (long)(1 << B); B += 1; } return B; } long AsnString::FindSizeConstraintBounds(int &iSCLowerBound, int &iSCUpperBound)const { int count = 0; int numSizeConstraints; const SizeConstraint* sizeConstraints = SizeConstraints(numSizeConstraints); while(count < numSizeConstraints) { if((unsigned)iSCUpperBound < sizeConstraints[count].lowerBound) { iSCUpperBound = sizeConstraints[count].lowerBound; } if( sizeConstraints[count].upperBoundExists == 1 && (unsigned)iSCUpperBound < sizeConstraints[count].upperBound) { iSCUpperBound = sizeConstraints[count].upperBound; } if( (unsigned)iSCLowerBound > sizeConstraints[count].lowerBound ) { iSCLowerBound = sizeConstraints[count].lowerBound; } count++; } return ( (iSCUpperBound - iSCLowerBound) + 1); } AsnLen AsnString::EncodeWithSizeConstraint(AsnBufBits &b)const { FUNC("AsnString::EncodeWithSizeConstraint"); AsnLen len = 0; int B = numBits(); int B2 = findB2(B); int numSizeConstraints; const SizeConstraint* sizeConstraints = SizeConstraints(numSizeConstraints); int iSCLowerBound = sizeConstraints[0].lowerBound; int iSCUpperBound = iSCLowerBound; int minBitsNeeded = 0; int minBytesNeeded = 0; long Range = FindSizeConstraintBounds(iSCLowerBound, iSCUpperBound); long tempRange = Range - 1; long size = length(); long count = 0; unsigned char* pStr = new unsigned char[1]; while(tempRange > 0) { tempRange -= (long)(1 << minBitsNeeded); minBitsNeeded += 1; } if(size < iSCLowerBound || size > iSCUpperBound) { delete [] pStr; throw EXCEPT("String size not withing restricted bounds", RESTRICTED_TYPE_ERROR); } if(Range > 1) { if( ((iSCUpperBound * B2) > 16) && b.IsAligned()) { len += b.OctetAlignWrite(); } minBytesNeeded = minBitsNeeded / 8; minBitsNeeded = minBitsNeeded % 8; size -= iSCLowerBound; if(minBytesNeeded > 0) { pStr[0] = (unsigned char)(size >> minBitsNeeded); len += b.PutBits(pStr, 8); } pStr[0] = (unsigned char)size; pStr[0] <<= 8 - minBitsNeeded; len += b.PutBits(pStr, minBitsNeeded); } if( ((iSCUpperBound * B2) > 16) && b.IsAligned()) { len += b.OctetAlignWrite(); } while((unsigned)count < length()) { len += Interpret(b, count); count++; } delete [] pStr; return len; } void AsnString::DecodeWithSizeConstraint(AsnBufBits &b, AsnLen &bitsDecoded) { FUNC("AsnString::DecodeWithSizeConstraint"); int B = numBits(); int B2 = findB2(B); int numSizeConstraints; const SizeConstraint* sizeConstraints = SizeConstraints(numSizeConstraints); int iSCLowerBound = sizeConstraints[0].lowerBound; int iSCUpperBound = iSCLowerBound; int minBitsNeeded = 0; int minBytesNeeded = 0; long Range = FindSizeConstraintBounds(iSCLowerBound, iSCUpperBound); long tempRange = Range - 1; long count = 0; long decodeSize = 0; unsigned char* pStr = new unsigned char[1]; Clear(); while(tempRange > 0) { tempRange -= (long)(1 << minBitsNeeded); minBitsNeeded += 1; } if(Range > 1) { if( ((iSCUpperBound * B2) > 16) && b.IsAligned()) { bitsDecoded += b.OctetAlignRead(); } minBytesNeeded = minBitsNeeded / 8; minBitsNeeded = minBitsNeeded % 8; if(minBytesNeeded > 0) { delete [] pStr; pStr = b.GetBits(8); bitsDecoded += 8; decodeSize <<= 8; decodeSize |= (long)pStr[0]; } delete [] pStr; pStr = b.GetBits(minBitsNeeded); bitsDecoded += minBitsNeeded; if(minBitsNeeded > 0) { decodeSize <<= minBitsNeeded; pStr[0] >>= (8 - minBitsNeeded); decodeSize |= (long)pStr[0]; } } decodeSize += iSCLowerBound; if(decodeSize > iSCUpperBound) { delete [] pStr; throw EXCEPT("String size not withing restricted bounds", RESTRICTED_TYPE_ERROR); } if( ((iSCUpperBound * B2) > 16) && b.IsAligned()) { bitsDecoded += b.OctetAlignRead(); } while(count < decodeSize) { Deterpret(b, bitsDecoded, count); count++; } delete [] pStr; } AsnLen AsnString::Interpret(AsnBufBits &b, long offset)const { AsnLen len; int B = numBits(); int B2 = findB2(B); int sizepermittedalpha; const char* permittedAlphabet = PermittedAlphabet(sizepermittedalpha); int ub = (int)permittedAlphabet[sizepermittedalpha - 1]; bool bNotFound = true; int count = 0; if(b.IsAligned()) len = B2; else len = B; unsigned char* seg = (unsigned char*)getChar(offset); if(ub <= ((1 << len) - 1)) { len = (sizeof(char) * 8); } else { while(bNotFound) { if(permittedAlphabet[count] == seg[0]) { seg[0] = (char)count; bNotFound = false; } count++; } } seg[0] <<= ((sizeof(char) * 8) - len); b.PutBits(seg, len); return len; } AsnString& AsnString::operator=(const char* str) { if (str == NULL) erase(); else assign(str); return *this; } void AsnString::Deterpret(AsnBufBits &b, AsnLen &bitsDecoded, long) { AsnLen len; int B = numBits(); int B2 = findB2(B); int count = 0; bool bNotFound = true; int sizePermittedAlpha; const char* permittedAlphabet = PermittedAlphabet(sizePermittedAlpha); int ub = (int)permittedAlphabet[sizePermittedAlpha - 1]; if(b.IsAligned()) len = B2; else len = B; if(ub <= ((1 << len) - 1) ) { len = (sizeof(char) * 8); } unsigned char* seg = b.GetBits(len); bitsDecoded += len; seg[0] >>= ((sizeof(char)*8) - len); if(!(ub <= ((1 << len) - 1)) ) { while(bNotFound) { if(count == (int)seg[0]) { seg[0] = permittedAlphabet[count]; bNotFound = false; } count++; } } putChar((char*)seg); delete [] seg; } void AsnString::PDec(AsnBufBits &b, AsnLen &bitsDecoded) { int numSizeConstraints; const SizeConstraint* sizeConstraints = SizeConstraints(numSizeConstraints); if(sizeConstraints == NULL && numSizeConstraints == 0) { DecodeGeneral(b, bitsDecoded); } else { DecodeWithSizeConstraint(b, bitsDecoded); } } AsnLen AsnString::PEnc(AsnBufBits &b) const { FUNC("AsnString::PEnc"); int numSizeConstraints; const SizeConstraint* sizeConstraints = SizeConstraints(numSizeConstraints); if(checkConstraints(NULL)) throw ConstraintException("String not within constraints", STACK_ENTRY); if(sizeConstraints == NULL && numSizeConstraints == 0) { return EncodeGeneral(b); } else { return EncodeWithSizeConstraint(b); } } AsnLen AsnString::BEnc(AsnBuf &b) const { FUNC("AsnString::BEnc"); if(checkConstraints(NULL)) throw ConstraintException("String not within constraints", STACK_ENTRY); AsnLen l = BEncContent(b); l += BEncDefLen(b, l); l += BEncTag1(b, UNIV, PRIM, tagCode()); return l; } void AsnString::BDec(const AsnBuf &b, AsnLen &bytesDecoded) { FUNC("AsnStringType::BDec()"); AsnTag tag = BDecTag(b, bytesDecoded); if ((tag != MAKE_TAG_ID (UNIV, PRIM, tagCode())) && (tag != MAKE_TAG_ID (UNIV, CONS, tagCode()))) { throw InvalidTagException(typeName(),tag, STACK_ENTRY); } AsnLen elmtLen1 = BDecLen(b, bytesDecoded); BDecContent(b, tag, elmtLen1, bytesDecoded); } AsnLen AsnString::BEncContent(AsnBuf &b) const { FUNC("AsnString::BEncContent()"); #ifndef DISABLE_STRING_CHECK if (!check()) throw EXCEPT("Invalid character present", RESTRICTED_TYPE_ERROR); #endif b.PutSegRvs(c_str(), length()); return length(); } void AsnString::BDecContent(const AsnBuf &b, AsnTag tagId, AsnLen elmtLen, AsnLen &bytesDecoded) { FUNC("AsnString::BDecContent()"); // Erase the existing characters erase(); // If tag is constructed... if (TAG_IS_CONS(tagId)) { BDecConsString(b, elmtLen, bytesDecoded); } else // primitive string { if (elmtLen != INDEFINITE_LEN) { if (elmtLen > 0) { b.GetSeg(*this, elmtLen); bytesDecoded += elmtLen; } } else { throw BoundsException("Indefinite length not allowed on primitive", STACK_ENTRY); } } } void AsnString::Print(std::ostream& os, unsigned short /*indent*/) const { os << c_str() << std::endl; } void AsnString::PrintXML(std::ostream &os, const char *lpszTitle) const { const char* title = lpszTitle; if (title == NULL) title = typeName(); os << "<" << title << ">" << c_str() << ""; } void AsnString::BDecConsString(const AsnBuf &b, AsnLen elmtLen, AsnLen &bytesDecoded) { FUNC("AsnString::BDecConsString()"); AsnLen totalElmtsLen = 0; while ((totalElmtsLen < elmtLen) || (elmtLen == INDEFINITE_LEN)) { AsnTag innerTag = BDecTag(b, totalElmtsLen); if ((innerTag == EOC_TAG_ID) && (elmtLen == INDEFINITE_LEN)) { BDEC_2ND_EOC_OCTET(b, totalElmtsLen); break; } AsnLen innerLen = BDecLen(b, totalElmtsLen); if (innerTag == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE)) { char *seg = new char[innerLen]; b.GetSeg(seg, innerLen); bytesDecoded += innerLen; totalElmtsLen += innerLen; append(seg, innerLen); delete [] seg; } else if (innerTag == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)) { BDecConsString(b, innerLen, totalElmtsLen); } else // wrong tag throw InvalidTagException(typeName(), innerTag, STACK_ENTRY); } bytesDecoded += totalElmtsLen; } // end of AsnString::BDecConsString() void WideAsnString::PDec(AsnBufBits &b, AsnLen &bitsDecoded) { DecodeGeneral(b, bitsDecoded); } AsnLen WideAsnString::PEnc(AsnBufBits &b) const { FUNC("WideAsnString::PEnc"); if(checkConstraints(NULL)) throw ConstraintException("Wide string not within constraints", STACK_ENTRY); return EncodeGeneral(b); } AsnLen WideAsnString::BEnc(AsnBuf &b) const { FUNC("WideAsnString::BEnc"); if(checkConstraints(NULL)) throw ConstraintException("Wide string not within constraints", STACK_ENTRY); AsnLen l = BEncContent(b); l += BEncDefLen(b, l); l += BEncTag1(b, UNIV, PRIM, tagCode()); return l; } void WideAsnString::BDec(const AsnBuf &b, AsnLen &bytesDecoded) { FUNC("WideAsnString::BDec()"); AsnTag tag = BDecTag(b, bytesDecoded); if ((tag != MAKE_TAG_ID (UNIV, PRIM, tagCode())) && (tag != MAKE_TAG_ID (UNIV, CONS, tagCode()))) { throw InvalidTagException(typeName(), tag, STACK_ENTRY); } AsnLen elmtLen1 = BDecLen(b, bytesDecoded); BDecContent(b, tag, elmtLen1, bytesDecoded); } void WideAsnString::Print(std::ostream& os, unsigned short /*indent*/) const { std::string utf8Form; getAsUTF8(utf8Form); os << utf8Form.c_str() << std::endl; } void WideAsnString::PrintXML(std::ostream &os, const char *lpszTitle) const { const char *title = lpszTitle; if (title == NULL) title = typeName(); std::string utf8Form; getAsUTF8(utf8Form); os << "<" << title << ">" << utf8Form.c_str() << ""; } // Set the wide-character string from the UTF-8 string void WideAsnString::set(const char* str) { FUNC("WideAsnString::set()"); const size_t wcharSize = sizeof(wchar_t); // Erase the existing characters erase(); // If the string is NULL, just return if (str == NULL) return; // Reserve space for a worst case wchar_t string unsigned int strLength = strlen(str); reserve(strLength); // Convert the UTF-8 string to a wchar_t string unsigned int i = 0; while (i < strLength) { // Determine the number of UTF-8 octets that follow the first unsigned short j; for (j = 0; (j < MAX_UTF8_OCTS_PER_CHAR) && ((gUTF8Masks[j].mask & str[i]) != gUTF8Masks[j].value); ++j) ; // Throw an exception if the first octet was invalid or if the // number of subsequent octets exceeds the UTF-8 string length if ((j == MAX_UTF8_OCTS_PER_CHAR) || ((i + j) >= strLength)) throw EXCEPT("Invalid UTF-8 string", RESTRICTED_TYPE_ERROR); // Throw an exception if the size of the wchar_t doesn't support the // size of this UTF-8 character // if ( (unsigned long)(abs((j * 6) - gUTF8Masks[j].bits)) > (wcharSize*8)) { throw EXCEPT("UTF-8 character too large for wchar_t", RESTRICTED_TYPE_ERROR); } // Copy the bits from the first octet into a temp wide character wchar_t tmp = (char)(~gUTF8Masks[j].mask & str[i++]); // Add in the bits from each subsequent octet for (; j > 0; j--) { // Throw an exception if the subsequent octet isn't properly // formatted if ((str[i] & 0xC0) != 0x80) throw EXCEPT("Invalid UTF-8 string", RESTRICTED_TYPE_ERROR); tmp <<= 6; tmp |= str[i++] & 0x3F; } append(1, tmp); } } wchar_t* WideAsnString::getWideChar(long offset)const { return (wchar_t*)&(*this)[offset]; } // Convert wide character string to UTF-8 character string // void WideAsnString::getAsUTF8(std::string& utf8String) const { FUNC("WideAsnString::getAsUTF8()"); // Size the resulting string for a worst case UTF-8 string utf8String.resize(length() * MAX_UTF8_OCTS_PER_CHAR); // Convert each wide character into a UTF-8 char sequence std::string::size_type x = 0; for (const_iterator i = begin(); i != end(); ++i) { // Determine the number of characters required to encode this // wide character unsigned int j; for (j = 0; (j < MAX_UTF8_OCTS_PER_CHAR) && ((unsigned)*i > (unsigned)gUTF8Masks[j].maxCharValue); ++j) ; // Return an error if the wide character is invalid if (j == MAX_UTF8_OCTS_PER_CHAR) throw EXCEPT("Invalid wide character", RESTRICTED_TYPE_ERROR); /* Skip over the first UTF-8 octet and encode the remaining octets (if any) from right-to-left. Fill in the least significant six bits of each octet with the low-order bits from the wide character value */ wchar_t temp_wchar = *i; for (unsigned int y = j; y > 0; --y) { utf8String[x + y] = (char)(0x80 | (temp_wchar & 0x3F)); temp_wchar >>= 6; } // Encode the first UTF-8 octet utf8String[x] = gUTF8Masks[j].value; utf8String[x++] |= ~gUTF8Masks[j].mask & temp_wchar; // Update the UTF-8 string index (skipping over the subsequent octets // already encoded) x += j; } // Resize the string to the correct length utf8String.resize(x); } // end of WideAsnString::getAsUTF8() void WideAsnString::Deterpret(AsnBufBits &b, AsnLen &bitsDecoded, long) { wchar_t* seg = (wchar_t*)b.GetBits(sizeof(wchar_t)); bitsDecoded += (sizeof(wchar_t)); putWideChar(seg); delete [] seg; } char* WideAsnString::getAsUTF8() const { std::string utf8Form; getAsUTF8(utf8Form); return strdup(utf8Form.c_str()); } // end of WideAsnString::getAsUTF8() AsnLen WideAsnString::CombineConsString(const AsnBuf &b, AsnLen elmtLen, std::string& encStr) { FUNC("WideAsnString::CombineConsString()"); AsnLen totalElmtsLen = 0; while ((totalElmtsLen < elmtLen) || (elmtLen == INDEFINITE_LEN)) { AsnTag innerTag = BDecTag(b, totalElmtsLen); if ((innerTag == EOC_TAG_ID) && (elmtLen == INDEFINITE_LEN)) { BDEC_2ND_EOC_OCTET(b, totalElmtsLen); break; } AsnLen innerLen = BDecLen(b, totalElmtsLen); if (innerTag == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE)) { char *seg = new char[elmtLen]; if (seg == NULL) throw MemoryException(elmtLen, "seg", STACK_ENTRY); b.GetSeg(seg, elmtLen); totalElmtsLen += elmtLen; encStr.append(seg, elmtLen); innerLen -= elmtLen; delete[] seg; } else if (innerTag == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)) { totalElmtsLen += CombineConsString(b, innerLen, encStr); } else // wrong tag throw InvalidTagException(typeName(), innerTag, STACK_ENTRY); } return totalElmtsLen; } // end of WideAsnString::CombineConsString() bool NumericString::check() const { for (const_iterator i = begin(); i != end(); ++i) { // Check for 0-9 if ((*i < '0') || (*i > '9')) { // Check for space if (*i != ' ') return false; } } return true; } const char* NumericString::PermittedAlphabet(int &alphaSize) const { alphaSize = 11; static const char kNumAlpha[] = " 0123456789"; return kNumAlpha; } const SizeConstraint* NumericString::SizeConstraints(int &sizeList)const { sizeList = 0; return NULL; } const char* PrintableString::PermittedAlphabet(int &sizeAlpha) const { sizeAlpha = 74; static char pPbleAlpha[] = {0x20, 0x27, 0x28, 0x29, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3D, 0x3F, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A}; return pPbleAlpha; } bool PrintableString::check() const { for (const_iterator i = begin(); i != end(); ++i) { // Check for A-Z if ((*i < 'A') || (*i > 'Z')) { // Check for a-z if ((*i < 'a') || (*i > 'z')) { // Check for 0-9 if ((*i < '0') || (*i > '9')) { switch (*i) { case ' ': // space case '\'': // apostrophe case '(': // left parenthesis case ')': // right parenthesis case '+': // plus sign case ',': // comma case '-': // hyphen-minus case '.': // full stop (period) case '/': // solidus case ':': // colon case '=': // equal sign case '?': // question mark break; default: return false; } } } } } return true; } AsnLen WideAsnString::Interpret(AsnBufBits &b, long offset)const { AsnLen len = sizeof(wchar_t); unsigned char* seg = (unsigned char*)getWideChar(offset); b.PutBits(seg, len); return len; } const char* WideAsnString::checkStringTypPermittedAlpha(const char* permittedAlphabet, long permittedAlphabetSize)const { char* pError=NULL; const char* cstr; int found=0; int x = 0; int count=length(); if(count > 0) { std::string utf8Form; getAsUTF8(utf8Form); cstr=utf8Form.c_str(); while(count) { found = 0; for(x = 0; x < permittedAlphabetSize; x++) { if(permittedAlphabet[x] == cstr[count - 1]) { found = 1; } } if(found == 0) break; count--; } if(found == 1) { return pError; } else { return ConstraintErrorStringList[ WIDE_STRING_PERMITTED_ALPHA ];; } } return pError; } int WideAsnString::checkConstraints (ConstraintFailList* pConstraintFails)const { int count = 0; int sizefailed = 1; int alphafailed = 1; std::string ptr; const char* tmpptr=NULL; int numSizeConstraints; const SizeConstraint* sizeConstraints = SizeConstraints(numSizeConstraints); int sizePermittedAlpha; const char* permittedAlphabet = PermittedAlphabet(sizePermittedAlpha); if (sizeConstraints) { char *utf8str = getAsUTF8(); for (count = 0; count < numSizeConstraints; count++) { tmpptr = NULL; if (sizeConstraints[count].upperBoundExists == 1) { if ((sizeConstraints[count].lowerBound > strlen(utf8str)) || (sizeConstraints[count].upperBound < strlen(utf8str))) { tmpptr = ConstraintErrorStringList[WIDE_STRING_SIZE_VALUE_RANGE]; } } else { if (sizeConstraints[count].lowerBound != strlen(utf8str)) { tmpptr = ConstraintErrorStringList[WIDE_STRING_SIZE_SINGLE_VALUE]; } } if (tmpptr) { ptr += tmpptr; } else { sizefailed = 0; } } free(utf8str); } else { sizefailed = 0; } if (sizePermittedAlpha > 0) { tmpptr = NULL; tmpptr = checkStringTypPermittedAlpha(permittedAlphabet, sizePermittedAlpha); if (tmpptr) { ptr += tmpptr; } else { alphafailed = 0; } } else { alphafailed = 0; } if (sizefailed || alphafailed) { if (pConstraintFails!=NULL) pConstraintFails->push_back(ptr); return 1; } return 0; } /* char* WideAsnString::checkStringTypSize(unsigned int m_Size)const { char* pError=NULL; char cTmperr[300]; std::string utf8Form; getAsUTF8(utf8Form); if(m_Size>=(strlen(utf8Form.c_str()))) { return pError; } else { sprintf(cTmperr, "_______\nRestricted Char String Type--Size Constraint:\n_______\nError: --String length must be less < or = to Size Constraint--\nValue: %d is not < or = to Size Constraint: %d \n", strlen(utf8Form.c_str()), m_Size); pError = strdup(cTmperr); return pError; } return pError; } char* WideAsnString::checkStringTypSize(unsigned int m_LowerSize, unsigned int m_UpperSize)const { char* pError=NULL; char cTmperr[500]; std::string utf8Form; getAsUTF8(utf8Form); if(m_UpperSize>=(strlen(utf8Form.c_str())) && m_LowerSize<=(strlen(utf8Form.c_str()))) { return pError; } else { sprintf(cTmperr, "_______\nRestricted Char String Type--Size Constraint:\n_______\nError: --String length must be between bounds--\nValue: %d is not between Lower Size Constraint: %d\n and Upper Size Constraint %d \n", strlen(utf8Form.c_str()), m_LowerSize, m_UpperSize); pError = strdup(cTmperr); return pError; } return pError; } */ const char* AsnString::checkStringTypPermittedAlpha(const char* permittedAlphabet, long permittedAlphabetSize)const { const char* pError=NULL; const char* cstr; int found=0; int x = 0; int count = length(); if(count > 0) { cstr=c_str(); while(count) { found = 0; for(x = 0; x < permittedAlphabetSize; x++) { if(permittedAlphabet[x] == cstr[count - 1]) { found = 1; } } if(found == 0) break; count--; } if(found == 1) { return pError; } else { return ConstraintErrorStringList[ STRING_PERMITTED_ALPHA ]; } } return pError; } int AsnString::checkConstraints (ConstraintFailList* pConstraintFails)const { int count = 0; int sizefailed = 1; int alphafailed = 1; std::string ptr; const char* tmpptr = NULL; int numSizeConstraints; const SizeConstraint* sizeConstraints = SizeConstraints(numSizeConstraints); int sizePermittedAlpha; const char* permittedAlphabet = PermittedAlphabet(sizePermittedAlpha); if (sizeConstraints) { for (count = 0; count < numSizeConstraints; count++) { tmpptr = NULL; if (sizeConstraints[count].upperBoundExists == 1) { if (sizeConstraints[count].lowerBound > size() || sizeConstraints[count].upperBound < size()) { tmpptr = ConstraintErrorStringList[STRING_SIZE_VALUE_RANGE]; } } else { if (sizeConstraints[count].lowerBound != size()) { tmpptr = ConstraintErrorStringList[STRING_SIZE_SINGLE_VALUE]; } } if(tmpptr) { ptr += tmpptr; } else { sizefailed = 0; } } } else { sizefailed = 0; } if (sizePermittedAlpha > 0) { tmpptr = checkStringTypPermittedAlpha(permittedAlphabet, sizePermittedAlpha); if (tmpptr) { ptr += tmpptr; } else { alphafailed = 0; } } if (sizefailed || alphafailed) { if (pConstraintFails != NULL) pConstraintFails->push_back(ptr); return 1; } return 0; } const char* IA5String::PermittedAlphabet(int &sizeAlpha) const { sizeAlpha = 128; static const char IA5Alpha[]= { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f }; return IA5Alpha; } bool IA5String::check() const { for (const_iterator i = begin(); i != end(); ++i) { // Check that character is less than 128 if ( ((unsigned)*i > 127) ) return false; } return true; } const char* VisibleString::PermittedAlphabet(int &sizeAlpha) const { sizeAlpha = 95; static const char VisibleAlpha[]= { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e }; return VisibleAlpha; } bool VisibleString::check() const { for (const_iterator i = begin(); i != end(); ++i) { // Check that character is between ' ' and '~' inclusive if ((*i < ' ') || (*i > '~')) return false; } return true; } // Encode BMPString octets into byte stream // AsnLen BMPString::BEncContent(AsnBuf &b) const { FUNC("BMPString::BEncContent"); const size_t wcharSize = sizeof(wchar_t); AsnLen len = 0; const_reverse_iterator wstrI; for (wstrI = rbegin(); wstrI != rend(); ++wstrI) { wchar_t wc = *wstrI; for (unsigned int i = 0; i < 2; ++i) { b.PutByteRvs((unsigned char)wc); wc >>= 8; ++len; } // Check that the upper bytes, if any, are zero if ((wcharSize > 2) && (wc != 0)) throw EXCEPT("Invalid BMPString", RESTRICTED_TYPE_ERROR); } return len; } void BMPString::BDecContent(const AsnBuf &b, AsnTag tagId, AsnLen elmtLen, AsnLen &bytesDecoded) { FUNC("BMPString::BDecContent"); // Erase the existing characters erase(); if (elmtLen == INDEFINITE_LEN || elmtLen > b.length()) { throw MemoryException(elmtLen, "elmtLen requests for too much data", STACK_ENTRY); } // If tag is constructed, decode and combine the segments std::string encStr; if (TAG_IS_CONS(tagId)) { bytesDecoded += CombineConsString(b, elmtLen, encStr); } else { // tag is primitive, just combine the one segment char *seg = new char[elmtLen]; b.GetSeg(seg, elmtLen); bytesDecoded += elmtLen; encStr.append(seg, elmtLen); delete [] seg; } // encoding length must be a multiple of two since BMPString uses // 2 bytes to represent a character. if (encStr.length() % 2 != 0) { throw EXCEPT("Invalid BMPString length not multiple of 2", RESTRICTED_TYPE_ERROR); } // decode BMPString into wide string resize(encStr.length() / 2); std::string::const_iterator iEnc = encStr.begin(); for (size_type i = 0; i < size(); ++i) { wchar_t wtmpCh = (unsigned char)*iEnc++; wtmpCh <<= 8; wtmpCh |= (unsigned char)*iEnc++; at(i) = wtmpCh; } } // Encode UniversalString octets into byte stream AsnLen UniversalString::BEncContent(AsnBuf &b) const { FUNC("UniversalString::BEncContent"); const size_t wcharSize = sizeof(wchar_t); AsnLen len = 0; const_reverse_iterator wstrI; for (wstrI = rbegin(); wstrI != rend(); ++wstrI) { wchar_t wc = *wstrI; for (unsigned int i = 0; i < 4; ++i) { if (i < wcharSize) b.PutByteRvs((unsigned char)wc); else b.PutByteRvs(0); wc >>= 8; ++len; } // Check that the upper bytes, if any, are zero if ((wcharSize > 4) && (wc != 0)) throw EXCEPT("Invalid UniversalString", RESTRICTED_TYPE_ERROR); } return len; } void UniversalString::BDecContent(const AsnBuf &b, AsnTag tagId, AsnLen elmtLen, AsnLen &bytesDecoded) { FUNC("UniversalString::BDecContent"); // Erase the existing characters erase(); if (elmtLen == INDEFINITE_LEN || elmtLen > b.length()) { throw MemoryException(elmtLen, "elmtLen requests for too much data", STACK_ENTRY); } // If tag is constructed, decode and combine the segments std::string encStr; if (TAG_IS_CONS(tagId)) { bytesDecoded += CombineConsString(b, elmtLen, encStr); } else // tag is primitive, just combine the one segment { char *seg = new char[elmtLen]; if (seg == NULL) throw MemoryException(elmtLen, "seg", STACK_ENTRY); b.GetSeg(seg, elmtLen); bytesDecoded += elmtLen; encStr.append(seg, elmtLen); delete[] seg; } // encoding length must be a multiple of four since UniversalString // uses 4 bytes to represent a character. // if (encStr.length() % 4 != 0) { throw EXCEPT("Invalid UniversalString length not multiple of 4", RESTRICTED_TYPE_ERROR); } const size_t wcharSize = sizeof(wchar_t); // decode UniversalString into wide string // resize(encStr.length() / 4); std::string::iterator iEnc = encStr.begin(); for (size_type i = 0; i < size(); ++i) { wchar_t wtmpCh = 0; for (unsigned int iByte = 4; iByte > 0; --iByte) { // Check that the wchar_t won't overflow if (int(int(wcharSize) - int(iByte)) < 0) { if (*iEnc++ != 0) { throw EXCEPT("UniversalString not supported by platform wchar_t size", RESTRICTED_TYPE_ERROR); } // else just skip the zero byte } else { wtmpCh <<= 8; wtmpCh |= (unsigned char)*iEnc++; } } at(i) = wtmpCh; } } AsnLen UTF8String::BEncContent(AsnBuf &b) const { std::string utf8; getAsUTF8(utf8); AsnLen len = utf8.length(); b.PutSegRvs(utf8.data(), len); return len; } void UTF8String::BDecContent(const AsnBuf &b, AsnTag tagId, AsnLen elmtLen, AsnLen &bytesDecoded) { FUNC("UTF8String::BDecContent()"); // Erase the existing characters erase(); try { if (elmtLen == INDEFINITE_LEN || elmtLen > b.length()) { throw MemoryException(elmtLen, "elmtLen requests for too much data", STACK_ENTRY); } // If tag is constructed, decode and combine the segments std::string encStr; if (TAG_IS_CONS(tagId)) { bytesDecoded += CombineConsString(b, elmtLen, encStr); } else { // tag is primitive, just combine the one segment char *seg = new char[elmtLen]; b.GetSeg(seg, elmtLen); bytesDecoded += elmtLen; encStr.append(seg, elmtLen); delete [] seg; } // Decode this UTF-8 string and assign it to this object set(encStr.c_str()); } catch (SnaccException& snaccE) { snaccE.push(STACK_ENTRY); throw; } } esnacc-ng-1.8.1/cxx-lib/src/asn-tag.cpp000066400000000000000000000103251302010526100175410ustar00rootroot00000000000000// file: .../c++-lib/src/asn-tag.C - ASN.1 tag manipulation routines // // MS 92/06/18 // Copyright (C) 1992 Michael Sample and the University of British Columbia // // This library is free software; you can redistribute it and/or // modify it provided that this copyright/license information is retained // in original form. // // If you modify this file, you must clearly indicate your changes. // // This source code is distributed in the hope that it will be // useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // // $Header: /baseline/SNACC/c++-lib/src/asn-tag.cpp,v 1.15 2004/03/25 19:20:16 gronej Exp $ #include "asn-incl.h" using namespace SNACC; /*returns the number of bytes that are in the encoded tag passed in*/ long SNACC::BytesInTag(AsnTag tag) { if( (tag & 0x00FFFFFF) == 0 ) { return 1; } else if( (tag & 0x0000FFFF) == 0 ) { return 2; } else if ( (tag & 0x000000FF) == 0 ) { return 3; } else { return 4; } } /* * Decode a BER Tag from the given buffer. Error is * flagged if the tag is too long or if a read error occurs. */ AsnTag SNACC::BDecTag(const AsnBuf &b, AsnLen &bytesDecoded) { FUNC("BDecTag()"); // Read first byte and shift it into the AsnTag unsigned char tagByte = b.GetUByte(); AsnTag tagId = tagByte << ((TB - 1) * 8); bytesDecoded++; // Check if long tag format (last 5 bits all set) */ if ((tagByte & 0x1f) == 0x1f) { int i = 1; do { // Read next tag byte tagByte = b.GetUByte(); tagId |= tagByte << ((TB - i - 1) * 8); bytesDecoded++; i++; } while ((tagByte & 0x80) && ((unsigned)i < TB)); // Check that tag isn't too long if (tagByte & 0x80) throw EXCEPT("Tag value overflow", INVALID_TAG); } return tagId; } /* BDecTag */ /* * Function: PDecTag() * Decodes a BER Tag from the given PER buffer and updates the * number of bits decoded parameter. Exceptions are thrown if * the tag is too long or if a read error occurs. */ AsnTag SNACC::PDecTag(AsnBufBits &bufBits, AsnLen &bitsDecoded) { FUNC("PDecTag()"); // Read first byte and shift it into the AsnTag unsigned char tagByte = bufBits.GetByte(); AsnTag tagId = tagByte << ((TB - 1) * 8); bitsDecoded += 8; // Check if long tag format (last 5 bits all set) */ if ((tagByte & 0x1f) == 0x1f) { int i = 1; do { // Read next tag byte tagByte = bufBits.GetByte(); tagId |= tagByte << ((TB - i - 1) * 8); bitsDecoded += 8; i++; } while ((tagByte & 0x80) && ((unsigned)i < TB)); // Check that tag isn't too long if (tagByte & 0x80) throw EXCEPT("Tag value overflow", INVALID_TAG); } return tagId; } // end of PDecTag() // //RWC; This routine returns the number of bits encoded. AsnLen SNACC::PEncTag(AsnBufBits &b, unsigned char ucClass, unsigned char form, long code, long lByteCount) { unsigned char ucChar; /*#define BEncTag5( b, class, form, code) b.PutByteRvs ((code) & 0x7F); b.PutByteRvs ((char)(0x80 | (char)((code) >> 7))); b.PutByteRvs ((char)(0x80 | (char)((code) >> 14))); b.PutByteRvs ((char)(0x80 | (char)((code) >> 21))); b.PutByteRvs ((class) | (form) | 31)*/ if (lByteCount == 1) { ucChar = (unsigned char)((ucClass) | (form) | (code)); b.PutBits(&ucChar, 8 ); } else { ucChar = (unsigned char)(ucClass | form | 31); b.PutBits(&ucChar, 8); if (lByteCount == 2) b.PutBits((unsigned char *)&code, 8); else // MUST be 3, 4, or 5 { if (lByteCount >= 5) { ucChar = (unsigned char)(0x80 | (unsigned char)((code) >> 21)); b.PutBits(&ucChar, 8); } if (lByteCount >= 4) { ucChar = (unsigned char)(0x80 | (char)((code) >> 14)); b.PutBits(&ucChar, 8); } ucChar = (unsigned char)(0x80 | (unsigned char)((code) >> 7)); b.PutBits(&ucChar, 8); ucChar = (unsigned char)(code & 0x7F); b.PutBits(&ucChar, 8); } // END IF 2 } // END IF 1 return(lByteCount*8); } /* PEncTag */ esnacc-ng-1.8.1/cxx-lib/src/asn-type.cpp000066400000000000000000000055601302010526100177540ustar00rootroot00000000000000// file: .../c++-lib/src/asn-type.C - Abstract class that all ASN.1 types are derived from // Design motivated by ANY type. // // Runtime cost in speed and space for virtual fcns will // hopefully not be too bad // // If your ASN.1 code does not use ANY or ANY DEFIND BY // types then you could make the BEnc, BDec and Clone // non-virtual in the AsnType to improve performance. // (undef SUPPORT_ANY_TYPE) // // NOTE: The virtual encode/decode/print etc fcns // could be purely virtual (= 0) creating an abstract class // but the ANY handling code needs to instantiate the AsnType // base class (via Cloning). Also it allows for default // error reporting for ANY types that have not been // instantiated properly. // // Copyright (C) 1992 Michael Sample and the University of British Columbia // // This library is free software; you can redistribute it and/or // modify it provided that this copyright/license information is retained // in original form. // // If you modify this file, you must clearly indicate your changes. // // This source code is distributed in the hope that it will be // useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // // MS 92 // // $Header: /baseline/SNACC/c++-lib/src/asn-type.cpp,v 1.17 2004/02/11 19:08:48 nicholar Exp $ // #include "asn-incl.h" _BEGIN_SNACC_NAMESPACE AsnType::~AsnType() { } bool AsnType::BEncPdu (AsnBuf &b, AsnLen &bytesEncoded) const { try { bytesEncoded = BEnc (b); return true; } catch (...) { return false; } } bool AsnType::BDecPdu (const AsnBuf &b, AsnLen &bytesDecoded) { try { bytesDecoded = 0; { BDec (b, bytesDecoded); return true; } } catch (...) { return false; } } #if META const AsnTypeDesc AsnType::_desc (NULL, NULL, false, AsnTypeDesc::VOID, NULL); const AsnTypeDesc *AsnType::_getdesc() const { return &_desc; } AsnType *AsnType::_getref (const char *membername, bool create) { return NULL; } const char *AsnType::_typename() const { return _desc.typenames[_getdesc()->type]; } #if TCL int AsnType::TclGetDesc (Tcl_DString *valstr) const { return TCL_OK; } int AsnType::TclGetVal (Tcl_Interp *interp) const { Tcl_AppendResult (interp, "can't get value from ", _typename(), NULL); return TCL_ERROR; } int AsnType::TclSetVal (Tcl_Interp *interp, const char *) { Tcl_AppendResult (interp, "can't set value in ", _typename(), NULL); return TCL_ERROR; } int AsnType::TclUnsetVal (Tcl_Interp *interp, const char *) { Tcl_AppendResult (interp, "can't unset member(s) in ", _typename(), NULL); return TCL_ERROR; } #endif /* TCL */ #endif /* META */ _END_SNACC_NAMESPACE esnacc-ng-1.8.1/cxx-lib/src/asn-usefultypes.cpp000066400000000000000000000316441302010526100213650ustar00rootroot00000000000000#include "asn-incl.h" using namespace SNACC; EXTERNALChoice::EXTERNALChoice(const EXTERNALChoice &that) { Init(); *this = that; } void EXTERNALChoice::Init(void) { // initialize choice to no choice choiceId = NoChoiceCid; NoChoice = NULL; }; void EXTERNALChoice::Clear() { switch (choiceId) { case single_ASN1_typeCid: delete single_ASN1_type; single_ASN1_type = NULL; break; case octet_alignedCid: delete octet_aligned; octet_aligned = NULL; break; case arbitraryCid: delete arbitrary; arbitrary = NULL; break; default: arbitrary = NULL; } // end of switch } // end of Clear EXTERNALChoice &EXTERNALChoice::operator = (const EXTERNALChoice &that) { if (this != &that) { Clear(); switch (choiceId = that.choiceId) { case single_ASN1_typeCid: single_ASN1_type = new AsnOcts; *single_ASN1_type = *that.single_ASN1_type; break; case octet_alignedCid: octet_aligned = new AsnOcts; *octet_aligned = *that.octet_aligned; break; case arbitraryCid: arbitrary = new AsnBits; *arbitrary = *that.arbitrary; break; default: arbitrary = NULL; } } return *this; } AsnLen EXTERNALChoice::BEncContent (AsnBuf & b) const { FUNC("EXTERNALChoice::BEncContent"); AsnLen l=0; switch (choiceId) { case single_ASN1_typeCid: l = single_ASN1_type->BEncContent (b); l += BEncDefLen (b, l); l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE); l += BEncConsLen (b, l); l += BEncTag1 (b, CNTX, CONS, 0); break; case octet_alignedCid: l = octet_aligned->BEncContent (b); l += BEncDefLen (b, l); l += BEncTag1 (b, CNTX, PRIM, 1); break; case arbitraryCid: l = arbitrary->BEncContent (b); l += BEncDefLen (b, l); l += BEncTag1 (b, CNTX, PRIM, 2); break; default: throw EXCEPT("Can not encode non optional empty CHOICE", ENCODE_ERROR); } // end switch return l; } // EXTERNALChoice::BEncContent void EXTERNALChoice::BDecContent (const AsnBuf & b, AsnTag tag, AsnLen elmtLen0, AsnLen &bytesDecoded/*, s env*/) { FUNC("EXTERNALChoice::BDecContent()"); Clear(); AsnLen elmtLen1; switch (tag) { case MAKE_TAG_ID (CNTX, CONS, 0): tag = BDecTag (b, bytesDecoded); if ((tag != MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE)) && (tag != MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE))) { throw InvalidTagException(typeName(), tag, STACK_ENTRY); } elmtLen1 = BDecLen (b, bytesDecoded); choiceId = single_ASN1_typeCid; single_ASN1_type = new AsnOcts; single_ASN1_type->BDecContent (b, tag, elmtLen1, bytesDecoded); if (elmtLen0 == INDEFINITE_LEN) BDecEoc (b, bytesDecoded); break; case MAKE_TAG_ID (CNTX, PRIM, 1): case MAKE_TAG_ID (CNTX, CONS, 1): choiceId = octet_alignedCid; octet_aligned = new AsnOcts; octet_aligned->BDecContent (b, tag, elmtLen0, bytesDecoded); break; case MAKE_TAG_ID (CNTX, PRIM, 2): case MAKE_TAG_ID (CNTX, CONS, 2): choiceId = arbitraryCid; arbitrary = new AsnBits; arbitrary->BDecContent (b, tag, elmtLen0, bytesDecoded); break; default: throw InvalidTagException(typeName(), tag, STACK_ENTRY); break; } // end switch } // EXTERNALChoice::BDecContent AsnLen EXTERNALChoice::PEnc (AsnBufBits &) const { AsnLen len=0; return len; } AsnLen EXTERNALChoice::BEnc (AsnBuf & b) const { AsnLen l=0; l = BEncContent (b); return l; } void EXTERNALChoice::BDec (const AsnBuf & b, AsnLen &bytesDecoded/*, s env*/) { AsnLen elmtLen; AsnTag tag; /* CHOICEs are a special case - grab identifying tag */ /* this allows easier handling of nested CHOICEs */ tag = BDecTag (b, bytesDecoded); elmtLen = BDecLen (b, bytesDecoded); BDecContent (b, tag, elmtLen, bytesDecoded); } void EXTERNALChoice::Print(std::ostream& os, unsigned short indent) const { FUNC("EXTERNALChoice::Print"); switch (choiceId) { case single_ASN1_typeCid: os << "single-ASN1-type "; if (single_ASN1_type) single_ASN1_type->Print(os, indent); else os << "-- void3 --\n"; break; case octet_alignedCid: os << "octet-aligned "; if (octet_aligned) octet_aligned->Print(os, indent); else os << "-- void3 --\n"; break; case arbitraryCid: os << "arbitrary "; if (arbitrary) arbitrary->Print(os, indent); else os << "-- void3 --\n"; break; default: throw EXCEPT("Can not encode non optional empty CHOICE", ENCODE_ERROR); } // end of switch } // EXTERNALChoice::Print void EXTERNALChoice::PrintXML (std::ostream &os, const char *lpszTitle) const { os << ""; if (lpszTitle) os << lpszTitle; os << "-" << std::endl; switch (choiceId) { case single_ASN1_typeCid: if (single_ASN1_type) single_ASN1_type->PrintXML(os,"single-ASN1-type"); else { os << ""; os << "-- void3 --" << std::endl; } break; case octet_alignedCid: if (octet_aligned) octet_aligned->PrintXML(os,"octet-aligned"); else { os << ""; os << "-- void3 --" << std::endl; } break; case arbitraryCid: if (arbitrary) arbitrary->PrintXML(os,"arbitrary"); else { os << ""; os << "-- void3 --" << std::endl; } break; default: break; } // end of switch os << "" << std::endl; } // EXTERNALChoice::PrintXML void EXTERNAL::Init(void) { direct_reference = NULL; indirect_reference = NULL; data_value_descriptor = NULL; #if TCL encoding = new EXTERNALChoice; #else encoding = NULL; // incomplete initialization of mandatory element! #endif // TCL } void EXTERNAL::Clear() { delete direct_reference; direct_reference = NULL; delete indirect_reference; indirect_reference = NULL; delete data_value_descriptor; data_value_descriptor = NULL; delete encoding; encoding = NULL; } EXTERNAL::EXTERNAL(const EXTERNAL &that) { Init(); *this = that; } EXTERNAL &EXTERNAL::operator = (const EXTERNAL &that) { if (this != &that) { Clear(); if (that.direct_reference) { if (!direct_reference) direct_reference = new AsnOid; *direct_reference = *that.direct_reference; } else { delete direct_reference; direct_reference = NULL; } if (that.indirect_reference) { if (!indirect_reference) indirect_reference = new AsnInt; *indirect_reference = *that.indirect_reference; } else { delete indirect_reference; indirect_reference = NULL; } if (that.data_value_descriptor) { if (!data_value_descriptor) data_value_descriptor = new ObjectDescriptor; *data_value_descriptor = *that.data_value_descriptor; } else { delete data_value_descriptor; data_value_descriptor = NULL; } if (that.encoding) { if (!encoding) encoding = new EXTERNALChoice; *encoding = *that.encoding; } else { delete encoding; encoding = NULL; } } return *this; } AsnLen EXTERNAL::BEncContent (AsnBuf & b) const { AsnLen totalLen = 0; AsnLen l=0; l = encoding->BEncContent (b); totalLen += l; if (NOT_NULL (data_value_descriptor)) { l = data_value_descriptor->BEncContent (b); l += BEncDefLen (b, l); l += BEncTag1 (b, UNIV, PRIM, OD_TAG_CODE); totalLen += l; } if (NOT_NULL (indirect_reference)) { l = indirect_reference->BEncContent (b); l += BEncDefLen (b, l); l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE); totalLen += l; } if (NOT_NULL (direct_reference)) { l = direct_reference->BEncContent (b); l += BEncDefLen (b, l); l += BEncTag1 (b, UNIV, PRIM, OID_TAG_CODE); totalLen += l; } return totalLen; } // EXTERNAL::BEncContent void EXTERNAL::BDecContent (const AsnBuf & b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded/*, s env*/) { FUNC("EXTERNAL::BDecContent()"); Clear(); AsnTag tag1; AsnLen seqBytesDecoded = 0; AsnLen elmtLen1; tag1 = BDecTag (b, seqBytesDecoded); if (tag1 == MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE)) { elmtLen1 = BDecLen (b, seqBytesDecoded); direct_reference = new AsnOid; direct_reference->BDecContent (b, tag1, elmtLen1, seqBytesDecoded); tag1 = BDecTag (b, seqBytesDecoded); } if (tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)) { elmtLen1 = BDecLen (b, seqBytesDecoded); indirect_reference = new AsnInt; indirect_reference->BDecContent (b, tag1, elmtLen1, seqBytesDecoded); tag1 = BDecTag (b, seqBytesDecoded); } if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OD_TAG_CODE)) || (tag1 == MAKE_TAG_ID (UNIV, CONS, OD_TAG_CODE))) { elmtLen1 = BDecLen (b, seqBytesDecoded); data_value_descriptor = new ObjectDescriptor; data_value_descriptor->BDecContent (b, tag1, elmtLen1, seqBytesDecoded); tag1 = BDecTag (b, seqBytesDecoded); } if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 0)) || (tag1 == MAKE_TAG_ID (CNTX, PRIM, 1)) || (tag1 == MAKE_TAG_ID (CNTX, CONS, 1)) || (tag1 == MAKE_TAG_ID (CNTX, PRIM, 2)) || (tag1 == MAKE_TAG_ID (CNTX, CONS, 2))) { elmtLen1 = BDecLen (b, seqBytesDecoded); encoding = new EXTERNALChoice; encoding->BDecContent (b, tag1, elmtLen1, seqBytesDecoded); } else { throw EXCEPT("SEQUENCE is missing non-optional elmt", DECODE_ERROR); } bytesDecoded += seqBytesDecoded; if (elmtLen0 == INDEFINITE_LEN) { BDecEoc (b, bytesDecoded); return; } else if (seqBytesDecoded != elmtLen0) { throw EXCEPT("ERROR - Length discrepancy on sequence", DECODE_ERROR); } else return; } // EXTERNAL::BDecContent AsnLen EXTERNAL::PEnc (AsnBufBits &) const { AsnLen len=0; return len; } AsnLen EXTERNAL::BEnc (AsnBuf & b) const { AsnLen l=0; l = BEncContent (b); l += BEncConsLen (b, l); l += BEncTag1 (b, UNIV, CONS, EXTERNAL_TAG_CODE); return l; } void EXTERNAL::BDec (const AsnBuf & b, AsnLen &bytesDecoded/*, s env*/) { FUNC("EXTERNAL::BDec()"); AsnTag tag; AsnLen elmtLen1; if ((tag = BDecTag (b, bytesDecoded)) != MAKE_TAG_ID (UNIV, CONS, EXTERNAL_TAG_CODE)) { throw InvalidTagException(typeName(), tag, STACK_ENTRY); } elmtLen1 = BDecLen (b, bytesDecoded); BDecContent (b, tag, elmtLen1, bytesDecoded); } void EXTERNAL::Print(std::ostream& os, unsigned short indent) const { os << "{ -- SEQUENCE --" << std::endl; ++indent; if (NOT_NULL (direct_reference)) { Indent(os, indent); os << "direct-reference "; direct_reference->Print(os, indent); } else { Indent(os, indent); os << "direct-reference "; os << "-- void --"; os << "," << std::endl; } if (NOT_NULL (indirect_reference)) { Indent(os, indent); os << "indirect-reference "; indirect_reference->Print(os, indent); } else { Indent(os, indent); os << "indirect-reference "; os << "-- void --"; os << "," << std::endl; } if (NOT_NULL (data_value_descriptor)) { Indent(os, indent); os << "data-value-descriptor "; data_value_descriptor->Print(os, indent); } else { Indent(os, indent); os << "data-value-descriptor "; os << "-- void --"; os << "," << std::endl; } if (NOT_NULL (encoding)) { Indent(os, indent); os << "encoding "; os << *encoding; } else { Indent(os, indent); os << "encoding "; os << "-- void --"; os << std::endl; } os << std::endl; Indent (os, --indent); os << "}"; } // EXTERNAL::Print void EXTERNAL::PrintXML (std::ostream &os, const char *lpszTitle) const { if (lpszTitle) { os << "<" << lpszTitle << ">" << std::endl; os << typeName() << " SEQUENCE" << std::endl ; } else { os << "<" << typeName() << "> SEQUENCE" << std::endl; } if (NOT_NULL (direct_reference)) { direct_reference->PrintXML(os, "direct-reference"); } else os << "-- void --" << std::endl; if (NOT_NULL (indirect_reference)) { indirect_reference->PrintXML(os, "indirect-reference"); } else os << "-- void --" << std::endl; if (NOT_NULL (data_value_descriptor)) { data_value_descriptor->PrintXML(os, "data-value-descriptor"); } else os << "-- void --" << std::endl; if (NOT_NULL (encoding)) { encoding->PrintXML(os, "encoding"); } else os << "-- void --" << std::endl; if (lpszTitle) { os << "" << std::endl; } else os << "" << std::endl; } // EXTERNAL::PrintXML esnacc-ng-1.8.1/cxx-lib/src/hash.cpp000066400000000000000000000212021302010526100171260ustar00rootroot00000000000000// file: .../c++-lib/src/hash.C // // This was borrowed from Don Acton and Terry Coatta's Raven Code. // It has been modified somewhat. // - Mike Sample 92 // // This is a set or routines that implements an extensible hashing // algorithm. At the moment it assumes that all the hash codes are unique // (ie. there are no collisions). For the way hash codes are currently being // supplied this is not a bad assumption. // The extensible hashing routine used is based on a multiway tree with // each node in the tree being a fixed array of (2^n) size. At a given // level, i, in the tree with the first level being level 0, bits // i*n through i*n through (i+1)*n-1 are used as the index into the table. // Each entry in the table is either NULL (unused) or a pointer to an // object of type entry. The entry contains all the information about a // hash entry. The entry also contains a field indicating whether or not this // is a leaf node. If an entry isn't a leaf node then it references a table at // at the next level and not a value. With the current implementation // a 32 hash value is used and table sizes are 256. The algorithm used // here is the same as the one used in the Set class of the Raven // class system. // // Copyright (C) 1992 the University of British Columbia // // This library is free software; you can redistribute it and/or // modify it provided that this copyright/license information is retained // in original form. // // If you modify this file, you must clearly indicate your changes. // // This source code is distributed in the hope that it will be // useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // // $Header: /baseline/SNACC/c++-lib/src/hash.cpp,v 1.9 2004/03/22 20:16:59 gronej Exp $ // $Log: hash.cpp,v $ // Revision 1.9 2004/03/22 20:16:59 gronej // took out #include since asn-incl already included them // // Revision 1.8 2004/03/22 18:30:17 leonberp // Fixed Linux warnings. // // Revision 1.7 2002/05/29 19:26:06 leonberp // removed PDU_MEMBERS_MACRO and added BDecPDU and BEncPDU to AsnType // // Revision 1.6 2001/10/15 17:14:26 leonberp // mem leak fixes // // Revision 1.5 2001/07/19 16:02:52 sfl // Yet more string.h updates. // // Revision 1.4 2001/07/12 19:33:43 leonberp // Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. // // Revision 1.3 2001/06/28 15:29:46 rwc // ADDED "SNACCASN" namespace definition to all SNACC data structures. // This should not affect most applications since we do not have any name // conflicts. // ALSO, combined all ASN primitive data type includes into asn-incl.h. // // Revision 1.2 2001/06/18 17:47:45 rwc // Updated to reflect newly added C++ Exception error handling, instead of "C" longjmp and setjmp calls. // Changes made to both the compiler and the SNACC C++ run-time library. // // Revision 1.1.1.1 2000/08/21 20:36:09 leonberp // First CVS Version of SNACC. // // Revision 1.7 1997/02/28 13:39:46 wan // Modifications collected for new version 1.3: Bug fixes, tk4.2. // // Revision 1.6 1997/02/16 20:26:08 rj // check-in of a few cosmetic changes // // Revision 1.5 1995/07/24 20:34:07 rj // use memzero that is defined in .../snacc.h to use either memset or bzero. // // changed `_' to `-' in file names. // // Revision 1.4 1994/10/08 04:18:32 rj // code for meta structures added (provides information about the generated code itself). // // code for Tcl interface added (makes use of the above mentioned meta code). // // virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included. // // made Print() const (and some other, mainly comparison functions). // // several `unsigned long int' turned into `size_t'. // // Revision 1.3 1994/08/31 23:43:05 rj // FALSE/TRUE turned into false/true // // Revision 1.2 1994/08/28 10:01:21 rj // comment leader fixed. // // Revision 1.1 1994/08/28 09:21:11 rj // first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. /*#include */ #include "asn-incl.h" _BEGIN_SNACC_NAMESPACE /* * * From sdbm, an ndbm work-alike hashed database library * Author: oz@nexus.yorku.ca * Status: public domain. * * polynomial conversion ignoring overflows * [this seems to work remarkably well, in fact better * then the ndbm hash function. Replace at your own risk] * use: 65599 nice. * 65587 even better. * * [In one experiment, this function hashed 84165 symbols (English words * plus symbol table values) with no collisions. -bjb] * */ Hash MakeHash (const char *str, size_t len) { register Hash n = 0; #define HASHC n = *str++ + 65587 * n if (len > 0) { int loop; loop = (len + 8 - 1) >> 3; switch (len & (8 - 1)) { case 0: /* very strange! - switch labels in do loop */ do { HASHC; case 7: HASHC; case 6: HASHC; case 5: HASHC; case 4: HASHC; case 3: HASHC; case 2: HASHC; case 1: HASHC; } while (--loop); } } return n; } /* Creates and clears a new hash slot */ static HashSlot * NewHashSlot() { HashSlot *foo; foo = new HashSlot; if (foo == NULL) return NULL; memset (foo, 0, sizeof (HashSlot)); return foo; } /* Create a new cleared hash table */ static Table * NewTable() { Table *new_table; // new_table = new Table; // whose bug is it that gcc won't compile the above line? new_table = (Table *) new Table; if (new_table == NULL) return NULL; memset (new_table, 0, sizeof (Table)); return new_table; } /* This routine is used to initialize the hash tables. When it is called * it returns a value which is used to identify which hash table * a particular request is to operate on. */ Table * InitHash() { Table *table; table = NewTable(); if (table == NULL) return 0; else return table; } /* When a hash collision occurs at a leaf slot this routine is called to * split the entry and add a new level to the tree at this point. */ static int SplitAndInsert (HashSlot *entry, void *element, Hash hash_value) { if (((entry->table = NewTable()) == NULL) || !Insert (entry->table, entry->value, entry->hash >> INDEXSHIFT) || !Insert (entry->table, element, hash_value >> INDEXSHIFT)) return false; entry->leaf = false; entry->value = NULL; // this is now contained in entry->table->value, so // avoid a double release return true; } /* This routine takes a hash table identifier, an element (value) and the * coresponding hash value for that element and enters it into the table * assuming it isn't already there. */ int Insert (Table *table, void *element, Hash hash_value) { HashSlot *entry; entry = (HashSlot *) (*table)[hash_value & INDEXMASK]; if (entry == NULL) { /* Need to add this element here */ entry = NewHashSlot(); if (entry == NULL) return false; entry->leaf = true; entry->value = element; entry->hash = hash_value; (*table)[hash_value & INDEXMASK] = entry; return true; } if (hash_value == entry->hash) return false; if (entry->leaf) return SplitAndInsert (entry, element, hash_value); return Insert (entry->table, element, hash_value >> INDEXSHIFT); } /* This routine looks to see if a particular hash value is already stored in * the table. It returns true if it is and false otherwise. */ int CheckFor (Table *table, Hash hash) { HashSlot *entry; entry = (HashSlot *) table[hash & INDEXMASK]; if (entry == NULL) return false; if (entry->leaf) return entry->hash == hash; return CheckFor (entry->table, hash >> INDEXSHIFT); } /* In addition to checking for a hash value in the tree this function also * returns the coresponding element value into the space pointed to by * the value parameter. If the hash value isn't found false is returned * the the space pointed to by value is not changed. */ int CheckForAndReturnValue (Table *table, Hash hash, void **value) { HashSlot *entry; if (table) { entry = (HashSlot *) (*table)[hash & INDEXMASK]; if (entry == NULL) return false; if (entry->leaf) { if (entry->hash == hash) { *value = entry->value; return true; } else return false; } return CheckForAndReturnValue (entry->table, hash >> INDEXSHIFT, value); } else return false; } _END_SNACC_NAMESPACE esnacc-ng-1.8.1/cxx-lib/src/meta.cpp000066400000000000000000000272471302010526100171500ustar00rootroot00000000000000// file: .../c++-lib/src/meta.C // // $Header: /baseline/SNACC/c++-lib/src/meta.cpp,v 1.6 2004/03/22 20:04:18 gronej Exp $ // $Log: meta.cpp,v $ // Revision 1.6 2004/03/22 20:04:18 gronej // took IBM references out of the code (to the best of our knowledge, we don't use any of it anymore) // // Revision 1.5 2004/02/09 20:38:50 nicholar // Updated AsnOid and AsnRelativeOid classes // // Revision 1.4 2001/07/12 19:33:43 leonberp // Changed namespace to SNACC and added compiler options: -ns and -nons. Also removed dead code. // // Revision 1.3 2001/06/28 21:38:29 rwc // Updated to remove referneces to vdacerr, which originally replaced the cerr standard error output. // Updated all references in macros and source that printed to vdacerr. All code now performs an // ASN_THROW(...) exception. // // Revision 1.2 2001/06/28 15:29:46 rwc // ADDED "SNACCASN" namespace definition to all SNACC data structures. // This should not affect most applications since we do not have any name // conflicts. // ALSO, combined all ASN primitive data type includes into asn-incl.h. // // Revision 1.1.1.1 2000/08/21 20:36:09 leonberp // First CVS Version of SNACC. // // Revision 1.5 1997/02/28 13:39:47 wan // Modifications collected for new version 1.3: Bug fixes, tk4.2. // // Revision 1.4 1995/08/17 15:23:51 rj // introducing an AsnEnumTypeDesc class with its own TclGetDesc2 function that returns the value names but omits the numeric values. // utility function AsnSe_TypeDesc::mandatmemberr added. // // Revision 1.3 1995/07/26 19:39:35 rj // comment leader fixed // // Revision 1.2 1995/07/25 22:11:31 rj // lots of new data types, and new data and function members in old ones. // // use memcmpeq that is defined in .../snacc.h to use either memcmp or bcmp. // // code extracted from AsnOcts::TclGetVal and AsnOcts::TclSetVal in asn-octs.C into ::debinify and ::binify. // // #if TCL ... #endif wrapped into #if META ... #endif // // call constructor with additional pdu and create arguments. // // changed `_' to `-' in file names. #include "asn-incl.h" _BEGIN_SNACC_NAMESPACE #if META AsnMemberDesc::AsnMemberDesc (const char *_name, const AsnTypeDesc *_desc): name (_name), desc (_desc) { } AsnMemberDesc::AsnMemberDesc(): name (NULL), desc(NULL) { } int AsnMemberDesc::TclGetDesc (Tcl_DString *desc) const { if (name) { Tcl_DStringStartSublist (desc); Tcl_DStringAppendElement (desc, (char*)name); this->desc->AsnTypeDesc::TclGetDesc (desc); TclGetDesc2 (desc); Tcl_DStringEndSublist (desc); return TCL_OK; } else return TCL_BREAK; } int AsnMemberDesc::TclGetDesc2 (Tcl_DString *desc) const { return TCL_OK; } AsnSe_MemberDesc::AsnSe_MemberDesc (const char *name, const AsnTypeDesc *desc, bool _optional): AsnMemberDesc (name, desc), optional (_optional) { } AsnSe_MemberDesc::AsnSe_MemberDesc(): AsnMemberDesc() { } int AsnSe_MemberDesc::TclGetDesc2 (Tcl_DString *desc) const { Tcl_DStringAppendElement (desc, optional ? "optional" : "mandatory"); return TCL_OK; } const char *const AsnTypeDesc::typenames[] = // NOTE: keep this array in sync with the enum Type { "(void)", "(alias)", "INTEGER", "REAL", "NULL", "BOOLEAN", "ENUMERATED", "BIT STRING", "OCTET STRING", "OBJECT IDENTIFIER", "RELATIVE-OID", "SET", "SEQUENCE", "SET OF", "SEQUENCE OF", "CHOICE", "ANY", }; AsnTypeDesc::AsnTypeDesc (const AsnModuleDesc *_module, const char *_name, bool ispdu, Type _type, AsnType *(*_create)()): module (_module), name (_name), pdu (ispdu), type (_type), create (_create) { } const AsnModuleDesc *AsnTypeDesc::getmodule() const { return module; } const char *AsnTypeDesc::getname() const { return name; } bool AsnTypeDesc::ispdu() const { return pdu; } AsnTypeDesc::Type AsnTypeDesc::gettype() const { return type; } const AsnNameDesc *AsnTypeDesc::getnames() const { //Asn1Error << typenames[type] << "::getnames() called" << endl; ASN_THROW(0, "AsnNameDesc *AsnTypeDesc::getnames() called", NULL); abort(); return NULL; } //const AsnMemberDesc *AsnTypeDesc::getmembers() const //{ //Asn1Error << typenames[type] << "::getmembers() called" << endl; //abort(); //} //\[banner "names types (int, enum)"]----------------------------------------------------------------------------------------------- AsnNamesTypeDesc::AsnNamesTypeDesc (const AsnModuleDesc *module, const char *name, bool ispdu, Type type, AsnType *(*create)(), const AsnNameDesc *_names): AsnTypeDesc (module, name, ispdu, type, create), names (_names) { } const AsnNameDesc *AsnNamesTypeDesc::getnames() const { return names; } //\[banner "enum type"]------------------------------------------------------------------------------------------------------------- AsnEnumTypeDesc::AsnEnumTypeDesc (const AsnModuleDesc *module, const char *name, bool ispdu, Type type, AsnType *(*create)(), const AsnNameDesc *names): AsnNamesTypeDesc (module, name, ispdu, type, create, names) { } //\[banner "members types (choice, set, sequence)"]--------------------------------------------------------------------------------- AsnMembersTypeDesc::AsnMembersTypeDesc (const AsnModuleDesc *module, const char *name, bool ispdu, Type type, AsnType *(*create)()): AsnTypeDesc (module, name, ispdu, type, create) { } //\[banner "choice type"]----------------------------------------------------------------------------------------------------------- AsnChoiceTypeDesc::AsnChoiceTypeDesc (const AsnModuleDesc *module, const char *name, bool ispdu, Type type, AsnType *(*create)(), const AsnChoiceMemberDesc *_members): AsnMembersTypeDesc (module, name, ispdu, type, create), members (_members) { } int AsnChoiceTypeDesc::choicebyname (const char *name) const { for (int m=0; members[m].name; m++) if (!strcmp (members[m].name, name)) return m; return -1; } const char *AsnChoiceTypeDesc::choicebyvalue (int value) const { return members[value].name; } //\[banner "set/sequence type"]----------------------------------------------------------------------------------------------------- AsnSe_TypeDesc::AsnSe_TypeDesc (const AsnModuleDesc *module, const char *name, bool ispdu, Type type, AsnType *(*create)(), const AsnSe_MemberDesc *_members): AsnMembersTypeDesc (module, name, ispdu, type, create), members (_members) { } //\[banner "list type"]------------------------------------------------------------------------------------------------------------- AsnListTypeDesc::AsnListTypeDesc (const AsnModuleDesc *module, const char *name, bool ispdu, Type type, AsnType *(*create)(), const AsnTypeDesc *_base): AsnTypeDesc (module, name, ispdu, type, create), base (_base) { } //\[banner "alias type"]------------------------------------------------------------------------------------------------------------ AsnAliasTypeDesc::AsnAliasTypeDesc (const AsnModuleDesc *module, const char *name, bool ispdu, Type type, AsnType *(*create)(), const AsnTypeDesc *_alias): AsnTypeDesc (module, name, ispdu, type, create), alias (_alias) { } const AsnModuleDesc *AsnAliasTypeDesc::getmodule() const { return module; } const char *AsnAliasTypeDesc::getname() const { return name; } bool AsnAliasTypeDesc::ispdu() const { return pdu; } AsnTypeDesc::Type AsnAliasTypeDesc::gettype() const { return alias->gettype(); } const AsnNameDesc *AsnAliasTypeDesc::getnames() const { return alias->getnames(); } //const AsnMemberDesc *AsnAliasTypeDesc::getmembers() const //{ //return alias->getmembers(); //} //\[banner "Tcl routines"]---------------------------------------------------------------------------------------------------------- #if TCL int AsnTypeDesc::TclGetDesc (Tcl_DString *desc) const { Tcl_DStringStartSublist (desc); Tcl_DStringAppendElement (desc, getmodule() ? (char*) getmodule()->name : ""); Tcl_DStringAppendElement (desc, getname() ? (char*) getname() : ""); Tcl_DStringEndSublist (desc); Tcl_DStringAppendElement (desc, ispdu() ? "pdu" : "sub"); Tcl_DStringAppendElement (desc, (char*) typenames[gettype()]); return TCL_OK; } int AsnTypeDesc::TclGetDesc2 (Tcl_DString *desc) const { return TCL_OK; } int AsnNamesTypeDesc::TclGetDesc (Tcl_DString *desc) const { AsnTypeDesc::TclGetDesc (desc); return TclGetDesc2 (desc); } // for BIT STRING and INTEGER: int AsnNamesTypeDesc::TclGetDesc2 (Tcl_DString *desc) const { Tcl_DStringStartSublist (desc); const AsnNameDesc *n; if (n = names) for (; n->name; n++) { Tcl_DStringStartSublist (desc); Tcl_DStringAppendElement (desc, (char*) n->name); char buf[32]; sprintf (buf, "%d", n->value); Tcl_DStringAppendElement (desc, buf); Tcl_DStringEndSublist (desc); } Tcl_DStringEndSublist (desc); return TCL_OK; } int AsnEnumTypeDesc::TclGetDesc2 (Tcl_DString *desc) const { Tcl_DStringStartSublist (desc); const AsnNameDesc *n; if (n = names) for (; n->name; n++) Tcl_DStringAppendElement (desc, (char*) n->name); Tcl_DStringEndSublist (desc); return TCL_OK; } int AsnMembersTypeDesc::TclGetDesc (Tcl_DString *desc) const { AsnTypeDesc::TclGetDesc (desc); return TclGetDesc2 (desc); } int AsnChoiceTypeDesc::TclGetDesc2 (Tcl_DString *desc) const { Tcl_DStringStartSublist (desc); const AsnChoiceMemberDesc *m; if (m = members) for (; m->TclGetDesc (desc) == TCL_OK; m++) ; Tcl_DStringEndSublist (desc); return TCL_OK; } int AsnSe_TypeDesc::mandatmemberr (Tcl_Interp *interp, const char *membername) const { sprintf (interp->result, "(in type %s.%s:) member %s is mandatory and can't be deleted", getmodule()->name, getname(), membername); Tcl_SetErrorCode (interp, "SNACC", "MANDMEMB", NULL); return TCL_ERROR; } int AsnSe_TypeDesc::TclGetDesc2 (Tcl_DString *desc) const { Tcl_DStringStartSublist (desc); const AsnSe_MemberDesc *m; if (m = members) for (; m->TclGetDesc (desc) == TCL_OK; m++) ; Tcl_DStringEndSublist (desc); return TCL_OK; } int AsnListTypeDesc::TclGetDesc (Tcl_DString *desc) const { AsnTypeDesc::TclGetDesc (desc); return base->AsnTypeDesc::TclGetDesc (desc); } int AsnAliasTypeDesc::TclGetDesc (Tcl_DString *desc) const { AsnTypeDesc::TclGetDesc (desc); return alias->TclGetDesc2 (desc); } //\[sep]---------------------------------------------------------------------------------------------------------------------------- // designed to be used with Tcl_SplitList(): argument list that automagically frees itself when it goes out of scope: Args::Args() { v = NULL; } Args::~Args() { if (v) free (v); } //\[sep]---------------------------------------------------------------------------------------------------------------------------- // since Tcl cannot handle binary strings, the following hack is needed: int debinify (Tcl_Interp *interp, const char *bin, size_t len) { char* str; int i, o; str = (char *) mem_mgr_ptr->Get (2*len+2); for (o=i=0; i 0) os << '\t'; } std::ostream& operator<<(std::ostream& os, const SNACC::AsnType& v) { v.Print(os); return os; } esnacc-ng-1.8.1/cxx-lib/src/snaccdll.cpp000066400000000000000000000016241302010526100177740ustar00rootroot00000000000000#ifdef WIN32 // snaccDLL.cpp : Defines the entry point for the DLL application. // #include #if defined(_MSC_VER) #include "stdafx.h" #endif #include "snaccdll.h" extern "C" SNACCDLL_API BOOL WINAPI DllMain( HANDLE , DWORD ul_reason_for_call, LPVOID ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } // This is an example of an exported variable SNACCDLL_API int nSnaccDLL=0; // This is an example of an exported function. SNACCDLL_API int fnSnaccDLL(void) { return 42; } // This is the constructor of a class that has been exported. // see snaccDLL.h for the class definition CSnaccDLL::CSnaccDLL() { return; } #endif esnacc-ng-1.8.1/cxx-lib/src/snaccexcept.cpp000066400000000000000000000137121302010526100205120ustar00rootroot00000000000000// FILE: snaccexcept.cpp // // #include "snaccexcept.h" #include #include namespace SNACC { const char * ConstraintErrorStringList[ SEQ_OF_SIZE_VALUE_RANGE + 1 ] = { "INTEGER VALUE CONSTRAINT ERROR :: Integer value is not within Upper and Lower constrained Bounds!!\n", "INTEGER VALUE CONSTRAINT ERROR :: Integer value is not equal to single value constraint!!\n", "STRING SIZE CONSTRAINT ERROR :: String size is not equal to single value size constraint!!\n", "STRING SIZE CONSTRAINT ERROR :: String size is not within Upper and Lower constrained Bounds!!\n", "STRING ALPHA CONSTRAINT ERROR :: String contents not within designated permitted alphabet!!\n", "STRING ALPHA CONSTRAINT ERROR :: String contents not within designated types normal alphabet!!\n", "WIDE STRING SIZE CONSTRAINT ERROR :: String size is not equal to single value size constraint!!\n", "WIDE STRING SIZE CONSTRAINT ERROR :: String size is not within Upper and Lower constrained Bounds!!\n", "WIDE STRING ALPHA CONSTRAINT ERROR :: String contents not within designated permitted alphabet!!\n", "WIDE STRING ALPHA CONSTRAINT ERROR :: String contents not within designated types normal alphabet!!\n", "OCTET STRING CONSTRAINT ERROR :: Octet String size is not equal to single value size constraint!!\n", "OCTET STRING CONSTRAINT ERROR :: Octet String size is not within Upper and Lower constrained Bounds!!\n", "BIT STRING CONSTRAINT ERROR :: Bit String size is not equal to single value size constraint!!\n", "BIT STRING CONSTRAINT ERROR :: Bit String size is not within Upper and Lower constrained Bounds!!\n", "SET OF CONSTRAINT ERROR :: Set Of element count is not equal to single value size constraint!!\n", "SET OF CONSTRAINT ERROR :: Set Of element count is not within Upper and Lower constrained Bounds!!\n", "SEQ OF CONSTRAINT ERROR :: Seq Of element count is not equal to single value size constraint!!\n", "SEQ OF CONSTRAINT ERROR :: Seq Of element count is not within Upper and Lower constrained Bounds!!\n" }; } using namespace SNACC; SnaccException::SnaccException(long errorCode) throw() { m_errorCode = errorCode; stackPos = -1; memset(&stack[0], 0, sizeof(CallStack)*STACK_DEPTH); } SnaccException::SnaccException(const char *file, long line_number, const char *function, const char *whatStrIn, long errorCode) throw() { memset(&stack[0], 0, sizeof(CallStack)*STACK_DEPTH); try { if (whatStrIn != NULL) this->m_whatStr = whatStrIn; } catch (...) { // do nothing } m_errorCode = errorCode; stackPos = 0; stack[0].file = file; stack[0].line_number = line_number; stack[0].function = function; } SnaccException::~SnaccException() throw() { m_errorCode = DEFAULT_ERROR_CODE; stackPos = -1; } SnaccException & SnaccException::operator=(const SnaccException &o) { try { stackPos = o.stackPos; memcpy(stack, o.stack, sizeof(stack)); m_errorCode = o.m_errorCode; m_whatStr = o.m_whatStr; } catch (...) { // do nothing } return *this; } void SnaccException::push(const char *file, long line_number, const char *function) throw() { if (stackPos < STACK_DEPTH - 1) { stackPos++; stack[stackPos].file = file; stack[stackPos].line_number = line_number; stack[stackPos].function = function; } } const char * SnaccException::what() const throw() { return m_whatStr.c_str(); } void SnaccException::getCallStack(std::ostream &os) const { int i = 0; char *ptr=NULL; for(; i <= stackPos; i++) { #ifdef WIN32 if ((ptr=strrchr(stack[i].file, '\\')) == NULL) #else if ((ptr=(char *)strrchr(stack[i].file, '/')) == NULL) #endif ptr = (char *)stack[i].file; else ptr++; os << ptr; os << "\t" << stack[i].line_number; if (stack[i].function) os << "\t" << stack[i].function << "\n"; else os << "\t" << "\n"; } } FileException::FileException(const char *filename, enum FileErrType errType, const char *file, long line_number, const char *function) throw() : SnaccException(file, line_number, function, NULL, FILE_IO_ERROR) { switch (errType) { case OPEN: strcpy(whatStr,"Error opening file: "); break; case CREATE: strcpy(whatStr,"Error creating file: "); break; case READ: strcpy(whatStr,"Error reading file: "); break; case WRITE: strcpy(whatStr,"Error writing file: "); break; } strcat(whatStr, filename); } const char * FileException::what() const throw() { return &whatStr[0]; } MemoryException::MemoryException(long memorySize, const char *variable, const char *file, long line_number, const char *function) throw() : SnaccException(file, line_number, function, "MemoryException", MEMORY_ERROR) { sprintf(memoryInfo, "Error allocating %ld bytes for ", memorySize); int memUsed = strlen(memoryInfo); int len2copy = strlen(variable); if (len2copy > (128 - memUsed - 1)) len2copy = 128 - memUsed - 1; memcpy(&memoryInfo[memUsed], variable, len2copy); memoryInfo[memUsed + len2copy] = '\0'; } const char * MemoryException::what() const throw() { return &memoryInfo[0]; } InvalidTagException::InvalidTagException(const char *type, long tagId, const char *file, long line_number, const char *function) throw() : SnaccException(file, line_number, function, "InvalidTagException", INVALID_TAG) { sprintf(wrongTagInfo,"Tag [%ld] is invalid for type ", tagId); int memUsed = strlen(wrongTagInfo); int len2copy = strlen(type); if (len2copy > (128 - memUsed - 1)) len2copy = 128 - memUsed - 1; memcpy(&wrongTagInfo[memUsed], type, len2copy); wrongTagInfo[memUsed + len2copy] = '\0'; } const char * InvalidTagException::what() const throw() { return &wrongTagInfo[0]; } esnacc-ng-1.8.1/cxx-lib/src/tcl-if.cpp000066400000000000000000000652541302010526100174000ustar00rootroot00000000000000// file: .../c++-lib/src/tcl-if.C // // $Header: /baseline/SNACC/c++-lib/src/tcl-if.cpp,v 1.2 2001/06/19 15:19:46 grafb Exp $ // $Log: tcl-if.cpp,v $ // Revision 1.2 2001/06/19 15:19:46 grafb // Re-ordered includes and removed redundant includes for g++ 3.0 compile // Also ifdef-ed out two macro definitions in asn-real.cpp due to conflict // with this compiler version. // // Revision 1.1.1.1 2000/08/21 20:36:09 leonberp // First CVS Version of SNACC. // // Revision 1.6 1997/02/28 13:39:47 wan // Modifications collected for new version 1.3: Bug fixes, tk4.2. // // Revision 1.5 1997/01/01 23:24:35 rj // `typename' appears to be a reserved word in gcc 2.7, so prefix it with `_' // // Revision 1.4 1995/09/07 18:57:13 rj // duplicate code merged into a new function SnaccTcl::gettypedesc(). // // Revision 1.3 1995/08/17 15:09:09 rj // snacced.[hC] renamed to tcl-if.[hC]. // class SnaccEd renamed to SnaccTcl. // set Tcl's errorCode variable. // // Revision 1.2 1995/07/27 09:53:38 rj // comment leader fixed // // Revision 1.1 1995/07/27 09:52:22 rj // new file: tcl interface used by snacced. #include "asn-incl.h" #if TCL #ifdef _AIX32 extern "C" int strncasecmp (const char* s1, const char* s2, size_t number); extern "C" int strcasecmp (const char* s1, const char* s2); #endif #include "tcl-if.h" #include "init.h" //\[banner "utility functions"]----------------------------------------------------------------------------------------------------- static bool strniabbr (const char *pattern, const char *test, size_t min) { register len; if (strlen (pattern)create(); fn = NULL; fd = -1; filesize = 0; } ASN1File::ASN1File (const AsnTypeDesc *typedesc, const char *_fn, int _fd) { type = typedesc; pdu = type->create(); int fnlen = strlen (_fn) + 1; fn = new char [fnlen]; memcpy (fn, _fn, fnlen); fd = _fd; } ASN1File::~ASN1File() { delete pdu; delete fn; if (fd >= 0) close (fd); } bool ASN1File::bad() { return fd < 0; } int ASN1File::finfo (Tcl_Interp *interp) { Tcl_AppendElement (interp, fn ? fn : ""); char *acc = "bad"; if (!bad()) { int flags; if ((flags = fcntl (fd, F_GETFL)) != -1) switch (flags & O_ACCMODE) { case O_RDONLY: acc = "ro"; break; case O_WRONLY: acc = "wo"; break; case O_RDWR: acc = "rw"; break; } } Tcl_AppendElement (interp, acc); return TCL_OK; } int ASN1File::read (Tcl_Interp *interp, const char *rfn) { int rfd; TmpFD tmpfd; delete pdu; pdu = type->create(); if (rfn) { if ((rfd = open (rfn, O_RDONLY)) < 0) { Tcl_AppendResult (interp, "can't open \"", rfn, "\": ", Tcl_PosixError (interp), NULL); return TCL_ERROR; } tmpfd = rfd; } else if (fd < 0) { Tcl_AppendResult (interp, "can't read, file is not open", NULL); Tcl_SetErrorCode (interp, "SNACC", "MUSTOPEN", NULL); return TCL_ERROR; } else { rfn = fn; lseek (rfd = fd, 0l, SEEK_SET); } struct stat statbuf; if (fstat (rfd, &statbuf)) { Tcl_AppendResult (interp, "can't fstat \"", rfn, "\": ", Tcl_PosixError (interp), NULL); return TCL_ERROR; } filesize = statbuf.st_size; char* buf = new char[filesize]; if (::read (rfd, buf, filesize) != filesize) { Tcl_AppendResult (interp, "can't read \"", rfn, "\": ", Tcl_PosixError (interp), NULL); delete buf; return TCL_ERROR; } AsnBuf inputBuf; inputBuf.InstallData (buf, filesize); size_t decodedLen = 0; jmp_buf env; int eval; if (eval = setjmp (env)) { char eno[80]; sprintf (eno, "%d", eval); Tcl_AppendResult (interp, "can't decode (error ", eno, ")", NULL); Tcl_SetErrorCode (interp, "SNACC", "DECODE", eno, NULL); delete buf; return TCL_ERROR; } pdu->BDec (inputBuf, decodedLen, env); if (inputBuf.ReadError()) { Tcl_AppendResult (interp, "can't decode, out of data", NULL); Tcl_SetErrorCode (interp, "SNACC", "DECODE", "EOBUF", NULL); delete buf; return TCL_ERROR; } #if DEBUG cout << "DECODED:" << endl << *pdu << endl; #endif if (decodedLen != filesize) sprintf (interp->result, "decoded %d of %d bytes", decodedLen, filesize); delete buf; return TCL_OK; } int ASN1File::write (Tcl_Interp *interp, const char *wfn) { int wfd; TmpFD tmpfd; if (wfn) { if ((wfd = open (wfn, O_CREAT|O_TRUNC|O_WRONLY, 0666)) < 0) { Tcl_AppendResult (interp, "can't open \"", wfn, "\": ", Tcl_PosixError (interp), NULL); return TCL_ERROR; } tmpfd = wfd; } else if (fd < 0) { Tcl_AppendResult (interp, "can't write, file is not open", NULL); Tcl_SetErrorCode (interp, "SNACC", "MUSTOPEN", NULL); return TCL_ERROR; } else { wfn = fn; int flags; if ((flags = fcntl (fd, F_GETFL)) == -1) { Tcl_AppendResult (interp, "can't fcntl \"", wfn, "\": ", Tcl_PosixError (interp), NULL); return TCL_ERROR; } else { if ((flags & O_ACCMODE) == O_RDONLY) { Tcl_AppendResult (interp, "can't write, file is read only", NULL); Tcl_SetErrorCode (interp, "SNACC", "WRITE", "RDONLY", NULL); return TCL_ERROR; } } lseek (wfd = fd, 0l, SEEK_SET); } size_t size = filesize ? filesize : 10240; char *buf; AsnBuf outputBuf; size_t encodedLen; for (;;) { size <<= 1; buf = new char[size]; outputBuf.Init (buf, size); outputBuf.ResetInWriteRvsMode(); encodedLen = pdu->BEnc (outputBuf); if (!outputBuf.WriteError()) break; delete buf; } outputBuf.ResetInReadMode(); size_t hunklen = 8192; char* hunk = new char[hunklen]; for (size_t written=0; writtenresult, "wrong # args: should be \"snacc import filename\""); return TCL_ERROR; } const char *fn = argv[1]; int fd; if ((fd = open (fn, O_RDONLY)) < 0) { Tcl_AppendResult (interp, "can't open \"", fn, "\": ", Tcl_PosixError (interp), NULL); return TCL_ERROR; } TmpFD tmpfd (fd); struct stat statbuf; if (fstat (fd, &statbuf)) { Tcl_AppendResult (interp, "can't fstat \"", fn, "\"'s fd: ", Tcl_PosixError (interp), NULL); return TCL_ERROR; } off_t filesize = statbuf.st_size; char* ibuf = new char[filesize]; if (::read (fd, ibuf, filesize) != filesize) { Tcl_AppendResult (interp, "read error on \"", fn, "\": ", Tcl_PosixError (interp), NULL); delete ibuf; return TCL_ERROR; } int result = debinify (interp, ibuf, filesize); delete ibuf; return result; } int export (Tcl_Interp *interp, int argc, char **argv) { if (argc != 3) { strcpy (interp->result, "wrong # args: should be \"snacc export str filename\""); return TCL_ERROR; } const char *str = argv[1], *fn = argv[2]; char* obuf = new char[strlen (str)]; // the binary buffer is as most as long as the escaped Tcl string. size_t olen; if (binify (interp, str, obuf, &olen) != TCL_OK) { delete obuf; return TCL_ERROR; } int fd; if ((fd = open (fn, O_CREAT|O_TRUNC|O_WRONLY, 0666)) < 0) { Tcl_AppendResult (interp, "can't open \"", fn, "\": ", Tcl_PosixError (interp), NULL); delete obuf; return TCL_ERROR; } TmpFD tmpfd (fd); if (::write (fd, obuf, olen) != olen) { Tcl_AppendResult (interp, "write error on \"", fn, "\": ", Tcl_PosixError (interp), NULL); delete obuf; return TCL_ERROR; } delete obuf; return TCL_OK; } //\[banner "ctor & dtor"]----------------------------------------------------------------------------------------------------------- SnaccTcl::SnaccTcl (Tcl_Interp *i) { interp = i; Tcl_InitHashTable (&modules, TCL_STRING_KEYS); Tcl_InitHashTable (&types, TCL_STRING_KEYS); const AsnModuleDesc **moddesc; for (moddesc=asnModuleDescs; *moddesc; moddesc++) { int created; Tcl_HashEntry *entry = Tcl_CreateHashEntry (&modules, (char*)(*moddesc)->name, &created); assert (created); Tcl_SetHashValue (entry, *moddesc); const AsnTypeDesc **typedesc; for (typedesc=(*moddesc)->types; *typedesc; typedesc++) { char buf[1024]; sprintf (buf, "%s %s", (*moddesc)->name, (*typedesc)->name); char *_typename = strdup (buf); int created; Tcl_HashEntry *entry = Tcl_CreateHashEntry (&types, _typename, &created); if (!created) { cerr << "fatal error: duplicate type " << _typename << endl; exit (1); } Tcl_SetHashValue (entry, *typedesc); } } Tcl_InitHashTable (&files, TCL_STRING_KEYS); } SnaccTcl::~SnaccTcl() { Tcl_DeleteHashTable (&files); } //\[banner "utility functions"]----------------------------------------------------------------------------------------------------- const AsnTypeDesc *SnaccTcl::gettypedesc (const char *cmdname, const char *_typename) { Tcl_HashEntry *typedescentry; if (typedescentry = Tcl_FindHashEntry (&types, (char*)_typename)) return (const AsnTypeDesc *)Tcl_GetHashValue (typedescentry); else { Tcl_SetErrorCode (interp, "SNACC", "ILLTYPE", NULL); Tcl_AppendResult (interp, "snacc ", cmdname, ": no type \"", _typename, "\"", NULL); return NULL; } } //\[banner "data manipulation functions"]------------------------------------------------------------------------------------------- Tcl_HashEntry *SnaccTcl::create() { static unsigned int id; int created; Tcl_HashEntry *entry; do { sprintf (interp->result, "file%u", id++); entry = Tcl_CreateHashEntry (&files, interp->result, &created); } while (!created); return entry; } int SnaccTcl::create (int argc, char **argv) { if (argc != 2) { strcpy (interp->result, "wrong # args: should be \"snacc create {module type}\""); return TCL_ERROR; } const char *_typename = argv[1]; const AsnTypeDesc *typedesc; if (!(typedesc = gettypedesc ("type", _typename))) return TCL_ERROR; Tcl_HashEntry *entry = create(); ASN1File *file = new ASN1File (typedesc); Tcl_SetHashValue (entry, file); return TCL_OK; } //\[sep]---------------------------------------------------------------------------------------------------------------------------- // snacc open {module type} filename ?flags? ?permissions? int SnaccTcl::openfile (int argc, char **argv) { if (argc < 3 || argc > 5) { strcpy (interp->result, "wrong # args: should be \"snacc open {module type} filename ?flags? ?permissions?\""); return TCL_ERROR; } const char *_typename = argv[1]; const char *filename = argv[2]; bool rw_spec = false; int oflags = 0, omode = 0666, fd = -1; switch (argc) { case 5: if (Tcl_GetInt (interp, argv[4], &omode)) return TCL_ERROR; // \(da fall thru case 4: { Args flags; if (Tcl_SplitList (interp, argv[3], &flags.c, &flags.v) != TCL_OK) return TCL_ERROR; for (int i=0; ibad()) { delete file; Tcl_AppendResult (interp, "internal error on \"", filename, "\": bad status", NULL); Tcl_SetErrorCode (interp, "SNACC", "OPEN", "BAD", NULL); return TCL_ERROR; } Tcl_HashEntry *entry = create(); Tcl_SetHashValue (entry, file); return file->read (interp); } //\[sep]---------------------------------------------------------------------------------------------------------------------------- int SnaccTcl::finfo (int argc, char **argv) { if (argc != 2) { strcpy (interp->result, "wrong # args: should be \"snacc finfo file\""); return TCL_ERROR; } Tcl_HashEntry *entry = Tcl_FindHashEntry (&files, argv[1]); if (!entry) { Tcl_AppendResult (interp, "no file named \"", argv[1], "\"", NULL); return TCL_ERROR; } ASN1File *file = (ASN1File *)Tcl_GetHashValue (entry); return file->finfo (interp); } //\[sep]---------------------------------------------------------------------------------------------------------------------------- // snacc read file ?{module type} filename? int SnaccTcl::read (int argc, char **argv) { const char *_typename, *filename; switch (argc) { case 2: // reread from old fd _typename = filename = NULL; break; case 4: _typename = argv[2]; filename = argv[3]; break; default: strcpy (interp->result, "wrong # args: should be \"snacc read file ?{module type} filename?\""); return TCL_ERROR; } Tcl_HashEntry *entry = Tcl_FindHashEntry (&files, argv[1]); if (!entry) { Tcl_AppendResult (interp, "no file named \"", argv[1], "\"", NULL); return TCL_ERROR; } ASN1File *file = (ASN1File *)Tcl_GetHashValue (entry); if (_typename) { const AsnTypeDesc *typedesc; if (!(typedesc = gettypedesc ("read", _typename))) return TCL_ERROR; delete file; file = new ASN1File (typedesc); Tcl_SetHashValue (entry, file); } return file->read (interp, filename); } //\[sep]---------------------------------------------------------------------------------------------------------------------------- int SnaccTcl::write (int argc, char **argv) { if (argc < 2 || argc > 3) { strcpy (interp->result, "wrong # args: should be \"snacc write file ?filename?\""); return TCL_ERROR; } Tcl_HashEntry *entry = Tcl_FindHashEntry (&files, argv[1]); if (!entry) { Tcl_AppendResult (interp, "no file named \"", argv[1], "\"", NULL); return TCL_ERROR; } ASN1File *file = (ASN1File *)Tcl_GetHashValue (entry); return file->write (interp, argv[2]); } //\[sep]---------------------------------------------------------------------------------------------------------------------------- int SnaccTcl::closefile (int argc, char **argv) { if (argc != 2) { strcpy (interp->result, "wrong # args: should be \"snacc close file\""); return TCL_ERROR; } Tcl_HashEntry *entry = Tcl_FindHashEntry (&files, argv[1]); if (!entry) { Tcl_AppendResult (interp, "no file named \"", argv[1], "\"", NULL); return TCL_ERROR; } ASN1File *file = (ASN1File *)Tcl_GetHashValue (entry); delete file; Tcl_DeleteHashEntry (entry); return TCL_OK; } //\[sep]---------------------------------------------------------------------------------------------------------------------------- int SnaccTcl::modulesinfo (int argc, char **argv) { if (argc != 1) { strcpy (interp->result, "wrong # args: should be \"snacc modules\""); return TCL_ERROR; } Tcl_HashEntry *moduleentry; Tcl_HashSearch hi; for (moduleentry=Tcl_FirstHashEntry (&modules, &hi); moduleentry; moduleentry=Tcl_NextHashEntry (&hi)) Tcl_AppendElement (interp, Tcl_GetHashKey (&modules, moduleentry)); return TCL_OK; } //\[sep]---------------------------------------------------------------------------------------------------------------------------- int SnaccTcl::typesinfo (int argc, char **argv) { switch (argc) { case 1: Tcl_HashEntry *typeentry; Tcl_HashSearch hi; for (typeentry=Tcl_FirstHashEntry (&types, &hi); typeentry; typeentry=Tcl_NextHashEntry (&hi)) Tcl_AppendElement (interp, Tcl_GetHashKey (&types, typeentry)); return TCL_OK; case 2: Tcl_HashEntry *moduleentry; if (moduleentry = Tcl_FindHashEntry (&modules, argv[1])) { const AsnModuleDesc *moddesc = (const AsnModuleDesc *)Tcl_GetHashValue (moduleentry); const AsnTypeDesc **typedesc; for (typedesc=moddesc->types; *typedesc; typedesc++) Tcl_AppendElement (interp, (char*)(*typedesc)->name); return TCL_OK; } else { Tcl_AppendResult (interp, "snacc types: no module \"", argv[1], "\"", NULL); return TCL_ERROR; } default: strcpy (interp->result, "wrong # args: should be \"snacc types ?module?\""); return TCL_ERROR; } } //\[sep]---------------------------------------------------------------------------------------------------------------------------- int SnaccTcl::typeinfo (int argc, char **argv) { if (argc != 2) { strcpy (interp->result, "wrong # args: should be \"snacc type {module type}\""); return TCL_ERROR; } const char *_typename = argv[1]; const AsnTypeDesc *typedesc; if (!(typedesc = gettypedesc ("type", _typename))) return TCL_ERROR; Tcl_DString desc; Tcl_DStringInit (&desc); int rc = typedesc->TclGetDesc (&desc); Tcl_DStringResult (interp, &desc); return rc; } //\[sep]---------------------------------------------------------------------------------------------------------------------------- int SnaccTcl::info (int argc, char **argv) { if (argc != 2) { strcpy (interp->result, "wrong # args: should be \"snacc info path\""); return TCL_ERROR; } Args path; if (Tcl_SplitList (interp, argv[1], &path.c, &path.v) != TCL_OK) return TCL_ERROR; if (path.c < 1) { strcpy (interp->result, "snacc info: wrong # args in path"); return TCL_ERROR; } Tcl_HashEntry *entry = Tcl_FindHashEntry (&files, path.v[0]); if (!entry) { Tcl_AppendResult (interp, "snacc info: no file named \"", path.v[0], "\"", NULL); return TCL_ERROR; } ASN1File *file = (ASN1File *)Tcl_GetHashValue (entry); AsnType *var = (AsnType *)*file; for (int i=1; i_getref (path.v[i]))) { Tcl_AppendResult (interp, "snacc info: illegal component \"", path.v[i], "\" in path", NULL); return TCL_ERROR; } Tcl_DString desc; Tcl_DStringInit (&desc); int rc; if ((rc = var->_getdesc()->AsnTypeDesc::TclGetDesc (&desc)) == TCL_OK) rc = var->TclGetDesc (&desc); Tcl_DStringResult (interp, &desc); return rc; } //\[sep]---------------------------------------------------------------------------------------------------------------------------- int SnaccTcl::getval (int argc, char **argv) { if (argc != 2) { strcpy (interp->result, "wrong # args: should be \"snacc get path\""); return TCL_ERROR; } Args path; if (Tcl_SplitList (interp, argv[1], &path.c, &path.v) != TCL_OK) return TCL_ERROR; if (path.c < 1) { strcpy (interp->result, "snacc get: wrong # args in path"); return TCL_ERROR; } Tcl_HashEntry *entry = Tcl_FindHashEntry (&files, path.v[0]); if (!entry) { Tcl_AppendResult (interp, "snacc get: no file named \"", path.v[0], "\"", NULL); return TCL_ERROR; } ASN1File *file = (ASN1File *)Tcl_GetHashValue (entry); AsnType *var = (AsnType *)*file; for (int i=1; i_getref (path.v[i]))) { Tcl_AppendResult (interp, "snacc get: illegal component \"", path.v[i], "\" in path", NULL); return TCL_ERROR; } return var->TclGetVal (interp); } //\[sep]---------------------------------------------------------------------------------------------------------------------------- int SnaccTcl::test (int argc, char **argv) { if (argc != 2) { strcpy (interp->result, "wrong # args: should be \"snacc get path\""); return TCL_ERROR; } Args path; if (Tcl_SplitList (interp, argv[1], &path.c, &path.v) != TCL_OK) return TCL_ERROR; if (path.c < 1) { strcpy (interp->result, "snacc get: wrong # args in path"); return TCL_ERROR; } Tcl_HashEntry *entry = Tcl_FindHashEntry (&files, path.v[0]); if (!entry) { Tcl_AppendResult (interp, "snacc get: no file named \"", path.v[0], "\"", NULL); return TCL_ERROR; } ASN1File *file = (ASN1File *)Tcl_GetHashValue (entry); AsnType *var = (AsnType *)*file; for (int i=1; i_getref (path.v[i]))) { Tcl_AppendResult (interp, "snacc test: illegal component \"", path.v[i], "\" in path", NULL); return TCL_ERROR; } cout << *var; strstream s; s << *var; s.put ('\0'); cout << strlen(s.str()) << endl; cout << s.str() << endl; return TCL_OK; } //\[sep]---------------------------------------------------------------------------------------------------------------------------- int SnaccTcl::setval (int argc, char **argv) { if (argc != 3) { strcpy (interp->result, "wrong # args: should be \"snacc set path value\""); return TCL_ERROR; } Args path; if (Tcl_SplitList (interp, argv[1], &path.c, &path.v) != TCL_OK) return TCL_ERROR; if (path.c < 1) { strcpy (interp->result, "snacc set: wrong # args in path"); return TCL_ERROR; } Tcl_HashEntry *entry = Tcl_FindHashEntry (&files, path.v[0]); if (!entry) { Tcl_AppendResult (interp, "snacc set: no file named \"", path.v[0], "\"", NULL); return TCL_ERROR; } ASN1File *file = (ASN1File *)Tcl_GetHashValue (entry); AsnType *var = (AsnType *)*file; for (int i=1; i_getref (path.v[i], true))) { Tcl_AppendResult (interp, "snacc set: illegal component \"", path.v[i], "\" in path", NULL); return TCL_ERROR; } return var->TclSetVal (interp, argv[2]); } //\[sep]---------------------------------------------------------------------------------------------------------------------------- int SnaccTcl::unsetval (int argc, char **argv) { if (argc != 2) { strcpy (interp->result, "wrong # args: should be \"snacc unset path\""); return TCL_ERROR; } Args path; if (Tcl_SplitList (interp, argv[1], &path.c, &path.v) != TCL_OK) return TCL_ERROR; if (path.c == 1) { strcpy (interp->result, "snacc unset: sorry, but you are not allowed to unset the file itself"); return TCL_ERROR; } else if (path.c < 1) { strcpy (interp->result, "snacc unset: wrong # args in path"); return TCL_ERROR; } Tcl_HashEntry *entry = Tcl_FindHashEntry (&files, path.v[0]); if (!entry) { Tcl_AppendResult (interp, "snacc unset: no file named \"", path.v[0], "\"", NULL); return TCL_ERROR; } ASN1File *file = (ASN1File *)Tcl_GetHashValue (entry); AsnType *var = (AsnType *)*file; for (int i=1; i_getref (path.v[i]))) { Tcl_AppendResult (interp, "snacc unset: illegal component \"", path.v[i], "\" in path", NULL); return TCL_ERROR; } } return var->TclUnsetVal (interp, path.v[path.c-1]); } //\[sep]---------------------------------------------------------------------------------------------------------------------------- int Snacc_Cmd (ClientData cd, Tcl_Interp *interp, int argc, char **argv) { SnaccTcl *ed = (SnaccTcl *)cd; #ifdef DEBUG ed->ckip (interp); #endif if (argc < 2) { strcpy (interp->result, "wrong # args: should be \"snacc option arg ?arg ...?\""); return TCL_ERROR; } --argc; argv++; switch (**argv) { case 'c': if (!strcmp (*argv, "close")) return ed->closefile (argc, argv); else if (!strcmp (*argv, "create")) return ed->create (argc, argv); break; case 'e': if (!strcmp (*argv, "export")) return export (interp, argc, argv); break; case 'f': if (!strcmp (*argv, "finfo")) return ed->finfo (argc, argv); break; case 'g': if (!strcmp (*argv, "get")) return ed->getval (argc, argv); break; case 'i': if (!strcmp (*argv, "import")) return import (interp, argc, argv); else if (!strcmp (*argv, "info")) return ed->info (argc, argv); break; case 'm': if (!strcmp (*argv, "modules")) return ed->modulesinfo (argc, argv); break; case 'o': if (!strcmp (*argv, "open")) return ed->openfile (argc, argv); break; case 'r': if (!strcmp (*argv, "read")) return ed->read (argc, argv); break; case 's': if (!strcmp (*argv, "set")) return ed->setval (argc, argv); break; case 't': if (!strcmp (*argv, "test")) return ed->test (argc, argv); else if (!strcmp (*argv, "type")) return ed->typeinfo (argc, argv); else if (!strcmp (*argv, "types")) return ed->typesinfo (argc, argv); break; case 'u': if (!strcmp (*argv, "unset")) return ed->unsetval (argc, argv); break; case 'w': if (!strcmp (*argv, "write")) return ed->write (argc, argv); break; } sprintf (interp->result, "bad command option %s: should be close, create, export, finfo, get, import, info, modules, open, read, set, type, types, unset or write", *argv); return TCL_ERROR; } //\[banner "check for proper initialization & finalization"]------------------------------------------------------------------------ struct check { int i, j; check (int); bool bad(); }; static int cki; check::check (int v) { i = v; j = ~i; } #define CK 42 bool check::bad() { return i != CK || j != ~CK; } check check (CK); //\[banner "initialization & finalization"]----------------------------------------------------------------------------------------- void Snacc_Exit (ClientData data) { delete (SnaccTcl *)data; } // prohibit function name mangling to enable tkAppInit.c:Tcl_AppInit() to call this function: extern "C" int Snacc_Init (Tcl_Interp *interp) { if (check.bad()) { static const char emsg[] = "linkage error, constructors of static variables didn't get called!\n"; write (2, emsg, sizeof emsg); exit (1); } SnaccTcl *data = new SnaccTcl (interp); Tcl_CreateCommand (interp, "snacc", Snacc_Cmd, (ClientData)data, Snacc_Exit); return TCL_OK; } #endif // TCL esnacc-ng-1.8.1/cxx-lib/src/tkAppInit.c000066400000000000000000000067761302010526100175710ustar00rootroot00000000000000/* * snacced - Snacc_Init added to the default tkXAppInit. * * $Header: /baseline/SNACC/c++-lib/src/tkAppInit.c,v 1.1.1.1 2000/08/21 20:36:09 leonberp Exp $ * $Log: tkAppInit.c,v $ * Revision 1.1.1.1 2000/08/21 20:36:09 leonberp * First CVS Version of SNACC. * * Revision 1.2 1997/02/28 13:39:48 wan * Modifications collected for new version 1.3: Bug fixes, tk4.2. * * Revision 1.1 1997/01/02 09:07:59 rj * first check-in * */ #include "snacc.h" #if TCL /* * tkXAppInit.c -- * * Provides a default version of the TclX_AppInit procedure for use with * applications built with Extended Tcl and Tk. This is based on the * the UCB Tk file tkAppInit.c * *----------------------------------------------------------------------------- * Copyright 1991-1993 Karl Lehenbauer and Mark Diekhans. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appear in all copies. Karl Lehenbauer and * Mark Diekhans make no representations about the suitability of this * software for any purpose. It is provided "as is" without express or * implied warranty. *----------------------------------------------------------------------------- * $Id: tkAppInit.c,v 1.1.1.1 2000/08/21 20:36:09 leonberp Exp $ *----------------------------------------------------------------------------- * Copyright (c) 1993 The Regents of the University of California. * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */ #ifndef lint static char rcsid[] = "$Header: /baseline/SNACC/c++-lib/src/tkAppInit.c,v 1.1.1.1 2000/08/21 20:36:09 leonberp Exp $ SPRITE (Berkeley)"; #endif /* not lint */ #include #include "init.h" int main(argc, argv) int argc; /* Number of command-line arguments. */ char **argv; /* Values of command-line arguments. */ { Tk_Main(argc, argv, Tcl_AppInit); return 0; /* Needed only to prevent compiler warning. */ } int Tcl_AppInit (interp) Tcl_Interp *interp; /* Interpreter for application. */ { if (Tcl_Init(interp) == TCL_ERROR) { return TCL_ERROR; } if (Tk_Init(interp) == TCL_ERROR) { return TCL_ERROR; } Tcl_StaticPackage(interp, "Tk", Tk_Init, (Tcl_PackageInitProc *) NULL); if (Snacc_Init (interp) == TCL_ERROR) return TCL_ERROR; if (Tree_Init (interp) == TCL_ERROR) return TCL_ERROR; Tcl_SetVar (interp, "tcl_rcFileName", "~/.snaccedrc", TCL_GLOBAL_ONLY); return TCL_OK; } #endif esnacc-ng-1.8.1/cxx-lib/src/vda_threads2.cpp000066400000000000000000000027051302010526100205600ustar00rootroot00000000000000 // The following "SM_NO_THREADS" define allows the application/lib code that // uses threads to not require this define (cleaner). In this source module // the thread lock logic is disabled (there is some slight performance loss // in the wasted no-op call to the thread lock/unlock, but the logic is // cleaner). This technique also has the advantage that only this source // file needs the "SM_NO_THREADS" definition to turn thread locking off. #include "asn-incl.h" _BEGIN_SNACC_NAMESPACE #ifdef NO_THREADS void threadDestroy() { } void threadLock() { } void threadUnlock() { } #else #ifdef WIN32 #include HANDLE gMutex; #else #include pthread_mutex_t gMutex; #endif #ifndef WIN32 void initMutex(void) { pthread_mutex_init(&gMutex, NULL); } #endif // // void threadDestroy() { #ifdef WIN32 CloseHandle(gMutex); #else pthread_mutex_destroy(&gMutex); #endif } // // void threadLock() { #ifdef WIN32 gMutex = CreateMutex(NULL, false, "Win32_Mutex"); WaitForSingleObject(gMutex, INFINITE); #else //UNIX #ifdef SUNOS pthread_once_t once_block = {PTHREAD_ONCE_INIT}; #else pthread_once_t once_block = PTHREAD_ONCE_INIT; #endif pthread_once(&once_block, initMutex); pthread_mutex_lock(&gMutex); #endif //WIN32 } void threadUnlock() { #ifdef WIN32 ReleaseMutex(gMutex); #else //UNIX pthread_mutex_unlock(&gMutex); #endif //WIN32 } #endif _END_SNACC_NAMESPACE // EOF vda_threads2.cpp esnacc-ng-1.8.1/doc/000077500000000000000000000000001302010526100141125ustar00rootroot00000000000000esnacc-ng-1.8.1/doc/PERCompilerRequirementsMatrix.doc000066400000000000000000005450001302010526100225170ustar00rootroot00000000000000ÐÏࡱá>þÿ `bþÿÿÿ]^_ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿì¥ÁM ð¿ÇÆbjbjâ=â= "Ö€W€WÉ¿ÿÿÿÿÿÿl¤¤¤¤¤¤¤¸,~,~,~,~T€~̸·½‚X‚X‚X‚X‚X‚3ƒ3ƒ3ƒ½½½½½½½$9¿ YÁŠ,½E¤3ƒ3ƒ3ƒ3ƒ3ƒ,½å”¤¤X‚X‚Ûq½å”å”å”3ƒ¶¤X‚¤X‚½å”3ƒ½å”Xå”=˜¾š¤¤ ›X‚L‚ @;†m#­Ã¸t|,~鈢Öš ›ü!‡½0·½Þš,ãÁ‹ZãÁ ›å”¸¸¤¤¤¤Ù PER Compiler Requirements Matrix (Derived from ASN specification X.691, 2002) Robert W. Colestock DigitalNet (KATSIPP contract) Introduction This document presents a basic requirements matrix for the Packed Encoding Rules (PER) features of the eSNACC freeware compiler. Matrix The matrix is presented as a list of ASN.1 components (e.g. INTEGER) with references to notes that designate the appropriate specification reference. Release legend: 1.0, Future, NI (Not Implemented), Encode (ONLY); notes are referenced by “()”. DescriptionStatus (Version 1.0)AlignedUnalignedGeneral PER Compiler RequirementsIndefinite-length(3.6.13) (DECODE ONLY)FutureXXFixed-length(3.6.14)Fixed-value (3.6.15)Textually dependent (3.6.26)Simple type (3.6.25)?????RWC????Canonical encoding, PER (3.6.4)1.0XXBasic encoding, PER (DECODE ONLY)1.0 Decode ONLYXXExtensible for PER encoding (3.6.11)NININIOutermost type (3.6.21, 10.1.1), always 8 bit alignedRelay-safe encoding (3.6.23) ??RWC??Optional?NININIValue set assignment type (9.6.5), BER encodedPER encoding of a component: preamble/length/content; OR arbitrary number of parts, constructed (9.5.2) (RWC;TBD; ADD TO ALL ASSOCIATED TYPES FOR TESTING)PER encoding included in bitstring, octetstring, Open type, external or embedded pdv type, or carrier protocol (10.1.1) (RWC;TBD; ADD TO ALL ASSOCIATED TYPES FOR TESTING)PER encoding included, UNALIGNED (10.1.3)1.0XPER encoding included, UNALIGNED (10.1.3), empty bit string1.0XPER encoding included, ALIGNED (10.1.4)1.0XPER encoding included, ALIGNED (10.1.4), empty bit string1.0XGeneral Constraint RequirementsHuman readable constraints are not PER-visible (9.3.1)Variable constraints are not PER-visible (9.3.2)All size constraints are PER-visible (9.3.8) SIZE, < 128 SIZE, 128 <= X <= 64k SIZE, 64k <= X <= 4GSerial constraints with extension, not PER-visible (9.3.18)Intersecting constraints of PER-visible parts (9.3.19)Intersecting constraints, UNION (9.3.19)Intersecting constraints, EXCEPT (9.3.19)Type is extensible for PER if derived from ENUMERATED, SEQUENCE, SET, CHOICE (9.3.20)NININIFragmentation Encoding Details (for Integer, Octet String, BitString, All single character strings (e.g. PrintableString, IA5String, NumericString, IGNORE WideCharacterStrings for the time being)Integer, non-Constrained, <=16k bytes longInteger, non-Constrained, >= 64k bytes longOctetString, non-Constrained, <= 16k bytes longOctetString, non-Constrained, > 16k, < 32k bytes longOctetString, non-Constrained, > 32k, <= 64k bytes longOctetString, non-Constrained, > 64k bytes longPrintableString, non-Constrained, < 64k bytes longPrintableString, Constrained, <= 16k bytes longPrintableString, Constrained, > 16k, <= 32k bytes longPrintableString, Constrained, > 32k, <= 64k bytes longPrintableString, Constrained, > 64k bytes longIA5String, non-Constrained, > 64k bytes longNumericString, non-Constrained, > 64k bytes longINTEGERUnconstrained SIZE/length encoding (NOTE:1)1.0XXNormally small non-negative whole number (for SIZE/length) (3.6.18)(10.6)Non-negative-binary-integer encoding (3.6.20)Semi-constrained whole number (3.6.24)Unconstrained whole number (3.6.27)Constrained whole number (3.6.7)(10.5), < 2561.0XConstrained whole number, = 256 (10.5.7)1.0XConstrained whole number, 256 < X < 64k (10.5.7)1.0XConstrained whole number, > 64k (10.5.7)1.0XConstrained whole number (3.6.7)(10.6)(indexed value)1.0XBitstring type (15.)Fixed length, <= 16 bitsFixed length, 16 < X < 64k bits (no length encoding)Fixed length, >= 64k bitsFixed length, >= 64k bits, fragmentedGeneral String RequirementsKnown-multiplier character string type (3.6.16)Effective size constraint (for a constrained string type) (3.6.8)Effective permitted-alphabet constraint (for a constrained restricted character string type)(3.6.9)Effective permitted-alphabet constraint for a constrained type(3.9.11)Single value subtype constraints applied to a character string type are not PER-visible (9.3.15)Constrained String, Bit-length for data (not length), set to next-up power of 2 (to force byte alignment, perhaps multiple data elements in 1 byte, but always byte aligned in next byte, ONLY for Aligned case)X2 Octet Size Limit, bypassing alignment rules (assuming Constrained/Indexed strings can load multiple elements in 2 Octets, ONLY for Aligned case) (27, Note 1)XGeneralized time (9.6.4) BER encoded1.0XXUniversal time (9.6.4) BER encoded1.0XXObject descriptor (9.6.4) BER encoded1.0XXObject Identifier (10.1.1) BER encodedReal type (14.) BER encoded, length/contentConstraints are not PER-visible (9.3.14)Set type (9.6.5) BER encodedOpen type (10.2)NININIEnumerated type (13.), same as constrained integer with no extension marker, indexedEnumerated type, same as constrained integer if extension marker, not indexedNULL type (17.), ignored when encodingSequence type (18.)Sequence type (18.), no OPTIONAL elementsSequence type (18.), with OPTIONAL elementsSequence type (18. , 18.6), with extensionsNININISequence type (18.), DECODE ONLY, with extensionsFutureSequence type (18.3), with OPTIONAL elements, sequence > 64k (ignore “ub”/”lb”)Sequence type (18.5), with DEFAULT fields (must be missing when encoding)Sequence-of type (19.)Sequence-of type, no constraintsSequence-of type, (19.5) constant length constraint < 64kSequence-of type, (19.5) constant length constraint > 64kSequence-of type, (19.6) variable constraint (“ub” is different from “lb”Set type (20.)Set type, tagged Choice typesSet type, untagged Choice types (test ordering logic)Set type, non-Choice elementsSet-of type (21.)Set-of type, (21.1) CANONICAL-PER (test ordering logic)Set-of type, (21.2) BASIC-PER encodingNININIChoice type (22.)Choice type, one alternative (no index encoded)Choice type, multiple alternativesChoice type, extension bit (DECODE ONLY)FutureOCTET STRING (16.)EXTERNAL type , open type (7.9)Octetstring, fixed length < 2 octets, not alignedOctetstring, fixed length < 64k, (no length encoding)Octetstring, fixed length > 64kOctetstring, fixed length < 64k, fragmentedEXTERNAL (always 8 bit aligned)OCTET STRING choice, default (7.9)Open Type encoding, if already in PER (7.9)ExamplesAx ::= IA5String (FROM("AB") | FROM("CD")) Bx ::= IA5String (SIZE(1..4) | FROM("abc")) (3.6.8)Ax ::= IA5String (FROM("AB") | FROM("CD")) Bx ::= IA5String (SIZE(1..4) | FROM("abc")) (3.6.9)MY-CLASS ::= CLASS { &name PrintableString, &age INTEGER } WITH SYNTAX{&name , &age} MyObjectSet MY-CLASS ::= { {"Jack", 7} | {"Jill", 5} } Bar ::= MY-CLASS.&age ({MyObjectSet}) Foo ::= INTEGER (Bar | 1..100) (3.6.26)A ::= IA5String(SIZE(1..4))(FROM("ABCD",...)) (9.3.18)A ::= IA5String (SIZE(1..4) INTERSECTION FROM("ABCD",...)) (9.3.19)A ::= IA5String (SIZE (3..6)) -- Length is encoded in a 2-bit bit-field. B ::= IA5String (SIZE (40000..40254)) -- Length is encoded in an 8-bit bit-field. C ::= IA5String (SIZE (0..32000)) -- Length is encoded in a 2-octet -- bit-field (octet-aligned in the ALIGNED variant). D ::= IA5String (SIZE (64000)) -- Length is not encoded. (10.9.3.3)NOTE – For example, if in the following a value of A is 4 characters long, and that of B is 4 items long: A ::= IA5String B ::= SEQUENCE (SIZE (4..123456)) OF INTEGER both values are encoded with the length octet occupying one octet, and with the most significant set to 0 to indicate that the length is less than or equal to 127: 0 0000100 4 characters/items Length Value (10.9.3.6)Example subtypes, limiting an ASN.1 type: AtomicNumber ::= INTEGER (1..104) TouchToneString ::= IA5String (FROM ("0123456789" | "*" | "#")) (SIZE (1..63)) ParameterList ::= SET SIZE (1..63) OF Parameter SmallPrime ::= INTEGER (2|3|5|7|11|13|17|19|23|29) (E.4)Example ::= SEQUENCE {first INTEGER (0..127), second SEQUENCE {string OCTET STRING (SIZE(2)), name PrintableString (SIZE(1..8)) }, third BIT STRING (SIZE (8)) } (Asn1_Complete, 1.5.)INTEGER (0..7) INTEGER (8..11) (Asn1_Complete, 1.5.) Terms and Definitions Per-Visible: defines if the ASN.1 specified constraints of a type are used in the encoding rules. Subtype: value constrained primitive type. Simple Value: primitive ASN.1 data type. Composite Value: value built of other Composite Value(s) and primitive data types. indefinite length case (when referring to numbers): inferring that an explicit length encoding is necessary semi-constrained (when referring to numbers): lower bound is known, but no upper bound can be determined. unconstrained whole number: Always encoded as “indefinite length” Notes These notes refer to the ASN.1 PER encoding rule specification, X.691. (1) Unconstrained SIZE/length encoding of PER Integers is performed using the same encoding rules as BER. 3.6.14 fixed-length type: 3.6.15 fixed value: 3.6.16 known-multiplier character string type: 3.6.17 length determinant: 3.6.18 normally small non-negative whole number: 3.6.19 normally small length: 3.6.20 non-negative-binary-integer encoding: 3.6.22 PER-visible constraint: 3.6.25 simple type: Aligned encoding requirements Un-aligned encoding requirements NOTES::: 3.6.4 canonical encoding: A complete encoding of an abstract syntax value obtained by the application of encoding rules that have no implementation-dependent options; such rules result in the definition of a 1-1 mapping between unambiguous and unique bitstrings in the transfer syntax and values in the abstract syntax. (RWC; ??? RICH?) 3.6.7 constrained whole number: A whole number which is constrained by PER-visible constraints to lie within a range from "lb" to "ub" with the value "lb" less than or equal to "ub", and the values of "lb" and "ub" as permitted values. NOTE – Constrained whole numbers occur in the encoding which identifies the chosen alternative of a choice type, the length of character, octet and bit string types whose length has been restricted by PER-visible constraints to a maximum length, the count of the number of components in a sequence-of or set-of type that has been restricted by PER-visible constraints to a maximum number of components, the value of an integer type that has been constrained by PER-visible constraints to lie within finite minimum and maximum values, and the value that denotes an enumeration in an enumerated type. 3.6.8 effective size constraint (for a constrained string type): NOTE 1 – For example, in: Ax ::= IA5String (FROM("AB") | FROM("CD")) Bx ::= IA5String (SIZE(1..4) | FROM("abc")) Ax has an effective permitted-alphabet constraint of "ABCD". Bx has an effective permitted-alphabet constraint that consists of the entire IA5String alphabet since there is no smaller permitted-alphabet constraint that applies to all values of Bx. NOTE 2 – The effective permitted-alphabet constraint is used only to determine the encoding of characters. 3.6.9 effective permitted-alphabet constraint (for a constrained restricted character string type): A single permitted-alphabet constraint that could be applied to a built-in known-multiplier character string type and whose effect would be to permit all and only those characters that can be present in at least one character position of any one of the values in the constrained restricted character string type. NOTE 1 – For example, in: Ax ::= IA5String (FROM("AB") | FROM("CD")) Bx ::= IA5String (SIZE(1..4) | FROM("abc")) Ax has an effective permitted-alphabet constraint of "ABCD". Bx has an effective permitted-alphabet constraint that consists of the entire IA5String alphabet since there is no smaller permitted-alphabet constraint that applies to all values of Bx. NOTE 2 – The effective permitted-alphabet constraint is used only to determine the encoding of characters. 3.6.11 extensible for PER encoding: (RWC;NOT SUPPORTED) 3.6.13 indefinite-length: (RWC;ONLY SUPPORTED FOR Decoding) 3.6.16 known-multiplier character string type: A restricted character string type where the number of octets in the encoding is a known fixed multiple of the number of characters in the character string for all permitted character string values. The known-multiplier character string types are IA5String, PrintableString, VisibleString, NumericString, UniversalString and BMPString. 3.6.21 outermost type: An ASN.1 type whose encoding is included in a non-ASN.1 carrier or as the value of other ASN.1 constructs (see 10.1.1). NOTE – PER encodings of an outermost type are always an integral multiple of eight bits. 3.6.23 relay-safe encoding: A complete encoding of an abstract syntax value which can be decoded (including any embedded encodings) without knowledge of the environment in which the encoding was performed. (RWC; NOT SUPPORTED, FUTURE?) 3.6.24 semi-constrained whole number: A whole number which is constrained by PER-visible constraints to exceed or equal some value "lb" with the value "lb" as a permitted value, and which is not a constrained whole number. NOTE – Semi-constrained whole numbers occur in the encoding of the length of unconstrained (and in some cases constrained) character, octet and bit string types, the count of the number of components in unconstrained (and in some cases constrained) sequence-of and set-of types, and the value of an integer type that has been constrained to exceed some minimum value. 3.6.26 textually dependent: A term used to identify the case where if some reference name is used in evaluating an element set, the value of the element set is considered to be dependent on that reference name, regardless of whether the actual set arithmetic being performed is such that the final value of the element set is independent of the actual element set value assigned to the reference name. NOTE – For example, the following definition of Foo is textually dependent on Bar even though Bar has no effect on Foos set of values (thus, according to 9.3.5 the constraint on Foo is not PER-visible since Bar is constrained by a table constraint and Foo is textually dependent on Bar). MY-CLASS ::= CLASS { &name PrintableString, &age INTEGER } WITH SYNTAX{&name , &age} MyObjectSet MY-CLASS ::= { {"Jack", 7} | {"Jill", 5} } Bar ::= MY-CLASS.&age ({MyObjectSet}) Foo ::= INTEGER (Bar | 1..100) 3.6.27 unconstrained whole number: A whole number which is not constrained by PER-visible constraints. NOTE – Unconstrained whole numbers occur only in the encoding of a value of the integer type. 7.2 Without knowledge of the type of the value encoded, it is not possible to determine the structure of the encoding (under any of the PER encoding rule algorithms). In particular, the end of the encoding cannot be determined from the encoding itself without knowledge of the type being encoded. 7.3 PER encodings are always relay-safe provided the abstract values of the types EXTERNAL, EMBEDDED PDV and CHARACTER STRING are constrained to prevent the carriage of OSI presentation context identifiers. 7.6 If a type encoded with BASIC-PER or CANONICAL-PER contains EMBEDDED PDV, CHARACTER STRING or EXTERNAL types, then the outer encoding ceases to be relay-safe unless the transfer syntax used for all the EMBEDDED PDV, CHARACTER STRING and EXTERNAL types is relay safe. If a type encoded with CANONICAL-PER contains EMBEDDED PDV, EXTERNAL or CHARACTER STRING types, then the outer encoding ceases to be canonical unless the transfer syntax used for all the EMBEDDED PDV, EXTERNAL and CHARACTER STRING types is canonical. NOTE – The character transfer syntaxes supporting all character abstract syntaxes of the form {iso standard 10646 level-1(1) ....} are canonical. Those supporting {iso standard 10646 level-2(2) ....} and {iso standard 10646 level-3(3) ....} are not always canonical. All the above character transfer syntaxes are relay-safe. 7.7 Both BASIC-PER and CANONICAL-PER come in two variants, the ALIGNED variant, and the UNALIGNED variant. In the ALIGNED variant, padding bits are inserted from time to time to restore octet alignment. In the UNALIGNED variant, no padding bits are ever inserted. 7.8 There are no interworking possibilities between the ALIGNED variant and the UNALIGNED variant. 7.9 PER encodings are self-delimiting only with knowledge of the type of the encoded value. Encodings are always a multiple of eight bits. When carried in an EXTERNAL type they shall be carried in the OCTET STRING choice alternative, unless the EXTERNAL type itself is encoded in PER, in which case the value may be encoded as a single ASN.1 type (i.e., an open type). When carried in OSI presentation protocol, the "full encoding" (as defined in ITU-T Rec. X.226 | ISO/IEC 8823-1) with the OCTET STRING choice alternative shall be used. ITU-T Rec. X.691 (2002 E) 11 9.3 PER-visible constraints NOTE – The fact that some ASN.1 constraints may not be PER-visible for the purposes of encoding and decoding does not in any way affect the use of such constraints in the handling of errors detected during decoding, nor does it imply that values violating such constraints are allowed to be transmitted by a conforming sender. However, this Recommendation | International Standard makes no use of such constraints in the specification of encodings. 9.3.1 Constraints that are expressed in human-readable text or in ASN.1 comment are not PER-visible. 9.3.2 Variable constraints are not PER-visible (see ITU-T Rec. X.683 | ISO/IEC 8824-4, 10.3 and 10.4). 9.3.3 Table constraints are not PER-visible (see ITU-T Rec. X.682 | ISO/IEC 8824-3). 9.3.4 Component relation constraints (see ITU-T Rec. X.682 | ISO/IEC 8824-3, 10.7) are not PER-visible. 9.3.5 Constraints whose evaluation is textually dependent on a table constraint or a component relation constraint are not PER-visible (see ITU-T Rec. X.682 | ISO/IEC 8824-3). 9.3.6 Constraints on restricted character string types which are not (see ITU-T Rec. X.680 | ISO/IEC 8824-1, clause 37) known-multiplier character string types are not PER-visible (see 3.6.16). 9.3.7 Pattern constraints are not PER-visible. 9.3.8 Subject to the above, all size constraints are PER-visible. 9.3.9 The effective size constraint for a constrained type is a single size constraint such that a size is permitted if and only if there is some value of the constrained type that has that (permitted) size. 9.3.10 Permitted-alphabet constraints on known-multiplier character string types which are not extensible after application of ITU-T Rec. X.680 | ISO/IEC 8824-1, 48.3 to 48.5, are PER-visible. Permitted-alphabet constraints which are extensible are not PER-visible. ISO/IEC 8825-2 : 2002 (E) 9.3.11 The effective permitted-alphabet constraint for a constrained type is a single permitted-alphabet constraint which allows a character if and only if there is some value of the constrained type that contains that character. If all characters of the type being constrained can be present in some value of the constrained type, then the effective permitted-alphabet constraint is the set of characters defined for the unconstrained type. 9.3.12 Constraints applied to real types are not PER-visible. 9.3.13 An inner type constraint applied to an unrestricted character string or embbeded-pdv type is PER-visible only when it is used to restrict the value of the syntaxes component to a single value, or when it is used to restrict identification to the fixed alternative (see clauses 25 and 28). 9.3.14 Constraints on the useful types are not PER-visible. 9.3.15 Single value subtype constraints applied to a character string type are not PER-visible. 9.3.16 Subject to the above, all other constraints are PER-visible if and only if they are applied to an integer type or to a known-multiplier character string type. 9.3.17 In general the constraint on a type will consist of individual constraints combined using some or all of set arithmetic, contained subtype constraints, and serial application of constraints. The following clauses specify the effect if some of the component parts of the total constraint are PER-visible and some are not. NOTE – See Annex B for further discussion on the effect of combining constraints that individually are PER-visible or not PER-visible. 9.3.18 If a constraint consists of a serial application of constraints, the constraints which are not PER-visible, if any, do not affect PER encodings, but cause the extensibility (and extension additions) present in any earlier constraints to be removed as specified in ITU-T Rec. X.680 | ISO/IEC 8824-1, 46.8. NOTE 1 – If the final constraint in a serial application is not PER-visible, then the type is not extensible for PER-encodings, and is encoded without an extension bit. NOTE 2 – For example: A ::= IA5String(SIZE(1..4))(FROM("ABCD",...)) has an effective permitted-alphabet constraint that consists of the entire IA5String alphabet since the extensible permitted-alphabet constraint is not PER-visible. It has nevertheless an effective size constraint which is "SIZE(1..4)". Similarly, B ::= IA5String(A) has the same effective size constraint and the same effective permitted-alphabet constraint. 9.3.19 If a constraint that is PER-visible is part of an INTERSECTION construction, then the resulting constraint is PERvisible, and consists of the INTERSECTION of all PER-visible parts (with the non-PER-visible parts ignored). If a constraint which is not PER-visible is part of a UNION construction, then the resulting constraint is not PER-visible. If a constraint has an EXCEPT clause, the EXCEPT and the following value set is completely ignored, whether the value set following the EXCEPT is PER-visible or not. NOTE – For example: A ::= IA5String (SIZE(1..4) INTERSECTION FROM("ABCD",...)) has an effective size constraint of 1..4 but the alphabet constraint is not visible because it is extensible. 9.3.20 A type is also extensible for PER encodings (whether subsequently constrained or not) if any of the following occurs: a) it is derived from an ENUMERATED type (by subtyping, type referencing, or tagging) and there is an extension marker in the "Enumerations" production; or b) it is derived from a SEQUENCE type (by subtyping, type referencing, or tagging) and there is an extension marker in the "ComponentTypeLists" or in the "SequenceType" productions; or c) it is derived from a SET type (by subtyping, type referencing, or tagging) and there is an extension marker in the "ComponentTypeLists" or in the "SetType" productions; or d) it is derived from a CHOICE type (by subtyping, type referencing, or tagging) and there is an extension marker in the "AlternativeTypeLists" production. 9.5.2 The encoding of a component of a data value either: a) consists of three parts, as shown in Figure 1, which appear in the following order: 1) a preamble (see clauses 18, 20 and 22); 2) a length determinant (see 10.9); 3) contents; or b) (where the contents are large) consists of an arbitrary number of parts, as shown in Figure 2, of which the first is a preamble (see clauses 18, 20 and 22) and the following parts are pairs of bit-fields (octet-aligned in the ALIGNED variant), the first being a length determinant for a fragment of the contents, and the second that fragment of the contents; the last pair of fields is identified by the length determinant part, as specified in 10.9. Preamble | Length | Contents | Length | Contents . . .Length | Contents (may be missing) 9.6.4 The following "useful types" shall be encoded as if they had been replaced by their definitions given in ITU-T Rec. X.680 | ISO/IEC 8824-1, clause 41: – generalized time; – universal time; – object descriptor. Constraints on the useful types are not PER-visible. The restrictions imposed on the encoding of the generalized time and universal time types by ITU-T Rec. X.690 | ISO/IEC 8825-1, 11.7 and 11.8 shall apply here. 9.6.5 A type defined using a value set assignment shall be encoded as if the type had been defined using the production specified in ITU-T Rec. X.690 | ISO/IEC 8825-1, 15.8. 10.1.1 If an ASN.1 type is encoded using any of the encoding rules identified by the object identifiers listed in clause 29.2 (or by direct textual reference to this Recommendation | International Standard), and the encoding is included in: a) an ASN.1 bitstring or an ASN.1 octetstring (with or without a contents constraint); or b) an ASN.1 open type; or c) any part of an ASN.1 external or embedded pdv type; or d) any carrier protocol that is not defined using ASN.1 then that ASN.1 type is defined as an outermost type for this application, and clause 10.1.2 shall apply to all encodings of its values. NOTE 1 – This means that all complete PER encodings (for all variants) that are used in this way are always an integral multiple of eight bits. 10.1.2 The field-list produced as a result of applying this Recommendation | International Standard to an abstract value of an outermost type shall be used to produce the complete encoding of that abstract syntax value as follows: each field in the field-list shall be taken in turn and concatenated to the end of the bit string which is to form the complete encoding of the abstract syntax value preceded by additional zero bits for padding as specified below. 10.1.3 In the UNALIGNED variant of these encoding rules, all fields shall be concatenated without padding. If the result of encoding the outermost value is an empty bit string, the bit string shall be replaced with a single octet with all bits set to 0. If it is a non-empty bit string and it is not a multiple of eight bits, (zero to seven) zero bits shall be appended to it to produce a multiple of eight bits. 10.1.4 In the ALIGNED variant of these encoding rules, any bit-fields in the field-list shall be concatenated without padding, and any octet-aligned bit-fields shall be concatenated after (zero to seven) zero bits have been concatenated to make the length of the encoding produced so far a multiple of eight bits. If the result of encoding the outermost value is an empty bit string, the bit string shall be replaced with a single octet with all bits set to 0. If it is a non-empty bit string and it is not a multiple of eight bits, (zero to seven) zero bits shall be appended to it to produce a multiple of eight bits. NOTE – The encoding of the outermost value is the empty bit string if, for example, the abstract syntax value is of the null type or of an integer type constrained to a single value. 10.1.5 The resulting bit string is the complete encoding of the abstract syntax value of an outermost type. 10.2 Open type fields (RWC; NOT SUPPORTED!!!) 10.5 Encoding of a constrained whole number NOTE – (Tutorial) This subclause is referenced by other clauses, and itself references earlier clauses for the production of a nonnegative-binary-integer or a 2’s-complement-binary-integer encoding. For the UNALIGNED variant the value is always encoded in the minimum number of bits necessary to represent the range (defined in 10.5.3). The rest of this Note addresses the ALIGNED variant. Where the range is less than or equal to 255, the value encodes into a bit-field of the minimum size for the range. Where the range is exactly 256, the value encodes into a single octet octet-aligned bit-field. Where the range is 257 to 64K, the value encodes into a two octet octet-aligned bit-field. Where the range is greater than 64K, the range is ignored and the value encodes into an octetaligned bit-field which is the minimum number of octets for the value. In this latter case, later procedures (see 10.9) also encode a length field (usually a single octet) to indicate the length of the encoding. For the other cases, the length of the encoding is independent of the value being encoded, and is not explicitly encoded. 10.5.6 In the case of the UNALIGNED variant the value ("n" – "lb") shall be encoded as a non-negative- binary-integer in a bit-field as specified in 10.3 with the minimum number of bits necessary to represent the range. NOTE – If "range" satisfies the inequality 2m < "range" =ð ð2m +ð ð1, then the number of bits = m +ð ð1. (RWC: THE VALUE IS NOT ENCODED HERE, just the index since the lower bound is known at both encoding and decoding time.) 10.5.7 In the case of the ALIGNED variant the encoding depends on whether: a) "range" is less than or equal to 255 (the bit-field case); b) "range" is exactly 256 (the one-octet case); c) "range" is greater than 256 and less than or equal to 64K (the two-octet case); d) "range" is greater than 64K (the indefinite length case). 10.5.7.1 (The bit-field case.) If "range" is less than or equal to 255, then invocation of this subclause requires the generation of a bit-field with a number of bits as specified in the table below, and containing the value ("n" – "lb") as a non-negativebinary-integer encoding in a bit-field as specified in 10.3. "Range" Bit-field size (in bits) 2 1 3, 4 2 5, 6, 7, 8 3 9 to 16 4 17 to 32 5 33 to 64 6 65 to 128 7 129 to 255 8 10.5.7.2 (The one-octet case.) If the range has a value of 256, then the value ("n" – "lb") shall be encoded in a one-octet bitfield (octet-aligned in the ALIGNED variant) as a non-negative-binary-integer as specified in 10.3. 10.5.7.3 (The two-octet case.) If the "range" has a value greater than or equal to 257 and less than or equal to 64K, then the value ("n" – "lb") shall be encoded in a two-octet bit-field (octet-aligned in the ALIGNED variant) as a non-negative-binary integer encoding as specified in 10.3. 10.5.7.4 (The indefinite length case.) Otherwise, the value ("n" – "lb") shall be encoded as a non-negative-binary-integer in a bit-field (octet-aligned in the ALIGNED variant) with the minimum number of octets as specified in 10.3, and the number of octets "len" used in the encoding is used by other clauses that reference this subclause to specify an encoding of the length. 10.6 Encoding of a normally small non-negative whole number NOTE – (Tutorial) This procedure is used when encoding a non-negative whole number that is expected to be small, but whose size is potentially unlimited due to the presence of an extension marker. An example is a choice index. 10.6.1 If the non-negative whole number, "n", is less than or equal to 63, then a single-bit bit-field shall be appended to the field-list with the bit set to 0, and "n" shall be encoded as a non-negative-binary-integer into a 6-bit bit-field. 10.6.2 If "n" is greater than or equal to 64, a single-bit bit-field with the bit set to 1 shall be appended to the field-list. The value "n" shall then be encoded as a semi-constrained whole number with "lb" equal to 0 and the procedures of 10.9 shall be invoked to add it to the field-list preceded by a length determinant. 10.9.3.3 Where the length determinant is a constrained whole number with "ub" less than 64K, then the field-list shall have appended to it the encoding of the constrained whole number for the length determinant as specified in 10.5. If "n" is nonzero, this shall be followed by the associated field or list of fields, completing these procedures. If "n" is zero there shall be no further addition to the field-list, completing these procedures. NOTE 1 – For example: A ::= IA5String (SIZE (3..6)) -- Length is encoded in a 2-bit bit-field. B ::= IA5String (SIZE (40000..40254)) -- Length is encoded in an 8-bit bit-field. C ::= IA5String (SIZE (0..32000)) -- Length is encoded in a 2-octet -- bit-field (octet-aligned in the ALIGNED variant). D ::= IA5String (SIZE (64000)) -- Length is not encoded. NOTE 2 – The effect of making no addition in the case of "n" equals zero is that padding to an octet boundary does not occur when these procedures are invoked to add an octet-aligned-bit-field of zero length, unless required by 10.5. 10.9.3.6 If "n" is less than or equal to 127, then "n" shall be encoded as a non-negative-binary-integer (using the procedures of 10.3) into bits 7 (most significant) to 1 (least significant) of a single octet and bit 8 shall be set to zero. This shall be appended to the field-list as a bit-field (octet-aligned in the ALIGNED variant) followed by the associated field or list of fields, completing these procedures. NOTE – For example, if in the following a value of A is 4 characters long, and that of B is 4 items long: A ::= IA5String B ::= SEQUENCE (SIZE (4..123456)) OF INTEGER both values are encoded with the length octet occupying one octet, and with the most significant set to 0 to indicate that the length is less than or equal to 127: 0 0000100 4 characters/items Length Value 10.9.3.7 If "n" is greater than 127 and less than 16K, then "n" shall be encoded as a non-negative-binary-integer (using the procedures of 10.3) into bit 6 of octet one (most significant) to bit 1 of octet two (least significant) of a two-octet bit-field (octet-aligned in the ALIGNED variant) with bit 8 of the first octet set to 1 and bit 7 of the first octet set to zero. This shall be appended to the field-list followed by the associated field or list of fields, completing these procedures. NOTE – If in the example of 10.9.3.6 a value of A is 130 characters long, and a value of B is 130 items long, both values are encoded with the length component occupying 2 octets, and with the two most significant bits (bits 8 and 7) of the octet set to 10 to indicate that the length is greater than 127 but less than 16K. 10 000000 10000010 130 characters/items Length Value 10.9.3.8 If "n" is greater than or equal to 16K, then there shall be appended to the field-list a single octet in a bit-field (octet-aligned in the ALIGNED variant) with bit 8 set to 1 and bit 7 set to 1, and bits 6 to 1 encoding the value 1, 2, 3 or 4 as a non-negative-binary-integer (using the procedures of 10.8). This single octet shall be followed by part of the associated field or list of fields, as specified below. NOTE – The value of bits 6 to 1 is restricted to 1-4 (instead of the theoretical limits of 0-63) so as to limit the number of items that an implementation has to have knowledge of to a more manageable number (64K instead of 1024K). 10.9.3.8.1 The value of bits 6 to 1 (1 to 4) shall be multiplied by 16K giving a count ("m" say). The choice of the integer in bits 6 to 1 shall be the maximum allowed value such that the associated field or list of fields contains more than or exactly "m" octets, bits, components or characters, as appropriate. NOTE 1 – The unfragmented form handles lengths up to 16K. The fragmentation therefore provides for lengths up to 64K with a granularity of 16K. NOTE 2  If in the example of 10.9.3.6 a value of "B" is 144K +ð ð1 (i.e., 64K +ð ð64K +ð ð16K +ð ð1) items long, the value is fragmented, with the two most significant bits (bits 8 and 7) of the first three fragments set to 11 to indicate that one to four blocks each of 16K items follow, and that another length component will follow the last block of each fragment: 11 000100 64K items | 11 000100 64K items | 11 000001 16K items | 0 0000001 1 item Length Value Length Value Length Value Length Value 11.2 The bit shall be set to 1 for TRUE and 0 for FALSE. 11.3 The bit-field shall be appended to the field-list with no length determinant. 12 Encoding the integer type NOTE 1 – (Tutorial ALIGNED variant) Ranges which allow the encoding of all values into one octet or less go into a minimum-sized bit-field with no length count. Ranges which allow encoding of all values into two octets go into two octets in an octet-aligned bit-field with no length count. Otherwise, the value is encoded into the minimum number of octets (using non-negative-binary-integer or 2’scomplement-binary-integer encoding as appropriate) and a length determinant is added. In this case, if the integer value can be encoded in less than 127 octets (as an offset from any lower bound that might be determined), and there is no finite upper and lower bound, there is a one-octet length determinant, else the length is encoded in the fewest number of bits needed. Other cases are not of any practical interest, but are specified for completeness. NOTE 2 – (Tutorial UNALIGNED variant) Constrained integers are encoded in the fewest number of bits necessary to represent the range regardless of its size. Unconstrained integers are encoded as in Note 1. 12.2.6 Otherwise, (the indefinite length case) the procedures of 10.9 shall be invoked to append the field to the field-list preceded by one of the following: a) A constrained length determinant "len" (as determined by 10.5.7.4) if PER-visible constraints restrict the type with finite upper and lower bounds and, if the type is extensible, the value lies within the range of the extension root. The lower bound "lb" used in the length determinant shall be 1, and the upper bound "ub" shall be the count of the number of octets required to hold the range of the integer value. NOTE – The encoding of the value "foo INTEGER (256..1234567) ::= 256" would thus be encoded as 00xxxxxx00000000, where each 'x' represents a zero pad bit that may or may not be present depending on where within the octet the length occurs (e.g. the encoding is 00 xxxxxx 00000000 if the length starts on an octet boundary, and 00 00000000 if it starts with the two least signigicant bits (bits 2 and 1) of an octet). b) An unconstrained length determinant equal to "len" (as determined by 10.7 and 10.8) if PER-visible constraints do not restrict the type with finite upper and lower bounds, or if the type is extensible and the value does not lie within the range of the extension root. 13 Encoding the enumerated type NOTE – (Tutorial) An enumerated type without an extension marker is encoded as if it were a constrained integer whose subtype constraint does not contain an extension marker. This means that an enumerated type will almost always in practice be encoded as a bit-field in the smallest number of bits needed to express every enumeration. In the presence of an extension marker, it is encoded as a normally small non-negative whole number if the value is not in the extension root. 14 Encoding the real type NOTE – (Tutorial) A real uses the contents octets of CER/DER preceded by a length determinant that will in practice be a single octet. 15 Encoding the bitstring type NOTE – (Tutorial) Bitstrings constrained to a fixed length less than or equal to 16 bits do not cause octet alignment. Larger bitstrings are octet-aligned in the ALIGNED variant. If the length is fixed by constraints and the upper bound is less than 64K, there is no explicit length encoding, otherwise a length encoding is included which can take any of the forms specified earlier for length encodings, including fragmentation for large bit strings. 16 Encoding the octetstring type NOTE – Octet strings of fixed length less than or equal to two octets are not octet-aligned. All other octet strings are octet-aligned in the ALIGNED variant. Fixed length octet strings encode with no length octets if they are shorter than 64K. For unconstrained octet strings the length is explicitly encoded (with fragmentation if necessary). 17 Encoding the null type NOTE – (Tutorial) The null type is essentially a place holder, with practical meaning only in the case of a choice or an optional set or sequence component. Identification of the null in a choice, or its presence as an optional element, is performed in these encoding rules without the need to have octets representing the null. Null values therefore never contribute to the octets of an encoding. 18 Encoding the sequence type NOTE – (Tutorial) A sequence type begins with a preamble which is a bit-map. If the sequence type has no extension marker, then the bit-map merely records the presence or absence of default and optional components in the type, encoded as a fixed length bit-field. If the sequence type does have an extension marker, then the bit-map is preceded by a single bit that says whether values of extension additions are actually present in the encoding. The preamble is encoded without any length determinant provided it is less than 64K bits long, otherwise a length determinant is encoded to obtain fragmentation. The preamble is followed by the fields that encode each of the components, taken in turn. If there are extension additions, then immediately before the first one is encoded there is the encoding (as a normally small length) of a count of the number of extension additions in the type being encoded, followed by a bitmap equal in length to this count which records the presence or absence of values of each extension addition. This is followed by the encodings of the extension additions as if each one was the value of an open type field. 18.1 If the sequence type has an extension marker, then a single bit shall first be added to the field-list in a bit-field of length one. The bit shall be one if values of extension additions are present in this encoding, and zero otherwise. (This bit is called the "extension bit" in the following text.) If there is no extension marker, there shall be no extension bit added. 18.2 If the sequence type has "n" components in the extension root that are marked OPTIONAL or DEFAULT, then a single bit-field with "n" bits shall be produced for addition to the field-list. The bits of the bit-field shall, taken in order, encode the presence or absence of an encoding of each optional or default component in the sequence type. A bit value of 1 shall encode the presence of the encoding of the component, and a bit value of 0 shall encode the absence of the encoding of the component. The leading bit in the preamble shall encode the presence or absence of the first optional or default component, and the trailing bit shall encode the presence or absence of the last optional or default component. 18.3 If "n" is less than 64K, the bit-field shall be appended to the field-list. If "n" is greater than or equal to 64K, then the procedures of 10.9 shall be invoked to add this bit-field of "n" bits to the field-list, preceded by a length determinant equal to "n" bits as a constrained whole number with "ub" and "lb" both set to "n". NOTE – In this case, "ub" and "lb" will be ignored by the length procedures. These procedures are invoked here in order to provide fragmentation of a large preamble. The situation is expected to arise only rarely. 18.4 The preamble shall be followed by the field-lists of each of the components of the sequence value which are present, taken in turn. 18.5 For CANONICAL-PER, encodings of components marked DEFAULT shall always be absent if the value to be encoded is the default value. For BASIC-PER, encodings of components marked DEFAULT shall always be absent if the value to be encoded is the default value of a simple type (see 3.6.25), otherwise it is a sender's option whether or not to encode it. 18.6 (RWC; extensions not supported!) 19 Encoding the sequence-of type 19.5 If the number of components is fixed ("ub" equals "lb") and "ub" is less than 64K, then there shall be no length determinant for the sequence-of, and the fields of each component shall be appended in turn to the field-list of the sequenceof. 19.6 Otherwise, the procedures of 10.9 shall be invoked to add the list of fields generated by the "n" components to the field-list, preceded by a length determinant equal to "n" components as a constrained whole number if "ub" is set, and as a semi-constrained whole number if "ub" is unset. "lb" is as determined above. NOTE 1 – The fragmentation procedures may apply after 16K, 32K, 48K, or 64K components. NOTE 2 – The break-points for fragmentation are between fields. The number of bits prior to a break-point are not necessarily a multiple of eight. 20 Encoding the set type The set type shall have the elements in its "RootComponentTypeList" sorted into the canonical order specified in ITU-T Rec.X.680 | ISO/IEC 8824-1, 8.6 and additionally for the purposes of determining the order in which components are encoded when one or more component is an untagged choice type, each untagged choice type is ordered as though it has a tag equal to that of the smallest tag in the "RootAlternativeTypeList" of that choice type or any untagged choice types nested within. The set elements that occur in the "RootComponentTypeList" shall then be encoded as if it had been declared a sequence type. The set elements that occur in the "ExtensionAdditionList" shall be encoded as though they were components of a sequence type as specified in 18.9 (i.e., they are encoded in the order in which they are defined). EXAMPLE – In the following which assumes a tagging environment of IMPLICIT TAGS: A ::= SET { a [3] INTEGER, b [1] CHOICE { c [2] INTEGER, d [4] INTEGER }, e CHOICE { f CHOICE { g [5] INTEGER, h [6] INTEGER }, i CHOICE { j [0] INTEGER } } } the order in which the components of the set are encoded will always be e, b, a, since the tag [0] sorts lowest, then [1], then [3]. [RWC;MUST be compiler generated order when encoding, specific to individual element tags; special case for untagged Choice(s).] 21 Encoding the set-of type 21.1 For CANONICAL-PER the encoding of the component values of the set-of type shall appear in ascending order, the component encodings being compared as bit strings padded at their trailing ends with as many as seven 0 bits to an octet boundary, and with 0-octets added to the shorter one if necessary to make the length equal to that of the longer one. NOTE – Any pad bits or pad octets added for the sort do not appear in the actual encoding. 21.2 For BASIC-PER the set-of shall be encoded as if it had been declared a sequence-of type. 22 Encoding the choice type NOTE – (Tutorial) A choice type is encoded by encoding an index specifying the chosen alternative. This is encoded as for a constrained integer (unless the extension marker is present in the choice type, in which case it is a normally small non-negative whole number) and would therefore typically occupy a fixed length bit-field of the minimum number of bits needed to encode the index. (Although it could in principle be arbitrarily large.) This is followed by the encoding of the chosen alternative, with alternatives that are extension additions encoded as if they were the value of an open type field. *****Where the choice has only one alternative, there is no encoding for the index. Additional Notes (from ongoing coding details) SIZE constraint is not used in ASN.1 INTEGER type, only value limits. When unaligned PER encoding, a restricted string with constraints may be encoded as an index; 0 starts at MIN, up to the specified MAX in a single range limit. If multiple range limits are presented, OR an additional enumerated character, OR “FROM(…)” is specified, then the maximum value is used to determine the number of bits used to encode the data. Otherwise, the index max, not the data max character, is used to encode the data (the decode MUST be aware of this range value to properly reconstruct the decoded data). (REQUIREMENT 27.???) When unaligned PER encoding, our eSNACC buffer handling will create intermediate bit buffers, then reconstruct a final bit buffer with all relevant buffers appended, with the beginning data properly aligned. This will pad the final data properly, even though we reverse load the data (in Sequence, SequenceOf, Set, SetOf). (REQUIREMENT 27.???) FROM X.691 NOTES for Set/SetOf ordering... 9.2 Use of tags to provide a canonical order This Recommendation | International Standard requires components of a set type and a choice type to be canonically ordered independent of the textual ordering of the components. The canonical order is determined by sorting the outermost tag of each component, as specified in ITU-T Rec. X.680 | ISO/IEC 8824-1, 8.6. [RWC; for our application of the PER compiler, all Set definitions appear to have application level tags. These appear to be necessary since any non-application specified tags would be removed for PER encoding by default, even if EXPLICIT TAGS were used.] X.682 is on page 187 of .pdf file #GHj¢·»ÐÔñõ:CewyzŸ¥¨©ßãJNéí˜ œ Æ Î  : B | „ … ‰ Š Ž “ ” ˜ ™ ž ¢ £ § ¨ ¬ ­ ± ² ¶ · » ¼ À Á å $ U Y … † Š ™ ¶ º Ò Ö   M Q z ~ ¨ ¬  ùóïïïïïïïíïíïïïïïïïïïïïïïïïïïïïïïïïïèïïïïïïïïïCJaJ]5\ 5CJ \ 5CJ,aJ,\#Pd‚ƒ„‘’²³ 5=Gýýûýýýýýùýýýùýýýýýóóóó$IfÇÆýGHjklmg˜aaaa$If—$$If–l4ÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laömn–Ÿ¡¢·¸¹ºiÐccccid]ccc$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö º»ÐÑÒÓÔñòóôidc]]]i„c]]]$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö ôõ:>@Bi”c]]]i¤c]]]$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö BCeuwyzŸ¢¥¨iÜc]]]i¼c]]]$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö ¨©ßàáâãièc]]]iàc]]]$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö JKLMNéêëìiÌc]]]i|c]]]$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö ìí˜ ™ š › œ Æ Ê Ë Í i¼c]]]iÈc]]]$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö Í Î     : > @ A ic]]]iÀc]]]$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö A B | € ‚ ƒ „ … † ‡ ˆ ic]]]ic]]]$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö ˆ ‰ Š ‹ Œ Ž ‘ ’ ic]]]ic]]]$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö ’ “ ” • – — ˜ ™ š › œ ic]]]ic]]]$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö œ ž Ÿ   ¡ ¢ £ ¤ ¥ ¦ ic]]]ic]]]$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö ¦ § ¨ © ª « ¬ ­ ® ¯ ° ic]]]ic]]]$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö ° ± ² ³ ´ µ ¶ · ¸ ¹ º ic]]]ic]]]$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö º » ¼ ½ ¾ ¿ À Á Â Ã Ä ic]]]ic]]]$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö Ä Å å æ ç è é ! " # ic]]]iìc]]]$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö # $ U V W X Y † ‡ ˆ ‰ iÔc]]]iÄc]]]$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö ‰ Š ™ š › œ ¶ · ¸ ¹ iLc]]]itc]]]$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö ¹ º Ò Ó Ô Õ Ö     ipc]]]ic]]]$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö   M N O P Q z { | } iìc]]]i´c]]]$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö } ~ ¨ © ª « ¬    i¸c]]]i€c]]]$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö         ic]]]ic]]]$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö      Þ ß ã >Brv¬°çëQU…‰ÀÄûÿ.2_c”˜™ž¢£§¨¬­±²¶·»¼ÀÁÅÆÊËÏÐÔÕÙÚÞßãä¤Ê’œ±ü—©, þU a ¸ Ä ”!!üüü÷üõüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüéééäCJaJ5CJOJQJ\aJ5CJaJ5\Z       ß à á â ic]]]i c]]]$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö â ã >?@Ai¼c]]]iÀc]]]$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö ABrstuv¬­®¯iÐc]]]ièc]]]$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö ¯°çèéêëiìc]]]iÌc]]]$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö QRSTU…†‡ˆiÜc]]]iÐc]]]$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö ˆ‰ÀÁÂÃÄûüýþiìc]]]iìc]]]$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö þÿ./012_`abiÌc]]]iÄc]]]$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö bc”•–—˜™š›œiÔc]]]ic]]]$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö œžŸ ¡¢£¤¥¦ic]]]ic]]]$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö ¦§¨©ª«¬­®¯°ic]]]ic]]]$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö °±²³´µ¶·¸¹ºic]]]ic]]]$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö º»¼½¾¿ÀÁÂÃÄic]]]ic]]]$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö ÄÅÆÇÈÉÊËÌÍÎic]]]ic]]]$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö ÎÏÐÑÒÓÔÕÖרic]]]ic]]]$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö ØÙÚÛÜÝÞßàáâic]]]ic]]]$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö âãäåæçèðñòóic]]]i0c]]]$If$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö óô $&()stuvwiÔcccci8cccciÈ$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö w¥¦§¨©ÐÑÒÓÔøùùùùc¬ùùùùc ù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If øùúûü*.012[_ùùùcØùùùùcÄùù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If _abc”˜š›œÅÉËùùcäùùùùcÄùùù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If ËÌÍ    ùcøùùùùcùùùù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If iccccicccci$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö  !"#$ùùùùcùùùùcd–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If $9:;<=VWXYZùóóó]tóóóó]è–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If$If Z‘’“”®¯°±²Øùùùùcxùùùùc¨ù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If ØÙÚÛÜÝÞßàáâãùùùcùùùùcùù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If ãäåæçèéêëìíîùùcùùùùcùùù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If îïðñòóôõö÷øùùcùùùùcùùùù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If ùúûüýþÿiccccicccci$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö      ùùùùcùùùùcù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If 4ùùùcùùùùc€]$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If 45678hijkl®¯ùùùcÐùùùùcùù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If ¯°±²abcùùc ùùùùc,ùùù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If cdeÆÇÈÉÊ›œžŸùc”ùùùùcXùùùù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If Ÿ @ACDEFGHIJi”ccccicccci¸$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö Josuwx›Ÿ¡£¤ùóóó]°ùóóó]¼–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If$If ¤ÊÎÐÒÓúûüýþùùùùc¬]ùùùcÀ$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If þ*+,-.WXYZ[ùóóó]´óóóó]–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If$If [\]^_`}~€ùùùùc„]ùùùcl$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If ’•˜›œñòóôõCùùùùcdùùùùcHù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If CDEFGnopqr†ùùùc¬]ùùùc`]$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If †‡ˆ‰Š´µ¶·¸äåùùùc¸ùùùùcÀùù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If åæçèPWXùùcØùùùùcðùùù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If XYZª«¬­®øùúûùcPùùùùc8ùùùù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If ûü89:;<ilcccci”cccciø$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö <vwxyz´µ¶·¸ùùùùcøùùùùc8ù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If 78ùùùcLùùùùcˆùù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If 89:;qrstu“”•ùùcèùùùùcˆùùù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If •–—©ª«¬­åæçèùcXùùùùcðùùùù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If èé,-./0iÄcccciXcccciÐ$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö 0`abcd‡ˆ‰Š‹´ùùùùcœùùùùcÌù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If ´»¼½¾¿ÀÁÂÃÄÅùùùcùùùùcùù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If ÅÆÇÈÉÊËÌÍÎÏÐùùcùùùùcùùù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If ÐÑÒÓÔÕÖרÙÚÛùcùùùùcùùùù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If ÛÜÝÞßàáâãäåæiccccicccci$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö æçèéêëìíîïðñùùùùcùùùùcù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If ñòóôõö÷øùúûüùùùcùùùùcùù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If üýþÿùùcùùùùcùùù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If      !"#$ùcùùùùc\ùùùù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If $%EFGHI{|}~icccciØcccciè$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö µ¶·¸¹ÙÚÛÜÝ ùùùùcùùùùcÀù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If     ùùùcùùùùcùù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If ùùcùùùùcùùù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If  !ABCDEhijùc]ùùùcœùùù$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If jkl˜™š›œžŸ ùcÀùùùùcùùùù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If  ¡¢£¤¥¦§¨©ª«iccccicccci$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö «¬­®¯°±²³´µ¶ùùùùcùùùùcù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If ¶·¸¹º»¼½¾¿ÀÁùùùcùùùùcùù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If ÁÂÃÄÅÆÇÈÉÊËÌùùcùùùùcùùù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If ÌÍÎÏÐÑÒÓÔÕÖ×ùcùùùùcùùùù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If רÙÚÛÜÝÞßàáâiccccicccci$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö âãäåæçèéêëìíùùùùcùùùùcù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If íîïðñúûüýþùùùc4]ùùùcŒ$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If þ) U ] ^ _ ` a Œ ¸ À ôôîîîîXŒôôî–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If $7$8$H$If À Á Â Ã Ä !P!v!•!ž!Ÿ!ùùùcxXXXXXù $7$8$H$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If Ÿ! !¡!¢!Ù!Ú!Û!Ü!Ý!"!"ùùcìùùùùc Xù $7$8$H$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If !¢!Ø!Ý!"%"C"n"”"À"â"9#X#r##´#¶#Ø#Ú#ë#($ö$/%&& &­&®&È&æ&ç&):)b)* *8*9*:*L*M*N*{*}*–*—*˜*Ç*È*É*å*æ*ç*+++1+2+3+E+F+G+L+›+³+Ú,Û,ì,ôôôèôèôèôèãôãôãôãÙÔȿȿ·ÔÔ¯ªÔ¯ªÔ¯ª¯ªÔ¯ªÔ¯ªÔ¯ªÔ¯ªÔ¯ªÔª¯ªÔªCJaJ5CJ\aJ5CJ\aJCJOJQJaJ5CJOJQJ\aJCJaJCJOJQJ\aJCJaJ6CJOJQJ]aJ5CJOJQJ\aJC!"""#"$"%"n"À"#9#r#}#ùùùcpXXXXXù $7$8$H$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If }#~##€##ë#û#($Ì$ùùùcXIIX„Ð$7$8$H$If^„Ð $7$8$H$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$IfÌ$ö$%%%%%/%Q%ôîîîîX îI„Ð$7$8$H$If^„Ж$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If $7$8$H$IfQ%o% %Ð%& & & & & &ððððêêêêTì–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If„Ð$7$8$H$If^„Ð &"&;&K&k&&®&Ä&Å&Æ&Ç&ôôôôôôîîîî$If $7$8$H$If Ç&È&×&ç&ý&þ&ÿ&''''iä^^XXXXiXX$If $7$8$H$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö '''''' ' ' ' ' ''ùùcùùùùcùùù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If ''''''''''''ùcùùùùcùùùù–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö$If ''''''' '!'"'8'icccciaaa_$If–$$If–lÖÖ\”ÿdÔs"È(ÐpŸUÖ0ÿÿÿÿÿÿö4)6ööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö laö 8'9'œ'È'ò'F(´()b)c)d)e)f)g)m)´)** *:*N*}*˜*É*ç*+3+G+H+ýýýýý÷÷÷ýýýýýõýýý÷÷÷ý÷÷÷÷÷÷ý7$8$H$H+I+J+K+L+M+k+l++Ž+++‘+’+›+Û,í,10r0Œ0·0ã0Û1F2³2ã3ý3(4T4ýýýýýýýýýýýýýý÷÷÷÷÷÷÷÷÷÷÷÷÷÷7$8$H$ì,í, -Ú-00106070p0r0Œ0æ011 1#1n1x1×1Ù1E2F2¨2ã3ý3W4‰44‘4”4ß4é4H5J5¶5·5Ù5ñ5 6/6\6U7^7`7o7q7~7€777Ÿ7£7¬7­7®7Ã7=8•8–8°89‚9¦9a:Ð;Ñ;ë;b=c=“=—=±=µ=Á=Å=Ö=Ù=>>2>6>_>c>ûóîéûóûóîéÝéÝéÝéÝéÝéûóîéÝéÝéÝéÝéÝéûóîóîóîÑîÑîÑîÑîÑîÑîûóîéûóîûóîéûóîûéÝéÝéÝéÝéÝéÝéÝ5CJOJQJ\aJ5CJOJQJ\aJCJaJCJaJ5CJ\aJCJaJRT4L5·5ñ5/6®7=8–8‚9a:Ñ;c=ƒ>Ø>?5?T?»?@@CABD`EhFËFåHæHùùùùùùùùùùùùïïïïùùùùùùùùùùù „Ð7$8$H$^„Ð7$8$H$c>}>€>ƒ>S?T?u?»?@@@BACAGA•AAŸA¬A°AÁABBBQB]B_BpBsB|BßBëBíBþBC CNCZC\CeChCyCÛCçCéCòCöCDD_E`EdEhFlFËFÏFiGrG”G¡GÀGÉG¶HÃHäHåHæHçHII IáJçJFKLK­K³KLûïûïêâÝûêâÝêâÝÑÝÑÝÑÝêâÝÑÝÑÝÑÝÑÝÑÝÑÝÑÝÑÝÑÝÑÝÑÝÑÝûêâÝâÝâÝÑÝÑÝÑÝÑÝÈêâÝÀûâÝâÝâÝ5CJ\aJCJOJQJaJ5CJOJQJ\aJCJaJ5CJ\aJCJaJ5CJOJQJ\aJCJaJLæHçHI IáJFK­KLjLMÜM NMNOO'PAPûQ9RaSSýS£TUëUrVªWSXiXý÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷7$8$H$LLjLpLM MÓMÙMÜMâM NNMNSNO$O'PHPûQR9R@RÛRäR S/S6SƒTƒrƒòêâÝâÝØâÝÓØâÝâÝâÝÓâÝØËØËÓØâÝÓÆÓ½ÓÆ´ÆÓ½ÓâÝâݬÝâÝâÝâÝËÓâÝâÝØâÝÓ 5CJOJQJ\aJ5CJ\aJCJOJQJaJCJOJQJaJCJaJ5CJ\aJCJaJCJaJCJaJ5CJ\aJ5CJ\aJ5CJOJQJ\^JaJ?ïbŒc c²cÇcœdJe;f•f¯féf!gªg:hj¦knÉn5ocooîsÊtFwÜw,x\x¯xùùùùùùùïïïïíùùùùùùùùùùùùïïï „Ð7$8$H$^„Ð7$8$H$¯xìx(zIzOzXzgzsz€zzšz¨z‹{®|(~d~G;€>ƒTƒƒïƒ3„h„¡„‹…-‡õïïõõõõõõõõïïïïïïïïïõõõõõíï7$8$H$ „Ð7$8$H$^„ÐrƒƒÃƒïƒ„h„‡„¡„Š…‹…”…-‡`‡b‡„‡†‡—‡Ô‡¢ˆ«ˆ“ŠÃŠÅŠìŠîŠ×‹#Œ,ŒÌ´Ž¿Žíúv‘z‘”‘˜‘ ‘¤‘¬‘°‘æ’µ“¶“»“Ù“Þ“è“í“ï“ô“A”B”_”˜‚˜‰˜Ãšåš›dœrs“pŸôèôèôèôãÛÖÑèÑèÑèÑÛÖÑèÑèÑÉÛÖÑÛÖÑÀÑÀÑÀÑÀÑɸÛÖ¬Ö¬ÖÛÖã¤ÑãÛÖÑèÑÖã¤Ñ5CJ\aJ5CJOJQJ\aJ5CJ\aJCJOJQJaJ5CJ\aJCJaJCJaJ5CJ\aJCJaJ5CJOJQJ\aJ6CJOJQJ]aJ@-‡—‡§‡Ô‡xˆ¢ˆ“Š×‹Œ#ŒÌ´Žíúæ’G“¶“ï“B”_”´—‚˜!™Ãš›dœÊœsùïïùùùùïïùùùíùïïùùùùùùïïïïï „Ð7$8$H$^„Ð7$8$H$s“qŸ‹Ÿ 1 õ¡¢o£‰£¥5¥±©+«ù­I¯°°¨° ²1²R²I³‹´ã´vµµÉ¸¹$¹ùùùùùùùùùùùùùùùùùùùùùùùùùùùùù7$8$H$pŸqŸ‹Ÿ  1 ô¡õ¡¢n£o£‰£¥¥5¥°©±©¶©+«0«~«‡«Š«‘«ù­þ­I¯°$°¨°­°ß°ç°]±e± ²²/²Q²R²W²I³N³‹´uµvµµÉ¸Ñ¸ ¹¹¹ù¹AºBºDºEºGºHºXº\ºoºrºyº|ºÿº»»»"»€¼Û¼à¼9½U½µ¿º¿À ÀÄûóîûóîûóîûóîûóîûæáæáÕáÕáæáîæáæáÕáÕáæáóûæáæáîûóáæáÕáÕáÕáÕáÕáÕáÕáÕáûáóæáîæáóîÍîû5CJ\aJ5CJOJQJ\aJCJaJ5CJ\aJCJaJ5CJ\aJCJaJO$¹&¹7¹F¹J¹]¹o¹t¹¹ƒ¹¹–¹«¹¿¹Æ¹Ó¹Ù¹í¹ó¹÷¹ù¹€º»»»€¼Û¼9½U½µ¿ùùùùùùùùùùùùùùùùùùùùùùùùùùùùù7$8$H$µ¿ À À À À ÀÀÀÀ?À…ÀªÂÄÄÄ0Ä1Ä^ĚŠÆzÆœÆÆžÆŸÆ Æ¡Æ¢Æ£Æùù÷÷÷÷÷÷÷òòò÷ùùùùùùùùùùùùùùù & F7$8$H$Ä^ğƠƣÆÇÆøóîãCJOJQJ^JaJCJaJCJaJ5CJ\aJ£Æ¤Æ¥ÆÇÆýýý 1h°Ð/ °à=!°"°# $ %° i8@ñÿ8 NormalCJ_HaJmH sH tH R@R Heading 1$¤ð¤<@&5CJ KH OJQJ\^JaJ 2@2 Heading 2$@&5\<A@òÿ¡< Default Paragraph Font8B@ò8 Body Text 7$8$H$CJaJ<P@< Body Text 2 7$8$H$CJaJÉ¿Öÿÿÿÿ#Pd‚ƒ„‘’²³ 5=GHjklmn–Ÿ¡¢·¸¹º»ÐÑÒÓÔñòóôõ:>@BCeuwyzŸ¢¥¨©ßàáâãJKLMNéêëìí˜™š›œÆÊËÍÎ :>@AB|€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅåæçèé !"#$UVWXY†‡ˆ‰Š™š›œ¶·¸¹ºÒÓÔÕÖMNOPQz{|}~¨©ª«¬                 ß à á â ã      > ? @ A B r s t u v ¬ ­ ® ¯ ° ç è é ê ë      Q R S T U … † ‡ ˆ ‰ À Á Â Ã Ä û ü ý þ ÿ . / 0 1 2 _ ` a b c ” • – — ˜ ™ š › œ ž Ÿ   ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ­ ® ¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è ð ñ ò ó ô $ & ( ) s t u v w ¥ ¦ § ¨ © Ð Ñ Ò Ó Ô ø ù ú û ü *.012[_abc”˜š›œÅÉËÌÍ     !"#$9:;<=VWXYZ‘’“”®¯°±²ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ     45678hijkl®¯°±²abcdeÆÇÈÉÊ›œžŸ @ACDEFGHIJosuwx›Ÿ¡£¤ÊÎÐÒÓúûüýþ*+,-.WXYZ[\]^_`}~€’•˜›œñòóôõCDEFGnopqr†‡ˆ‰Š´µ¶·¸äåæçèPWXYZª«¬­®øùúûü89:;<vwxyz´µ¶·¸789:;qrstu“”•–—©ª«¬­åæçèé,-./0`abcd‡ˆ‰Š‹´»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ     !"#$%EFGHI{|}~µ¶·¸¹ÙÚÛÜÝ      !ABCDEhijkl˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñúûüýþ)U]^_`aŒ¸ÀÁÂÃÄPv•žŸ ¡¢ÙÚÛÜÝ!"#$%nÀ9r}~€ëû( Ì ö !!!!!/!Q!o! !Ð!" " " " " """;"K"k""®"Ä"Å"Æ"Ç"È"×"ç"ý"þ"ÿ"######### # # # # ################### #!#"#8#9#œ#È#ò#F$´$%b%c%d%e%f%g%m%´%&& &:&N&}&˜&É&ç&'3'G'H'I'J'K'L'M'k'l''Ž'''‘'’'›'Û(í(1,r,Œ,·,ã,Û-F.³.ã/ý/(0T0L1·1ñ1/2®3=4–4‚5a6Ñ7c9ƒ:Ø:;5;T;»;<<C=>@`AhBËBåDæDçDE EáFFG­GHjHIÜI JMJKK'LALûM9NaOOýO£PQëQrRªSSTiT—TU¢UÿUXXUXÃX@Y°YÜYIZ•Z[D[à[\q\œ\À\Ð\E]µ] ^^–^ï^Œ_ _²_Ç_œ`Ja;b•b¯béb!cªc:df¦gjÉj5kckkîoÊp¥qðq.r^r±rîr*tKtQtZtitut‚ttœtªtu°v*xfxIy=zƒ{@}V}Ÿ}ñ}5~j~£~/™©Öz‚¤‚•„Ù…†%†Î‡¶ˆï‰Šè‹IŒ¸ŒñŒDa¶„‘#’Å“!”f•Ì•u–•–s˜˜™3™÷š›qœ‹œž7ž³¢-¤û¦K¨!©’©ª© «3«T«K¬­å­x®‘®Ë±²&²(²9²H²L²_²q²v²²…²’²˜²­²Á²È²Õ²Û²ï²õ²ù²û²‚³´´´‚µÝµ;¶W¶·¸ ¹ ¹ ¹¹¹¹¹¹A¹‡¹¬»½½½2½3½`½œ¾¿|¿ž¿Ÿ¿ ¿¡¿¢¿£¿¤¿¥¿¦¿§¿Ë¿˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€˜0€€0€€˜0€„˜0€„˜0€„0€€˜0€˜0€˜0€˜0€˜0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€©0€©0€™0€©0€©0€©0€©0€©0€©0€™0€©0€©0€©0€©0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€©0€™0€©0€©0€©0€©0€©0€©0€©0€©0€©0€™0€©0€©0€©0€©0€©0€©0€©0€©0€©0€™0€©0€©0€©0€©0€©0€©0€©0€©0€©0€©0€™0€©0€©0€©0€©0€©0€©0€©0€©0€©0€©0€™0€©0€©0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€©0€©0€©0€©0€™0€˜0€˜0€˜0€0€€˜0€"#˜0€"#˜0€"#˜0€"#˜0€"#˜0€"#˜0€"#˜0€"#˜0€"#˜0€"#˜0€"#˜0€"#˜0€"#0€€˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€€˜@0€g%˜@0€g%˜@0€g%˜@0€g%˜@0€g%˜@0€g%˜@0€g%˜@0€g%˜@0€g%˜@0€g%˜@0€g%˜@0€g%˜@0€g%˜@0€g%˜@0€g%˜@0€g%˜@0€g%˜@0€g%˜@0€g%˜0€€˜0€€˜0€€˜0€€˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜ 0€g%˜ 0€g%˜ 0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€€˜@0€g%˜@0€g%˜0€€˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g%˜0€g% !ì,c>L–brƒpŸÄÇÆgÎÚÜÞàãæéGmºôB¨ìÍ A ˆ ’ œ ¦ ° º Ä # ‰ ¹  }  â A¯ˆþbœ¦°ºÄÎØâówø_Ë$ZØãîù4¯cŸJ¤þ[C†åXû<8•è0´ÅÐÛæñü$ j «¶ÁÌ×âíþÀ Ÿ!!"}#Ì$Q% &Ç&'''8'H+T4æHiXïb¯x-‡s$¹µ¿£ÆÇÆhjklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÏÐÑÒÓÔÕÖרÙÛÝßáâäåçèêÇÆið8ð@ñÿÿÿ€€€÷ð’ðð0ð( ð ððB ðS ð¿Ëÿ ?ðdnùÿ>AV _ „ “   ­ ¶ Ê B M v ° » ë ö  - U d ‰ ˜ Ä Ó ÿ  c p $- ¢çéITйÄÝè)+NQŒŽ±´ßî$[ehsvy/!;!Q!`! !­!Ð!Ú!p""–( (p)r)Ÿ)¡)À)Â)·,¹,Ü,ß, -"-×-Ù-(0*0M0P0‘0“0H1J1`3o3q3~3€333ž3£3¬3“9–9Ö9Ú9::_:b:ž:­:Ø:ã:;$;';2;5;8;z@}@¿@Â@è@ë@yB…BˆN”NtV~VmYvYZZXZjZwZƒZºZÃZ [[+[2[l[u[¾[Ò[GbPb]bhbÜbßb¦k¯k›n§nNsWsåsós&u.u³w¶wúwxÍ{Ï{ü‰ŠH’K’e“g“ç“ê“͔Ӕ8•C•—•š•$™-™E™O™±™»™››-¨/¨a¨c¨€«‚«–«˜«?¬I¬+­-­b­d­¾®Ó® °7°ž°³°±0±Ì²Í²Í»Ó»×¼á¼è¼í¼ ½%½À¿Ã¿Ë¿y€¨¯ þº¾im  fkTYùü.4þ)-HMaeŒ«°ÇÎ(/PUv{¢¥¾ÃÝà %(nqÀà 9<ëîûþ( , /!=!Q!b!™!›! !¯!Ð!Ü! ""#"(";"A"L"R"k"o""•"Ò"Ô"á"ã"F$P$´$¸$%,%—'š'à(ã(Œ,,·,»,Ö,Û,³.¼.ý/0(0,0G0L0á1å1Ü4ç4±9´9†::ç:î:;;5;:;W;h;“@•@Ø@Ú@QI¹IhKsKK˜KñKL4L7LªLºLQ!QiTlT…TŠT—TšTwU|UUƒUU’U¢U¥UéV WXXCXHXUXXXCYEY°Y¶YßYáYIZOZ˜ZšZ[ [G[I[\%\t\u\Ÿ\ \Ã\Ë\Ô\Ù\E]G] ^(^Ž_™_¢_«_´_º_>b@b˜bšb²bµbìbïb!c%c¡k¥kôqùq2r7rbrgrµrºrÙzàz|Ü|V}Y}Ÿ}¢}ñ}ô}8~;~j~m~™œ©¬ÖÚë‹ö‹…ÉŽ;ŽÜç÷“ù“””!”#”̕ו¼œÈœgžužxŸôŸœ ð ‚©©’©™©ËªÌªq­s­ò­þ­C®N®Ü±ë±²²*²+²;²<²P²Q²c²d²x²y²‰²Š²ž²Ÿ²³²´²Ì²Í²á²â²û²³†³‹³¸_¸{º€º¥»©»½½¿¿|¿€¿Ë¿33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333HNóónn–œNN¼ÅÎ{³´ÄÅ Þ ã  = B q v ã   ) ) Q c l r )*-./2Z[^_`c“”—˜™œÄÅÈÉÊÍ $8=Êšœ ?AB)‘’”•—˜šœðõmr…г¸OPVZ©®÷ü7<uz³¸6;pu’—¨­äé+0_d†‹³´º Iz´¹ØÝ%|!!" "Ã"È"ü"####³¢³¢²ú²}³´¹¹½È¿Ë¿ÿÿcolestorcolestorcolestorcolestorcolestorcolestorAC:\devel.d\develPER.d\SNACC\doc\PERCompilerRequirementsMatrix.doccolestorAC:\devel.d\develPER.d\SNACC\doc\PERCompilerRequirementsMatrix.doccolestorAC:\devel.d\develPER.d\SNACC\doc\PERCompilerRequirementsMatrix.doccolestorAC:\devel.d\develPER.d\SNACC\doc\PERCompilerRequirementsMatrix.doccolestorAC:\devel.d\develPER.d\SNACC\doc\PERCompilerRequirementsMatrix.docÔJ—4Ò5Šýÿÿÿÿÿÿÿÿÿ„Є˜þÆÐ^„Ð`„˜þOJPJQJ^Jo(-€ „ „˜þÆ ^„ `„˜þOJQJo(o€ „p„˜þÆp^„p`„˜þOJQJo(§ð€ „@ „˜þÆ@ ^„@ `„˜þOJQJo(·ð€ „„˜þÆ^„`„˜þOJQJo(o€ „à„˜þÆà^„à`„˜þOJQJo(§ð€ „°„˜þư^„°`„˜þOJQJo(·ð€ „€„˜þÆ€^„€`„˜þOJQJo(o€ „P„˜þÆP^„P`„˜þOJQJo(§ðÔJ—4ÿÿÿÿÿÿÿÿrˆ¬C         5=GHjklmn–Ÿ¡¢·¸¹º»ÐÑÒÓÔñòóôõ:>@BCeuwyzŸ¢¥¨©ßàáâãJKLMNéêëìí˜™š›œÆÊËÍÎ :>@AB|€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅåæçèé !"#$UVWXY†‡ˆ‰Š™š›œ¶·¸¹ºÒÓÔÕÖMNOPQz{|}~¨©ª«¬                 ß à á â ã      > ? @ A B r s t u v ¬ ­ ® ¯ ° ç è é ê ë      Q R S T U … † ‡ ˆ ‰ À Á Â Ã Ä û ü ý þ ÿ . / 0 1 2 _ ` a b c ” • – — ˜ ™ š › œ ž Ÿ   ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ­ ® ¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è ð ñ ò ó ô $ & ( ) s t u v w ¥ ¦ § ¨ © Ð Ñ Ò Ó Ô ø ù ú û ü *.012[_abc”˜š›œÅÉËÌÍ     !"#$9:;<=VWXYZ‘’“”®¯°±²ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ     45678hijkl®¯°±²abcdeÆÇÈÉÊ›œžŸ @ACDEFGHIJosuwx›Ÿ¡£¤ÊÎÐÒÓúûüýþ*+,-.WXYZ[\]^_`}~€’•˜›œñòóôõCDEFGnopqr†‡ˆ‰Š´µ¶·¸äåæçèPWXYZª«¬­®øùúûü89:;<vwxyz´µ¶·¸789:;qrstu“”•–—©ª«¬­åæçèé,-./0`abcd‡ˆ‰Š‹´»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ     !"#$%EFGHI{|}~µ¶·¸¹ÙÚÛÜÝ      !ABCDEhijkl˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñúûüýþ]^_`aÀÁÂÃÄžŸ ¡¢ÙÚÛÜÝ!"#$%}~€!!!!! " " " " "Ä"Å"Æ"Ç"È"ý"þ"ÿ"######### # # # # ###################Ë¿žžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžž–ÿ@€l³l³€¿tl³l³@qrŠ‹É¿P@PvPð@PP$@ÿÿUnknownÿÿÿÿÿÿÿÿÿÿÿÿG‡z €ÿTimes New Roman5€Symbol3& ‡z €ÿArialO1CourierCourier New?5 ‡z €ÿCourier New;€Wingdings"qˆðÐhYbxF¸Š{&; ¾#žPQ"^ RV$ð¥À´´203€¼² 3ƒQðÜHÿÿ PER Compiler Requirements Matrixcolestorcolestorþÿà…ŸòùOh«‘+'³Ù0˜ÄÐäðü $0 L X dpx€ˆä!PER Compiler Requirements MatrixrosER  colestorleroleole Normal.dotr colestortr59eMicrosoft Word 9.0e@F&nŠ@ƒÝ`Ã@¨”K#­Ã¾#žþÿÕÍÕœ.“—+,ù®0$ hp˜ ¨° ¸ÀÈÐ Ø äDell - Personal Systems GroupeQP3Âí !PER Compiler Requirements Matrix Title  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëþÿÿÿíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLþÿÿÿNOPQRSTþÿÿÿVWXYZ[\þÿÿÿýÿÿÿýÿÿÿýÿÿÿaþÿÿÿþÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿRoot Entryÿÿÿÿÿÿÿÿ ÀF 9£m#­Ãc€1TableÿÿÿÿÿÿÿÿÿÿÿÿìãÁWordDocumentÿÿÿÿÿÿÿÿ"ÖSummaryInformation(ÿÿÿÿMDocumentSummaryInformation8ÿÿÿÿÿÿÿÿÿÿÿÿUCompObjÿÿÿÿjObjectPoolÿÿÿÿÿÿÿÿÿÿÿÿ 9£m#­Ã 9£m#­Ãÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿ ÿÿÿÿ ÀFMicrosoft Word Document MSWordDocWord.Document.8ô9²qesnacc-ng-1.8.1/doc/eSNACCManuals.zip000066400000000000000000006515771302010526100172000ustar00rootroot00000000000000PKôŒë.u£ë¶aEsnaccOriginalMaterial.docì[KŒ\IVM{F&ù43½@BŠn1r•œ•år» Ýîiu9]nª)WY®êñX­È÷"3Ã~ïEöûT9ùH°Clm ¶H°› ˆÅìÐ 4¾#µf³ f…øO›sïxŸ¬,7X° ¥ÊÏ{ñnܸ÷ÜoDýå_üÄßþÎïÿÔßõ–^oö>×ûäéó½n]£ïÿyÞÿøñ^ï|?‡¯Ÿ<}ú”.ý3~ÿ þþÿ†¿Çßàïéÿ¿þϾþá÷¾Ñ»¥žZ{ájÍâ…+׫ó½íŒ|÷+ßýJïÔëùç^ì½¼÷¹Þ¯½ßã¿ëï=ëõôé}ê÷ðJøý¯ŸëÕŸíïg}~±Eá{þúWÿôìÏߥ/Öë}í|3þƒÙùÞWñûëßêõ^Äï?ÿ–\Öçü󰘿êõöðÜoþM¯·³øxz¾GòøÎT¤òßùü|þáƒó=…KßNÎ÷>Àïàú—z§_aÝðí7{§ù ãÂçü¼¿}ÿ.Ë3<^á÷ Ï‹­ç–?‰þŸ¼šÎòï§]´„ç?ë+¬çãÖzÞû¡†Þ÷ÇçzïüH¯çÞ?ßûúçO¯óú ó…õ| Ÿ_Àç[?ýëÿøOoÿñ9ÂÓñ7¼Îõ^Øêõ.|x¾÷ÍtÖ ×K=Á½þã¾~©üþ ¬‡L3üþxI¿ß[ZßYŸç{ßÁ{¿ß?Ìt©­áåüÁëê ·S›éDÝÒYťɭNúáµ¥Þ©’…º|éÒ+ø¥Ö¸›c“¸¹‰Õx¡nÙh¦M¢u:OŒÚzíµWúiÁ?ÞŠŠa5ކ‘îß0s—©ÉJå&jäÒy…ùÔadM™þ»™=6yaËݾžÛÒ3 Kªtluÿê+¯^UÛÓÜFURV9ؽûïé,ržœzBt¦c=Pï]=R[¿x¹¿½CéjJ 0Û¯÷︱ÉKõŽsóþOªŸ¿{{çÎÞîþ/¨—Sm“Ò½ž?x+×6»“¡Í606±Ù06/«s_<ãÖ—ÖIn_ØÍÊÜÅUTZ—©Ò)s¸¿=©;&1º€€†¯zMD‚ML¡¶÷‡[êÞÖ}µ¶=.Ê\G¥:\d¥~¤ö]©™ÐAfÖU ºô€Í@w4P£‹•ËU¹˜Uê1n ÕÑ̨©ÉL®i¥#ºOÃ"¼¨Í e>ªì±NH±.µÂ¤`¸ÊA[g±Ê]UÚ ?0 ž9&Aax…+cSžƒ…a°arÂÐZ˜f]åf* ,l5¹—ç.‹m6U×wî¨{—±Ü뺰‘ÚùúZݺš¸<Õ¥,%Ó©Q Øe‰=¥£Üe‹”†©Çvû¦š˜$ö¢$élò²G"ãüÉPõfxÞ =W'ºP'€M‰ÅNíâN±Ã/LiOs“3?€©¢•é<šñÔ)°?‚ñg ´÷ÊýIáÞF÷iÙxˆ-ÔåL—5¡ÚV¥‰f–ƒlOl’`ZÈkl”>I™ê@ž”s5É]ªÞ½…[|AB‰mn¢Òå …•°€xÆË «W•èlZé)4 sÙÉ‚…‘˜G Ш°2ÐJlQz˜¨‚UÂÚÉè'€D,c‡¬BžÂãBcŽ0Äf±™¼ee­3™‹mžÖo±xbk æ¹;¶,h­*ñTCyP,Fè±*̤JXÐÅLçD€‚„fÓ8²W*`]þ°ðÂÁ|‘)X#Ù®Æ.ªØe¶±ª‹¢J‰KBèérÅÚÄj€Û–3¿"š¼ ÕÍ*ÇhŒËľh.ëŽbtƒWe¤G ù `}ï*½Á?Ñ0.d)†E|qIÄDæJè23'ÊÆF«qUª”àxöÒ¹¤@}R ø¿ŸÅ$»‡7vpéöÎí»›êöÁá]Ì»…43 ”š„U€A_£;"Â3æ^»¢J›RÀŒAŠû¤oò\œW±Hú‡Ø0 ÙÄh‰ù6‹’*6¯«¾‡íh´{tÔ€× pÕ˜…ĤO.ÃÏË“Â)<”Ô`£žTÈ_ÖvoÝ>¸st¸©v>à/ë}‰º ¯\ºÄT÷oÝžêUÌX¬ú|©­ê`ýòªÌÉä¹"ÉýÐóì ÄášXD~š Ì AS¢@iÕ!ÓŒÖ< O4–E6£E(mI?÷î;®§ëþ µÔ UYÑP\ggt¤voììíÞÜݹSÀ îí¼oâ—öv¶÷…=ø©¬HØ´9Ëa3âSÔ^ÖÇ Lýò¯^Pašyù¿º$ÕwsZ S(ª9%2…z|í‰*(× ).°Ó–´Odj º¯òÈø¨× î!e8¢1F( YlÚh¤þÓ 3S´>øp6—;ØsJÖ°½WÝØ¹¹»¿sC]¿ës 6/Y ø§ŒØd0Šž6ŽP)xèô›œ5•Ú?8Ú9Tk¨€^]ä!0¾CÉÔ$é9yɸ\–ˆÐƒŽ$§K.”kº*g.'¥&º(ù ÅÝ–`›(Š[ÓX¶tÎùJó[,^ eª@ÓUÓ<92Žœ1:€"%šLÈ´‡Ãáæ~fjöÜTõ÷ávWøšá ™?U´"ÑÔ”œÍÃb …XÒ,L`)) À/Ѩh¼–IQ!j>¢<,Ñ‘X0–Ck/8ì1䨡å=CÌ'P“{ž‚ûtØA!òÔœ.9æº$ûíéªNÊ¡B›™>¶Uç  u—ìJ¿*¦VÙñ~>ݪ}êéªäΨ4å”Ç;Uð‘ vítŸ<ÀXGáikiRﱡbЏ¬ç |¨¶ô)°”p•è¥þÁæ…TÓN3)ÚçD7VLÊlÆkªU|RÝ ˜’Ž˜•Ôp†ÞäŸz Éyaq(õJð­±^VU!®o\Ù$/†Ô¼4þûè(®‰Õ6ý˜¹=¦Ê`­Ž¢¤yNœFU°ûÀì§ÙÅ: J5-¢Ü¯®µ4]¢ëÞÎ<þLl!F ÆÌ¥pHˆÈ¯ÂãA‚œÏy÷ƒUîÙ¬zÄÊØNæ3­onnI6\̸`…HÆ1 S’› J€î^½¢ÆÈè"¸‡ ³¡Þ¤D)¨ŒùmÀ2:¸s}hO­Q­´a³ 8Ê)L¨ Èi(}ÑÄÁºè?˜\á:7¾FilÅQ››Ô‘¹“h†Î‰žGj–î#÷5':‚Cç:_ø¢E9ørÈ@qÈ1êèå½&7_QEJ â‘Ö¢*Ï¥cÁŒ¬‹l€%Þ—ïË.rù\2õ¹C‰³ÀІ¾Ï`$ª&ðå_¬fÕ”Z;yI ²{öI•E¾p¹Q/HøÄÂþ’apÆ…Èì³ %T¹S‡åDCïyº5A¤ÇËcá­ 2ºÂj£]]ÅËÊ+”ñDýÖ9?Bö+z©sZÅZ¿úÔ²0©Ýˆ\â|Ð_µÈSËA–ëÁñ–ÅþøÈ׊ïq­¸GÑXL¤)y§é÷ßÝÛS<ŠäÉ¿|«%Œà¶x±HÇ–ò˜FÓCÚÉo¬ýž‚H¯Æ2qUMepÑU¬á! ‡.ÝG•KMrNécg)ZÛ"P¦ô&Ê9̽»w÷nmÐ4!èZ㺱‚áb1ûãöX©(D–êò¥+?‡<‹–;#*C Ê=4^s{N_ˆtüƒO ØmĦ Ô¡wN•“÷j{ÿp—à–¹lƒ¿†rmä ÓØLt•”×df_HîRå’b°ÜŒ>ô¡eZÿ0d7àñzM¤Ë.4e«˜±1ðž†3…›A ô­ÚÝ$ÏË©¯x‹LµqØL.YØ*òh3LÓº}IÕ7Úƒ©@øÆ_` Töic.^\E*¡ºÎ¨3Yëƒ+#¬gPÇ›ú [Ôìð$î„·^VÃ5"¹qyxyøŠZepÙ¦-¤›MÓšrýhà7tà…N9N–è 8sÿkp*(ª°ÙÓ4b»ë°ddÂCGÞ· JØ/¥óÚüò–RQR‚/_V ÉþûKñ…FÓ9©µ¦}ÛÚ*^çöG=ªÕ*¡ÃËÅóÉ3rð–o/h?sŽ|‚w¤Æ¡LÎYÄXÜèC#垉}½$«C„4ÿ´ªÚ°×ɲǨÍ&yø…­)¾’ߊq5jÕ\0á‚w|1 Ϙ–AÙèò4ú/‚ÐYdg¯&„{n!ÑÞ©Ç99C †ûx?¦î %I£YœŸ¦ …¡k5OTÙCŸ÷òíržËvê”r­Õ;~ 6Xä¡ËF["mÜ4YÒ¼õ5x˾ؤñlPá a«ØÙãBzÍ= ¸¥Ôý••[jô$5XÙbºèÚw—W!ðlÎ „„@ä¸#ñÐþ&Js=õÁ·î0-m¶‚ѬÉí—7[eí±ƒ›åJuËg/mT±qûÈc¤ŒÚ +6š¥PXÉrds©öÔåpı¥ÝÙ2TR"†îp –2›þǾkE; uc³cdM7×û®Nç’¾P4æÛ‹ÌÍ [)õü½ 5»¯ð~›ßK~7üóûœß'÷UÿžÚˆÔ¯¨½©7ÄZí×7ï÷1´Roø=iëK†#÷ H'ê dN’ƒp›61™¿—¨723õ}ºöFó87Öß rhuÐÂAŸEqþAémªËöhƒHÓÚâm:ŠsdX%¢ ßfwÀ4õ}ÉòC:ÕÚPô»jÈ_ÞÒ î¸Y]6Þßã´ÕSå´•ÅÉ›Ÿ›íÖêJ«:ådÓ45åÌŘ€ÜFó–a›ÒæísIÏ£i÷h,Íà…Â;Tu«¿ ’¡ZÚ‰ k¦éweƒ°TZ𸵫\º©aï·NqÍPñÄ T}>m~§»ÕÄiU"ŸD Þ…å™pi/¿ã]¸ëí}%åû¶”ê}šôÅÙGzÙ[IÙÑìRóÞgçŠ[1]Y—@R²ÒvVgkq:‰ÁùÌN6¯­%1åU Ëq‹ãO±ê¡Ú§jª4HËBŽ…p’DKµê%ÄÒêzI‹dRÙb M>¹“žw³‹¹Gaí¬×zs^S7Žø õ_íÝQÖÄK€í?cJAŸ=Ëhi–@µ Ä: µ=.ïQ¶÷í|—¬‹Áy}„mcF™‹Ä#Ο ÄÁó¼€õY ßr´|ºf#’²½h:xõÂFíøÒô6ˆ?_eÖÛ“ qDùÌŸ”òÚà4A´Åµàp¨,ÔiÆxhN7<Ф$µÞˆõÑ3XïG}$‚?ó‘v¸" ɹ0•†–—ØŽ¨X*²Û§èI`¥áÞñ/¹@ö³´){R¥jí¦-i11ÀÆ>ZjˆÎiRæ<œìè_WÓi“@qâ=.L~i>lÑŽâQ>ŽÔF.ì”þ€g^H¼1Á™oî"^CÐY‰¿cüüç¹ð½1 Aî„Oʹ‡¬uêwê¤=Ý ‚KÈ£< a)v6AÃ%ûЬÁUÚ`n•+[é9'(OSÏŸ§¤Í¹:%4i-s%Ûy “Ò*Œ»Íx«•úÅã™øÔ—DÉÕ«,ë}wÖwB»|Ü<Í­O|[mænò@½$®§xû0k"fàâš—@ÜqK£¸ƒí ±µ–vjÇ{2–+jË¥ÉFù)ÖµâLβ£­}gs|(ŸMùÌã>ŸBšŸk…Ï„Hí‰M­OÂ9©AëtúHqü Oã3ôÚ>›(â³ /çûŸðülÂóˆ?#ÝÉÙt»µÇg!Ûv‚œqð±kÙ»8+€ûí¦Îœ3 NhKÊK¾9jθÉA–æ ­žÃˆËrY<7V™Ãmø¢X%õŽiZ¹ª øÜ”ú‡4ŸT:Šv ó ÃØ£‘ú|h%×Ü/ón¼3hudöaU.¢³4u—¹è“Í1]ùÏ‚IÝT<£ËÜí /OVL’E·Ô’à$Cá}¡>ïCG¿}áÕáÖBMµ:\Ó$SéTÜm£]}ʶ·ìL Èr"]åsW²‰g.ÎV¹¿f‚Žç N³ÎJPg>åN§ˆî<ÃÌpdJܘñ×ü;åý´á"yÃ5ú‡…æÑÖ‚Iï´«Û5)X+Ry¢8HÑQhKÞM2kã눺¿Ä»X”f Çí9¼äV÷¨H*èÛ†<6¤‹ÿÅÞ›Æu•gÃ#h –²Ã%,–œ‘lyKl'Y–oHr–ãŒfFÒG3bîȶHMÙ ”.@ÊZ¶e+m)Pø ,¥´…eß—?JP(P–ÿy·³Ü™‘'ú}Øy♹÷ž{Ö÷¼ûa’h)0§ûYbÞUç%Ô©¸œþÒÊ”x†yƒ¤&ÛÓ5’$O¸¯[Gìã¥XcÍiibt‹}¼¨U^œ÷…NLíߺy«»È“½n_NM“VÕ~ÇFZ•Æ/ŸŸÜ7ºóoaÖ|5t Ro ×Þ±éF¢e»i&33–Õk9ò.ô%Η)ìªFnp¶\<ØePi†ÜR&‘&";Ö¦•¸A5>QÑâPÇŒ!/Peq˜pšJE'œõ›©µÙqªY_²_Bw* j`@§H5ä¼^ÚJ§ÔG¬i…$ ÚXVÝM¤„5¢òp‘'.ž€f¤Æ2¡0YWø 2²¼'ê<ý'Í )8­’ŸS¹E8ÛÙ¢EÔCt‡Àn‰Â˜}: |(xhdÃbÛñP°Ÿ¸ˆ9£,Á‹³eÙUIz°Å´”ËÀ+6¨±˜ßOBtk¸í—l^á½Ö·ÇYðć"V¢Ç¤§ÙŠ £lhËrë•3ýÐìhklÛµ9Þ½µãõå<ï)Ž´õ*ëð«µÔ1lãæ ¼ ë)â1`!˜:ËšJþŠÜ Þ×!!-´¨e¥†·z•„~ód\XjÌ©¢Œ_Ï ¦¦—øzuHF!KjmðØ4¸Äé5¨]VL}*åÅ´MdB%  D‚š:TÈŸm½ÒBBE“*¤ÆÊÚËõšl/¬À¢ÅUJªer>Š•WJGÊì;Ëáb2ï@yQSt`MwiÝ,³dóðFnüVü;k{.ŬPËýÖ«ÒZ¸XSµ;³w)éRÕXçEWâf„a¢í4Î+•®*‡µ¶Òº@ßÈŽÔ2;¢æì 4‰…-òÂj„šr$0¥®WÞ¸5AäZg©½³ÝZjT¨NqÞTÖg©›JÆ=.+[©A»ÙŸë'å3…mRæ‡,"´tÍÆaô’\ˆÚ !»V&“­ÌòÌ ùñ ᔫ# @o=pTÇ<߃ºaõWÙZüU–fĹBâ7 Á¶€.¯È댇ÍÜŠ½*08¦BÞr´ÕÀäÑg!œ%Ùdå» ”W@c‘P?¹¡õurê/%  OBÓ±òšö¨¬š²Àœ¡ZD÷Ä^°L~` ªT±À\¦ŒdÖ”UÅ;|íDÛ…0¸Õ…‹2J[ž¼ÉÛ?DÛÎÖ–«ˆrQNÏ*Ó³ 6‡ºSó¬[V÷£î’©|!®Þ¹Fqcø 7¯wb'õÏÙže¾wê?1Ët¢$š º¸Å[˜°õ~ÕÈ¿†9e§“P×ì Ö&Lcq6Ëä§©tÉû&Òâ+k0¦L,5¯¥EI~3d¯Ã–CÂIÐ-´ 0aˆ©µnZ¿BYÏ‹oPèÀÎ¥¹,ôªït[öNDÁï騾ý‚djüÇ÷'Å«“b‚?XÚÕiT $ßÉ´ž Â-Å“Xw|—2vñþ‰ Œ²)'´ŒÓJj .bÚm½Î”´G–£óÂQ3#•òaf‹0nTßL >V…Pð4mŒ'„ ‘ᇂ¯nu Ì”tK^I÷pÁd,š¯•5°#Å0WS^ìëåÅ‹eÿ j7¼qaLçyìèÝÎ`IJrÇðP_q§”‰=Ñ%M[ý‘Ý„_`jKò>ÓÀ(ôý,QÖ:%½ ¹¶¶˜ LP÷5Ž&Æ>/5êéÑZ}y0îÞ«¨kËU¡‘e–2R¶¦—Û\(&&‹&îFSsbP¼jÕø=Ô^]^‚ˆò\³gÑ LëYYbX Ç×ÛàÀÁTÍ…ØsáBìø µ(Ö‘ RÄ› 0¼Þhà® ÞÙ8±@JÖdšma`dxdÐô ³ÀfþðÎ<1 Ž·³âý]•Ä SôåEDXª.¹Ãù ùð°Ä%¹ù†–™H©ž¡­$¼PW𠡏’4Ù¦pOÔAZªRÖ@ª¡Âu*G-õäM ìYÂ,%þ˜ì©uT|nIÜ 1w«œÛ€xનA*5ÓÏ,ÍéV"]D šf³Uf–D™žY6kÞ@:Œ‰ŽqÁK/N3Çî,·@&wB6'Žógô“O­r! ¿nÙ œ‰D2°iKiÆ ç$:€>´þ¡fð:’a YrùðÈYæUÈ‘XoKÜ ‰ñð)R²Ð»™ÝÅkw cŠ÷.åbá oãQT—wºOÞÑ&ÁÏ’oލÙ`æéq:z0xü ÿ5Nž9Ç Žæ`fUeH-4$%# ¾m_]j‰ªƒ½@‰×X†„™1E?ï]½ewÆ~á´yQÉVkUoi•qŽ¢K8²ÌÊYOòùz®ëD± *O+Gi´ò|¯” Ì:Xö F—:›²Sy1U=š.j¾¯°eÝÊ––I^¡\Ò*Éò´IªSUK.U‘hR§úSY"—¤€–mJ|^¦' žÑu:½‚„Þ!7 ñoBq§c–JÒ³:‹QFqAìÖÉüó¹ô²61Y¹:K„މ°äˆã,Ýä¨*%J“£Íj¤ù'Q‹õÓ]@v¡ã‘Û‚´g°lbšF»«h]#™qG¹ø™JÌ÷ Ôê<ªªÓò³vÎÆ³W…¤ø"¼(ÅîO¥F†µw"fdð¡433XÜh÷ß…gZ=€ÀInfÓÚPXŽ,'Îg‰uw‰&)n¶·h¤Pþú–ÞE[ö©žeovCPnvñÜaíãpùí¼a܃È%Õ \/ˆèr–ír“êu‚T_QÜ6,b“˜bENGíF6 ¾7ì)ÉêMº˜qñàéX[BÂT3½:_¹âÈÆà,®”DL‘åÍ0Oì+y_ÙhÚa¢€qÃ""˜8…âPvSgè>º:$Q*C£Rêyùœsø.·Ç=iµÎ÷ºá­«‘íɲ·þ”I?ÍÝ%úÓ [W«$³WiËv¥Õ÷*”×û©”&Z)ÓðÄF逆P•xMµ•6ט·&5IT—&u³Þ@ÏÔN¤™X§ÌkŸvQÙú˜÷ Ü_8µ’ùtÏ`ÔgSÕH8“\×v­-ƒ›ª:=;¥:’ÅW®/?Æùq¢½úK,±9ÚfÆk¡.D]4g"2]•mœ35Ö©›ÉÝ¥È ŠIùkÛ…þš×+¿Ô´Û^+Æ"ž~ï±r‹¼eLØÖì:*¤I›ˆ#£œí¡´azœkÆ®å•é‚)$v<ê7mžw¸c2]urC q‡R/ϱš¾Õ”L›©¦Q´kíZ½ì1mÚ‘Â^”¦,G”Oø žÅ`Æëý´fLdÊêdÒü¨/›d”Ê=#;¬'1x/†¬ÌÙ ÒÀØú¼:â6SÅ”äO¢!Lœ*,¾3rkvß½kB—> ;ɦáÍ=µÏ˜u¹É. :õhQ£’ME•+µ\ý;*£Ä~ÏEžÆÏuDá° b^%r]¸¼Ð#ºËQüº{¶D5êö쪋-Œ:Ç9Ú*·H' òê>–ùdcsVxÊÕ‰J¿i³kZ6RÙ°¹3d$2ÇH§táS3¨{A)ɹ ÊÈáîùïÒV0;XòC§ÆwÜ#:ljé‰ýû¦X \Ü9~Ñľ.NtñÐÁ}—ŽONîIÎ=Lîö{&Æ&¦“ýcÓãÓÉÔôäľ‹òιÇFÎëù\Þk#ÿä¶žOÆî¹ç6nèýœóYý3ì0Òûe#= Kòlìù®Ø%ÿÜ–êÈ4¨Çs[{>¹¸¬þ±Ø&ÿ\ï‰bN3ù'6êMλ&ÿäæžO:7œÜ#átì0£H¼æß6;ü2“ýhéŒî)ñXuϘ-ÃÝ)eó~?ÄLúPÕ¯²Že—ÌE2™¹†~Ôúò1ú a‰ 1Ãz“9ìŒR24lÇdxðO7A½ÚCèbvP9Ôk:—‚GÊ­™´Í”úP8•wN¸¹/÷žägäÿãûv9•Û’z<º!j³áÊ™vLWÂ;pÓŒingXš°5AÔ~mÌi)¤·J®û‚Ø/fÇ)+!%}Ñ䋺m»²@ð£êgw”MwÎEÔT]U¾¡baGæ"9lš¨r#ÊøØ=Ç©±¯ „êx®2oóÕ\Qn¶°oKI銰ÑKRí½&zí‘$+(S ­€“ñR®ñ(¬s–À§ ÚëyÚ8'Z·d ޵&ÎRmÙsèK> a9xËprEY#X³Ö"S‰±u¬*åÁW|»pÍ^$£@!xRtPu| UR\.}TÆ`žÔ‹£ŽËo§5âÓÐ÷+PÁ‘óŠð#y±@ú¦¸-°ƒev2dˆÎÑ´XÔ¬xÖ ³ø1ró8Zkp.éBw&⥎cטÏûî‘ Œº‰ ¡Õšy¡›"%±€J5Èë’¥u#ñ%l¨ /³œÝGì§{¢>2O UºoŠ(î~,¨µT&„© ÙY‘=£Éwº©éjl°¹3ÔÎAE§/ÒC"+9ÑI%ή:¿¶c¾ýªuÁ*ª7µ!WŸ\›©E77'DÁbDþ É [ Ì£œS vTBX  }{ñ|¬m2Á°™„“Šaõµ.LöŽŽMîçíL86HþBVÇ)”BL a²{¹‹ZJwñê@WÛ¢uiU1Ц¯VAÕ”æO(‹äiÑuÌtÊ¥Ò]Ô>í)qEn•gfœôiW§ ßœí‹é«‰e:÷TZ&×7–‹¸ºe΄ԨÔV ‰D—Ù]Úi,½K’BÛÍ–F%Ë5ñ®¡@Ô(ý®ØƒT¥VÍF6ŽtÞX£ð>u0%{/)ÊÊæI²„â‚ÄEB@gj³M¥2ºîðêùæbÌàlâËÚÖÒGàù˜F§œ;æ3Ü{Ÿ¼«N)|‰¸ÃVÈ \ip9j§I Ôl7Åx¸ø&ñJtq–Ö ªï½²mÚNé!Ù.%Š'IÌ=Ÿ¶dîñàdÞÈë2m#Õ*d¢ÜÈšõclûN|*¼c «}šf@Úè¶öX2“Êt§”—:z­EEˆ­2림Õ$]¼«Ø$F©§©¹‘åtw1ÕÍ,´²‚NT¦·Ãæ'$!'Rú§3“Œ Ôù*VT8n‹û÷6ÔqÔÒÍéÖH‚Fì.µÞîvÃê=!®7¤g㡽Ð&/MžmÞéŽó€c’q}ãH„ ¢—…æºlѼf"e‰žˆðä®RŒL}@dKŠºR`PZæäHº¯‰'JèÆfÔÈ|ª˜Î"lÊ`]uÈF#˜“ã7e+¾¨KùÝâÅ.›¯iSÙž0§ ‹-r)VÿRu5æ|ªi§n+¨”[(]k§]Õ)Pa2”»´Ð§¼m,w˜6ÈÃMGH.Í–Ž•–So6--9^çÖa&ÑÝ«û@v6Åí,e5dê³#Û¶m´„DÎPfösÖÙe&IÁñº”舶‹-OÛôñ¦c»;ãmØ@îÅêr™æš§íæzê°0ƒ]ÙÉì´ýV¾Ì‰á-……æ6çN¯;õ°[SŸ;^ÜäXâ°[c‡)…÷‰xÕ®ÍÂhÛ¼…ÈcCÛ”ÑöØ5º¼ƒòIËr*d£ý4ôQdÌSÞ0°MÉ“¥ Š× ÔNTÈž,)|ز|CÒRzŠ>ñF ÅLnÉ·É4‰qÁÆüð®ÑŠöIÞ«£ÇzkBž›RÁÆšJÀ¯]ŠD’¼âZPL³9²«äé­¯t‘\%©oÓÆR8ÚléÍoÂÅÝÖµ¹²;û»Ïz¯¾ŒH‚tpùµéážv*m~—1Y®ÁüKצ–„HO31ez4^%K¼|h àb[rvKÜP¥ßY`ê }Òù Æq>zÖ€Åñų6ǰi'ç¹¾ƒÖf­NŒp[6 Ók.Ÿz0¢l¶|áçrZëX%$e‚z¹ÙÚ9R]ÞUê=|Ö|}A]`—n"çûi@ûÈ[åëµ9|Ò×ô}å.‹zl°w—uáÙ›ýËY×è–%uŸ[¹ƒºñ¥mÓvÝ´©^ôsõgå®/KƒÚ—Ô*zÊÐVssæ]Ú™3gÎ"޵Ùbûé4dÜ[åü2s‡è0ó R\¸ygõìzÇ k¶_.ÙùŒ›Ë·¦¬âÝí`Ë•+åb½/ÖZõe‹DñÇU”“©ñ=Øå'öï“wpÑÁ>rOžÇÌU©Æ˜îæäÄû÷Ø¿ÜÁT²·Ž?ÃÔøtg9øñ©ò¼Ë“rÅľÍ^ñ¨ 5b±?¹È Á~eRÆöI,G§RƦ¬ØùœL ê÷©R29>ºGD͵0•¸Ð&Zaä¦\Ë©6euú.®ö1§Â¨uõ,¤‰©°èß%²(óƯͬ#½è‚–SÚm~ÛÞ4l}*Yæ%PÛ8Wž3[nA¥¦`½NKƒå,$Ïš‚U\ ýåF5_Ω²•’¥Å¹VÙ±[q7é”×웦Lç K®+¹`8»'u jë”ñÜf›6<²Ð;x^J*ç8µNiCÊœå\5¬q^«DAD:©ÍjLI©ÉTaÚl˜Çq«¢N#æE¡³¥ó…ä{7ÌXHêíÒ£ZYì²a;½óÁðouú£îï k5ÚO…Gv–4ÆuuÎåÃÉÆ çEYh‚ÙN/J]eWí@¥”š¤©RIÛ46”¶,¹Šœî‡ðeˆuùI,Š#•oõ?§q?8eíF:¨“ºÐÓsúZuUÌÚhO¹U¥¬®st\ /¤!9pÔ¾DQ 3µÖÐL³ÊîÙN®«5[så†EãJº±Ù\ÐFªmq ^ÈeÓgÓ[®ÏÑÛæ¯Ù…Ò#&n쌡ÐJz(¦îTG‘oœõ§»ö‚4˜ é¬î£A’¬YŸn ˆâ‰Àí‰àå,$Ôz¼‰ùÊX¢ ;c£z•Mæt»Kê¤~nκ7ÒZ„ q,Á™×()š]¿sˆ»“Yí}nke¨ì—Ï)Wr'œ³Yv3™ÍR‹ TøJ–$á.à°ÊFd$€™f°³F¤-£lÁêô¤n¦ÕáÊ ¸Yp$’ç%Eš¤$#I1·ôðãÆ¤h«„o/v_)òx¸ZøÑ^ëå‚d•$A"Uû ¥»„ó\^¹ÊçcèÛ¤H=ÜtÈŽg’²˜MØâµÃ›Î— êá¼G†@~˜e"$ÚžP¾môÐÛòüfØè²½® æõµâmÃMYL=¬„(;9F‰¿ßñ®Ôò,vìâˆàø—p¿Õi$êµßоïÕ×YÌ™)ÉYuzóE“….ee§'ÜD°êõ%þZÍÚÕWÕÎì{–[QR7LúÙf·–=ìêü¦ƒ™vÞy´6N&Å™r-ž>FEŽðMd"µåM×0Uç–@bWz”ŸÂÓ‹Í£i·Öù;±*—’Mƒt?ÛŒ¼·zzª&n\m£ü§Ù4_ÀÆS·Îß¼‰nö2^ÚpÚÐ‘á š1ƒh¡Mª}²ipP‚¹(w|Sg,YíÎRk¹ÉÊÚ~9Y¸Ù˜»NŒjFÞho’˜ròГW€ÍÙ¢ÇsV³-xS½¦,*ÅÙÔÛéb}9Øã÷MÄñ©D‹v®¶Ójp'ÉÆCj.­(Û qÈß±WÖŽ<=a¤Îr5fÑîsh„»·x Ïáuûâp˜uP1T0sn5âûßìÐd°¸`. ¹léë!@¬r£²Ü©òm¶ò!­M‰ó½¯…ê¹Ü"ÇzElp¼–~!”‚P&g‹í½ñA)Tl÷£1µüymlS’t7å{`kËzS÷¹K™<ƒ:u9¿3ï Üyd§;¬3„oËÄ#Åm H´"èáx*sUzT3Ë '.«Nöiç÷È”ã,ÞÁI#AJ7sîPP°DzNÜäùÚE„öòs\–¾* œƒ´æ¼UòQn.“«E¥^Ôa^%Q‹‚'e§y8µó°©wâˆ9Ÿ¤C$õ`€œ¯vtÊQ §†qŸ;DýÄ.žs…÷8Ñ—b»sÁ\üÀ|³^5¡µ^£Ì¢iìóËIY\KU;°ì1mkß9DÜ­…8½‚¬5&#MöŒ_h†1Lâ‚S ÝpzŠL0ù\°"*=lú#cì€]ǤPθã“£¬&˜Ü?5˜Ç''÷OÚ—ûvÙçƒûÂo£È‘ŸšŸ¼tbl|h|Ïø^¬øn·ŒíDzº|ZüM÷MñûöNOòí§©.¿ NOONì<8=î/Nïøø¾Üס]£Ó£þ·©ñ±ƒ“ÓW áýã퟼Â_Râ4@GRŸ‹ï”Ý›dÂã¿îœšž­‘Æwül½Òq!èØŽkÚÇî÷=¨áÄôÅ{é§-¶Qû÷M^q`z|—ÿéÀäþiT<üijâ¢}£Ó'ÇãŸÂ[BJ9@t¿9f£é|2¦ì+™%‰ŒÍNFì~8ƒÝ¯Ù‹âK¦{­›û¦i;ÏÝš.“ææô²st¡ð̆mð.ÚÎoµ™Ð¢•&Çó>Õ¼dJý¢5&ŽÊ[3’†É´dã–óôŒd“Næ´¼D±ð®F;s»Õ²gÐøÃ9Õt¯71eéx|Ó°{W‰^^r¼TTžúÚÕßCrí¼~AØÅìå+À9å%bÍâÐòœÑ0…]î¬ÏiC=*¯qÞÍÓ£M]›³N´Ëstlgž‡2Mì¡Ñ ‚~ãᄲ÷HZ¤qE«æ)ð{áøS’;à )N±),5ôíªä'fÃ~"FC•þ[œB<óæNKrHþÁÎi;º>“ªóÎø¾ƒ{i½céI—ÞÔ®Ö·¢y)C™5LÁfÃT|sF(ÕC70ZmˆP²¹)ϨÉIH#¤œ)ðä9ÝרÛÌTÌñk òÊ3ÎMË0ϹoʨcA¦”UìŽïq!LYÀé°îP´JŠ'iâEÛ¹(½$Ë'†ÅŽÝÑ´Ÿíf»\WÝDyŽ9y q£3p¥[-P0œ¬cma~2sQ‚¸•ÓYB$i³–؉B²‘4T ú9çäÈ©«§£R(WìôØéA+™Ù¯^† \ahçMëgÔSŒü’ý"³ÜñÔIÌrÁü'ojÖ)WI‡“ ½Á*á}aìx ;øTº;# >ççcj­æmPuºœC—c¢òS=>˜…kbí=^nU¦xJñÇ !™ô’âUÕOû]™ï0.ý8;„‰¬%ù:ëÇËËû76xM°¾šå©'íþUB ›êìQ®{Æ-±xDÖ§åÑcF]x Q²1ìùë’Ê‚êØ%ã‰ô9+¿„¡¤+jÓ£°•Z¹éýÕ2”_T JÇùžªä6ëÈS("z7Ïy[÷Ñ:Û¢›Áöb­®Ùñ0 :®Â¬Mëjaçn_•31Txw'rcì;˜Q ï¢þ U:~wW¾eYvJ1¢þº’–=áÌÅf©‘>š¼&Šâ#¤êåRòÓ†Z'ª9çhÔßQ¯2iÏÍø®ÅP5ç9%pâ_ÍS\êš‹L¤sǃæ+!³YUV"uÙ!^.™iâ X MXD;$ÐOPWÊܧÅŻƌÆh5Ù±Ð9rãQïŸ"æD1g²Åò2z‹“5bÙa07<6†¼­§ßÀ/<è;kÐõ§,™WqÍMIFBi+h(ÙF­éÈ?šÑ st1_Gî "…Ý‚°•, ¹Ôe>çD/m´J‚5º-JºV+·ÜŒÕ·ªÖYEßEÍ–›Øæ(&;¡pµ5  #s¯Ôý†“ÏÒ \ÊiÅÃÀ“·!¹¿ø]‹n;JA¦AºæEºåUÒÀ£åxg-"V¢Uì\?¯ç먠¨û…7ÐHù X‘A«l~,xÙr2põÉÁÈ$¯‘ºìåLm¶ÌAœúÏO/aáÖ.«×Ääi O*•8°£øëk³Žu*ú ÷6ŸC´T-X¡N—_è„IGùɾ¬yƒ6l×$ÌKŽ­gQƒ8µd"`à b6¥Œ-:qògèäù7a+--Ufé7™ÞHíó'¹œü»³G@8Š`æ¿­CfÉ ‰k%¼î«œ=2ͧäãUÝ¡å˜ZÕ×Aߎ—S×7é«Õž÷öïr«U^VNËBÜÖ™ÒÍ|SÝÛ#QAyÖèwŸöªd]ÃïcÕÿvÙ/Å÷…/ÒW¼3 üÚ›õU&’Õ¥dzòà¸;‚¢‹4VNì:è™OòÝá2y·°_¢ =7{¡™Mvh­¦Ë;N•]"³Ì±4Ș$* "œ‹ªÕTÙY>äuÖâŠ=m t±q™XŒ&Hedâu7š©Ð¼Ð)¿>S­6-„œl›jF2ô^ØÍèWÄíÚ-Œ/­£]!ëûP£fDF&î¨.#ÃT×Ó£²d½­µÌ­@'S1|ådðÊœ=¾G¥•v¤yã·zÃ*·C5{«#ª–ºj,‘ï.þK´"žãñ~ÕÆŸp¯s:J•¯D gØÕ…¼×†;PTÏðJnEwÞ‡_;bî.÷»Ý6Uk6ªSµG»EÓkÉJ_ßHr°' –ãªKîÐOüR„TSô¯– ¨%)í8?aÈã‰=Â1'¼,¸{få`k™r,ávYE]•ä猌?NíŽSšïsä´¢†a?`jtОoq¢õš¤õaüÒF5ǃF3 {Íýe6ÇUÆÄö×f+¬ìp²—´¹V¸Ç[h˜Ë”DÙ r¶¾µY® |1º1™^@ †Í^ɱ©ä7Ìž¶^÷£aÎY<¨b´O–òUõ4\,-‰¸¡¶Fýêœ_Eï‹6ãõ…¶I9N´¢Z»óJ+e32ÂÈœ2ÓsJ\»è[œR‰TU¦NÕKE÷®Ì¨j¼L­ø¿5ˆH¥­v*+Y ¾r½ò„,îŠßÕxL‚êLq¦ŸÓ¬Ï˜˜’¤Z’3(Qe¤2·Q£ù¾ÕS¸fËÈŽ’:[Ë2zçæUbØAÿ¼:²óûFÞFÃ2΂åÖ_hµUV  ­úäkàŒd²í˜ˆL>Á€Iž35 vÞ–†Þµ¡§\É×>ö§uY‘hhasþºÙÍòÇØup§ÓV¢è‰,xfè€n×nÊ!Aj–è\uŸ¶˜°®Å%Ãô°A-ÕÝ>ØÍô˜VÂî%—Í78«Ù8FÑÕµ k»Kñâ-þ+ŸÄ"B·˜‰UÇS.LÂèóž”Ø#eŽŸšºg ³ÃT|)²,˜ßS`kPO‹ê tLbXÜåP…`F[7]R-ÇrÔɲÃ)»5£”O#sD´™nêÕc~ë²üöR{tóJ-„ÙZJ?°dµ ö›ÿÞ¦VUÆÐÙ™Ã2å4Vª[çSÒrÖfÜÎR0DŸ[kÍY—ÚB)%KɦR²™ú~™y«²½™%öÑ)-tA<:8%ó©«žfZì0ÏMÇ¿æ_b¬/{;qqdš+Š(©»¥áòyÄy¦aÁ¢ìšz`(9̱!R$õ;³æ±—ÔêPG³dÍv¼²¦Ë]”eä^¡½ªÜª/dbÙû.4-ψõR$q°¥|‘δ ³°øv&(]'F<»Å-od+Rc9ÐÔu›é|<…ŽÐX×Ýœ *Ð89ÖfAWU·›ø}>#ëC:ofii£Údä`y¡nÇ›Žºy«2õù­¸_¤®ÑOަX7P…üÕ¦wwsTEζÒ~à™¢G5råtÅ÷xÐRºq“”%«©œùÖ…±Þ –á6“2M´B Î+Ø ª;Ì®‘jçÉ)0]Æä¤œîz?ã|z½@´‹Lõá`ÉʲêoÊOÎ ñÒXâ"}…`™{KMÕ"­$’̶áuI"žKNšµŽWV{Ð6ï–ð°Ï°n6ºôäZÏÃÓ«‡ùW,êÕ¹Ò°²èçyà`hG,Ð>!×™êÑ,%›.EVÌÜá¢D3¿6/•ôž;|ŠªÑ"‘é2ÔeÚy6„²]ãëš‘‰sÌ`ˆ7ŸœŠwÙSš<Òç!/p3ÖI„ É9y” k±&É,¹óË|ª:%BcSä0$Dï v p°¡ë¶›už’ãR¸ëûž¢c·ÜüÌ’1Þƒ[·àV)¤wÇŸ›—«¸k`Þõ·zЕ½2)Ùœ'´¸©µùX5æF2ßèAüêÑ2%âK0À¿FŽe¥ð€Öéäê$8QuÆ|ü(Hrg¹ãJ·vI8Ãàx€³U×EsÐÌÔ˜qKÕH×ÚRë×q}Ö­ç<ç£Yc‚L£;èwóA¤k¸°³ !b†¯XuéÊI*fGGÙÔ .[[á_°ŸÜT¸˜Îˆ9º+¨Ü:yäW¡ÔaéŒyGéCæxa•‘ÈÂyÕSP9´-d¼ykt•*ÛÁyÌËdw «4ì³ayîœ yn{šï+Éǜ⬜Eå&©Õ¸ò«þ±\žm\í¨œdÛZ˜wV°l5 ;‚S6:¿*HºÃ}•z¹åö• o¥ ²÷Ë›.•·wx¹DÝ|ŸEP²²$Yîrµ™º9Kš“ÈZ!)¾Ó[’ßÌ„ˆ}ÝL×0 Û• qKDϤÎ9DîUr@¦{Q)mŒˆJ%;öÌk’¹Â æ¬ðpÊq¦$M>¡—ΛÎÌ*,OtÂä=Iøï“«‘öNyâ³´çO•:V™LI|iF:…’s ¦ö‰× xÙ˜ÂAä€v”¶;µ È¢ï ç R¢Ð+½€wN;{è¸Úد>8勪Ò3êÉ9ûG.ÍI°PCèãrwŘmqqÖ"é­ ~;Ðf×kUot BxRÚ •=¸•¶m€‚â"VX’y,,šDÚ®ü¨F.Œ¶ä ž{LTNœ8uÇÆ cÁ å\ØŽž”YMî)œK²c€¨ŸBj4«¡ ©ÏU_ÎøÇõ˜#'}†€¼UZzúµê+9bÉ\ÏoÇUJ.ª5L´–÷Ū:3>~OSÁ‘ºƒHw;'̶‘Û`Áé86ŽÆ«ÂùÒ:1êM¦‹úÎ7GºÕèr͹ºtNä?_C‹—pø°?¸¦lóÓÙΜp¤;£«Ë¼gÛiØÇ@üìØD<7¹ÔâƒVöÈñGÅÉH’¨MíKFL '*K æ¦Åéì%2.–²9C,ä¿ÎçÏú3â‚øc–äñáâø‰ÅK³ÉNÊVßÒØIýmF£ž-ã‘%>öX2e{ÏN»Ë9¼s|b±ÌáóœÝ§fN 3¬MŸˆ‘wÅgþ5=¥R+À‰t-Q%XûðþGù›œ8l¸¦óÁ ÜEm;†€¾Ñ2Ø!õd^‚é /!­„ðD’ÕMæ»P^o¹VIËE^3ÎM§R¤K¯õ'sŠ!Ì”õèŸ!4XÎÕæ ÿ± s«,ò€,Wé(,‰âe¾EŠÔí8[/ËŠÇ3ø™^º ž|()&xãŽDN'SþG^˜mIŽ$Ó€ÎLŽ¡©QnRNdrK?ëö¨Iœ‚óvåX…ÎvI“BýΗÚ&îRt…µ´z¼šžÅ­àÄp]ÔØ&ÚÍJ³®a2tRÄLZ''m)/«iŸyw .m~IõàáiÀe=0 îôi>DÙ ºõNª›`îr죭'š-žv)dS_™\·ˆé´çäPv§ ×NN¦Ú”éYZ˜EFk7 “·^f} ú4˜ŽÀ†M-É‹­š„rÚÛé`^Úß$›æ¯ë(/)C˜â]sWn’,YíZvûd%ˆ>2I7N4ø®ÉcÙ^\4KN}«©šÒBÝéèœA>—…q£Ë™^Mrsæt¤9ß!Ê®YæV.Ed¶DLᯤNqJ &œL¢3"5/b)­\•sPŒ¥pš%‰L<ÎÉnèû,™8ìŽï±¾,©{¹ö ùP=ˆ\(7+Ê`š4n=‹6h@¸g{3 3ÜÍh*Ó3uˆô—³7\ä lâ<uKìò„tòP)¹‡4°×nÑ{úf†RŽé~zc+ // ‡MÓ¶VJya¥dÁq¦òª ™½V¨Ñ,S²:« i{Ü´Ps~›5¿0y&å‹¥|-Í?›f~ä×­³jj,™w°ÚèÉ@\=bB.‹¶É”¼iFÆÛ´" é*ë*Ò6w£³Ó^)–ETý =R‘XL-ªMFZmŽÅzØÉ‹Gk¤’#o¹ÅÔ[ÖÉÊÇ nãd¦ÉÓ·Ýêè—Z¦r+›L\ãˆbÎÔôlê ,®3rû—X¥pázíÛ\K¶,ºî"|vÖŽ‚ÇœȲ®Ð<6.޲Pn”çä‡ Üè üNçÆç$éÙ‚AáígI¶EÔ],õ|%q?';äô5Ô˲]¹d>©Zh8ý íš ®ÒL­ÝÖµ§=¢o¤IO)±3ÛtÊBpKžöŽ{âjÛ*gƒlp>½¬öè%zߪ[¥ØcæýÖågé¢[¬ò‹š!À¦(ÀÜv–$‡yÞP²¨y´µ¥áü¦íƒòÕÏ-¥âÍM7@fCç­3«ËÛèPZtÎ.Td¢Áoo7Õ¾&o%^3¿¯'û‰"û[R'ih3¤òV5ŸØUö²’B½ìhÄ(°Ï"A qó¬ò‘½ËÚ# ,iÛ&»¦ÁLb_Óa>믜û5wzO™ý±Ò”ÕZ¥9½øH»q£1 @Z®ö˜MŽè]’†MVÞÀÎĨ³f%µ7Èä p¢²E½®ú­87+ðå¡ £™¯ZXTÑnçÁÝG8Ö ‰´n Ú™ysv£ð3‰I4Ô@&|eŽ–ð[úrT¯`ßH-(³,ÎyÿS ŒL¹üRD†3ŽÉ?j÷Ί“ó|¬Á‰¶‘ŒB‘$ÖƒL¨ µz2Iq.@âêÄlpÀ«Ü«3ÃŽofÉ!H-ªÞXÌ4ÎÚçŒ^@ËŽrŽ…ò =Xi{Å9 îå3‰Ò¶mD“e?¦£ôø%¨3õ®2Ôêw2°¸ðeÎf<œÏTåŸkÕtò²R•"» – ç:0r<²í¿9‰Þå×985~düòG0ÏÌñÏ9Zâm±Cq³-°Å±Ä*/¬Hü(ëAc :íËð)kYœ¹¾œ5†èHŠtŽUœf)Èõ=Q•èÄf—é*b•ꨘ?—ÀëȳeÊÎ3Ü2<²I½“ø#˜Ù**Apˬ”,529õ”Ö'¥ZÜ‘SG&Æš‹ËàŒæË­d]•¦¹_¡3=v?òSrÿZíèÎepÁót³”,?^TkOÕæ¢[ò¯X§ïZt`‰ž‚“{PëÌç˯ºž¨B×jÆï£[:_—7ƒ{èÉÊ ¹HÉôÊMú¨ü¡ =ùÌ?q™ãrxb0¿À:§óAYÓÅ1mÅx%©ÑQ¢Û?Ñqˆ{”zygý蘾\oulù®ÏV"š€CßÇ}YÝo ÅßÜÍöEþ%ŽþmT©¦¹âˆ‡öW{¿6¾0Vz+ä´â HÌZézÅì;qÇv¿};oôK}´=Þ¬ö¼º›´›½.^\Îö5»ôM¸ºé29½ÇwÄÃî朗´Ê[uâEw‹Å½)Ï·º ó‘ßÜQpØN¤ K ‘Þ‰@22öq®òÄŽBà §QUµ÷@Ûòdµ9§þMX>WÕ® R’SKŸ!Ûy•é}·DAšMOt’ª7Ï$Û8Ñu¯Î™ÂàzîZ¹»6—J>-}œ7~áÛZ5ËT¢ÆKî'*"Š·b•‹ ¬]›jN™òºu;t3Ÿ5Ë/ÿ,„,âÒˆ8ªjŽyÅPm&×XÓX–÷·kjHøÊrõXÙ°åMÆH¥Ukã©à‚%.–»]£LÐgáõV^‹Ôv³&ÑV‡ˆGa¦¹˜Óš4dt÷4¥›µÆAŒJ«r%mˆ@3£ª’À‡B¸¨À¹a¶Uæi¥Œ"%ßž`Ž@›F­>Y£ó0¯mÑÍÔJF6žwØ­Ân¾Ê‡äº'9‡nbçi¹Ó4ÙD“ ²n}²s¼QÉ¿oà!‰”V«i†‹¬Û"Ê©_Í÷,ÔÈãkCEØÜ8tmÍô¹¬Q@)b‹l²RGWG ®Bllë¡L¥àª 83uðäõåÄ`ó ?‘cÒüÿWËC¿ÔîY™¶üÔ1)š:€²Ê‰£r)Mí“îÌ‘¶Æ`p3ó&Œ¼½c3ãì ljàôQzÛð©‡k6T0¸óÞ¥&3¬VÒš°fÀNoj†Ùn¨-ƒV0&³ê=pr%šî LË(ÅHï$Q%ˆò`2A×E!ËrÊ‚QÉœ†‹^Z_ª]Ž‹Õã‹!ü5Löny CåY¼„´Di¶`ŵ pd¨ kµ Ħm{éRƒ_›ˆ_:µb† V\¡|ÉQ%Õ?Q+y2î‰E0ë¨ÀÙ&‡<ùF©HípbAe“‚&«]Kòˆ³Îж[Šªµ¬Zz¬™¦/ÚªÒŒš‚î$4NÊS)[ª-Ñlä’­I:*ÌÍ⧃Yx:¿&¦?­–ôéœ4ØöîC:ä%B¤ç:òE÷Nìë",â%/Ï´Ð1ÂG@D–3씡èÌu)çْƒ÷¯‰%ßP}|êç4y™ø ÓT¦Ù¼h*é¼&â\Þ}VTcN Ô]£Žæh‘ŒìHäÍ@ßL#èô.N#ÒoTo®xö5 S»V¥•‘ìrn]µÙXÛv šK]y)&B®ÚL)èƒ(óZG#mÖö\o8Z"'±ð¸R¿LñcM“ ;J°ñ°š„% ³{e[¢¦Ô\&yØj¦}à§{ÌØre>­3…›(5Yù*ìZn”ÒJ²WË^¯/î!ÕŽÖÐëÌK”[4­¤N& uZø%-eueðOøÄΣYÀ™Ê¿ìqM=_‹(ÚÑ 7fÞà(uI§K·ÛRtCÒüõ¦yñ‹Å÷UGŠ}µ½Ù‡Hf–î¼Vv•ï`“€×·Ñ·®¥“З$Gâò;é‹ßìàH2€¯–Lˆ£áŠbÃL`D`ÒY3©=sõˆÄû(ʉ¬ç^íÄs¢^›´]…×u¾6bx õ®Áòäb»e’`®]þŠL¾T”½µÆ1ãmbyo,´Ü?¾C7^šb”É5Ê™"%nMHØÉ;å5g;âlÕm‘ŒŸÖYù‰Õ’<ÌlU"Ÿ£&%åoÉúõªN—¨§Ý4¿Gß2Ù\­B(½³*µ¹l¾½æh&*Hƒèäù"mº×fñ䤕ºØž·ƒÜ,$Ð1¶-îKgÈ+D‰‰X×JÅjjÒã–*îq¥0Ës9¹&*ÿZ}vKà+Цá\íHêáÈx[ÜNrsC¸]yèñm7÷:Œ¶vÜŒšl»g•õ•Z*ÙBÔ_R½!À—ÕŽ;¿‡á(*Ù6ƒv«,bjÇ[,› 䃴F1$iÕR÷š0¾D×rw q»‡çMkGú:éȽt$Pç×J:”nj8ì±-H»·NŠ\Õ`uœ«ƒ×®MÍ/µ«ÍãðR‘9R+øµ,¢.³Ö±qqKm\ԫï ^ÊAÑ{$Wé²nSü¢H •nÕ)fûD&uîYE'¶Ï,{ŽÝ‹$nƒ2‹¹.òôUŸú°ÑK‰Ãtâò3&uÚ°Y/¤ˆÙb©™Ùÿœñ;ÆÎ5TX{þÚ¤Y!¿pšÒæ›ç¢…Å­¯$>bê Ñ¤óR¦Aä$€ð¾ÞæÖ,ž`îB±EÈËÂê²ú¢•–¶ÃµO“2liÍ#U‰}R3>}ZÖ\@ê˜èã]0sÂÎ'æÜæG¢„t²å&‘4K‰“QR#×Q3ݦd¢á"™&͊ɤÚíèY$Zês–ˆÃQz¨.Åša¹ai™è1iIˆŽvtV+R…zæeUûcAcMñ`y>«¶+t8åæˆ&α×ev„Ò0d}¼œ£0¾¬Ùdᵚfðr5;DÉÐ àªìrˆêyèÞYÚ^\// ?îdOŸÌT¤G/—/Ä}¢]jéÛ%SÍhZöš|ÂN•)ËNk§i9ޤÃMƒ§gS¼VÂâ‚BtÈc’x²Œj[­«8N“Ü‘xòRPoÕ¤"ófmjdcæ'8PšœqŽ+‰¤•¢.oÌ 6¥\/<tg¥šV¿q¬Ö:ãU>&ÈîµerUèŽâ7c¶s:Ö"ˆ-NÒ¤o/Q,ìŠK5GŒî‹ò^FÙ„ÖÊÄrhTf3(†–]q®ðNL´…§Ec.#Xc¾¨T¢–¹ûœJQ„Ó\áÔá9Y[²½e6=a/Ô!¥–hÔ&H¾ü ™¼'rÞYMtRî(¼.tMt¤–™ä+ŽTq¹“—c“Hêµ ÔfºŸNXáçù€•Èwkª$šêêg,B¨' *ÉÌìŸ_ÎLo Yùaœ½ lÎüÙÞZïFe@x_^Ä”ô‡èV¢Ÿ…óàî–X˜æK,=?2)ö£+ôÙ .àíî7ôn,%CÏ%F;ø´fÊ»hËÍwJ¥s˜3¶•ÔK(Eïò¬¯¶µò™©IäÕ¢}ðV' GÒ˜%Ê"EH§ Duv®CáBda«X¤´1ÒY”#HMq" ³pé15­1ï,ÀÚéÖ,ÕxóϘ»ÓåIŽ,”èÛ´¢I˜»8Ñ«–4²0ˆêâ;uu7‹bt?ÌFGí4g®"FŒ( J­Ljr>Á9çØ†BÖ‡eÕ°Ý˃r~’€*"ç ™›×1Þ 4J¼é“I'Ð`ñž%öc–PZŽqna³0„•aI†óõ'I«À¯5x?§—d£·jWi€\Ê[Ž%ûb‡•Å&Þ.uUÌ‚#BM’ò±2º—(‘Ħz=²ý’^ÀúŽ8 ig—/9€J·drúm¤•Z}Ùl'Tp”‰%*›ÉQêy‘ÂDäÔe T¼’T²ð&’¥à,é±Ð«XfÓ˜v —i¡jø¨Y2ÑfU>„PãHçH‹/.l² È/=½6“0f^I¶iÍVGo;@$ÅHK¸ç‹Í„ÛÈ8×Õ8§y¥u&8ñ‚$‘¸ÎZbŽ·$Ý3ää–úm²žÝ.˳–¡Ó8v?ÿnÐíÕ%=e®1§>KÓú"';Q'fóå£l~šãT\2éBžÌ±vù8ë…x7•´eWºÏRHûBÍô'f!¬¤ŒÇ…æŠ;ÆJ÷X/w¸£éùÉ@«–§M˜{z˜:÷çè¬eºqˆ2ﯜsÎê°^}0iëÍy„²ÜÎùŒdÞûDÁeµ½åd§ÅbÓÕ¢PÇt¡G÷²y3¯‰S«‹t¤EÄ<£lqe9–£îr»…K¨B)ϤrX­/‡å4Q­-mÉq yõLïØò¡ºš¼ÈŽ]¦ FD-j£¹§ºxẠJvЙç}Xxˆ‚b.¤¤Ñ°…ªÄÖyþˆ2ï›™lagÌ a8QЄSÚ—…HI2^Z(G¨¥NO›(…vÕ6“×tV[˜©«‡*yb‹†U&¨¦¬ªuy §¬dŠœeƘîú²ÚØãIÜ¡›Ì𠑘|üÈôèEG&v%ŽCH]6T˜õímöŒ§ê’ހߋIîŽdæ÷õ€†Q'‰wÏ=$£²Y<3LÓI/¥ú.¤BMÌ¥Ì?Îܰ@ƒÊnÜ8‚‰KæÖ’ÔQy}í'O³Ô%OÿîÒ¹²s¹H†o‘ŒÊ¨¨=NÑ&@ªF™s²i€»¤b•™ ñ¤ãóõçdÈ€k$„ˆRºXJÉ–Ó픕¶iDW<=PÎSK¤³óT.gí3¶K‘HeàåìÌâ#" í#gl×àötrbšY~µCDE"®ËA?®ÍÂ>Ž¥Ý@œ³ôuëAWÒBëCÅG%s‹sRuqÔëdIC±$Ê9£hYÔÇNQì{¹J„‡wÛ´ª£ç¥¼iúD;}Q÷YË.×gÙŽ ‡2P…Þ$À³-¾ÈAÏ/ŠÈ= ¼¦MS&#}ÊL­}¼ÖÅɼ¿L§nWÑûçËä0!»ÇtÜý5ÔZhX­Í¥v“ab„£50àæÙ gÐڗŤûƒk´Uh¿º¹?èm¢« Ϊ5xîttyþ-ÖA.}¬ìqŠfc”y¨:Å["ñÇ’"1c°‚õ¾l²Ø.R¬œH–%žIžE”)7„­¯”p­ü‘†*‹¤ä´Àôâþ’÷Ç#Õ-;¨·Y½´i£¨èÙº½–ȧê[ ÷ U‰U¤²k«/.e}L̵Hšê o;wÕ*crP´s±7‚2×à|s‘’n·­©›ßœ3³Î²B߯?ë¸\—cp6xwlÏ{¾CÝ„¢¸â¥×%†šl‹:R6@ª5ò¡ª"ÐÓmKE‹ýsë\)ž[é±TøÁ0[ñ˜7ÚÛÜ6Z;‘fÌ“;öCú°ã ™IÖS¢]£ ‡¨Ç Jö!¡³¥ŠQ#ƒ•“¤·Ç$'g‹Žž9ìÏš¶žØ0<¼yã¶ÍÛ¶ž»qÛ–Á•|k¨Ò. ,‹^½4ZfP—ö1ÿÂ'‘S#øNŽ8Þ…tnž÷ÿ9‘òfS¾WwÚØ NtXñkŒãåî#¤—mAˆÕPc;²¦vV†KÚ´@l›m’ž‹èØ)öò1m-¢ÙÐÙF­PŸ|ÊTË‹¨åbrhdËáa=Êa/$af¦rÊg1â‚’y§íL×;WIVŠ(ÁU’*gÕjÌq*ƒ¥–HÛDw‡ç†ýf-gÄ“Ð÷Ë)ÂÈ)‚÷’”bþv\"ÛËÊì#éx0giÔã ˆêQgsÚ=K.ÓŒM <˜vp9qªî48­ûZQÿ7Ú&c.Xw’™¿*©rÒŒŽÛŽ+ KÊ•åôIZÉy—E[•Šäî¾Èú¬ùZÉÙjÐlsxÞt‘fñÔ·dyÁÎÌK‚\ úÚµ‰j ð‰»äºÄX¹èt™UæhQ•ùÍK‹¬WiLYº‡èE Ésï5xPä Ö;¸&ñçÊ^C5¸–g Ñ5â*Ï?„ÛnrÍÞrZ¿6¹vÐSû”ÔÎ4úÕjË…‡ÒÏv<˜p²°šl÷ð.hTÁ!ª! Ó\Ü‘Viâ\T'ïÜM¨§üð…•¶|³øqJÒP-»\÷ù ùIŒ ¥]s£,R4]*¹:Š„¨§BZm̹šHW}9Põ*¿kÞ§ùÁ 6¢A6~0D¿+Öm[éOlÒo9ÿ?ÒGº†‚õÀÎÿóµò±åú²qFg—_Ô•æn6)9BÑ2Ôºž¢Çì»ã‰.³{¤‡êQóÑz]DK×áóÇ[t˜¦’±Eâ%؃…ò†'—æe%+z.h›·Z -·dçœÃq®b¾÷pUÚºNl ”éJpdRȆ?œ¹ì¶så°Ý·È1)zT.T…F˜t:Ài&yòhí›Øü—‡çÃUJ‡"W/™>fnvœ±©™6ª>§—äÿsÂzfv›»hØY^B;TT Rï°)«³&ÎsfŽM]‘% $Û¦„ c_v3D“@‚y4lÚù´Á܃©—›qv ^ªá8RÕÖ+7 6YFÅù˜è+7ÓvI÷—}€6ÜЮ½ãÓ£$#ø4=¶ç‚díÛ¶Ô s™qˆÖªÅSÒjk58BÉÓ¤µ*´†9ÄZ¡œ'§8ɬ$7sÃ_ ô¢BEÁr0HšéD²®å"}‰¹8&¼Jž‡¶3!]I¡”fž·—;5à°ºúLSåƒåX%Û­ZDh”¡É ™»TDÐR@ÛÜo¢jSŽNŠú:}v3®sîIJI" w†×Iš*GYùíI‘SHÑñâGhtˆYœ©i~"ÎããN+F!Dˆ·§ RÉç öç" òb-7Búcïl,Ð[³C‡õÅÒwh^íD¥¾”‰T”?"ŠëÞ¯‚–pL3©éɯ7Á ™9î$#5öÞÇͦZì3É`ÃuCKs‡fÈá+µïfl^.•pÇ2åÂÿ cÊ®SÚ ,•I!bNœül³=‚ïxÑÀ Û$IK¢»¬åyM³€§ º •V»˜tNÿÓìÊ•ª&fÆ D@'2Ó^â'å«ÕT'„ò;a)‰£á+yÔôõT7á”Úâ¸V;Qfͧ;ݼv‚Îõ&®K¼9Ýéì.ÜVÓZLÇ%£f,»@¬Ä6&;“¥;l -`#ÿv!©à¼ªÅÝ´7hBðâÕÅ~nû¡ ‡“tò&ÕjŠÉ~©Øo¢ ä½ÃÉþ±éq[¬tƒ§—’C;Þ<q‚r†xBÚtØ¥î¶ÃËwî™/ž,îrÛa¾Fµ‘ýNMÔ <Ïç¢!µ–8uŒ0͆€öm—Ó3ùÁ혤3´ºU^ÆKå‡íÅþÜ{û¹6;Šý”B¼ÒÎúû]¯ÈzñÛ:ëù‘’–Ó¯Ô G¨v˜Î&´ûuÕ³ê‘j0UcÝÒ.,‰~^;ºÞ³—gÝå Æ#¹Å•Ñ¿ŽÝUÀ—¥Rtƒ\£"Ïi02M %—Êf]³M'$³`Gkƒ¨=ö4 Y¿^ÃüWó„:f¹)yÖø"H{Ýóét½{½°¶_&Âÿ»=ÊÄ~†¢ç££YHÛåtÞêÙ!l\x0•0 ¹£‡+‹‹ê âŽ+â[MJòËÔx¥l²y)²æDO0•ᛉ0Åüİ:Ó[­“nr¯$z {)ÔÜ•è‰céçÚvÖC‡/@1IÇ¢%(=$7ñð=VÒ±*aŒžEw>«k<QH„Ø‹;¡>Ä;©°æ½óýbT’uÔ[‚ ÅW‘íÞ8’y>0âl¤i%c»™½‘É0H…öKrÈQé0ªÂ*ZfÞˆÁ!b@,å8×ÞëvY÷ÉGÅ–sz¹2÷)¼ì˜²'V 6Ã"„æŸõ8U@.Ø!À<ð°õÀXò›ìôEzõ}kîu&)ZÎvsQO&ë"› 4(†°¥GÐ:{|¾é*æuјhŒü£ ¹ «±¸27ÌÇRO#/ã“sGM«K¾>y—ùzzÿôøvËaK&]$›ír£â­…T(Ëªq’\ºbW‰?î™*ù³‰óüerœøú„J¡-Ó½ò€d R¦èÝY¶¬QùK3)å·¥ô™Üõ¶äguVHAê@.NL1A„¾³hÿž*G‚“‹¤¦¼ÙÉ•)íç#ûwÇWÜzš±´zßø÷$z·ŸºgGQvsîXŒÒ€20ƒ:ÉÒmÀtÊPêH‹;ñl8ÕºLd])(‡¾ñ›fælɳQA=i˜tÜuÊÎʬóÌmþ ­:î¤:w»OçW§Ûuí!”@-ïý&ÔŒy®fÜGáíë×w6Æ1RÒÙÈüCÌnNí ^–²Ô6]©_TkK—ãó‘]Âÿ%ëºT/ÿÄÆ^ÏAlµ”Ž ŠD |™¬•Uê}×¾¥ú*î )\ï»Hr]Å]iÕßT ®º„íŽßÑxñXºTÀÛÕD¤; 6—¬s‹ 蹺d¹kD—åø&VêÇyÞðÆá­ºÝ±æ€š˜=ŒŠ­•£Ú‰p‡.ÓÆz1¿4àbæÅUÄè^àèâИºKšéB_ÂÇ™9.wÔmhÓæ”ÆòîÞù–Ñ$> ›»l”9°nÞÈQÙ̇´ƒÝ™)èØn£æf.¹,Õ fyÔÖ¦ûµ‹Zu‹íÌ,od]U¢yF6 òNëõ×ê(Â/vœ=Þ"vR|Íõø >`±•šî¼Ì ªe*ä%Ñó2—n¸E.N³n$xÔÔh ‡{ª‹ôíÉ4hCíJ]1䔼^Ûüb…¯Hœ}ØQîD¸¶ëø×SØ!“æLÜuÚÊÜ‘ÌLÛ7™Ñó®·æ  *ƒî‹ÇÅŽº2êÓtD)Ízt;e›ÉÆÑ-‹Ñ˜£ãK<¿å(8înGjæî 8s ¥Ëá·#ÇÆge‰éWß ˆá|u5›åtJûRGŽ«U»)QúÝ*5íßM~óu²#ùgµ5³ì<™L£]ÎÂZa\k³Úæât|·©p59¡”ü¢.Žï”è_ò¼U;¤…ìˆÜKSß1ú!9 ´îœŽÎç_GâRù—•JŨ—,é°)ñ{µùa¡§Ð¼ZUTOªXbŸ¶ÜÌg‰Új®;xÉøÝÿM¾SR©Q„ 55…úzrìÓÑTv{SÜv’ÉçkõÅøAª^¹ž–;E>WÑ2(ùí&·§lôâû¯ž*T>;ôÎ ñªòa]µ,fŸi—Í‚¾êb/dvYÿ0¦7Òµs_užYÉ’4Ë@9­íšÞÕÏŸzi²uÝ-i0œGP3t;)‰¯ÎKé®]°·¥1Ê…`ÑñˆÇÌD,ˆ`Iq¿æRyž‰þF¯%7ÕP;¯[è“»ÙyUxKܨ\™Ìóßµ>ä“è™cóÍ´R{VòÌ©ZûY4ð‚Âo:`‘£°íüqž÷X{ŠXâ¯,qT\vmî&ÑQ:n,ê^ ü‰äÜÁu!:×JšVsdçÉ¥è ;*'qæùŽºÍÃÍ1ìÔ^æ¡VwGýÅÑ»öì9BG½*™ªñ¥­žQqäÓî¨2íLrµ‹l›¥ÎÇ•{ˆbÅï¯HßôqÔ1Ûã*’àå*i¯—‰¼#?Dš-Od4¸UÏÛoîÂ;lŸÞ¸Š®“=v°ûó7O¶Ì éô&YÑþÇh{ª¡k߈{¥GÃþobX‚ÆH/FmÉÕ&dr€ˆ´HÛ7ó‹¹·ú¾'j¾ãƒxKw{L$Ö vëb‹ÊjÄiIŸL0‹“¬ãýe1®…ܘ–ÓéÜxaû-b4òÈ9Å}²üýͧÁìt[]iï-Îî:^-xÓ-dϸ%˜Þ =¹ÝÉ|rðQÌž•U»tŸ¤ož1¿`³hž¬ÐØX,õÁÕ§"TW)U¤—ëîä ï« ‹ÑÂÃ*š U†UC¼†­ Ä”ÉY =Tõ>?îÅì!à4/$uO=òfòáâ¸@:îСˆeµÀ÷¨Ì|A4&9ÏB;ÇùÚ6›X:.Ÿ*Þö÷Ï”Áâè–CnµØÿd\«7Ûv˜}عÙÍéÿÙ¯~‚]½?WpþL’ÓõþTª×ŸgórdÊÞÞvi¹QÅΛ¦üM‰ÝU +ˆ])£\ñòŒ(Óp÷ÁFvª'rë|Xׯ§¦¸/<&´[Ùt|V&œcph¨Y·,È? NÜ¢˜y«®ãÆÀ«»™çÄuÄɘ¦VŒ›·waf]"™“Þ‚‚UHŠŽ°6*+[»8A…äOé°C¤¹t£ÔÚu‡G*Qñëi–â²±†Ò¹†H€œœâÑK)*À+LÖîkî ÏÃXK˜_#;вº0/pmئç5¸~íà¸>+7ûybÛê5#×Êõø©¡ {Ý[,ú+ƒÔM>F$O ã ‰C›µ# Á:ê9©ü:&q–MP¶ˆX3eq´.ùƼ¶ û Z‘bÀ‘<“3™ÎMc2D®PÂNTI7m›ÑB¦5× Ë 7äJ½½],ä*Ñ]Ô#Ljß\°LÇþËšš°5G’@;™l£ t^K\«Cªªû¼nu¼#§žîÊ>ÞO¶ ›æSj0Χ᭖'§kR9c?ÅáÁ¤XìžNF‚³©ÉX‰”iJD;·Ã2¶6»®«ÞD\þľäì_Î ÌwdkCU­JeÍW¥©Ï‚PöüNJ™F=ÓM¹V{Io+©¨ NÀ ¹¥ølW~wûF‰|ºöì· 1 Éú©±tÌoñÈù,zùñHºeOÛ6{uØïƒê¹¡Zë’ÏÝnáôx?ÇÏ’fG„emÐq4Y¶*óñJ¦¯¤±bgð@.±ùAi –º%ðv3/öP1Þ—»Ä¡IõÅ…"Î,AÅÓZ3eŸroš)Aò‘OzVkµ9 ÂßÙæÙ[Õƒ‰Ø=B*]%ã7YXÉ(ÔôZÆwÊ·%cì—%õ‹WîÚ"iìÝÑJ’øEt]Àý¨°‘Î9‘ŽpÍߨÍ× Úx­ˆ7;L¾ª¼Ä:´ª–PgÖ X[lQPE¤nùÖê1MB˜Ô5km̃œg¥ æ;£m,ª÷ÙÇØ¡ÆmdQ1¿œ¬‡Óü\7fÿâþî®Ë¦ÊîðY–áïê¬Ü9á»8 ܤý–†¹£sSS”³¦ß·z¸_13亄æƒU1Ù•IŽ„zNìvswW2Ûé5Ùçô¦¸’Û¡eŸ¥__¬™e“S/Æ@2’ê6[ê‘ê÷ åt[¤=_ô-v‚ñÇ$Ù&± ü= ÔŸÍffÝâ|äÐלå›ã¥ùÁåI§ðe¤9†º ÄZ±ºË»]¬xR/sÎ1Ú±,ãeÚÊÕd­Z7Ѥg+¨·ò»¿Â9¢œ€ ­ýee4ÕŸ`ž©Ü‹ÄóJ•Põºç%ûµËïà¤Àyì»"ð¹F!ä’b6Sà‡;部jh'ÞI¡ì‡F6æ®!Ï…äšr¦C&V}vh¦LžÉ–ɳÜv¹6¯5VÃk#ãs]Ò¶ˆœôK»nÁŸ —E±`¢H½N&çà¡C5Ñ7>““R3ÇX¡¥þ"÷hÊu픢v̸×pÎgêLÄZ}¶ OérOJŸ™ˆ²:dõâõüdä+IUàáN7Ÿúƒ6ÿeò^²s©-\4%·å4ë5Y•v˜š=j›„‰f±,5‚$)”‚/ÓÀ·2åõ©ÐyÖ숧ŽÂø‰æO£6WO]Vé\C6‹Ù®î •ÙêüšdYèéç´«L+’"Žfçp"'oWåØ` UÔží`e¿¦ ²ù™_$ö¾Lâ{BC]øß©¼3ïLc”z½°tŸY‰¾ZÎÜËwxg°e˜`(˜µá„Ê2us¼(ûv‰ˆ„ûì :Ñýt£°"¦‘ö%J{쨌ëd]Åš€²Ý¢ÅB’ã2 íXʸYÊLÇyáøÊÓÜ DMùp—j™3¦hWK'J˜D‘-êÙ…®%<*t ¨ŒX-˜2vÞb½)F'Ž`!¯J粋<æuU99~‡ ¨”+ÔÔTRXHÕ«jAi-5„#ËøèGŠøo*_?dL•u3ú9—ª6<úš yÕa¶$6ªAת¹¦Ù¸ÊE{ÉZËõs¶HÄÜ ö\:ŠÄ1P!ŠÐjPÒÃFÆÞœ4Ó5ã꨿°´›ÇÁ‚4ËÙïèAê î[¿AÉ9ë GÉzå¶KzgIþUJ»t¹Å‘BKœ›ëynÙ™ ÉŽÍGqÖË3M]ëv´CfÒ…`Ûì¦â°æÈ§Ä›DíGy`yΈ &ç,/j.|&ÍK‹*b7CþA4W!k.Γ‰µ’¯Eþ¤Êq{4%¦Ô^a{%óÂÖyd6nx°ÝêŠòe c-‰ýÀØ£[<N³ä1ăLË^P¼„e­ttÆ3îPaUø¶µÉ…k™9pdã “»­*(c˪Ç0‘0 ØÔ8ŸÔAÁ—ðûö >Tw¤|ŽGŒ1¦3ù}]NÉvRóVäY½½8ÚÖÜ‘…>—pøFâ Ë©- Iþ»9‘^:ù—T 4‡ýÓc~UÏI’xóp»Ö@Äo bÔ[ ëRvëg;—Ã]á{ˆö:7Ϊ kOiiî%W¯üw·òï5rÉ‘ 4œIŠbàdR‹f:Q×ðAA¼1‰z§§—U¢£'x"b£%½Že»m3÷á¡~c{òWÓÁÕ ¼ÓÕ£KÞKñ.‘笺r¬ÂÜÖN•Ú·›¶×fš{¹jÓwÌ»Ñûªas[8Z™¯Ê™ ¡#™o^lîFËx¶kmÐRãbmÒs ñ3gý׬»–¶8g`·º#C¿‡žSšùÙåã^ Ÿ©bàóWѳ/°Y­Ø‘¹{–"dÛ•:6 PÙõÓGƒtÑÍ–Odì͉eK»Âf”d$ƒS˜±99Rä÷í?Â÷Dy«å 4Îñ,õS»鳟ˆ81Ñï8÷1õ©Dw:£äÁrŒA³µ=OÎéÀtÛp09IŸDä·Î{ôt&!ݤ=Sí,IÕJåU¦¡‡ËKä0L—4çÉÃ!3¢1µ w¥ rh2ÕštR Ãm¢`×Ðk\ÿ?<™n6ëGÓöµÉ¡m‡‡©¨eœÝCÓ¬Z­i(‹j ýbI¬œ’o£,zK¿{Î,Kæ_wÚ¯µï;Êê·O9MOâf,°ä m>©V/™êOÜô3C¡)¨ÂüÂÖÎ4̾¤ô–EiêívÓR8.Üq-²öÜ“ˆ ˜(\±âÕZš|šûÍ Ì´ƇY&ê>ø‹*ÅÚ(—ªMÄÐ0³s9óGŒz)Fê'Â*ûÃO¤7*t¦1U€›(Ö0gÉöM µ3½?ìówËÞF”ΊҼáR<µÅ"ŠSíãÖëCZ¦îVœèmîN^§U&rŽ5÷í/%º.TµNŒ„¤_j«rƒÊýoê!;R ¯¦YäëR·%+fÖ'УD©ïÇa†BO"žo¢!÷§…–eå«ã0gkãö† £›|RF“§ôbÐXÔ_»“FFdÆrË”¢EHÇôPøR¢ÄYPqÊ’mô„)¹©Ã$o­*¹-›³|ìlq7 fºÖ9L‹ÔŽ—º“2VV4‰§Ÿã)* éF·îDü—Ý%.A@æÝ‘´™e¿ê´ÕC=Ód¡kÄ™Ì0„ÙK›Ü­é)¹¬Â>-Îz¦*Å>gÚÁý°È‡‡’ŒÀ²'ŸLD‹“©Jóº|¬™Vé¥uÌa¾$F%ÒhhEÄâůtLx¹·Dind¾¸¨E–ß°VÜp <üL”›Ä”p§©µƒ§ÚŠ*óMN¢CÔPÅLj§“y±©J%`tX代Ò{P]„<™,'†‘9…¨M'þ¤•£Jg×j°ò° Òlž9e:`‡#PIE­Y›Emf£ß‚™·è *Ý”ÝÐL_ÇÅä&UU¤$3²s¥<™-ÍØR\kö¡_®t?*ŸÏG~æõ¤yÛZ`<]”ãëšî¢™%IO¨¬uàNðÍv¤m;„¼+q¥/ B\ÌîÉ“ÐÅ—üuHè/i.nñªtJëvSÓQPeZMvégŽi®UªÀ›+ÍNõ~ÞÐIiÊõPÛ£ˆÔЃ€Älî$[wAÀÛÉÞfÕ- I“¥ ÞFë×K•ÒÌR<1tál³9t¡8 oÞ¸£øä„—?Q| {B^[ÔÁiºúycÓjÄ£IQžŠ*Éê'ÕY•ÃÓñærW£“,Ù>V!^XÌ]uø~¬†Ës!¥Ã|}ìH¹¶ÓîøØãvæ£÷ú$c|èytºTwµïGY@:òl}È]“›_gÕâ”SôRRößË[¦Í8°ë ·›Õ,_•룼^ð¼7 !v¹¡Å?(sÛƒ-|á­-¯M”.ŒnÀŠtÛ«;…Ϊ%ÛMnrwÓ.;ApѸ?r‰ÀNZ&UéÝs%yÜlz§BÏ[rVŸZx:O7 Š“g,/÷QtüH£ÚãÕíym%w]ýšVŸ‘3.Ûó`‡‰òiìr®œx&iåAgF4X®‹C:äÒbâeç¶ò…c¬ð‚°fRÝýS—ÓµF3)%˜¹à†å·ñ}ûÇ÷M'Wï#rEr}ó)<–Ÿù¤¶K´7Ž—™-§-:E¢9™F<:®"Q-ùY[¤ f’¼-×M·ß+•Z› xMSǤ”íÍ à½$mH¶½rHû Ò:'ùç‚ó6¤S§waüÉ.¨÷‹=u&sæ¨ HIEJçcŠU&5‚Œ=2ÜÙR2o™"w*œìùú:!8b(c¢ÌµjŽKwýX;ͽ¸qX~±XƒÛ­eur P‚š¨kýÁ b†ï¬Žg»¦–sy[p بIù¨ìõšî”B˜³þ1¯I·]w>ž1”O+ ßIÝc :3ç 9\sfÙú_¹–Î)-Ô#<»´‚:¢±,w3­/±¯’Ë0íŠ)ëÕ&cŒºW±hk›¤ÂNížÔõÖV6›uå–lêdþeo9íþâ^ÒdwÌêˆMñ©.T³8*k0ÍL"dïüR™bîˆÚ¨V8È5Wûk™Ô¡h.\å,kVäÜ1©4üŽïÃ䪴- ò4Úæ´3%3ˆëRUvAÚ^ŠÆDõi:·I(ÓÓÙVJ{DD4Ì]×…\V9¹X˨‹|8†½ÛÍ¡à!oâ7)9‰å]=õV9u©³§KËnzË¥p.•’–‘‡òq·ô+õffÕ£™¯®[ìi]šVËíðªÛ`¤.š/<4"$\í×î§'·źE gÞÙáç·?‹§‡£¡ciËÕY“ZœbZפDr3‹YÑø-ª¾ÑôTÐù¶ ]˜ ša£cO jÙux™srüƒ_!r€óÞƒSÓûŒï“©cÊœNË…WÚî ¶YÜØ×íÛ¿kœn8F\scú%•Á±˜`-NX¡«)A,Ñ*eɹÃ#çòû¶ lô“?mšÑ:­ [OZ§‹¢ I¢CÍe6I[¨¼°mFºü„¿;×Äníß¿óàn7W…ÒÉdõóÔ«`ü¬ä*6ä`®¶›ñL%¾ãs‡óTäg±–+=#!°ùÉûk7-'ä¨Qb¸WfíOã-—MNLSÒØ]û÷í¹Â×,É¿Ò:Ÿºãà:‚{*ß ©øï%äZ¿ìl¼mÆœd/æ)m‹»±wNëïàÅþ™rõÔ’ã]ÑÚþ–2÷QMÜ`wlÖüHs•˜‡˜˜õ×óm=ãoÞ9vè´“çí—@cI¦->ó[baè±×Úîö…rñµ5“¶9¬¾…x%þ‡€iTݧéÑh‚ñbcu>*®ò2UQ[#Víݪ\ÒíÑÆ&)zƒ¼4ïÙ¨ZL!DO²qp‚¤41oª®A,®Û¹3Ò¬³Êô²¬N.N¡N¬œ<¦Ö¢£”æìœ_±Õø»S:—| Ü—&dÉÂz‘ $ËIÎq’…•—ÚMŽ:!g)öÔ‡è+ĶÅuwf1áx\»$'¯Ñü­GÉ'»·ƒïíd_™[-¥<†bÌhY'ð”DAäЇ>ÅjõÊñðôhÉ7Ð6ñæÛur“}4ˆý0“#uÒP²ƒsIRn…ym«¸Øù…›§!7!wÜ+cc¥y¨Ôk¹^NJ’ñO 3Ÿ!)ýº/«QVU!‹UkÏ#´%`dÖ«A¥R$ç¨L¬µî6ž@‰ ì¨­uŽm6²iEdµÚ+ùm‹­ÅC‰Ø‹éI;ÑÏZ,*‘.,·thB¦6;¹ÖMg‚Y=­Š‘ Ú?f{ªÚ µR©G»‚­^R¥Çþ<y•dš©,ÈB¯[?‘Ž9jv¸!‘Öæ"Mí?¨~'k¸\#Þ,ŸOÅM0UéF cÓ¹p]iË´ñb5â¯r|VM̼ÁÔ­†Å<ñ‚ í®Âf]èµ6hCk•ËíðìSʪ€ÀÈâæƒ(=*w<”6ò²»=’|;KåÈœåEK…ή#e ÔNö·Uô(uy&‹yš°ØEl NËZ+ƒ+ _LM‘™‹ŠVRx¥J®6QóäJ¤—%†íF©MÒ¬cÂEÏÇ3‰"­¸íà/6 ‡Gjàê½f;e B9#Ã9–É9ˆ¾ƒâ\I¼^šI:Nm ìGY¢çHTC8wŠ·E‡´QZžâ'ÖóW$o =z¹Ø¿i8L‚}£TÊ¥Åð¥Q'9ÏÇd`|DJt¼ ãyA\ï¨Ù…ôÿ4M÷Jªu˜ú_ŒÍù"ÍM²?:GšËÖ@¾%u›|ÑÇyrˤš n÷tZC<4”rƒ-wŒ’,‘'ÚÄÈŠ'Ê@9šý§š&ƒ’*…Ü¢iÐ5°þìó÷¹f¢¶è§ÕÓ¥j‡ÉÀ 'fGlˆÜÏÍ™c)È&‘æ˜Þ `âN¦Cñ~‘E¶6 'rÁM<Æ´™TÇ)§¿.î–êÊ.Í)ùÜé]=ÜöããwÌtGÁ%ü S^K\ŽùÀ¯E—QÅ6„ y=¶GòCxm’»O¯Çy¤¤Jì) Ûš¥j¨p¸þ›ÊèI]d…³âS¿!èPÈÔ\¢Ü~²êx(ùý.‘8ûH©å@'P>t³ebƒ§(eìðÆý»‡sv%Ì/g3bmWÃy8veÇds—?è:µðyÝpæ£"ÊÝ´¥²C‹tÑeƒwabD\C7Dr—Q2É=SÞTø$^ØË.*G£âÛÑn,¤}€É•þó½ÎÕ‹NŠ’ 9ÉFŸHÕ.µ[…&Z5ÌÐa"ÉpäÜÍæÅoý~õÕ'“«OžäÝäêð¥'‡‹I¯I¶ÒVn4;ب˹'%=)wBJX—Áíl´ñ¾4~1µÂ´»¤Û5t#8õ©A±§P&Í¡º¬ýC¹i|8Ùp˜Íb?°<3ˆm \w]uáxÎwÅ<ù ù5ì÷š’uÿ&·æY⨮:*K-=Žƒ•0 /Í3ল–¸™ùä•8NrͤUͶ˜é´,›LOÔ%”í¬^ªç¼6õ;ÕAð_¤Q Í[Çé9&5TŽˆ:+p–`n’æÇÌRZo{™+LíÛ©¦Ì÷·¼©]Ñ+Åa¼J„%Ή?¹¾ßäâX"Jèéž2±’äYÕI5L;6?°ðcqÎ÷9:tLݵcOEïc0 ^ßÖ9y02pöó˜R=c…qdâëw‡<»úæúgzò ï.»G÷LM\Оõî@ñp³³»ØcBWb‡©T“Ãl¨?—f(P¥³@éÏœûû5ÔåŒ=³æ[Í¥9Ù5"ß™a³jktäyúk¯NkéÑûBÒæ}2ÝìôÍ ãškåùg¤Õ‰"ŒØ9‡o# å®…L4Ú> 9¦fê¥%"RLú|ý¬ûœœDeÓ4z91‘)µò©‰ö&)O¥n,}1v uVþùÔ…ð¦màôмd˜0-^VÒØ­“w±q)ÁHu'V2ÊÜ•ÞÁ*¤U2½±Žk~3Ì;Ô%Où‚P{OÄ"›Ÿ3,õ©›ÒB©ZY qñ÷‘u„[Èf9zŒ§fÌÂùu.ânMÌÅëMh©è«‹;KÓ7.¾¬®j˜'&Õ¢*lñR :Ó<®åt¾c—EYMÕÚûg»¼éRŒus)ëö,½näT Yñ­+ök¾y»ÊËûg1å.«ÕŽâÚ˜ze‹–xÀ\»ÌMdÆU´)9ÕÆµÒ;ó* qˆBuBM¢ÀžÆ 6Õl´e»LñèüVÞf*îÈ. ã_ ÿE±w˜¡{‚ùIEkÎÑØÊð ~i0A»÷é¿i+¹új¼–ÌM¬ùCWWhè·“>XPß%ü=èW=q6Wú²i9šA÷Ê\Ö‚0G©5»éï‰*zª¤´úJÔx-Ç€Q'zšÇµ’x559,”[G>°ë &@•çËF¬Ý¹¼WrãU†á¦¯ÕLu$Wvæw¤— ÔÊm̓Á•ýKºŽÒÙ’vó+Ï>Õpñ ASÖ¹%kV |Į́‹7w½“!)n­*…ÒL;ü‘ïµt=SKIŸjU,¨ÓÆ{>ãJ­æZ ÓÛƒYŽª§´‹®£ó÷ˆ$«!Öñƒ"\Ém_KÅpP'5‡$æ£ÁÁ/ÅÑì¨S}IÑkµ‡Rµp&µˆÆ¯Š–»QKV;lXn6röd7LO¨–K²57“t¾ÇS~YËÂÚš Î{’yœâÎU£ë»·ä‡ˆYÈ0aוx/ýêÊΑ ½×Q†•{²{C© “Õu÷Ú½=Òó1ïË5æW7âç¹­ÿMø4C Âf| Ö`®™lÁÇci“‚C·Z¹¾!ù-4ÑÄÑFĿۚ1R+4ôêJ¹.$EG¢²'¸ªËø?þa½Ú†۹瞻õ<«‹\ôKÃZçÊ­æ÷Æ$Ã*ѽí¡z1¢$6¹ÎN¤+P· ¾D'é·êlÂ^)oHÛ.Ñ9øxÍÆë†»Š é°©‚YÃQV&÷îÆ•êŒé›ÏN6nÙÊ•’šÐ†Zî$R)â%s¹ø7:Ë;‘ -ÈÔ¹ÆÚ2ØÞ«k|/7$ýî¦í>ÛÕælw+h$oâ½ ›Ñ>¿š¦1ëfì–Í›·lÙ:²ÕfîÈy#›7lÞrÞæmñà"IlÜé¢ #Pîª%‰N\^y$Φ™+µÚ`µÙ@³=‘/­§a#ù.•ôiC¤ÞS¾Á²¼Iú¿‹æÀ)¦-‘ÄS³;mø¸´ècw9´Í­Û.‹9p°Qêp6s|¨Aq"N2Ö=¡J˜13•„q•s΂l´>mTÖ·+õ¡tvX‹YË]äDæ`5ˆåÜ d.Š\'¡3_:ÝÜ«ì£à®&èzEÅ3eLâF¥¼-·Å„PNçæy‡¥d²Ûƒ„æuF¾Þ4Ë.»ˆX}â䦥 £­F,Q U¬£òDae)·iówNbʳZVűuÛE˜Ò¤Ý#½HLFTŒS6‡oXK³Æ²} ï®9È!°TŽŠ%Íeµ³ä)#†7•’kv.¥uö‚¸‚<÷o`¿&5¸‰0HIUä~[UªÈ.yºe—QíêìR}6Õ]’IÒÎ,¼ýÍ:’KŠÒ>ÊQ—¸dI!éY|žÛck{…d»jš`™ ¿TL49æ:íXé¼1|tU’“ÊZð¤í\êaª`IÒÄwüc $ÛÙU„=B䜄ÐåIT=ÏXvË`­4H)Ÿ¹Ptr À•ŸÒEÉ|~ŒÑCéáað\C'†‰¾NWm”û ªÂü[è“›v³HMsG“†ÌB†ä%µVí’Κ %Z?äüL¾9jBËHG@Ñy2óQº)©JÊê À@ÇÆ¦ P˜O6R¾J¶.›…Ë'`y/‘Se«(Ða/J£þ6«)Ñ.w?å–ãuÞ–“ Å2K‰gÓ YÚ|:VÒbzžGÆ7²:+ÑŠåÆþ´ŠištÚ ¶o¿àê‘dcB§øm<‰[««¹}ÓI:g×±òtêߦ¢ÄϸÐv˨¥¹,µ>æ[¥YXÜ»øa«ÊIÝ)8®-!FŸ6 \Xž9LÇ÷Òœ±ÜÚü%Jî<[¯` ‰æ2GrUèüt^d¸`{"Ñ/^­B‚Û®”|îâ•úRÕ¯r›¼«“˜Põ* ³ŸÎ5›à¨1ËHw©¶[#¶–!½xùÚË .ú#‚j‘ÊEê![ÌRV5UU¦…‡H!NŒ@šxª[èW,V q|÷{—˧ž.¤"%ðA M¾µT¼Á¢:¸2·½ß­>Ç$mÈÃá!0 ј#4Y^}Yòà±ñÊ"8Õr0~bqçÒ¬Û›¦ø ë¢$UÏ!nµ¼ÇPôü<³D3ƒmGì;jIdíçš“¯Íป0ZؾñZYk° y&ÁÊÔ™¬;±r ÊÉF$dåZèˆËŽ”OMILu0s¤È³ “A“:„ó{˜NÑãšÜ{€²­'càËU2e埰ƒW«åÖ çA‚1–…''š``±]W1NcÛŒ ”Ì6]×Qm6 '{šåjþèV/5øÔaòðQÏ·¸µÝí¿ƒ,óSíÚ")wJÔB[ÖtáCS;'Ȭ3D^ÙËÑ5ÙbÙ"_ÎÒšX‹ÅK€’•gkr¼EËáDKDꬹ ¥âøB9•©œŠKú/«E•äùNš÷¸oËtpMÖ’›¥ æ aÙÒ飫õx7:—ÛÉÖ2:ô÷DÜÇçÉåI§bL#ÄŠ/Óƒ’@åÅ©™úÞ &ß [Ñ5Td¸¢Œ‹h8§ìJ½*²sã@+ÓÅ¥ºšÉ÷Ë‹«|ìUZ­™o¾¦{”4x|Ò²Æ )å³zqœ¿í–-]sóÞ»+SFv]ÎOt‡YªãI×Qù25»½…–åÄ·ô„Å$óz L' °·Z´5×3 m4-wˆÏ—ád ì›7#ëǽìÒÍ€P.P*:Ç-«e¿l핹,’À²ˆÀŽì’…¼±6±SðR9%ÎÍ&úçè16Ù˜D“ž˜aæt^ÛÐc’ëvˆ˜h¨¢t‹Ù‰¢Å)[Ͳä“H§ Çò.”Y/Õ¢ˆrrn4¼Ü\;hÇð‘ìîø•Ù(²_n*%î r ûÃâ©Ú1ÙŒ¯Ô½,²nÐbì‘ÐÜÚñÁ’;¯ÒZšm“²ÀRK0›Ñ8jb†uYÆg3z»¢.Þq#\7¶j mžŸÒ¼ý5ìð*·´uY­§¬Êë1NCXÆ™®a.;ßú®±ÎA¯SÕˆbF¬£r˜·5)ω hÕ„ºˆ˜°l½ãú4I^°,u;ʽ.˜Bº%7èÙ›]ùÏŒCÚ]J,OॉÂ1ÔN€=÷“}Ùè°ð +Œ”J‹’+ÜB´\©ûý4ŸPéÓé_¨øÌ9…¸»äÊïp§x @Î…àßthoyyÆz’¸NÇ.ÇÇÑbò’}OÐÁä︘Y·>q§•sPÌ(|—ÅWÓ+yÖO7*v:’SÃçGùqG‚RBí ß°Ø×Bíæ6MgZ¾¼Ló}o$®¶ð°ñ6o‰§K,â±>ƒâ̽9C‡/]ï~.™mÝB¿u¯¢qÖmĘÊ:Ç9¼»öèÁ=Ó¾<ç¬,滽–¥äåvêŒ&« \§_UàâÛf|È]%Ž%<™XîXŒ°k$™³u%ñhYÌ(Z'¥„¤£Y¬°L)©«*)ºÞJ®ðv¯Ñ3PÂVÛ÷W¼‡«±ir#çÚf9o>T… CÓŒݵÝOëš¼ð†&³gAwRR LÏÔwÉ¢”‰õ¡ä¡ %‰úO›}Í6¹ÀË”kgïgÓszçž<Ã䣗æÔRçîgœ¹#|(ÿOØ)‹œ·:ê?´x~X.¸ø:ƉÞ ’è-~”ƒl ¬`ù0É¥†SŠqéB%ñI¥gôã2’—\ªÍŠ%¾ ­‚WŽpÂʘ¢cY²…h¾Ú"ñш0ñO[zTfG2yM2OF:ûJ&bnÎøõ¡6­‡,Cp u")P›©š¤¢ãÈ©¥Uf¯¨Æ’‹…ÃÛÍ ¦ºÐ‹úo $ŽE:ùBÉ„öð:­[´-9¼¢…Þy¾ÇeÒK ‡æ.' Sg/ê4™ÿaE¸gYš]r§‰™žœ%TK XΖmv®¸Ÿ…Z•£¯@9ÊDÛ¡ÚK^«8£œ®@pËt²›¹ù°W^©µ|Óõ ŽËQ¶W¢yY¹ÖCÄjfÛc”s• ¬¿ÆFv MÊCyŽUnçבŸLà2@‘XturV[±4V$j¨ÉQq¤ [n43öœÙî¦Ïù4·i.\˜’}”¿v¹]åG§{Ôt;²áåô’,ñ(mjW›´%ó‰§LMÜ1´6z¶k_”Ú™_:½\äG´8"&NJNH†&ÇÇDu4ALéo¼ÅãMìÃUj}£Q«Ob\Á™ÑµC£ì™¥»“ ‡“‰½ô•ä°Ó>¶3ùP¼¤¿ÿîéŸÝ2¥1¾Åq´¡¹\«í[’H"¥MÞ?{1èBÒhwïÂ%9xsÿìÔb“fÝ¡¸ EWæÓzüvrhÓáþ$ «àE¬1º)Ì gœöÕ'iÿ,v\nšÛÐ?Ö©ÝΔ²p[¨v\ÝÐÙ%#‡»Ô‡ú…1?u‡º±Ä?ΖÁ«-çnæ—Æ½×ùúÁëͼXä*wܺ)¼Õ½dh(¹öîݵ‹âGw¹‰ÎôJ‰eÀ)Û×kG£Äm¡nðoê_çºdGü»öIîWß)Ìé{¿“ZÛYŽñ¶¹ŠÑ^‡]¶^ݰC{ ?£Î/Ë?½#ê€=$àçËTíÑûg;«‘_R]k¶š×ÑŽŽ—›G:ªLËh‡/2\C;:4×|¥®'niîb2˜"fZt°L:i[NŠü6°ÛÁdĹª‰4:ŒŠ÷Ô IAk'©´MgK.º”ôÞNý;Œ qN6àöº•ÁŽót‡©)£Í´ßõj'Úfm$Vªƒ¾sÓ •‡$¾É,bÀã‡ÐCØþ†ÛmÙ‹SáÀ:\ °‚N·„z1•?–itOIŸO‹œ6ÙêFµz­˜fÝò³"]îE“Iî:¿#5I·áfØç¨«ÝähëµÅuÙáü›»¶Ž7"Ó»%8-Ló¡ƒSã»îé?÷šKûÙ³K »MM÷M\:>95º'97¨H$w÷‰ã`óz>Çd…V{'·õ|rš#*Otnã†ÞÏm¹ÑÏ\ –ºÙûe#=ôs:ÿÌÆžÏ\Ô*/Î÷êÊ[V¨$»Ãõxnkï:Níߺyë~Lüë=žë=SNM§F}‚'6êMääÛõÉÍ=Ÿ¿|z|’”¬¹GÂù:L‡¼Ñ£Ã}‹é^ÇmN5Ek¼<ÄÛÔPÕ¯£üÂ*‘¶HU ªá¢×ÓVR¯ a¥Ž ñöH$%lžã˜Þ!t'8:ÔkîáNŸKþP8Û‚DÅ“žtÄ’Zà>¤ λnéîÙy$ƒb‰} @‹Èÿ‰î¡˜‰ð>P]Œw‘ÓËá±ýŸ†ä&¶›Š±»«”аæBÃÌK7—/1o‰B…È1UdhI#ú Ù²ÛÉIÑn%3\XdI"°z”¥Ò»ø®ð±>d‹QZ‰Ç‰¹›R¨¶¨7ÙTaòàD˜Õœê”zoµjmfiŽcIÈäaJŠÀðÊÇð©o®0|¤Óé1qeb~Y=M/ΦEg–½oÚʵJdiç(¯jÊPé—r&ú|¦æ e›K+AïÛ]S³S‹R·;G•š3×öA Ù‡’óƒ|»N†¸É^xar>±VÒ~ŽÞ Fpr©Á¦x.—÷;8=yFÇ©K㨭±€)æ²Ï®Öšl__/Ü$Þ}öP2Äwk-/HúЇ–¤K.èxés’¢¼—9ÇánœMñ꘯[»¹¼uvëy[kk/&éïl:øþl| ؼµ›·èÅq½0{k·lÚZݺíÜÍ[ÏÓ›¦0aΦºœtÒÚ-¸¾uËÆ ›7nݶõ\ü»‰¾oÝrV8M®)Èâ|­–ÕôMÛèOÌA­Ý4²iÛ¦ó6mÜ´Ÿ6lÚ¬Ïl;o㆑ ›õɈ»Ê5¹ºuäÜçnÓ÷‚Rv4¹¢÷Üø&;þíj¦íÝ=‚§ÑpëpüœÉK‚÷oÙ¨—'oüûCY:k˦sÑQ›¨»\gm9Ý·Á=ÔYÑ ^±iëˆõCš•;:©j=xsTr+æVŒëˆ«äÖ‘ [7ŽÈCö®èaÉÈæMrÈŠ#–r’‚,‚8öBnY¶@ j…”f!!"׿ƒh$´±=_óg눊Md„r&1Mø×Û (F‚µêÃŽ—à:ñŽ` {`9/n•‡¥Bò´¨5ÃçEŰšªÍ!‘Lð¸Où±ìb±-ù‡Mp}L²3o—bvá¶a%x‰ˆ¹ ÚbÐ3ä¯'Ã%ý*Ô*]£¤ Ñ©Žƒ !U˜úsdLªQì^š-ˆ®D/3Åði’ËH}åžqrA´4'ªMñÇ4º„á¡g_ïÞ=@§EÊi°6?¨Ä–&ôe^;ÿq¦FJ9#ˆt´_¸:ø¨3UéüD{j.ÿ«(§I`xÜM)’¿ßÍ.²roŽ‹Ð´ v½a™’\€ò6™gncÓÁÔð¾K!9ƒ2K<•™ °8ÎçJÐÖ!æ%gePvï½ý˜ãiÊa—qTÝ$o$2OŠÅýâêAœ$È2gТÞÞF#ZÁ ‹žéõ~4I˜p-'Õ%1ÖÔ­ÁîÅ­—E°àív‰ãí̇b›6ÝùðQš6*1N&¾Ž²³ËVçßZš¦3á[˜o‰$Šæ¢mCVƒ’ a¢ÓAN`g%IÆc[£FÌ"J&ÏEw=hÄ¿ÊZ²kΑ©Põ,èÁT…0bý)P²”ÌwÆ€¸;ÜÀ†€/H;iÎóÉAZJ6lŽ8ISL˜ñ”;GÎõ÷ §ˆ«¨°»ø@¸Qˆò 6îÝ‹e9P.Í –Šý¤@MÊGF÷í:"ßv&3ƒüäÎÞO–*=Ÿ•oôe,©HAc+Tª®®(ÿeWRE¹ä>ëÿ©gµnop­­¨fÝ%·ÃjÌ]è*¬uáåý´}Èžî*³¨5ñ5sœ°‚Nû$×Q÷ˆHxnsç ”BŸCý…[A$&ן‰)â4L{ºã’Ϥ\;±HÍeá„»Ägp¶ÃÚYœ'2œI¤œN.¡K”W_ˆWÐÃåžT’u-p‹Ã6l>¯¼Ü#“#ɶd;þuŠHW±¼AY™"÷vÒñ<Áxd¤\ð×zêÎâR‹ÎW§Þ˜©‰d(³yàšÒµƒþl ÷çã£$5 Kµ=ºoj‚6núüð‡$“ô™’—ÎPL$ñ[$j§”µ™˜I:¦}%ïõ›-î\Ôm´mÑúá.*=$VFÕöqÔ %q¨“¹ìBñSM~4~†Ó&wLŸëêD OjeqÅ öZ²³5Ú¬¨âCÜi’œÄÜY’ÅŠÒ¡ÕÍñTroÈüÈrÄÍÏlwFSö»û-YNã"rWÃÄ®=ÚeL¾üÄÐWÖ4‹k4Í ÓoøE§³¢¤²z¹“!âbJ‰eR§•<Ìé}åÔ ¦lÏ25DY£sÃXÊ’nyÉèm t{u^„ê«yF‡ ªé7: ©8q‰m0&ôš€gøú€d/:Î LéUrYJ®jÎЃX,çÕR*y±%f„¤T´ãH¶s÷ïcÉ.’馜±„Xèd$Ùå}јÅÉ ‰º³Ä§$ÄÔÔº¼ÚŸžÎdh«+"æ] P‘·¸4dìÈ"aù³vczñBÍ’o•P»‰ ivÔRËPY^éG0»É¾Os£‹_–œb¼uPý »&©hj'j­Š¤,Zp—r\%'ÇTW ,¨¶&mU87ä~ L“ó† ?º^Èyþ Kþ'K±ë·´ ¬Î®Jœ±jG crš3ÚAÀ‹YJ^£ª9fkÝáwT!*\Ua˜ñ©ÚÌ'K [Îz”¡ZFb+S}"0®—J÷ñ `5§õy¶”¶M}æÔéí¦K—À´ÂÅCë¦—Ï fÁÞn&@Ýš|6^’ ˹$‚vO©LvD‰¬<t¹þ„è5NaOdG׎À‡(aÝAcå´Êš AÚ—ë0š¬Ô'>žn¢"´UKæK¿‰÷¢æâV"Ùcš†Óú°U3hKŠK± ¾â¢hü–žbÚªUÀ“•ЪÍfÉŒúvÐÛ¥ƒ®á{iÆO w±md}²á¼õÉÆmr‰tnh϶øyKÒʢߌd±p.Ffzô¢82aÂ"Ʉٓ´ô3XRþÙRy÷*];Eau$› Žnò¡DF ¥@Ž/&Ççàk>ªQ›¤·Ä—9¾l>(|p"ðÕxÉPóèÀ°#ô­’3ìFô'Ö¥ l<)Uš¨êk&ªä×_žu/G–оª§•´=„ëÎiVÜ/#\šôèTg¥´«‡0øaû®}ÌU³ßH# µ³¡˜à}?•ÄñjÍ£iù ?³R“¿T?éHÄ£åÌ'*ÒR›jUÈ/™%£½Ë.гrqµÕõ÷^÷Ÿ8Ñë‰'z?Óˆ¢ÙMi÷‹iµÞå \žØµ‡¯Fº n*MT;gJî]EòµêLeî’˜¡L=M„ú—j²ýìdÿÄ.: å@»…/Ó“ÇÏæ—æG§c‡7Ä·wÖ³cBʯ/¸y@ŸuTeEMÖfõ‰’¯xš7*»jTu÷èž)ª+Éyû|‚v_w+±GÍérxkg­Au›à§ªT“ ü·8 ùÓIÊÕ öP ë¡ ?›¯·œ cëÆÅVz [ÔT¥‰7¹¹"@ÁYÙÎqv{÷ïÚ7ºwiÛA~»öE°’::B¯%Åýiuk¢!wMí:Ÿ8¨¤ñ _ƒeHÝÔчåÆòD5¿J¨T{£¸kµ\kFç „ÀqÙÑ¿/ùß0Á«KÁwÊñWGÉcMÒf{j.³Ë…öÂb—_¥Y¿\YÛ|“yÒP#ˆHhcÈ¥+›Þ5!„#ú_ù÷r»ÝâŽŇbŸ‘Ê–vXL)ËÜ]Yô(upqº<×ÙuíJü”\kh•// ƒi<XÐ#c{F§¦$Íϼ™rV£eÄø°ôÔeìÞ?¹WŠ`YÈw¡mBAòú¡açåã¦qg  ôBGq´—%èí£ªì„—R&—CánOcV•W‹SÍu™d¼™Rã]pg¬äúõSïNûZʯGúI7ô“ÁÐOC?Ù{è¥7¤1 Ã\Œoï`>lƒá¬UÉzàî ÷WLŒ¦kŽÓP®KÌÌ"ÆF2¥‰šûGòM1gir7¥m ² ëéiuÒZæÐRCžÊ ê@ßlÖkå† Lþ"ñ¾dºê¢ªsm¦BÒ¶vH”Á¡óNév÷nî|ec 2xÿ¡-—Ä úÐÖÎ+GD—Îí¼Xxû·bݲڣ—8ĽÿжüÔ¯|›»kÿ,õYØ£:_)þuéYßCÏã®è âbG_FEØIx¸1ìÈ)»`ŹT«xå¡‘-/Äü:4©Ûôá&êë…„K¶^ÙÉY‡*Ü¥ûqi—PìËxC8 £Á%[Ïô]¬¸{[®>“Ä èâîÚ˜ïg¹‹•EF5Ðß{í»]£Ý—ÂNÞk¿üðmÆ ·h7ÑR ÙIt?JFnÔ)©{Š4ëCÝ`«™í·äйU8\ kGÄu¹?^˜“ú{îÞtÒP¼L'åçÜ3zï¦SÞ;šqF³Íñø5_…â¢%K÷U¢áhgålüD»ÖȤÂy´7ºØû1Ú?Îíù\ÖûAGΓˆìí~SG9ÓM:W®?¦ {Ý•î÷³‚0G"öFW;ž›"¦+m/^ÍQÎȘŠìívOX7I¿ÑAZFíJîö¤ ëÏ‘šQù=w뤘oúsäfÔ®änÕä25cº3_îñ¤NÕ˜ä¬îQ¿ÜbrÔk¹ê²;eòé¶ìʳ£u öóî”÷·˜—ç „Ñî_ÌâœD½žà*ûŸó#¯òYþénz½Ýœg6xÄ;ZR *îŠ ÷§Õ®oíT„;hagÇ“5wŽ) §µŒ[D´{ÙªF¬³ô7é&éZ†ëÄõs‰äFFBÂDãX“üÂkd/ª§]®¹7VVxa£Ù˜lZ^ިܙ¨´QK®?Óñ5íÚþ\åKa{öÏF¥‹‘°MÇØJÓr×Ñ¡ ªµ^×íü)>>ͶéÁ¼qwf­‹V©¾ ÛM_Ö”W(,ÕrÂh‡6¡B6PæÝÍÖÔÒ Ÿ>M;}”ùK=žš&{yFLðÊÏìªÕSö}‰øáü3IGe+õglã‰u*Æ´;O¢NõÅLêi<1«7îùžìꪋéd]»6†(ßÚI|à ÊQe‚í¦î…Ë´…g²ihÉaë–.§¡„ÌlÐq$Ä~á—@ [iÅ~Ý8hÙ~òÜw"é¸ÜUïYy·ª« ý;”g>{nxr7Äé»{1ò½7jh·‘.ÙÞ—oZ\¯^ÌnÇkõì$%Âzâr<àÄV‘Ò;GñxûßÄÙBÇ›~åôÖv+™!ý Ïtªn©›õÒÞFg‚—ù<ÿ6Óà¯j΀‰­ÑëÝ‹ªdg'f}Ixª%QèÞ×g\™0‹Wƪæˆ|ÒG48.RLµÅ9>GݺxkÑ[ly–EÁåø•;L ÙÊ+Kâë勆Ä^T¤+q÷…Ué^eÝââ=Ѫ®Ij ÐiÈLÜ$X—kÁ¥îŠV¡D¡f’}´¾8_ž©µ“ IÌó\ä2[\&y+p%QòCÊc)qä %úÚŽ§u„»L9Êó&R"æD£Ö²î‰•Dá%Ç$‡mè\•õæñZk¼Q üœ9ûhUÏkö\LÈí‰àW®HT³Ž:T\Ÿä7«g!÷ UÚ¼6)è -óWZ˜šñ´ÂÄþd),&K|7; ÷S~ÆÜÚCdd;p$7Ûš“{–}&­n¥$àȈJN3•pä¶jç ­e5ÈZ‘¢½ÙFŒ`òÎîc©«EÚ_Ï™­=¢!È‘–=Þì¦ñíz[D¶§¢k®ÞÍÆœ»}s·BÑC4³gÿ¾‹4›®o¥·L…4#´P‹Ñ'ÔNŽ ×"Õ™¤;"…ñ”¿à6‹¬’¦Ó¤ÈíCù ÃtÛÅØÝb%p·»v:kX¬üÍg7sV¤áíæ' Ú†”µ¨W¾¹·sJqFÇ%oWÊÕj1¸­W¶é’x[TÝ‘±Î])yk^7«+ׄâ³!('û¹d– à¾óºßÇëoŸE*Z!:måó•×Qä.–6†°&Ä_¬|‚? ú‡Ý$êx’²A/ex€,—‡x¦Ê–Pïü}dÐ6¾nÄKšuÚª9~¼»nŽnF5WÖÍEj¼S)çüè±õÔ_Êž“'¾¼ÞŠS½{Œf½úxERR}/¥Ìlª ‘e“7'þ¨[ÃÌ2mOrïL2°YnÍ4†w _¡}€ôÁ[ùk£)™ÌΕ›éK•.Ÿ7Hj´sLv Ú¥ØMaHìþnØÔÙÚ²~Ò#ÄËûM¿±é_ãZ–É¡ HÎ/]dĬ1¢½ù•tPv'q›Ð˜nQg«›×N-é/ù¹˜w ²Iù\‘»U¹N¦w)/·8ÃIrÊ?æ`&e7_ÛŒ«Ðn‘ZgY´Ç‘Ç’»2Ùye¢!ííòÄþÅÐûehH ™úrÓâÊJ2r3Ë>NÆÎt-kOJ+;'»6½O\3Ä$SzW þþˆIÓíșˆgzfóLaSW”½á=ª$éùk=.JR)]@K¨ÈàA_âÊxøÆøÒ®ZÏK»ýÛâ ¹qgª1$þÒä” 躛Ôu7¨,ªù.C_ÊŸD¯?bÄ\nÂCäxõùBBçòé6x=U»Ï?ZWU.,ZY¼¬ÔÍœhÓúDŽØ$ÂS¬0qѱà³g[© Ã>’ì™Ø™Ì¤íl=m=…Ì’ã4»•šg9{Üñž=î ˜Ðnwä¹ÜÃ?Y§‡÷vð¸Õìvk—€[QÛn·æxª$~ îÌO®UfóÙz`–@';%ª”gÓ´œ×1½sÏ`·`è8º{0*s[]]Ù_LR0.Ñéàáïf¾ƒr±9Ç+¿œ?š: “ÍÊÇè=×Ä‚eÙî¡q¾mÊZ$âÁ öÚt€j6³éÇ~b@ޱ:cžÚ·÷@²R|¾Ä5ÛÇå å·­/û`SÈŠÒª¶?ÅO`U$3Íf½ Y·,,?+I¤¸Bca¶iç!eÕ4î3åc·†òá´|žzH»sÊ2FÛ+ŒšïföY£zbÎÉÁ%‰”¥Ì{dy©i.¨õšwOK˜ï±KLaQ 9>ÉØV#ùäL±å áÄw\ˆP9Ôzˆ½³i¥Ç‘öT¼«9gb“¶R 7q6‹×<ÜÔƒ6àô g1 ›T—±·á-­ÚM—r°GCå¥i†ZÓÌSä³J5QÒ‘(¯^9k6x®r^=*£¦)æ$¥õZ¹¥‡KN3ŸpÖD1<& <€šØØrcÇÓ3m¢¸Ö/Ò´®øÊS’ñEäG1ÇÔ'wŽ•(Ë鯒ä:å'h"õ:ks¨Kèð2v¿Qô\¸YT—\D%~ŽÍ0Ív¹¾oiÁ¢CQ=¾C†{¾V_äÑÔ ÑîiÝïâÇSÞD7Òšlò­Vy9ŒŸ ô¿S°TçÏSÊkä®ì©5:¯XDt(¥¡,Tô$÷V¯PQÓræÙ'þ­ÃÈÜ;ì•Ù½ƒ’I¬›£•tºFV.gCåÃ’ãȃ\ûŒáÑÚ×®&8\€dàï’(mã^óÛ\¤óÐ4ÉØæšœ0äøürb1VàA`F>)<¬N÷ºLTs7½›ëä"ìâÞXn EËù$亦6¢¨'LKwêÛô€½ˆaã7zõJØB-%oX­à ßòÈ|Þë¢spuˆ&%0§³Ã&ãÁïé­L³"7ôù¨Å°œN£BhfF±^Ó/f%û€Ü’¶ELP6ýÆlöë&û•Å1ðMt|Ëû&æž­ö5ˆL‹ýèbÐÎó?µ“mù@êF6÷ð#öƒ™;F\…©ÓØX1²i0·¼´sœG'[g¿K¬«\£Ï<}$*:qx8Ù;z¹ƒÞØi’YjpÞR³Œ•ýétf˜‘ä·ÒçÍM]}2Ï”ŽñÏàYv3/g³ãÕ”2Jk..eAù–nyIиà;ÚŸèÞíI­Z;10È\~¤ß™¯úsÑ%W[DïŠãÕñCSrAaR#£dW,N–ÓÆLóøX³Þl…Ý_¼ºØßªU¹SšìCÃݱ\#N„ûbü|ƒçÜ ¸`žmtNï\“§Ú±”¿0ÍŠ'‹»ÊËûgÑìËjµ£¹Àk¦Ðúò2¿ho“?Ò‹¦ÁXÓgzÓeµjC¾ÑÛ¦ç—Zü…Þ¸²5>Ò§(4…¾ð;/&Þåߥ&µç—fø]$£?°Â$ïFZ­ÖkCú ½•Ö”}§÷ÖÓvÛß±™^æ›|àÜ»®ö…–’¸È“4[Šñxެ<œÆõV» ©¿˜cwt\AÐöONO%áø–’p$J ×{÷äþ½I0Mv'/Ú駃­<Ž5(öóøßgblq¬ÙlUYOp*f¬Üjײ“Ÿæli_}Bý&–ùß“(ò@“Ò-q¬¶»«Ì~^r' œÁœÀ;ù C©ö4½Š9zKží(öWìX*>r+(²,[ZC[äö¼¢÷´¤=Ϩ<†aôàži‘ÅiÒ³ˆd…|}|]¦µ.Bèˆ{ìPÔ<¯‹6|˜¨:5†÷:t8¶ ®½íàÅ~L®t4ÎÅ~r˜bvÇ V…˜öäh‚Г³Ê–ÃÒÃx EK‘s M|Ǭd_–¸ÇúÁ[ð•óâ+®×¨A~ʪÐ,áVùùâë‡ÆY’ã–Ô37¡[s3‰ÍWš—–ùÈð Jy®ñGi©Ôxf¹jqë9Ý„ºñ[aA#x÷–ÖdÌŠS”×RMQ¢kw‰…l¬d Éš‹àêÚ’¼W“™Û‘>”4Ì´(VIpNlűK§°nõDŽŠ¥-§àm"y'”ѧ&fÚ^|%ÚœZ¹z ’å~ÒÒE1 ásø¦'¨µ¬†3´Ð5e™(<™ZÎðÒdbbB0PŽk_ÞÓF¶G¤v‚ý¾SJ{Ÿ¶5é ßíeö:—ïî o*Šìx­{1F%©¥Ü‡¢ß”døäÉ&J‹öäGx›¢ü‚å¤NyC)áK ,(E­«YšêíΉuûB•t¼e»æs.“@êâ”™AbFÒ54ËÛ6ÝIDzÒwë}ú\ .¸·]N)ø͚Xœh—Þ,ócæ^#é8µ¤Ó¾P4­´æ^›h'<©Xš“Íq€žÑTmQ%«" ÿŸ*Ar~SFrÍLåô\Íž©5¥þ«UãÒ$úR2à±6!©ã¶·[ÍúuâNr<åüÑ$–üŠic¶^V6åÏR¦®KFÜÖ±V)¡s<ýåÔÑFç {–¶â*Òc~R%å¥vs¡ÜVÏ=“‹Êeøã<÷¢<7ËäÈ©€©l=——þ\ZÄ`5=†z д °»ä ¼€Ö¥¬ —ýnØì®ËàBó5q¾ŸàÒ ÿ(ÝjÌÚ`ÅÓ‹¼’ä»~ü³Ü´Æ´‡S*Ö¸#{*r\͘p®ê¡@cë9;3óDT_Étв/F´Qà#›|ZKr–½ôßOé¶ISÆca˃,|â¯ÜʱáÀfBnJѤr)í¢ñ9ê^JiJ¤‡Ï¹,çfF¸U^œ—yß²$’25L¿ä5³ìÀ;ôKÚæ!÷©}~`®‹íW$KÔù´¦ùù¶75wn¶ÝT³Ç›|º O1|2IU-wµíR«”‰ÚÒÖŸ&W¬2l‚ª©VÔ=ÝbÏFúŽ\éuÜê^ïãü¬Ô4áD]—äPNŸªÒ±F‰3³°kÜš”S¦JÒ?-îÝåôrlg‹vÄ„&×”©Î‡¢¸‰)ë@Ë|"&¿ö86éu>t›^Ái­£–ºs˜äÌœ ­ššx^²ÙóUgl“s^ä$Ÿ§Um0E*¹Ë65Öåôl!05[xùÁXZj7‡ªÄj¹×øþ"«ˆ31'û-auÉ(]PoÙ»„‘®¦U=]¢¤9ƒ@¦é´­À H ÓÆ˜•"•ìȤ5™¥ãÂ,k5/ËÜʦ3¯hÉlOúɆ0/ie¨õ²’Šü+®ÊWog^/¿P:mÿë^¢fÜWŽ:óèS¡uÎÄÛ¨Šá,¡ÃÁ[rVˆ?ÁãJˆ5bö×Ò¤ºÒe‰õ`m”0yq±Õ¤ý³Ý”ã*Ðøfm%.¹íi7sáX"ðÿ‡ÁdëÕvŒeea1¼‘?î aj<2)Ö*óÍäl) ˆì2¸Õ³w<Ò¿)|”žªg5üó É½ƒÁ ti6£6;K©AR›´q&³‚þIjn!´6éÜ4£5Ƶ¢ùFËÚæÜÌ’‡Žu-K™¬[|D¢>Ás½É‡#9/%™©þÀ ñ°óMëEÔPÜò]ê¨U´¸Œ’%Ò¢ó;ôèoVôj©r²ù,V…R";žÕ”7ðeé3.rmâ×Ü0§“V6•Ýâé«S5XÝL·8³„¤™æ'íÄO¡DdpÃtT%Õƒ 4¹¸ñyž- ‰wm áA˜Ôc§œÔüV²ýZOì¤ûÌ&bš\˜<èaÁâ´ö$ұMBøë¥…¶Ä.HéĘ$aI¹Z¼_ S»\Ò9pÇÕZ¶HDÇ¿@‹c†—–Žt>iŽdòw(Ù»ŽêaÝÁ+J9~)ÃD3À†Ýh‰£yQˆ Fw0»­I¬XÜ\&ý!îZ o•jãB]®Ó’É€7{¶GÒ{êµYN©Ï›‰ÐRá*ó¹œm›(ÉÏä3ï~ãÅÏ?ŸsNîe´^jñ ॣgìÌÈy³eZyÔItZà_¡›»œó$D!µST¹`·ô¹X(:ƒ[Ïb¹ÈM• 硤Ç0s¥øhØiˆÈX<ùÑ¥“vüDžS»‹˜løCÞˆ¤ÅÎT\ˆx-æ2›&žkÀµpÞܽTÆ.G%÷¸CÔvÓ‚§ãA¦jm⦤ÐÝ\¨Ìx÷”?zÍFŽG¢chø$ž[áÁ>(±`™¤Ì7Ý¿DüÙ3ÈûdËTF™v//rði,į£o™“ …ä%oà|=õ= Ê=‚‡÷¸™ÍËÔ…Y½¦ò×üù]:€Z3ýÌY‘~,-4JÁèØ)‘U;aÀ=J{WMØ5šó-:Ô*©,.’»yxzÅ u UÝR¨v(%ûÍ@8ÖÔC¡öZg¹!²ØÌýDÕ¤çérºR_?}”éïweö ÈØضӔr¾+¾–œ`í]PLŽN?l”Ó¼F©ªÜN}:å\G5)=^XÍè²8\áU^RÇ6áA|?óʦû(6­7žv’·yˆ€ÙÚäJ¢ókÅ/ˆéÑ.¡×Y…ñÛ|Ø -ôjš‘Le %›3Ë6‹“}ûLí±U³ØÄÜ\f2<ñ‡k%º ^3‘Ò‚N /üæÏoþüïýsF¡°¸0¬F€ €‡÷½u¡p?ààáÀ T0 ¼ø…ÂK€Ÿ~Âã€Ñ; €ß¥PøpÉ]Qð'w+ž ü(üv¡ðæ{ œuŸBáîÀa  \4GÇ€§¿<x6ð|à…ÀË€÷ÿ¼äA…Â+€ÆúBax5ðZ ¶¡P˜®ž<ø2ð5 ðã|·ð…¯áëùÂû¿ðõ÷ÞRx#ðºÂ«ùï[ ßÅ÷×ñß·¼N?¼ªð ùûÒ«n³åÌÇo=óñ…[áß[áÃåKÖ ·ßÉ­ nƒßãž»ŽáÚ~àÀ£¾÷¸:vÉopGÿn¿á’;èþv÷5(÷*¬ÛœÙG¿<³.œ%?¿œéžù­-Tb‰~¹+~¹«ý²¡p;þ÷>øÝõ0ÿ¾.sà  ÃÀz`C07.Ôù±üð"àíÀG_gÝZæÍ9`H?~οèËz~‰nûá-÷%zé*oûe}éÝoÑ—ÿ*tûÓ×Ü‘×û­ÔW~P_?îCßw.­‰KøÍŸÿþœqæD­Ç[ýV¡ðuàŒ~ÐëÛ‚ÆßŸAÇ׿s¡ïÿ¤t}êN…ÂÏ*‹g }Ÿ»³Ðw¢íF×ôCàuw/¾œsBa髞çó¥÷Âùþênëýå{á—Þ5øÎê¾|³ç—›ÜüçÖw,Üö!…ÛíÆpõaˆúÖ¸_nå>)5¸7Iýž…Â+u>¬ûì÷Ó^|ÿBácI¡pâ…Âw[ ºŒsÀ¥,Þ|ø pþC …Ck …s …󀋀gïX©ÚÿÑóÊ×W÷åœV¿’/½;¤s¸ƒ?6º·.œµŸún·»P(þã­ }[s›;>éakÎzÒ;ö(ü{%þåñ¿Ë·€Û ÀùÀ~àß× N¡ðÖaá¥^­<ñOÿN|ÓÖ÷&¬ÿÍà¶`Ì7·ßŠýä¼BávÛ1O€p°¸ ˜~Vùt¾ü÷ÿÍ_n¸Y¿Ð›·‘5¯g=éØ^S¸Ï×t<¿¹AÆóG:¦“:®gèØÖñ}“ŽñtœwãÀð<àEÀ»1Æÿ|(ž_(Ü ømà€g¯YFYÀ[€÷g?s˜®ž <øòã±ÊýO(lþ3ÌO` ¸8 ,Ÿ1 pà%…Âà-À{€¿´PØ<¸Øü2Ô8<xðàÀ^™xð<àÏ€wïõçàs§Ï^¼ ø8ð5`ó+À ׯ¦ÿý¼x#ð)àóÀ­_](Ü8 œ~œùÈ6ÀS¬íøï13~öcúï¿sÆèö·×ïü—¤“PZ)ÌÐzlþxðJà-ÛeiüF/ĺh¡ðÅQH c ó» …Ï_î:^(<¶ÓÀeÀUÀp¸xð“pRÞ¼_n^F;ZA_îyÛ¯þ ý9ëVXÝk¥ÿ0QúƒÒo¥§U¾ág´âïø¤ù¾GDzp/—·ãÙ_„½úbÈÚÀë/)®Üƒ±Þ Ùä?à<à{ðû$äwàmÀßž­À€÷ß§ …*ð'ÀÄÁÓãáNg㌤´¯õ¼-úòÅ_ã/+n÷-_ÍŽßW¸õû‚ì÷¤±¹h¯º¬Pxì…Â= {X^ \Üç‘XßÀSwÿ”cœçný(ÐB`X^|¸Õ¼ìÈJ\No®ø7_VýEþ`dW3pç½iLàQÀ3ÿ¼x/ð~à£Àž2ö,àä öˆ*x1`]­Px9P->8‡¥Ü1-þxäU˜ …Â]ØëÛ-b.<òcë×››þ_óžÞ_ÜŸUòÿ÷¦1ùHÙ¯ Z¾> x ð^àóÀµÇ@÷cŒO€–ƒ'»ÏIŒ=° ¸¸hO^ ¼x7ð à?€3[(<à÷PŸÇ­º «Üûn^ùïú_¯/«lœü±ý¼£n÷ž)ôÿ^4. Àãןþ ¸/xï‹GOÞ| |øw€û> 4áÉøý)øüTÐ|àpHãÀó€¿Þ |â©¿¢±Ê/7ïÒ]¥Öâ&Éÿ±Ñ½íªå—ïkž†õŒ£À~àp øcà5À{€Oß~ Üñé…ÂýMÀßvþA¡ðà;ÀÂ3 …Ýx‹òý¿ú/½iRt%’">ÛóÊ¿:ÿô÷NýùáèÏeø[ËõG­’¼c0K ÷ ñù4°á1–‚½þ™7à× /¼ò,ð—À[€5Ïÿ<xòuà3þ´Pxpîs±ß&žžøöóÁG¾ Pø÷œžþæÿ[Ým7ùKï÷DcóËúÕàs…îl oï>Ýnµk>˜/…{ÒØ<þ…Ý€¿^ð"ѳnås/Ê[T—òÕ¡WÝ éMörÐ Õ¾äéªù¸êEH'2þJÐWžÞºùÍ—SÉÿ៷þoúOãræ«DgõZÕU‘žŠtT¤Ÿ"ÝÔ­^‹uÜxðë±¶ÿûýÀ'_ÞòWØC€Í](| 8ûoPæ …;ü-ä ü&ðoþ¿b—HÅ*¿Ü¼¥E_rnôNP¸é7`lζ}+h;ðà÷g× <ø[àöoÃýÀϳþO¡pw Ö[mÀv`¸ hËÀŸ×¼ ø àÕÀ€¿Þü#ðoÀW¯wx;æp_`8<xðDà)ÀSgÏ^ü p‡(î ü1ðlúü^4¸7p` °¨ËÀ³ç/^¼ø p›¤oÜxpÛ÷ wÎîüð,`ã?a ~vÆXðõ/|½Àj× ¦½Á}¹ÁîüLx±ðQþÿ¿ÁTèåKr'òí°+ìãq×ð—G¿vñ9!]paŠÖå¡·`¼þ} üð1àGÀŒõå:æŸ Æý p9ðhà€k€7|ø¡ÎÇbü.{î{Ǫ97ÙÞqór½ˆ¾ü² ˆXE÷g«;àÞ û?ÍsÿcûN¬9»@÷ßuñžBax ðà¶ÿ k ‚y¾îŸ …ß{?Öà …¿ÿöú£à ïv kx#ðeà‡ü<x7ð_¿E üÿ„_zO³Èžÿõ—7Ï’'tô Þè>D³ŒbL/jÀQ , üðVàmÀ–­vç×Ï^¼~ǼÆ€]@¸ ø×BaXl Ì  Ìu`øÌ«+20üðEàKÀÃ0ß.¦1ç~x$ð(àýÀG€Ï_¾ ü¸;$ª{÷îœ \<x°sv+°í£¨/ðà¥ÀË€Wo>|ø<ðà‹•y>ð < œ\\<ØñiÈÏŸ.T=÷)øÇ®„ÏÈçoñÿ¿ôYüÿ³_â!õ^}Ý)~¼_¬@ÿ/¥õ8 õ~p«O %à àjàeÀ‡€ïg} ýÌ^ü=ðeàöhï6`û§¥ý®ý Æì¾bîÜØü¹›Áþÿ¿æË*‰üÂ/7o ‚?¶öCzpš§—ÏÁX½x%ð:àÀ?k1~ÃÀ¥À#'×꘾xðFàmÀ÷ilg~{ ðNà}ÀÀ …K€ ppé …ÃÀó—[¾„5L@ >¤@ ¸à+ãÀï~ýÊ^¼ x ðQàzà+À6ðÈ»+Oÿ üøàÖ5o }ó¸ø>0ô-Ì]àõؤÿøpûoƒö,ÿg¡ð$`çw@{€EpÎÿ>Þ\\< ¸¸xî÷¸uý-÷ÑŠþ~‰þû-þ/AöÿV@ìï—+ûw¬ÿ.4‚×ÿe´ÇiË—a¼Ž`Œî‡þ"ðàÍèó³¾Z(ܾûUéÛ?^©}ümôé+þ]úóZà]À§µoß‚¾üôÝÑo3ßûå-¸U>s ®¾_ý—àOß¡Ñú§ñxæñkþ«Pxzâ¥À¿ßîúÃBá`'p>zö`¸øƒA>êxÛ®Ÿ`lŸ‚ûªþkø(ز…_ ¿ø¹ø÷¦¯püŒ¾_ƒ^éM}¿~¹kp:YåL×?<ö}]è?Ѩ>Üsà¾À3ç/^\„Ú L— Àc~ 󅿯^` X2àCÀÇ/_¾ üøoàç?ôsè}˜?ÿ|ø(p%æP˜€Ðü>ðTàóëaÀgŽw?ú1Ï>|ø$pM-Khõc€—Ç|,ðÌÃþø8ðEàKÀ€?~¬¹u_á·€k/þè»M_áVÀ?þÊ>| :³/düˆÎ) ÞŸ+|¿|+ºÎW>îoº!P¸Ï"õ_¼®¯pSï€þßþošÖã `x ðDà®h×ÚÒž<mºS_á,àþÀpåmû 'o×W¸m±¯pðeàÿÜ}z'ôðià•g¡ïÜWxÐ]ú gÞµ¯ðmàtä¸höþ²Êg¢÷DKêt^z“¿¬ò¥7Æÿ£_åýýÜ×—“×-¸7Í× À`ðàUÀUãEà5ã¿Þ ¼ø(ðIàSÀ§çÝ¡¯ð à<Œý.` Æý<`h×/þx/p+š ÀqàñÀßo.ÃܸxpðIàsÀ™wü&€À#€)àeÀk;þv_ánÀ{gÝëxʽú ¯^| ø<ðc`ͽû çë à]÷í+Üî~˜ÛÀÿ| øà?? ÷Çû{ëÀyÀùÀn`ðdàéÀ['}…·ïþ¸Ýút-ÿPÿý>ù¿yîNÈÁõøkW¯§ÿËÏ_ЂøÒ·VÖž’+äõ9­IêÓŸ'´?| øp;ôç9À`¨³ÀIàOîîûüÓÀg¯ÿÜé}…çã@ D¾yÑ—ïöür“Uä·à—_}Esúý wþžÁªïBîEãr ðVà'Àmï Úl6ÓÀ¥À£€cÀ×o¾ÜëjðHà‰À“ï%ëÖ×$ÐŽü1ðË"«ÿk¾D‘A7¹´üŸæw›÷¦1yðv ï> iÀ!à0ð$à÷—ïÞ|øàÀ€m ¡;€ÃÀð'ÀK€¿þ xç}…Î> ´ñ÷ÿÍøß,_z‡–åÿœrüiL^}êܳû —{€£ÀŸüø9pæû wî <8˜ÚÀ“€kWoÞ¼ø8ðeààçÀm„2€»>è×AüôK<'îKüÉYÀçCÀ“€g¼x'ðaàÀ'ï?±ùl™?ß~h0²ß—Üfû p!° ¨‹ÀA_€§×ÏÞ¼øàCÀç€/·†äsGàRà‘@hÎï\Ì  |ø(ð1à³Àç€Ï·)õ‹À1àð»ÀcÇOž¼xðà߀ï?~ü°vü3°Øìì&€}À¥€Jr7¨P>ïzcøX¼A?†¼`Þ*¿" ]ø¿UËWÐZÖ—Wo¾œõ`Œ%0<x3ðàÀ Àƒ1Ö%`=p¸x ð>à?"óaãÿBà÷0†Ÿ<½uQ¸ß¬á•Wwü'¢ù/¾õ£€hýß›Æä*¬£‡ÐÜÆ<_ñ¾²ü:ð#à®#c`#°¸ ¸øðsàÀomÄuà(pð"à%ÀK÷ÿ Œoê+ìÝtzsàt»¿ùÒñ§CÿK´ihã l¡1öÆ€»bìï,¿¿AæÄË7c ·@ÚÀS€ßž |ø6pÏ­}…ûþæ\ÌàÀ¿_¾üð?ÀÏ€¾ó@›;çoÃ\zX_a;ðp`X>|¸Ã(êœ< 8w'öàqÀS§ëÆ0gÇû [ÀÀ(ðp`¸x.ðŒÝ s/îܸ 8T€«€þ è»|pàÁÀC½À$Pî;ÑWTvßPR}=ÿ¥OF¶åŠýŽÛ¿ñ)£æß¸Á}ü”#ðÁŸ»p¦˜˜ÜÇÔ~µÚñÿ¡õ¸ <x"ð$à5À뀻`¬ï ì¦1ËÀË6Ë<ر~Æ÷ÍÀûÙseìþ x ðvà‹À]·cŸ€ Ûÿ/çý~ÍUîOÇú§ñ˜ž ¼ø3àÅÀ/€¾}…»` x ð*à5ÀkOgœÚ<xðÀ€ÿ~ô]ÐWX¬F€Ãü†ÿÿ•}Éñÿ4_¾ÜéBÐH`'p p 8 <x<ðàuÀ'€OSí+L^ |ø ðyàÖ¾ 8ôø¥É‹c¿ÿ_Ù—ÜøÓXüpð6à+@ÿ.Œ?0 ,/>Ü ûå}s€áqÙ_ï–=ôO?Þ |M÷Ô;ë¾úÚ‹do¼°uâ7c ‰v ÜŸúoãòCà—`l€3޵º4¸×޾€q`0¶{ð\àö÷žüîìõ@u²¯0œ^¼x ðNà}À'ë¯_þøPœÂüž<¸X3 ™øàÀ;/ÇÜ®þ8|ö < ¸xÃï`¯d_áo·4k}…GoÞ œ1 ^xÑ<øàãÀW€¯_¾ ü7ð#àÇÀO€Ÿ“*= woà3ðÀ?×ì+¼xè"ä~àGZ¿­¿£ùÛõøßõî¾~¯§›>Ë¿Ð×ógüÿz¾õ³…Oò]ŸuŸÕÊ÷¼à8ûßY…GR¦Á³ ·êØß ã~àBàMÀ›¿¾ |ø¯Kd~üsã5˜¯þ¸Ë>™êÁÜøào÷_¾ |øé¾ÿ­ëÿ§šûÓ±þi< XÃýÀz` xÜ~YÛÏÔõý|àÀ›€¾ üxÖü%À^àw€Æ¡'•\|ø­G LàñÀk€<â7{À¯ìKnÿ§±øP^ ¬~(O =,hïƒöœ\~)è,èï_o½\hï‹€ÿø¢Òâ¯gßûè 0l-ÞñÈ_;ÿ¯[ð™[ðKdZi¸ÝŸ®þ4{MG°w] Y­Œ½¸0_é+¤À/?\ìÞüPÀžzО¼ø!ð[Øc¯ž5›óûY¥[tôe•DÝ]‰¢o¾~ùÌên‹¾ü²J‹¾è¶ã¯¹Ýî±e¿¯ã—Bø >äž46o9‡1þ¸'xå}¶ƒ×Ù\\ü°á(Æyô|σÝWøðW-ðgÀ'¯_~Ü9Ëù}|»ç—¨©QDtõ‘ž_¢>~é]Ú¯óþÓ×çÆrÒ]Þ—«‹mwUsâÄ«¾ xÿ¢Œá'uìhÜ.h÷vŽ/^ l9†y\T€&°\ <x ðÛÇA÷Ò2d>àp)¿ \ó˜¾Âó€ç/îx5îT€9à*  ü(ü.xMà·{÷ö^ ü5ðà_€'û 2à1ÀÏ®®õX¼8 <ø3àuÀC~týnákøÿ _àÿÿøcòÿýHá}…·¿¡ðZü}ûðW>áïøòkùïS¿‡dÛÛÉmÀƒß†Ønüú(|*Üy ý|~>ƒ~~þY“¿3rk\¸uK¸5[ùäq{¶‹'è)lƒ»hœ¼ãúBàÀ'– Ca ÿ ã÷oÀy' ÿŸÄ¸} ø:°[ÇîS:v4FïѾ§~ß„þ¼}ù]à¼Ç¡O¿ê}ÿ&o´½ILïg¾ÕóJï$=7¹:«ürªÝÝÖõHLÛ#š ñžù=à^4ß_¼ø,ðï:f?ú0ng¿ý8Ã1à p9PêÀË€×ïþ¸Æù®À9À üðYàkÀw€Ÿ·zèp'`ØlÞüð!àËÀWï? ORàÑÀc€ß^ ¼x7ð>àVOê+»R NÏ®^ ü9ðð'÷öOž¼ ø;`ÍÓ1Ç{/^¼ ¸êL+~\øÎõ ß¹þ;ø¿ýý±|ùg½©ËuzTÕ×Ó…^4 Ûú?=­ÿý´.Ÿ Li_÷Dé“KÐî' |xîïK?Pûÿð0–Àë€eôÁë?üþÂÝþ¨¯pø$pë?Æü!ðwÀýž¹j߯Þq«Ì¯}ó~‰–âM.m•í‰X™ÞWÜŸh­?éV:xýnôà^4‡Ÿ!ãøû:–oÞ ¼ø'àC:¾ ¼xð*à±ç'Ožü3ðA`Æ{ øcàyÀ[>|xòŸà~àgþ‰Ìû¯^|¸¸Ý³°æ€{N^¾8ûZȪ@¨Ož¼ x0ölÈ'ÀðdàéÀ»€Ð÷çà½À €—¯þx'ð~à£À·ï7¯ÿl ì.~ígßÑUÍ@ôgô/-òKýÃøû^£òU.¼Wè½÷çtvÊà‹Ï7Çúßg}¿ ø$0€~þ>°ýü×èË Ï–þüþ³¥OLíÿSôýs±?<ý Üõùèà*àÍÀs_Þì…ÛæöüÞ;ûÞÔ/_íù¥7ýo§ñ¥÷{¢/ï;/ô§Û:Ž~{âlÇ¿´Çê$Ü5ó!M¸;Íãià2àw€ÃÀÙó‹äìÈóðÁÊ?ëI_ýÙ•@W_ïn´åž4wï¡c>š@8ü®Î…—ß~œùpÖ‹e~ÜØLè\9<xºÎ›·÷Á¼y°¸à%2—v—U ŽÏž <x.ð5ààû:÷ÎÀÜ›ZÀïO}©ÌÇ?bNÀc^&sô³0Oï <Øœ\ür™¿W×ÿü¸õŸËœ¾=p'àžÀ§¯ß~ôa®ßñ2ïS`X~­ÿ¾†þ2>ÐfþÓ§öíSüéSÿê~òÿ÷ßü÷Ÿ®ÀtÏu㨄­ÿe]¿Ÿ®n…u|&ð^àCÀ§¯7`]ÿ¸Öôý€‰`ßåm ÓÀý[þhp%Ðî÷vüü8ò޾Â5Àó—¯^ü=ðn ý.Œðà÷?ÞðnÐyàîïí+¬6nø'ŒÇ?c>üðý¨'ðá`/øWðŸÀó?^<ムûu.LË@á‡ß(|ÍIiŸþDácîïûw½ß}ýBð÷M…7}  ß_M5ç£gʘîšn}Z=WŸúeäß,ó`Œhsñ5?`xð>à‡ÀÆ×‚^¼øpïס߀?þxp«×ãÞ¿?\¼x×ú ß’¿Â¸wþkЉ¿^uüïéXn²!áÌKu“¿DRhïÛÂ?.ol|„ËËù¿iL*ÀËÏ?îö7 ×À,ð<àÝÀ{/ÿ ì{#Ö)pø°æo±æ)à)À§€Û¿ <pø]à9ÀßïÓJsàæŽ_Ö°ßä÷œN«,:÷'?þ÷¡ñøp=ð}àoƾ _^þŒíßõðVÈÝÀ.à/Ö_ \ üèü¥Jã:¾Øû¡÷~ǪåÀÓ1ìΗޥõEî]@Ä~-üò¥žWVùå …þôù<À¿åõ³_/w×7«ý÷Žñ¸'Í¿¾¼âïû ïxg_a+öÚ«€¿Î}O_áeÀÓ°ß^õ¾¾Â?cŸ= {ìð ÝoÏÄþzà╽×öÚwa_ý8ð©­´ö{§î[å—(—ÃéhÓWù¥·©àWÿÅþ¨Œàô|ùuß§¹`îM<Ïã€ÇOþäC2^úaðÚÿ øð5àŒ€?®þ ø°æ£àÿ€»À^àrà•À«³>Z,¿<x°õã7€pXZÀ1à1À‡€O·ù$øàŸê+ Ã@hþû3¸þYÈ—ŸÃgàGÀ]>:¼xðŸÀš/€Oî ðé¯boúd à‘ÿøUà̯£<àíÀíþûp7à^ÀϾWøfá‹ø‹ÿÿ£¿ ñÍŽ¿_ü ~ÆüG|y}ý&?¦×¾Ùãàœžwsüb±P¸íáI¸šì/½¸QŽÿ¸„ÖäWï?nƒq?˜'§}8ž4îÜxð `p>p0 \ÿÈéÙþVùåæ-m•ïéí¹ÐûËçW÷å”þú‡×·ÆôõËç³x½¿øÖ¼Îÿ'4À­ýˆþÓØ< xz°¶ÿ˜ÀÚ}&Öéý±`#ðZ]—Ïø„¬ÇõÀ’®ÃoßøiðŽÀ°¸ìÓ}+ì•ßèù%Êßû¶Ó) Ú_O§è›ü%Òý|¼ç•ÜŸžóØ.ž)c»x¦Œí­üßmì»Í‘{Ðø4§ÿü+ðuà?iÜ€Ûƒ¾ÞØ\®< ø;à†Ïx:<ìÆÃ@<x6ðúÏÞÜt ÷Æ~“iÇ-HHnÁꄺΑÜú¿7ɇ€_¡ñî€=t p¸H“Às€×ï¾’Ûo£ûíçt¿=C÷اÏþ¸øÁV-ÿE_n²\v“¿ô~ODߢ+½…‰›,t®ò‹ñÿt¶ŸXþ£ñ¸ÝAç-Ày@ ø=à ÀÓ€?^ |¸Ý—0?€»çç“ÀUÀs€ç/Þ |øöUá­/?ýïÀ7€3ÀO¿æë«Öÿý²¾Üäþ]¥ ×M¦eÑ—ˆ‡Š®Øõÿêà:ô¯QY§ùfð»À+þøWà’ƒ¾ÑWØœ  ¼x'ð5àÀC¾ÙWXl¶çµoÞ¢c~:cq“O]»Éï‰nû|øå£…îºíåÝø¹ñã{é¸ÿí·ú oÖþÆxðûÀ÷€åoC œ>|øðsàÀîÿì+ìþx}þN_a¨ß~ <ö»Ø€O_nû½¾Âg~:¬ù h 0ð?˜sÀp)ðVà·ù)æ0,¿ Üégx8¯°¦° øÚmÖÆkMáÍg®)¼øØm×>|xÉí×>¤Å5…?ž\¼ø<°ók '¾ 9Œþ~¹ð úÿû¿ü ¶õ}…ÿ‡¿|Ãû¢¿Ÿ[ð÷ø?™…¾Lÿ|¹‹UG$þŠÄÿ@ïÙ£r}¨X1CG<`½AW]ÁÅ´>xðjà³À믷Ŝxðp`?ð8à‰ÀS€§}Ëϛϛ0Ö›±ÿ”ñþÒwV²û÷Všöþ°J/úÞ5ˆŠŽ¼|ÞßóË?‡_"÷èÊéÜFºéh{Êr»üö°Ûùµ¿x&чÞú€ ¹;Ñûtý]üðCà°¦€ë¿þø(pæáp¸x4ðTàÀ€÷_~ÜïËãÀÓüÁ¯ð+á~Eü_ÿOãño@ñ‡ ±ÀŸ_îûß}…yà-À É—ú#O£ÜùÇý€»%à9J³'”VÞ¦ô™hó_Oýùÿ¢ñ?“ÄÍËéÝä/¹?¦÷7:sk—÷þh7ðR`;öÏGgâÎ/½ÕšÂÕÀ±3Ö®> ÜãÖk ÏÞ¼øð˜ÛȾ{—ß’½÷r`•}ú_§ñåtä°Óq"Ìp½¿|ju·}°ç—¨€^^|òk¨îäöòÁG¼ýçnàÿh|¾œþèþÀugz~‰ø¤¿î}»5…A`° ¸ ¨ð»À€—oÞ¼øðYàzàß>ð[7Ypþ•8øõþÒÛ¹ÿt ¸É¥åÿtØýîÛ îMcr;à,`Øì.æcÀg×Ï»½ç¯ ^yñËÀÁ¢ðÓÄC¿x;ðå§÷ƒ> ¼ãkN‹ŽYí½+þ²¨ï¯¾¹?û?É7Ož | øÿ€oÿsºaMá `'0 Ê@ ˜€ x&ð|à­À»€Þl¸ÓšÂVàg: ó x"p ðzàÀew^S˜&{M¡|øpÛ(ïk /üÌ)à›ÀO€ ¡üG®)Üé0Þ}%®Í¬)|¸}eMánÀÛ>Z]SøðÈê ¼xp›Ù5…ß®˜C€§Î¯)ü!°9Å\îxÕšÂý€‡‡€ÿŸ½;¯áÚ8þŸÉ"ˆ%DD[í[ìD[Aìj_ŠZ‰ª¥ªH­OU”jíK½j)b)ªZKKÑZj© E´ZTm ÷›¹)¹‘‰qË{/Çç+™dægæΙ3sgn|v냿ؖâߥ¸#qw„“š}ü»”ìßWI_ã6Åi ðHñnlÒÝÙúù]òwvSý?³guæ?ÿ5PkÅØ÷Ny9A€º¸ª²5Ÿ%3ñ>Nâ *äW%S1Ÿ`;¾ÂUÜBNwU¼Ñm0£åžVÛ7îåŸV[yž'Œi5wëöž¢ïׯÿi9ù76#‰ÈU@•ÌÃFìG<þ‚«‡*åÐ]13°ßà[œC­1 ñö[ýÆ–A¤ñ~¶%€ñº¥;´É ãhZyÔû€V×ÿ´œÌÅ:lÀü‚ß¿ÇÔF ´B$†`2æa%b°ßá"ì+Ò?Àõ€ÎMÿÓ½K£Y½ã›îœdl†m‰fUÌÞó›<ÿZ^"1 ‹±'×JÔÔƒÂ0`WY•šè†žŽ‘XŽ•Ø†¸€_ð7¤Ê=þ›ÜÏÆLŠM†¶euÒ½ŒVÒìÿSÔ…‚ZNJ¢4êÁaˆÀ8LÄGXÝøWàPU'x "ª  :#C0 ³ªšîómiOp[Ú°ÉÛX¬èG 'RÃwø’÷õfïKªîZ~fÃÞ‡1|Ñã1 kqGq÷£š*^ÁH¼ˆC¶êÔtǸê¦Ï÷liï&÷¯ñ„q€ãæ&¬îÖ³š0¾Ë'íû´’ZõœåÎÙ–ïý²k÷ý<²}?T?RÔŸüZŽ&b.à3œ@rÔP%7ª¡9ZbfB©Éya0ÞÁ»Xƒoñ3nãÜj1¬eºï·º1Ìä„-ÖG3YžÉöX…~¬¾>Õñ¿–—îx£±;ðìj3†C TGc´EôÇ8LÄ*ìœÄ5܃Z‡Ü×QÓèIm9G6Ù/›Ì¡Õ„qÿoÜIO˜á'x´åX ôÂ(ÌÃBlÄfÄ!W;Uš·³íþïçlâ >±eËm‚Æòˆûÿ´|ŒÂÌÆ<|ŠD8·'g(„þX€/pÀ¹ó¡<:à5ŒÂ,ÌF ¶cNwH1°åž>«-Lw4[&2öuÒÍx‘‡rž¼>xjù8‹ëpx‘BT„/BÐ xÓ± ›ð ~Äiü…œ? $|áјƒ…XÕ§ÖŠž}5¹¥ÆËä«Õ5 «#—Vþ9Œ îç^¿ÿ[ËÉA-/ÈÓI•|,ÏWt@W ÃlÅvü„8øtf|‡`„`6æböá[œÁ¹¤ç4*¡:"»üõÿéNû³ŸHQêÿµ|LÄd¼‡eØ€M؃H@™®ª”C-ÔA; Æt|Šø{q7p ŽÝÿÃeÐíüøÿÜçߪý{jùhƒ0ŒÂT,ÅW؃“8…ëZþºsŒG=ÔGk ÀLínyëÌОÉB"î¡bŽ=™·ã‡ÞÿùÏØ du*c¼ŒÕåÂÇË¿âšìÙϤ¿¡ç¿²çá ãd²çßÊ£QË3p7á0@W”ƒ?Úcfa%Öcöao˜*'ð Â9GO+ïV…›Ü2ãgkL>uc2€ñ„ñCƳeìº=T̾ï£×òï¡å¶;z'Ëqޤz“»RaryVûž<¾=H•™8… ¸ˆË(¡JUTC BÐc"U‹cøñ¸ŸWT©‰ ˜ˆ)˜nCè+0ѰU•lȉ‚(Œ"(ŠRãáËq—ïÿÿà߉_á[ëÑóóYŒŸÚLþœhZÏ“šx6´²Ö.+!ƒ0S±b v†[ò>…\Æ'Ëg,:’¯NI9ô#þIù0¾Tcüv¨ñlÆÑŒŸ1ùÑ»V³Y}pñeã¿Ýc<‘qEÿü×TÏëûýß|^R9úe¥HÌÁŠ^1qõŠÆ8eñF±èEÅQ"æ‘k“Yþ«‹V¯>r®G”ƒ_ÿ:â¯Íû]ÞŠ’åÒôãìôS’î,ýÅÿ{H? —ž2H†IýûòLõæ7õ© òS"q)bùò³0}é2„¥k?vÄÌ’Y2KfÉ,™%³d–Ì’Y2KfÉ,™åÿ¾¸Š›d…æ\bwÿ§5Eüþ¸§òÕY¥9§Øƒõ“ðüN;¹w—ÁîÒ-P±ïÁ×°À¬ö¯`Z‰â§0O+–Ì*œ€÷à4\;ï+^RY´ Š8WôO#U%ïҫ⺴®ø•ÖD¿°é%M½, V»èéÅë«zÌæ©Æ¬¢ÇT-1•1‡S¹ÿçr-áX>z,{K,;ëíµ³ÄjÀéÿî)!â Ç I5V5=[’­¤½u {W±üÉ߬eSµ5k,Žz´Æ©F«®Gs$šƒu4‡¤µr³¬•u ‹§fªqjèq²ÇÑ:Ž£ˆ¯8éKú¦ºdM}I'–Ìb½dG±ü)ãÉšÆþ¨¥/Ÿ•嬗wrmõ­/»I]ñ÷»vo1_7iH´>Ä{U¿¬ä%¡|¯]Rê«ÿ!/ó³ÆÔûp~›¼”‘Öé_µu `Ž—dó¶!Þp}^GZ’V[D*H[¿%¢(’Öq\žÀÎâ[F (£F¼,rœT'v¥ºäà_s½¢¯[€¾–YvHR}ÏJ½Ö½¶NU¤Ëy+UX*»ÁrÚ2y,ËäÖ–ñ“Ä.l‡ëSüY3mÝÂõý;\ßž~,5P¿€æ"y-KÖ}ðæ¡ÐÂ[%‚ÖÒs§Á:_"É–Þ@=%ÇWY§,ÊA•x1Ä‹QhoÚ»ÄdðÕ™½Ø€,h¹¢ïµ‡#:H>ÉR\a›“ÚQàœ–,DªR\$ÄNJÊ=Šö3mµ¾KëåJë™)‹r(¯gK¤"*Aë§ê‰VƒEê‹vRd4 V,ÏújA]Z}Ðڎ釩°ã…âaï Jkqâûl"¥Ð‹°£³‹´vÉ“C¤-"ÊvôÅÑ\"MÉ×t^MóˆÜÄʼ"¿ ¬«È«˜OdY~‘ÏÐÅ]dÖc/º9L¯7¼ÈUØfá¾hWDd öáêz‹t*&RƒXMð.vãœKˆ¼€ºh‹ôÜ_–ÙÌ g‡.Govê \ÄyvîMvl(;VeÇvÂz8S‘è ³ÓB9ÔCÚ£/c,¦a–a¶#ˆm^§ŽÈi’åH¢Nø‰œD<\ýEJ¢4j¡ Ú£?Â0 ïabÈG¶µ¡H$V5éHÌ ‘ÂÁÔ ÔÄ!ü¼¹H4>ÇM¸µ - QØ«(*ò¢Ô’£ã£Ö"o´åÚ^¤ú!ËqžXWLÂV\G¹‰…¹8‡ŽÔK„!‹±vD À ]1_ »°‡ÒEdFueßvù ezˆ,ÅK=Eö÷"oÈEó_Î}xÍ~"yû‹¬@v4ŠÑá"ߢÞE°"EZbváffŸ½B<: è¡lÛ^UˆvŒ7±ë±Gñì_):’vö:ó# c±'q…Fñ;tÆdlÀá7D® Ð¶s,?âûqì3„¢ úaæ`5¶ã(þ„:žíAeø£ºa(¦avà(~Á]äš RU±û0Q$W6I¤ñd‘ã¨4…yß"Sù9ZN™-ò!VcÔw¨k‹ñ3¨ °ŸIÏï²ßpA³È=~úô>mcgS±óæˆøÌe?àÇylÿ|â£Y|²ð9îÁoÛŒ1ØŠ-¦=à|–S4ú€mÓRêê¿E>Á18|Èë C—Q?bá‰ËYÏäàêÎ`ÓJö7|V‰ÄÁ{51cDr®¡þ¡ÇZò³Ž>c½HíOYã0n£Ò‘ø'ἑ}ƒ¶è€HLÁ lÀgø7‘ˆ76Ñ'lf>Ìþœå¿9§¡“OØB?ö%};& Ù¶R/¶‹ôÚA=ÞEýßMÿð ýß^öÏ>Ž1ûé'Ñø ûëqîßQ?1 Ûq/|Ï46ÀŽJ9¼ˆ‘øp.‡é¿Ðc0_â œð;ÔF4ÅÌ£‡~ ¾cÝP>h„6ˆÁÇ©Ï'øý)Úæaãi^+ŽãÊã*ºŸeÿaŽâ÷Ÿ©£ç8.^àu° Çñ'6]¹ó+õþëú;mî2íäªÈ[ˆ,Á·¸ ×k·€ºÒ磺cÊuúp ¼!Òð&±p÷}Òmúmú‹ör‡z ·»Œ­áȾæè>#ðÞ„«ªHe;EÂ1ÅìÉíÀŠ <º;*2*‹"Ù²*ÒgðEvEö8+ò5ŽcYEr*R<—"N¹ù-9ð'`xEvá{ÆdÏ«HY„¢^BŒB4ÞÁÇIüŒ;ÈíªH ÔE#ôà lF²åc{P>hƒv芡xïásœ‡³›"!èŒ71”Ÿõ ÅTLÃ爅â®HctBŒÃD,ÅVìÆ ü†¸Z©ƒ.C4c5Ö`+¶Á¯ "G±ÊS‘… F`!Ö!‰p*¢H^¸¢(Ê¢/†`fâCÄb vãÎàáèE ¸¢*¢^ÄØ»x«ÆýàÏÚuHƒ¤AJ3‘Òp* I)C³”L"I¨ˆFBE³RWŠè&ä Q†&e¨”"usÍSRÿ÷rò;Ž}6îýÝ?÷çî{_oÕgí½öZÏó]ÏZ{Ÿ³Ÿ5›Pì`íJsú1›9<Ç—~HŽ¥"-¹‘ ¼ÄÇ|B…C£p?½Â*:yçyÄQQøâh}yŒuóþ±QØÊvJT°>*S•Ö´á-v²‹=³œ+Á8&0‘E,¡AÅ(4¥'}èϦòÅ+E¡,§Ò”³èÉ_x0άÊö™E\REýUÓLàÖS"+ Gr•¸ûËx`Qõ(”¤%¹Ž La*²Šü5¢PvœÇ‹,f;‰jzßGEާ=ëy—}Nˆ\÷E¡>¹ž›èC_¦òo±’æµ+´c2¯ó6ïQ[S…uõ7åOŒBC®æ.Fð4ï¿mL3z2ŽìS/ å8†ã¨HûúQ¸“‘Lb›(v²w8çQÊ5ˆÂd±•2§Fáê2‹Ù<ˇ|Á×lakCûzšu0“â#ï{µ'WÒ™Q<ÁL±™Oøœ„ÓíiNîbCÓÌâU6²“ÚhšÒ–«èÅM<Ã6²gSë¤/SYÌ&Âꉊ´å.ææ³og;v¨A›fQ˜ÞÂÂ\µÔæ<ÀßXÏÞ§X+µÞZÛq'´1&Ñ”*çFáÄvꪽº¢—u0ÆÒŸ÷ØÎáçë{Î`_.ˆB®aóÙÊž:0”Ù´»HÎ6ö¿Xûó 't´4¦ OQÉ›ÅÞ(ÖÉkvvLðøUj„•¼ÏF¶³o2öjc OòVWcè5žÓ- Ë©q­:dåuÖÅfN½^ÿ±Š¢ÝÕ /ôpÜôŒB7ªÜàüq£Z F/ûy“~§ùÍ^›½±}lw_ã"3Ų̀þÚðVýÀàÛÔ Ñs mbð cÀíꟕdÜ¡ ÌSèÍñAœÂJŽº+ _qäÝQ˜q¶¢ŽùŠÏ‡jŸaQ8í^5rŸþ®o(1Â9‡NÌfÔHç‘Q¶Ÿï8a´š#£í¹Ÿc³ÌàÄûõ wŒS³ãpüO0®MŒÂk|øÇ߃Îc4œ¤ hNƒ‡?™ì8¥Cy‰­TžâØã!泉²Ûîæaž&ß#;5 gÒ‰GxþQÇ7™Ù'öfÛ¹ˆy›o)ùWÇ—0šù,`=ŸrÆtçHzð.‰Çµ4çVVQx†6¢½γ,bøŠÒO¨eŽf#>i]3gEáNá¯|CÃÙú‰V<>ÇŸO©[«oiJ^c9+XÏCO;ÿÍø7O[ð0ÕŸuŽbÐó²\‹-p|¿¤M8–]¼ö²>{ÅñÎiôæÎWõÏ/r-À*6ò;Ùc±uÓŒ–ÜÄ FrÙç*ò/µß”å`£µiH Îå<:ÑÜÎP†ñ0–©Ç×Ôúr}Jeew®ˆÂÞoÿ¸Ž×ù/8ôMýKN¥5]È«,a3Ÿ²…Âo9¾©E]ZÒ‰¾ à)¾dEVZ/õi@{ºq'÷1e¬à}¾aïUúœ–´árnb8S™Ïûlc;ÅW»g>kù”üo{ng ù’-Z£¨F :Ò›~ b<YM¡µÙw§/É1Ô¦vß~ã˜Ë[¼Ã~ï8ÎÄólá¸uŽuF³‚½Ö»¦ ±†uä{Wßш¶´§/SYÊrÞ`57DáþAþ÷=†g(²Ñ1I/&ó2¯²„/)¼ÉXLu®çf¦ó›ØÅw]B5©MGzó°†õl`7«]NçLúП[ÄLfñU>tÊÉ\ò‘qƒ—>¶ŽOÔ<ãÙJÝOíoPñ3ýÌëøÜ2ZÒ†® d,ÓYÄFvqàj•6tçv²œ"_7ÏzÊ}å¸dù¿Î¾ãèHÞf [Øw‹š£Ç2|«sÊ6}Æ\¶Ss»ë9öùƱÉÀoÛ˜@Ùïì79a‡÷vø^pâ.×û\á^ÖP:J„;™Î"ÖqC"6Q<_"4  ë(–?b³™Ã'{$Â7ì¢ìž‰p4U¨Ik:Ò^ôc"Ó™Ç"Þ` ø€¨@"*}¿ Ôâs×ÓŸ;Æh&ð8|/¯M}Zr9ãxgxw8³`"´g‡îŠÆ¿Rž'Ñ~ŸDx®X"\³¯vb$køŒãŠ'ÂÕ f2Ÿ…|Î6ö.‘‡p6-¸‚Þôcsy†-™MËl–²™o(Q*ŽåΣÃxœWYÂF6³÷³ßtåNîæžá#¾c'G—ö8pí¸™ LcÛØsÿD(HEN¡!¸Š®ÜÊ Æ1•i,ß?ûîJò=ÅÊ$ÂÁÔ¤—qC¸¿Lö–^aÛ)\V›°‡p8W0•y,e9ÙÌ·9 àt®ä6Fò(/²–õìà°r‰pj¹ì;û ä¯,àe6‘80Êӂ븇GXÀç”:(ªs.=ÇKì©]iM/&2í|G¥ÝwiD/¦°‚qH"4eÏqh"T£33x‡9¸Žé|ÄA‡ëG:2©,"ßù€Ã8’ Æpf0“M”9Ríq&=¸‡a¼È2V𱋓Ò÷Œ`4óxž•|ÈþG;NiÊUŒá f±Œð1û•׆œÀ™4£+×2ˆ±<Æt–²œÈŒ}æN¤>íèÊ@&0—·ù–Çz-êpÅ2òUH„tàBzp#ðÏó"ß=ƒü÷„ãôGS‡“èÌÕ à6¦0•—x•ÏȨh|¡ ©LÃݳÈdz•_Kw†3Šü•ô5u9[È ^ç-v°‹"Ç'B&MvÏX~³y—‚•½çÿdöë1Œã)Þæ[ŠTq¼Q38»JöŒ×÷UU·tá†r³„÷ÙÎw”ª¦8Ÿ^ôæ^`!ù²ô‡“Å©´ä:eeϰÏÞ;¼Ì¾d‰ê^ƒý9Ž® bcy‚Y¼Îg­‘õèÍxæòwŠÔtŽ¢·±”-p‚§·ž=쪲g-]Ë8D?na4ë)X;ªR³hNwp3jgÏ*Z¬ŽþäLú1™¹<Ã.ŠÕU[dñ0/ðN<Ë(…N´~³˜È8I[R‡Ö\Ã`b.ÏðïðEÏp¬1œWøžÎÔW»g©zŽm|ÇÑg¹¢>hOWîçÖQælýA#.â&Æ2žÙÌåÝÝ3YÁMôac™ÉN 7÷ç(щqüOù‚Â-<®EöŒJm¸›Î(¦3Ÿ¬g_“ÑÒ1LEêÒ„s¹šþ a2sx•µ¬çön¥¿9‚ºÔ£7£ÏT–ñß³oëD(IÚpÝéÉsÌgïRµ¾§1MvÏö3†—YÌÞc#ûœ£†È¢+·1ˆçdÏ*3ëœì™e–òßR¾­ë9jR‹V\Ãf2›WXͰ=ÎU‹”æêÓ‚ÎÜÄ`d!/³†wø:~|;ýCN¤9WpƒÂP†1Žì¢b{í~žÇvÐ÷؆ ]r k:ê÷K²¿a_œËV2.uÞåXêÑšî ç1žäe³èrç þAF'õK%΢ ·2˜‰<Äã¼È"î¸Ò1MŸÎÆž¡mÛÁ­œÔÕës #Ãî_„‰ÿ×'öïLŠþ¡É¿¶=ÿÿZãK „Dfô ûÿ&Óï›D™y%Q®$_žI$%ù’’üIIÆOïë3?¬9þWòÆ¿›•W’?³XI””$r%E3¾ž¢?ÙÓT¯õû%¥mJâú+þm³‘!#3¯$JJ¹’äõ¤“œä×Z>þ¼tòŸì‘™W%%‰¤$_R’?)ÉHJöHJöLJ $%{%%“’BIIá\ÉÙÎGÅó¡üÂcâßýïIJ‡_7âßmý×’ìë„«7–{ŒŠC6÷³ŽK'?¹ÖŠ“_k±ø·ƒÓI:ù÷&¿VuñïÿžÉ¯mOü{ç–¤@f^I””$~’üZûÄ¿WÿïKöÊÌ+‰’’DR’/)ÉŸ”d$%{$%{&%’’½’’‚?I~­Åâoü÷$¿Öñ÷"þ}IÁ̼’()I$%ù’’üIIFR²GR²gRR )Ù+))˜”JJ '%E’’½“’¢IÉ>II±¤dߤ¤xRR"))™””JJöKJJçJ~Þ§¿V?ñ÷ZþÓ’_=Ç þ}“_Ûžø;=#C¡Ì¼’()I$%ù’’üIIFR²GR²gRR W’¼Í…“¶¹pÒ6ÿüY¿Öñ·”ÒI:ùß$¿Vcñ7ÐÒÉ?ŸÉÌ+‰’’DR’/)ÉŸ+I·ó/%¿VÏñ7Ï$ûóŸ{9?&çóø’G%™ÙŸÅ]²û;“¹×óm:I'Xþé$»žã±.ïzŽ¿mûgM²÷=>ÞóÞ÷øÿ%Éþ‰jê6Œ¿iœNþ IÈ•dŸ/~¼ˆåül½Îîo|ç^O³ß9ɩ̼·'þ¾ùoI²×“øÙzrZ#þžzîg¥N’ŸõkIö«Çíœ÷^Äß„ÿ-Iözò§\Oü ú¼“+Éî÷¯ôB®~/¶û›÷¹×sОäTBÞ[ÏWrff^I””$’’|IIþ\Éoyõt’NÒI:I'é$¤“tòG&9Ÿ}ÅÿJ~L<P:I'ÿw“œOÃò®ðxþ¨t’NÒI:I'éä?-Éù‰FÞç¯xþ½ÿž$»5âÏ!ónxFÁt’NÒÉZ’}äÆ?/ÈûÈçÍü-Iöz2R®'žoó??Éùé[Þ?»‰gMNrÞ­°{¶Ð܉ç ý×’œwIy¯9žy49Éù)^Þ{ÏQ:2œ•ù³$ú1yo÷<¦#?&ÛL~xV”ç³âYNs’è§ÉÏJäù¬¯Ïÿùkų£æ<ë¾sëY×\ðó׺&׳òçù¬­IÏÚšëYy>+ž5÷³þ' ?oÕœŸ{æÝòñL®#C³Ì¼’(Wòógeÿ$ôÇ-Œåü$4ž 6–ûYÓÉÏ’œŸÌæÝbñ\¸l’3’ÄÿJ~L<ïÈp|f^I”+I~V:ùÏMrÆù¼û=žùÏ‘ä¼oÊ{OãyœG†™y%QR’HJò%%ùs%ɯ•œ´JzõVI¯þ[Ö“NÒÉoMr®Þã{çŒ í2óJ¢\Iò³ÒI:I'éäŸKr>ÝÍ{DŠïd•NÒÉŸ;Éùt%ïkõøiÉIÎç$y?+¾›Z:I'ÿmIΧ|?=.r>C‹ïÚ÷[’ìÏÙ~œ£,–ûµâ»ýýßHJæJ²÷«Àî$$íW|W‘á¼Ì¼’()I$%ùr%ÉkN'¿GR ÔÎ,þ?IHêåø~é$¤“ÿü$ûXþqìÎõ˜R;£Nþ;“ÜÕK'é$¤“t’NÒI:I'é$¤“t’NÒI:I'é$¤“t’NÒI:I'é$¤“t’NÒI:I'éäÏ™”Ì•üÚoH¦“t’NÒI:I'ÿÿ“ô¹)¤“t’Nþèä_{KGd–ø¶ð÷|­t’Nþ7É¿V«y?+üÓIÈÂ&ÉÀ©!T~9„3W‡0ê«*ˆB¡ƒ£ÐªBÊ5ŠB£«£P¥w:Ý…ÓGD¡ðø(ô|ˆeQ(óAnÚ;Îí”õ¯K„ÚQõiÊY4£%­iG.¦WrV®¡=èÃm<©Ë6ÎáºÒ!¼tT—žÂè!4jÂþBè}MÅìÍ[C8upŒõçd™B×y!|ýfU׆pá!tÏ…OJDáòÒQ¸»lÞ:( %‹Âª££Ð´J*…öu¢põÉQȲß;ΈÂâ³£Pˆ½$ ûÆØ7 ‰Âû­ëËfDaѬ(¼6Ïz´G÷Qh½: ÓÖDa˺(<ÿ^¦nŽBÇ£ðîgQX¸% wF¡Íž‰N„yÚ®_é„íI„qåüû DhqH"qD" /ŸWUH„v:È¿«$€¬DØ¿f"”ª•·ÖM„¹õ¡VƒDhzZ"¬lœÇœ‘¯4K„3Z%Âú6‰°¬m"tm¯o:$B§Ž‰Pæªì~²›áDN¢v9œBN¥!§¡BcN§ š$œ‰f ÍiA+Úpm9—öœÇùÑ· rÑ”áR.ãr® 3]èʵ\Çõt§'7p#½¸‰›Q’qw„~ôg·p+ÄíÜÒ ƒ¹‹»¹Ý†2Œ{¹á(ñ0’QŒf cÑåaÊ?<À&ò&EÙµ·m]/e·Y¼Ïõ»&Bñ6%v•°kW#+:„¡K¸(ª‡þ_Éß²ü™jIÍKªûoª%ǧ\R9å’*)—TM¹¤ZÊ%Y)—TO¹$UTOÙ5R¶A”mP#eÔHÙ5R¶A”mP#ETö÷¼ŸSù‡¿§Z’wëÄKònÊ?,Kµ$ï6¨¬òÞÓxIª-¨šrIµý/IµmÕRn[µý/IµÕÕR¶uµ”ýS-e/Tû…=MÕ Y)Û +ed¥lƒ¬”m•² ²R¶AVÊ6ÈJ٩ƪÊ)ǪÊ!ÕX/IթƪxIª6H5VÅKRµAª±*^’ª ª§lƒTcUåþ›jIª6H5VÅKRµAª±*^’ª jüÂV§j)['þ3ï%5S¶AÍ”mP3eÔLÙ5µA|•Ù²H5 aÍI®jN áÀÆ!Gã³]Ñ´aéE!,èÂÇ=Cxãæž¸UîJòü¡®,F9©Oqõ:×Uų!Ôr5Ùÿö}7„:®”›qñvW'! Wå˾GÑAÙwìŠïËßÛ0¾£_|o°ø¾^ñ]±âûNÅw£Šï-ßå(¾Q<Ûv|OøñLâ{{Ä÷1ˆggýŽççŽg·Žçë‰gÆç°çƒ‹ç­ŒgŠ‹çÉŠg½Šgø‰gç‰g²ùaæ“ü‰°WQW‹Maª+Âaía{^˜};»jï’§tÍž¥&¾€‰ÿ–/ûB&ÄsÅóhÇsüÄóáìEA ýp‚f {S”}(ƾ§%)Å~¸xûS†²@9ä 29˜C8ÝçŽÄ…8šòñTà8*†ì·5ÇS™*T¥YT§5ñæ!Ô¢6u¨Ë‰œD=ês2Ê$x“N¥!§…ì«ÈÙv¦Ûä ]NÉ®£,ºª¥ËÕÒûjiZJÜÂ'ji±ZºB-õVK©¥2j©‹Z*ðœ+kµ4Z-ó®wJêè<.SK}õÄmj©œ::†•jélµôŠZªª–žPKYjiŽZ:B-®– ª¥¾ji?o­NSG­˜¡–6©¥©j©¾Zj¦–ŽTKõÕR µôŽZ:F-MVK•ÔÑŠyç’x_ ©¥zjé+µT^-WK3ÕR]µÔX--QKcÕQï,PKO«¥[~RKq Å5ãV8 ʾzßÕÅWàñ÷<{¡8–õld¸‚Ãd¦QXÁg‚¢{”iÌâi^`"¼‹wÙDykÙÈRÅù:_)Ðíì§HËÐŒ–\I†0œ3p *ââÌæ9Ê(èC¨B5šÐ’»A~Å^ˆ ¸œù¼ÂJÖ‘ÏPÖê§=3öË®¥/ÙF1H)ZÒ–öœÏÅ\ÎmÜÁÝÜËZÞ¥±ƒê Ú;¨Îçeq»l(ç8È®cc™ÁL>'áàËGYÊq"õèH?nánF0†¿ò¾` …¸‡q,•©FšÓ‰.ÌçEð*Ã2½³bñó¨äà¯Ew0‹XÃzÞcò9;ˆ ýx),¦²Á£:w1Œí|ÏI‡e· iÂ}Œæ`ƒÌaÇñœI ¾b;3 >OÓÝàÓ‹n ¬f# F÷ó$O±…oéb€º–‰Læ=6ñ%Û(gð:”¾ÜÊdåqÚ,N5¨¾{`Ë -x‹u¼Ë|Í. üŠÑ‘NÌãJËr»Aqc™À³¬ále+F3ŽB̲”£<ÇR‹:4¦5¹†ÞÜÍXÆ1‰ÉÌâîúpo'Ë@[›1<ÀWlg³qôcJ|÷£YÔá$ZÓž{µ£˜Æ °˜g Ò (k ÎdïðºûïÔ66ףёËèFžf/ð¥O7^1…Gùšo8²©¶àa¦ñýYúƘ S“<À¤øïÍ´o4W+iáÜH7zð}+cFkçWJr5}x„Ùlà hã¼Ç@†ó5Ñ9¶…šŒa ¯ó6mµ%›ÙƳí,d…Ïs®¦$¥i@Æ0ž¼ßð=‰ó­“+.á*†3š9j{Š^ìõxÅíèßLb*k/Qûv©ó4­8—ù,aðeŽ!j^îœËŽNÚå ½Ò¹˜Îtç3¿sËøô*íÐÅc®qLó7žc/síµ!ôdêu!Lçqžd/qËõö“{¸Ò=\‡°šuw-Xš8˜òT &õyÄùý Šõ²¿T¡6s)}¹•ñLd*Óy…Å,áu¾fûÞä5©EmÚq½¸‰AÜÅÃ<Â{læL×g3‡TîmücEŸÞdC_c¡Ÿ¾d/êPŸ‘ÜÏ+,a3ú{,+Zù©Uq6èÊâÛCXÎÖ;{œ}·>&ËõN- s~bõ½¶™á÷y=fò ŸŒ0&r°k££©:Æþs2¹‚«yg¬íâ¬ûËÌágŸéǽT¯ŽèÎ@žf1»ØûǃxŽ¼Æ›œ7A­ÑƒÛ¸ûx€©Lãiò:o²‰ª7¹—‡h1ÉxÅ£<É*Þ!ã!ÇWЃ¿ñ" X·˜l¬¢çÓ™ëÈÄGŒ­,žª½¹y–f#˜É2f[թˉ4àTцóâOÆéÁ`îaØììOÌÇ0§x–µlà}þΧ|A±9Æk29’,jr)èÂu\OO&1…é<ÁK,a)ËÙÈfŠ>el¢ûÓ™n\KwúП)LåQžˆŸóŒk4F3ž}æÙ>ªxÏVƒ{Í·„çÔ%¸›ûÈxÞM ÊPZt£÷1†y¬¦Ô|çH ¾àµ¸ƒ¡LaKxƒ]d¼¨F9z ŒWtä fòY ½7ac¨õ’Çr18ê×(´ãBÞf#m_U+\Kw^fa‘㕃9’“hÉÑ‹m -h˹´c+øœ­ÔX¢~¨´T-1v™d.KYÉ;œþšõÒšö\M7ºs7r ƒ¹‡¡Œä1¦3Ÿ×XÁ*6ó[øŽbËõ å8–ã¨JKÚЉîô¤7ƒ¹ŸñLâUVó_°ƒÂ+\/p8YÔf0#˜Ì žf9¯³ší|ÇvQàuÛÄAÎñ4¦ Í8‡\Àõôá^†3–)<Ç|^fo²’÷xŸð9[ÙNâ çF RŒýØŸòKejr"õhNKÎåB:r ]éFOúПÜÅ= ç~`Ó™Á°‚7x›Ïøž]dx?[†c¨@•7³?/©Ç™´âš·ôÃË-+;´JßR“ÚœÎÙ´ -í9Ÿ;ÇD¦ð$Oóß1dµëDžc!ǽmÜã":Ñju1†‰d­õz4ò>ü,ê®7^Ò^ôá6v¼«íß³ \FÍ Goúña2ðbßÂQ(Ã>äÅ"ÖÃ{Û'²”üEm7=è̡͓Í>^ƒaŒ`kÙ«XŠÒ˜3xGX·o>áÊâQ¸‘å¬b#_±ƒ|%¢PŒý8‚ Ï 4ç.âRºsƒ¸›ÑLâa¦ó4óYÀ"V±|Àw„’QhBs:pݹ…I<ÁLžâV³†÷ø˜m|G¢TŠP‚ý(Gyª’Å 4¥«YË9ûEá|.¤+÷1‰‡˜Í³,c9Ÿ’¯tŠS’ÊœF.¢+½éÏ &ò2«XÇ|Ê×lgÑþÖG&å9–JÔ£!§ÑŒnôä0ƒÙ.…}ø SÙÌG|ƾ#”Õ6ìÅ­ ŠÂ5|Cþ¢0—ù.g}JypÓx†å¼Éìี/Õ©C]Ñ‚ ˜ÌT¦ñ8Oó,«X˧l£T¦þâtZÐŽKéB/îb(ÃÉLæ%Þà-֎ž”å áHêÓˆ‹¸Š«éÁ½Là/<Æ«,á5Þf-›ÙÁ.Šâx厡"YT§>§Ðœ–´£=—щžÜH?ús÷0ž Láažd x‰¥,ãmÖò!Ÿ°Õìy˜þ¥)ÍèLú®ÏyŠçXÄR2Ž0¶Q‹œu¤cs¹Å¼ÉG©OÊS›éËý<Æ—|ÑG«[þ{÷dU¹¦ xõFJ ‚"J’œ£ä$ÉI‚(‚ ‚€"JP@ r@%rFDAI ( 9界™§ïî¾›ž3wêΙºÕ§ê9ݽÓZë_ßÿ¯EÕþ^sSˆ"”¤©Ê dÏ¢^È—Õó$ˤá5Þ¦ïsˆœäRôk²sŠRžF´§3½ÁŒb<Ó˜Ël`/'8ÍEî{V­ó‘†§y…×èÅF0ŠñLa*ß°ˆ5l`?ǹD‚QAb’”T¤'%©FMZð*Ýx‡÷ùŦ1—åüÌvNr–ß¸È ¢ÿÛhiIOFž%'E(OªS—z´áeÞ¤+ïÒ‹Á a‡8Êó¹\_èBÖ³™“œæ™ÜÎ)¨Ä—yÔ._³”嬿9ÄaŠæS”¦:ƒÍJ~e{8ÀYîÉoî‘‚')L1JR‰*Ô¥=x‡ÎçŒe“ùš…üȶ¯€sG*2S‚JT¥&õy™7éÆG g<“™Á—Ìg)ËÙÊvö±Ÿß9O¨ ã!1IHC:ò"¥*ÕiÈ‹t¦;ýùœ1Œe"3™Ï:6°…}à4W¹I¨ûîã1Òð,…¨Bs:ѾŒd£™Àtæñ;9ÈNp‰ô…Õ9ÈMªÑŒv¼IwzÑ—~ gÓøŠ•ìâçø“‡ŠX+HÎc‹XÍz6±•=ç§9ËEâ=g IJ Òñ$9ÉO1žc@)kCÎÆ0‰Ìf+ÙÊ6öp„ßùƒPiÛã>! uiB ^¦ïrˆcç"¡2æ%¨LMš2ƒ9ld''9Ç²Ž•ËÜà&Iʹ¶’ŠŒä 5¨OkÞ¢;=xÌ$æ²”¬b#›ÙÇ)~çâ• ИoYN¶ Î7—¸Æc£‚ ”¥ ]éÅ6R§’k3˜ÇV²‘-le;ÙÏrœÓ\à2)+«w2’•bTæyjМötà zчÏÇ6³…­ìeG8M’*Î#éx‚¬ä§%i@s:ЙïYÎ 6³•œæ ‰Ÿ7?x’œ”¢å©BmòoÓŸáŒ`ß²Œuld+»øË$¬ªöHNZr‘—‚”¢ ÕhH3ÚðÓ™Ï7üÀ6rœ«Ü_Íç1œ‘œçžêjˆ™^CrcüQÓ¿1j©§ÚÆ‚¦uÌúó1Ÿ0Ьçwnr‹û_°–Ò9|K¶ºŽƒ&´&I=ë25¨Ïl¾â[–0­¾º"QÿÖ¥7±¡¡uŒkÜär#ë|£ðwo¢¿3ñ )y‘Vlêc ½{E°€o8Ãï|ûžÏ"çê–P÷Õ f£™À*~¦k?óƒY|ÉÀþæ #ø‚žºV0žI,ekXËÔ/ t ñ ÷Ф&= >±O”잊¥üÈC\縎q+\'ÁãË£¤!¨L5^¡#ýÈd¦ó%Kø‹Ü$jªk¯2•Y,a9G9E©iÖFqœjÓ!¯Ò‰ž b³YËžèŸ3Ü«pŽËÜ$j¦ñ"-y†|”¥ /ÒŽ7éˇ àF1‘[„fož¦%)OejÓŒ—hGgÞ%ùlõ@r‹Â|ÆV²†DsœO²ªÔ¢5/³Ÿ#ÄŸëµä£0ÏSíìáw.D?7ϵ€šÔ¡;½øŒQÑXüÊAŽq™ëdÿÒAZщ÷ù–¥läÇ9C¾ùÆ‘s\æ ÁWÖ*Ò™®t£ù„œ ÔÕ¨Mš³ƒ½ã Ù¿¶ ¾ä[~`yôc߸~ñ"-hEÚщŸXGƒ…îÙÇŽrŠ«‹¬G¤ãirð<ÕÊçLb*KXÁôo]ßÙòùKçï½éËUnÑq±yÇv©ë…¨ÄAŽóàró›OÉ"–Òu…gë¹Ì+ýüÉÁ„UjŸ„«}ÉIE!JSjT§6/ÐŒŽtá ºÑ›¾ àS>gbôßk¬<þ³uJÔ +ïÒŸ™Í¾e1KYÅjÖó+›ØÎ^sŠs\%øÅ5§e)GuêPŸF´¦ èD7zЋÞôá#>e=Û9Ã9V¬Uìå0÷¬sM" “šÇ©H šÐ’¶täMz²‹ƒÜ»Þ5›Ô¤ãyêEÿý«{JS™®ô¤7ý(¼Á}­hÇ+tä ºñÓ†ð÷Š×³…{7ÙGR’ÏÇ›ÝÇ‚T´§ç¶?jS—ætàmfò=kÙÃ%‚­Æžò´¥3ï3„+Üäþm¶GrR“†,d'/ù(B ðýù”/˜ÅW,à;¾g-§¸Ìuow\$'iIGnòQ”b”¦ µèÁGŒf _²„elå¹Gø»Ú’³œçnD?¶Óq‘§ÉG3†KüÉã»Ü£ÑŠ.ôgãYÀOlcÇɺۜ¤(å¨IÞe{8CÊ=®MT£ ýÎ%âíµÎÑϘÌ}ûŒÏQ×yüûm‡FÍwþ<þ~zB’ð=Kù‘U\áÉ«#çYÚðØÀl–±–­$9bûô¤søŽXÍ-î;ê¸)Ë;ôg_q„³dþ>~yžg£©uʼ¦5¯pkl;íK¢3ê„'ÉIyªÒœWø˜! ã3Æ0‰ÌæK¾g8ÉÎrŽËÜäÞ³î‡ÉM>òSˆâ”¥.­èNo†3üÀJV±™]à0ǹL‚ß O’‰§ÉBòÓ‚nôâCFòwzþî\ñýÂLb‹ùUüÌvvr€Ãœç"7¸ÅƒçŒ'©IGvrP"T¢ u¨GÚÒ™wéË—,dëØÁQ.qƒÐyµFr2‰l ¥©DjÒ„6´å:Ñ…>ôçc†3‚Ï™Ì\°õle;»8Æ%î¹`^ð0©xŠÜ ¨FÑ„–¼FOÞ¥7ýøˆOÅÆ3…ÙÌe>?ð+‡8î‘ä¢ñ&™ÉCQJQ‘Ô¦èI_2Œ±Ìa «YÏVN] ÷·4¼äß24§%K®¨GnÿªmQ†×x›ã×ìïºóñ§yÅš ¬e;H ñ)(GEªQ‡¥¡Pð#G8Æ5nòH<¯§9­hË+<?d£/ÒŽW™Ë|vs˜•÷†‚ Ü"q‚PœGICžài²ƒB”¥µ‰N&hLZКv´§#¯óï1ˆŒaS˜Ê,æ²€¯ùŽÅ,g«ù™_ÙÂNvs€ã\¤RÂPðÍhÅÛt§½éÇ@†0Œ‘|ÎXr–«Ü á}¡ ÉIE&²•œä"?…)A)ÊQÔ¡> iÉ æð3ëÙÆîè÷%ö>êÐ~|ÂRVÐúþPð2ïÓ—"‡‚’Ì~ÄXQ;™ãåuzðø“¯“‡‚%<ž2<ÃvöóX*ÇCv.ô1õÃôa‹S«5Hëõ<Á*ŽpšM‡‚Pzã–!œâ:µžT{ì*œ ȤŸo°—S\`PfcÏœ,ö'²SeS!^vûDðl(HI_Fòf¿s+§÷år$Ë Ð9óÊh®ç5Ÿò©/~dßæ»8ÊoBÁƒCAZ~ãþBÎ5» «jQüμ¢¡`!¸Å#ÅÔx†’”§9cØÌvrˆé%BÁ/ìfG8Îäz.§,åxžê4 !-hMR•2'IOAÊQžj¼D^£3oЇ¾|Ì¥Ò¡à QeÌmÒ“be½ŸE¬`-gÊy-÷–Wol‡¤Õ~´Ê¡àYòÐŒŽã$¿ñ;©Šš¯j¾²‰÷ªÛzÔƒùŒ›5çZÖø’e¬ck=ûÀY¬ zR¶¹Áö“ª¡sM^J2A f"ÓÙýšFƆ d¦6 …û`£û'1“Y|ÍŸäi Š2±‰ç˜ËB6°ƒÝ"ISµJN 1‚±Ñ)+ÍýÎX¦0‡Õ%Ë‹¡ 7­xº¥z`bkãMü—Ô-“ŒT¤!Ùx–§_öùälk?ÉO:Ò‰îôà=†1šñü¹,` Ë8ÃyÒ· ORŒR´¢-ƒÊJÖpˆ£ç YÛÛJPžz4cC9Ãyj¾bí¤Ú«^CÞæ7Ý;„{F§1‡Sœç—¹÷5çŸLd¦mùˆA|ÏrîhM#;†{Piâüú¿éóþ³·ç?Gê rnîüyçëþ«ö)Nœ8qâĉçö{”8qâĉó_ã?²îþW¯Ñÿl{q׊8qâÄùŸ-Þÿúï_¼&Þ]¯Žóÿ§xÿûçÿÛ-ý{÷ñ‚4·Ip×ÿßýèÝÏüão‘GþúÑö)ÿj۽籿ÿãþõˆþëqþÇy÷×ûqç^ݾÿì=wñíýÕ ¿s?þãGr÷§D~Æ þÙ6ÿÕ8ÿwˆþßÓ‰‚ ; hÌ8&²Šµ¼›8> VÏS*&k÷ƒ‡‚ ?y“AA.p™®Á;ôHï' gå¶caÊ xæÑHæmlÖí|¾¢xª (˸´A09&»öRÚpvmÂtáìÚ'Ò…³kË1™¹lb;Kb2hײ™b齎ã\MÉ‚ý‰5œå7|*’’•lѹ°™í3}³A?Îp–Yƒà5¦3ƒtÙ‚ …)÷šÃv¨‘3j/WÜC#ó ¸?w<;œÑ:Òyƒ  ËóÁJ(hŸèV(Q®„±,ÎNME&ž!;9žûÇ Õ¦´¥=éD/Þc43(PÆ{XTÁ8ðI¥ ÎW•=F¾*AP‡Uƒ  CÁb–ñ’ªšsBÑ‘n|@~äg.rƒ6Õ«XGP3гŽq¦^Ý hU7œ‘ú^ÝpFêºáŒÔ uéY©MÓzá¬ÔüÀÏõ™©ñê‡3S‹Ð’NõÃÙ©ÓꇳSw×g§¦ y…t¦“˜Å¶°a ‚Btâ ~ã‡Û~aÇGÁé‘ŒÑØlѧ¾pÞ¾ø?Ͻý÷˜ÿxÖh“qáŒÑÇ…³Eg gŠn÷—%››Ú†qâ0'øv¦5Ë\ã«YÖžšm½ ñûKÒ¹Î;Ç9EËyAК|_ªaF1–&óWú|å¼2•ylf'W ANò/g•ˆÉ(]Ä.ö“äk5þu$«´uoË"]À7·eFgŒù&œ%:‹‡¾3Ø±Øø-gw¦_Îêü;óøšÆË˲pææë1™›Ëb27KÿÎÖÌ“¥Ù&&Có )תéµáìˉ1™—Ç(÷«¹ük$ãr>ßq€#<ºÁ~ш–ôcËYÍ%®ogO–£XÀ"âm²>œ›Â’oò6ï0É›"™Ž±ޱ™KXÎNd‹±aæV㓹8˜¼Û­”¥âöHÖ⦎ƒfí?ññmÙ†¿qâG]óÆ–²’ìá¾ã¶Í‹gÔÅ™pÖ`EžóF3† Le›9Ç’ŸwnˌάOò‹A‘4gëisÙùåÞëjùz$Ë/:Ão {8„3ü¦+^TP˜Öñ£‚ü|Tð׈ ®“ñÁ¨ Š æ ç©•4*hÌʇ½‡-ìàw®’䑨 ÙÈIMóíèIo†ð)‹YÎ.P,YTP‚rT¡-¯1Œ‘ÉÂw¿$‹dÚ%#y)Ä 4âc3‚Ñ|Ç2Žr*y8».]ŠHV]kÚQ)¥íR“z¼I>fXÊpVݯ)ÃuÉ gÓÕ§1/ò>}XÊJ6±åÑ»³é¥2V¥8MiÅ«¼ÆF0ž)©"YtÑÙsg(™:*¨Lõ4¶ÏbÖ¤ gË¥LÎÛ6’W•Z¼B'Æ1‰¯XDñÇ£‚ÒÜŸ>*HJ. °8Åyɱ>ÑY=Çx¡ºmUgò «Îâ9G£šÖaÔ²MöÕöúÚ‘,žñLf1Ë9Ä &Õ³Oœhäs(ØXmp ©÷S¾™óÈE®Ò©¹Zæ}r™ë yQíи…õœWZ:?\ã&›ZùL~oí1½ª®˜Àtæó +ù‘ìæ('_d·<ÜA 3¼cTðYÇpÆJw6¿ì¥HgµG¹7¬=|Á˜7"™)myõÍHVJŠ·¬T¡:ËYM©®®‰¼NWštSwô W·HVJlFJ=šr˜sÝÃ(9oË<‰Í8©ÜKÍôº;ã$6Ë$6äu?µÔïî “å¬ìÉ2Iõ¡ùLsZ°‹½Ü÷‘1f©¨½QÁ ‘¬’‹\çüÇÁSC­«C#Ù$ÑÙ#¿Œˆd”øÂx|Éü(þwcÄ`†’p¢k(&©÷Û²=ŽL±.nªù>5’•qxj8#cÈ´¨àoÜàÖ´HFFâÎ׌HF­™j|f$³âc†1‘éÌá+±˜å¬f›gÝaqgvÅ!NÎŽdVÄfUÄfTÔ£áÜHFEl6Å¿—I‘`¾ë³˜÷üÁ š}Î}ˆÍpx’L‹îÎphJ ®p/¹Òô]ÉˆÍØÁÑÍáÞÿПÍSd'÷–»3úñÉ–pÀ>ŽqfK$ àA’S„b[#Ùuh´õ3†±%[ïÎ ˆÍ(E™mwg¬göHÏlên¿»W¿ëNc°3Ü“?Žù…ó\ÜéÑO¼ËüÙéÕ/Hñ]ážý7y‡^»þ±wÿ›]ážý“$ÞíHÎcѻߖN¬dãîpÿo»Ã=ü™bzø›Åôð`)¿ÄôòÇßMɂ˞ã™+®;T¤*‹XÌUnPèªq¾éÃ~èûAêëQÁ”¦2ã™JáÖe:ßT_ŒBÁçìã ë¢B–‡PP& *Г^1ýØ'BáìGiD3r”ä÷xœ'yúžp¿õF®qƒ ÂýÖyÉOõá¾ê¼ÃÈá~é;ûžqŒKÜ IÂPðÏ…²”§yL?ô?ë}¾ÎÍ„áçgbz™ËÄô0×e ã˜Èt³Œ¬a¨ž(¼@cšS6±íó)#Øû°ñ ÷#¡ 0¯ó&G9Í5¢’…‚¤<Êd¥µ’EzÛÑ)¦×y™É"¾ã{–Çô@ÇK $U¨ÇLHé^Ç6Žq–?H˜"$#=Ù(HjÒ„ö¼Å; e4sù†µlã0G9Æ)®pR) y‡ âc†1–é|ÏœâòÀ£¡ 3ù(EÊRú4¤ÍèIof1Ŭá 7I”*¤$…(C9ÊS‰¦´¤#]éC?ú3„ÑŒe‹ØÀNŽq‚“œç&÷>é3ÏÀ³¢<5iL:Ð-¦}0Ÿ2Š©Ìe «ÙÀANp•[<”Ú\ã 2òYiG¦óeêHoû¶q˜£ã7®J î')iÈDejÑž.ôe #ø;3XÄ ~aǹAâ´ö‰| àf³ˆ•üÓ_¿þ¶ûPºPpYÈCmšÒ…®|ÂP¦1‹•¬çw®’âqõK Óf¼EOF3™Ÿ÷ó?Þñ’™|Ô¥ÝéÏx¦³˜¹Nü ¡ 'E(G*R‡î¼Ïf³‘]üÉ=OS²ò< yÿ‰p_ü\Æ>W¸ïþ[ŽrŒ¤ÅBÁÃç{~âK¨‘˜û"Ï…‚bÏ…{êsVpÜT$QçˆÕUÕ#ûê„‚31ý埽 >ë:Gåk–±š ?ïýEú*6³—C\âÙ¹6P’r"}éíéÒ(Ü[þ'¸@Öæ®'<Ò2¤åÁÖÖ3ÒñÙÉMYÊs™ë1=åInë'í#ŽÒÔ¥>oò6ÃÁL沊5´{Ùœãg~e'8ÁYâ·  xŒ4mÃý鹩NíÛzÔûð!ƒÓ›>‰i·õ§¯duÛHùINGÿþªçñ;„‚Ô͇»ú¾óĉ'Nœ8qâĉóoì] xU–>ýHº“¤HOy¿b@Qt/yH Þ“DBI€À(ˆŠÊÎ2Ž2 ®fQf‡ÁŒ Td}0 ŽŠ;ʬ»°LÖe]Yu\žfΩªî¾Õ}+Ý]‰(ñÜ|ªOݾÕ­>÷Ô½§Îéf0 Ø„ÿ²}úÿx$ýÞPØò½hIØ‚¾ƒ@e”æe°£ÜØØ÷8a”B1@9Tà«2càfÈ…¸o%¢Rñ5É¥øÞrM‡¯J ÷,€©Øª#hO1dâÿ lI{óµöÔöÇs¬2íXc•ú°ëJ°®Üز۹!÷Uà±/Æšœ–Ëð¯ß³@9vî/Á¶c)ß‘©Ô•áþrÄ"Ü›3•Ö •ö+®;‘•ØW*g¿ʱ5In¥•;Ì~ç㻲î°î°îøë.¸§±±ñÐg¯7ƃ_±À½X·wÀŽeuk±îì;wÖÉêÖQÝĽeuUX—\uöeYÝz¬kØó¯eu°îâÁÎGdu±®rè#% þUX· ë>úd¬´b]»ƒôOÆxýŸ`zT ÝÜÕ¿†xžXV m¼ù³À:ì´í³>äp.–µ³å6X»@”]VWæÞekÈóu§Óñ¾Íè\Ö)HùfVƒ¬Ý“…/F®¶ùiY»ò±•ŽÔÆOfÊÚ™U?¯kYÝ‘‚Ìè­›Û¬’qNœ½9:kËÑ,`Å»¼" ïÜNˆÂ«}.é@ôáÑ—¯ÈÚ­Nês4oY;Ùñ¾Žy%¶ÏökduާcÓ†×Ζq>7ù½¸­—ΑµËn÷p¢{ýÉçeí®ÄíNðò'Ù²vé¹·OëTû;Y»þ7uO™üùŸËÚ}Qq*åò™9‡eílKb:<žûÐ@Y»º¨·;N;p®¬îÑ¡sºÜ“Z|·¬®ýÂìîÑ_Îè/«–º·WŸùI>Lœ™Ý[®/.ØÛáXïE'oÊêrú¸úÙpËcñ×û$€g–\è+×]̘xo¿¼ÇֻƟ ò×Õõë1©¡^ÖnVÏÙýw½°ç€¬®m·=ý>ÛnKo°ÿ؉u²º¯2w ”ë5Ž‡Û¶ßpùtZgY]%ôH›öФE²ºÜ¹¥igÏnÈ’ÕÕTîO{ò·Û¶Ö¡.Åv´fíõ7Èê¾É<=X^ç‚ê)#†‡ö¹¯í1òƒÍ²v™¹uÃåç‚ý›;.½×ìOwÉêm~RRUü†¬îÔìî#9¿Lj_F%)›ouùh¤Ñç7<>:cǾ{Êê.ÅmmÔ.zêþ15ïö‹ ¬sÁŸà¹qõì¸WV—0ïóÛäz0ÆÚmü+‹ÿ*k·xÅúñr›ÐxݱÉ?_(½.ÝÓ—g¶‹Lß-k×=âÙ©òûŠ žš_~‡ÑýavÔ¥l¹ÍrÁÖ1û¦_÷ù YÝ¡AcgÈíµ ê‹vÎÚ¿óYéýakÇšÙîÞÖ$ß>dΡ‘ß+«Ûµ(k®{xŽtíV?oíÓµÝeuÉûÝeô¹¿6ðDÞ蓇FËÚM)é»`SûeÒkö¼´pÿþ~Óeízt=°üƒŸÞÙKV·=cp™|<œìß³ü©ó ¿—µ³Ì[UqÿõÉSduY…[+N ¨ÍÕ­^:å»#ïvÊêz®]³rìÙ=’ë‚6rHÏ5Ÿ ‹Û*«8tÂ:yßÜÃÞYgtÿ³hsª€’_ít$Toû6éHXœŽÈ»PÎCÙŠÕ©AZÖDx[ÖD`ËšˆP[¦Û½-ÓíØ2ÝjËãVoËãVlyܪoÙ>°Ä4ÑÏ©“,peÎôÁæ/54M!ïpXòž‡E!¿ ã«XhñRZ¢ÐêU”·ô;¸(\¾¦…ÚytQ(:Ùª3UŠN6¤èdËCyê$dM¤qÀ]“lDõ@!5Ú4úQ¢^ i‡&?':‘ÐéOX F„I á2§—p™ —9UB‡r†~d¿2<;•,#ÆK–ƒd1~WM${)HW]q^2W’¹âšÙÕ3./ážq5£«µm½dµm‘¬¶m3ºZ•ì%«JF²ªäfv5«ƒ—0«fuhFWƒDIW·’5O%„æØÌŒvÕ¬ž6$3£À†]5«À†g¦Yâ¶áYb¶¿Jaûû=Ø_Ù,&º‰¹ˆæ3}•ÖvC¹ 9,‡ÕC>§9¬‡zN2ùøñqØ ÂÓ#ùWÏb÷öLjE>ôô,Þ]•“Q^–“QÈr2ÊÿªDj³MãOG>nE‡ÆaüéìnãåØÝ9v·ñçpzf½|§ç;}k»Óóš‹ïù×Ü=Ÿ-1[âVg‰yÍeÞ(±ý5ßU¶¿lLö—˜¸U*p‡&ØÄý§<€P»jÆuë²€Qrµ–„ê,­«äº­µä¡,2¨@›œ!‡Áá+ª^Ð0ÈÀapøŠš‘[ÏÃ!e¡Á”vE?˜Ò–%Õã`$&‡Œ)çõ5—¦<š×çá¼¾æ²É!0¥âÙùØ¢$l ÈæRÙˆ­Ù\[”[ªÇ‰ª2Æ2VÙª«.©ú@Nê*{Ê>Æ c*ö_d `u¡íh¸¨(².´ }¬±¬©©gŽ÷g&«”wQo•òæø&˜SñjëÙ}áÇ*{ZdBõñ {Z$²§Eæ¡ìcOž NàuèkØ@wcž.ótù*N—¯šþÔ÷œ÷Sº…~jÚQ'B`iÛ¤ú‚vn€¤ žÛ@¥™1U}›„ê¯Õ C==å¬o“‡²¾›U«nëuUð$‚'WqÑò Ì“¶ÀWÙ»)„3EefZÆ‚¡£"Åæuu(1Y)6½«Ãž¥¦‡Gîª8г§Ê£ÄSÅÙ‡Sà‰qÉêå’:+ãò·òŠOÁãò·Rp{8Áùë㓹+êp(»ìÓ¯:JçwEtŸ]Ï)qXÔF'TÏR9S’HÍ¢óPöq¶‘rFøñº,(ì¨ê9×>R;*8Bâ y#ý¹8pÓUnwg²Q8pÓnW“ÜŽ~·cÍ)ÒÐUÇ¢S$1(¿SÙײf6Ùl²¯¢Éf¿›iõå)3O™Ùþ†ÔU¶¿>ÎÇÇqpÇ5ZÆ@·ùë|¡%RÈ=¦ªŽªz¦º ƒ@ ·yo?@‡Í~y;…ô'ç PŸUú8MG¼ß§dæþÖªqª •÷Gæ P{mÞ»`àOÁ!]Ð_—ƒ@¥ BÒÏÊA ®ª´ôÕwçÏûì}õÝùóHÊïɱYf³Ìáæêö;X ò×Ršï*-e“n9,f‹TR5o)(!4¿4$3³”5o)(!4¿4$3³”5o)(!lQ¯2‡7ýLÙ“Ñ£* »Ê?þÙä'jx?e?ò÷n{[—ê²Ýåh¶æŒR~†Ç¶W9;öµ±¯ÍÇË?ûÉœl²¯Áéróà §Yì´0ßUž<_­uÛa¶ÃWyêÌk?VàV7‘`ûËêËöWݲ³C¨] S›ÅìŒ \¯ú¨:“wF®¿RJ(fµÍÛ´šLwµMkZ(&i»GéÕö0C1)ÆH£ðÆ™ŤÈ"ÍWå,2ŠIƒD£ò’f„bÒ0Ñ–€åž¡¹ÎÃ[Hj óÈ'’‡·ÁJW}†ÆºÙ\*[±5 ›K`3\üšê*¼5U©f¯ŠUxkªÌ^“k@CCíBÛÑ ¹)Èv¸Ðv4Æ.èRÐØLK—‚>æV„†F: o®Ç/(ìi‘Èž†7×ã|ì¡, ›~¼±Ñî}¼±‘®÷F»éÇœPg¾«œPÇËBža´ÊÇ©µ€"v•ãÔÌwÕŒƒ‹)K dm›T`iBQÓçÅiÍæºÚªÒš›<‰àIÄ|Ñô†“•øVb¶Â¬À¬À¬À¬Àßµ€ŒW]F l¼êª ¤jžúJyÇË8­«-ý(ÃpBmöQ†á½ÁÌ£ C232 »jöQ†áÙ™y”aHfæQ†aWÍ>Ê0<;3ß h¨¾üåjf>Söÿšïj˜Ö7_?7ù½8ÊÄÙ›£Eyo‡c½Eyccc£(×E½ÝQ”ËÇVê†ÇGgˆrþºº~¢l™·ªB”W/¿R”OÍî>R”ŽÌÑÅ-´Ï}u¨({ο8ê³Ø¨Æoaë˜}ÓÅúý΃Ÿ¼ÞO®ò“7ùÉëüäµ~ò½~ò=~ò§RD¹{úòLQÎn÷p¢(çôqõåäÛ‡Ìåê)#t×£çÚ5ºëé˜qZŒ¦Û’˜¢Ü~avwQîÑõÀrQn¼îØdQÞÚ±f¶(ÿ ž'Ê™¹uÃEùР±3DyvÔ¥lQžÕsvQîñìTQþ:æÝùgnÕéÏW™;Šò‘‚L>WB4Q¾·;I”'ÎÌÖéû{ðÒBQ^Ô[äòÌ’ }E¹ÑÑæ'¢lËÕÒ¡´Òmé­DyJIߢüV—túþMæéÁ¢yb¿»D¹m·=ºë{)nÓhQv{g(KÝÛK”w-Êš+Ê{†ÕÏåsIt×ûÑ¡sºˆrMå~Ýõ¯/Ú9K”æ}~›(¼mû ¢œžû°n½“;·TÇ·Ó¶Ow½ËÜ»t\'û÷,åÅ+Öå1Ön:ùÉÂ#Eyýr]D×À¡t×+zêþ1¢üÔüò;D¹ÿMÝuãÝéx_w~O,«]™^ +çŽKåíƒËDùµ'òD¹ížkD¹Ñd¡ûÌ–Ñ–4Ú&¼’ Üˆùƒºm  lÛiÛ$m›¬mÛkÛm#† ~$.Á‹nH_ƒ¥©$¢®DÙmˆ„ÑëpÞÙ²ï ýüˆñð¥Ó‚3zÞÕã/Û†m»u—æö#”£~?×åûxWhŸAK^ÛD¨¼¯ÏËðU'D¨¢ÙØÅ¥0[£tc/åè1‘v+ã‚2<~¾Òfê -ºnú'¤hM` c…Ò®ÊdO/;m‹§I|a´ÒZ7É0¯C1JËq/-g¦6óLüùFD*Ÿ‰Kàg2Û”ÀbdP·´9Tùd¶(«5Âj7üdŒ®êõ`‡AÎM)ÐpÜêñÇUd¯ºqΪ]ô:ò±{åspùd£\‡…Ò:m®Ûqh8:ábêqêï|çíHÝlÐ ž:—pŠÓQñ"¼ë×'ê=W[!eŸ¼U`Ɉ×ù´âÛç¼qãô9‰v(°L@ äñß9Ð&”àØ^€nðxmœ(‘V“Å©ÀWe’=?–òm#e¾^wgî{úË S ]¿ù¹ú÷~á}¸5cŠêé‰:µÜª=Ù júô‹ fÓ5 úPsâ΀šÊü5¨÷§EM‘mgQS’ÉÓAiÄ·XÔl2ä)Ÿ†[Ê˱¨f¡Eu€[Ôã×ãA»jÜÙ%ù ¸)²2¸QîªoAiqAyE)~¸n_=îóMÞÆ)¥eKó‹S–V¨ÜºöÚ>êó tPÚÐùd-(+-/]TážYZ¶Ð}S*^° â½ÿ½• ½>“óMÌø7,Êëç?;ñ5¾¶iǧ-Y-Ú’å H‡äÂ… .\¸páÂ… .\L£õ?í±~øÎ‡O¦vrýâ—¸þpaïXÜá·/‹ÖìÚºÖ°íFkõe úÈ7@>€Pýä# à„ZP×Ùu ®éƒº†&Ÿ1ÕpTîOA¿Öw#ÆT”•–-è]î_º² ¬diAI…;»´xEEQiI¹²~&ŸmÉH[òHÑö³¸(ðDm»ºÔ>‰~…6.õ<è¨_ÓŠ*Š À³‚WûáY·»µ½=Bm24™^SŸr³&ŽÍ0yâ”Û³½}0¥rOŒöò‰[º¶×i ?y+ž«›¡ îÆ#•)ûJoø*HU^D‰<©ÅŠ” A t¹|þ_.\¸páÂ… .\¸páÒ:‹g=JkJzvOëJZ{ÒózZ÷Òsoz6OkbZ³ÒšœžÉÓŸÖí´¦§gø´v§dJD õ;­ñ)ë‚2([­¢3‚2ShíLkN7¢P<e@õ@ôDPö eQÖeúPö eÐPe¥"(C…â(¦ƒ²unD AP&Ö0e@Ѻû&Ä͈ˆ[·"([ˆ2v2@]oS6eƒ2©(†2R& &"&!nGPeŠQäeHe!(ÓäN Ø3Šc Ì7ʶš‰ ,ÊÔ¢l1ÊàÉAPæâS"`"1AIïE+òEˆÅ úRŠw#– (Bm)‚bâJAõ±P¦E«P\ee­@PöÅI‘a5‚²Q~Џq/b-‚2hªëÕˆû÷#@lB<ˆxñ0b3âï?Cü=¨ñ?G<‚øâQÄcˆ­ˆ_‚êûÙŽxñâIÄ? žB< ªOè;Ï žEìDPׯ@õýñOˆß ö ~‹Ø‹xTÒïÏ#^5î„‚ö#^Õ·tqñ2âÄ«ˆCˆ×@õÕü3âuĈ7o!Ž ~ª/êˆcˆ·D¼ƒx(IMõQ½ø $<5ÎåCÄ Ä¿‚ê»:…ø3âß!þñˆÓ ÆÃü'â,â/ˆzÄ!>Fü7â⟠þTØgˆÏ_ ÿ‡øñ¨q5E|ƒøÄyÄÄEÄ%ÄeÄÄ·%H¿…bhÈ7†°#"‘Õ_Fñ9QˆhDŒæç‹EÄ!â-êW~' m-jO"Ñ‘‚è€èˆè„èŒè‚芸áFtC\èŽèè‰è…èèƒè‹è‡è€ˆHEÜ`Qã…!#nD A E C G¤#nBÜŒaQãŠnEü1‘ñ·öîËP–r‘XœRy*P‘JT¦ U#±ø¥jT§’DMjEbqMu¨Ëc‘Xdc=êÓ ‹wJ&…TÒˆÆ4‰Äb³šÑœ'iAKZÑš6´å)ÚÑžtäi:ñ ÏÒ™.tå9ºÑô¤!Šóy^ }éGð"/1A¼Ì+ æU^ãu†0”a gD$\—NK©ÅhÆ0–qŒ·OTOb2S˜Ê›¼ÅÛLc:3˜É,f3‡¹¼Ã»Ìc>ïñ> XÈ|È">b1KXÊ2>f9+XÉ*>áSV³†µ¬ã3Ö³lâs¾`3[ØÊ6¾d;;øŠìâkv³‡½„\÷}|Ëwìçßó?ò?ó ¿"¿Fâ1¶>ø#‰!BÛñωdâ$NæN%3§q:g…ªy&g‘•³9‡sÉÆyœÏdçB.âb.áRrp9¹œ+¸’«¸š\\õ\Gn®'7p#y¹‰›¹…[¹ÛÉG~îàNîânîá^î£CªãŸÂ¡(PŒâ” $¥(̓ x‚dRH¥!hLšÒŒæd±˜%,e!ú|9+XÉ*>áSV³†µ¬ã3Ö³lâs¾`3[ØÊ¶Äعm»z_±“]|Íîxû^uHsßÇ·|Ç~ÄÛû'ñöt!Ï"ÕÌ1‡™oŠºqtƘñ’ÍŒ!=E6¬!N 'Œ„ØÜ*!6•þ£ôþfäîïš–OHsî$½&%kÉlörhšî¿oá½Î}ñpÿ¼fíIÑ܆Ó¾3Z²$Äþ[ÈÑô?Á¹“cãT1m^Û8¤Z4‹æÁ¤$öû G,ÙíX¯…u[Fû%gÉØ·‰™¬\B¯á;ÄðÚÓ{ÝèsJ޾2õÜN9Âãä:†ñÿ2ìz|ü3ýeÏîùäÓX·Mÿ{é?Í2I¶– .õ¸Ýß•¬úÖËG3þé=Åz­cšZO¦Æs—2^²Ùƒÿôã.½>´-üq0íxù¿–ˆWÿ„̱÷îŸÏÝáúÍŸr ¥Öj¢,¢×„J• ÷¹+z0…ÛyÒÛóäKØŸòa?cs¼üËïPKLŒ05Ú‘‰ñ| Esnacc.docì[Í#YRwõ¶–ÆËÇtïaOO bªvÜ.§?«ºÐh\.WgªìÂvuOï ;¤ÓÏvv§3=ùQn‴ˆ b%f.œbùV+hOËÄ-§Ú BBBš&>Þ³³\v–gáÀaRªÊr:óïEÄ/"^¾¨¿ÿ»_ø—?þ³¯ÿkjåx+õ•Ôç¯Ò©Ÿ‰]ûYøÙ¿£>ü|*eÀßøñóW¯^á¥oÀ‡7á' ?á'?¿?Ÿãù+©Ô«/ÿwÇ¿ÿé_§~ó7ÒwS©ÿúÅ¿ZX0üÓÞI}5ÕÞþ“ÓŸœ¦né»_KåRwS¿—MÑÏþß°s¼qóV:^½ú¹[ÿÖÇwé÷_~5µ8ÇÿÞt¾CøuýëoïÜ8À¹ç×`Àß:ÞIýàÎòþ÷爛í¹ÆNê‡iÐKk'õŸk«çWÎÿ ç·€Å÷wRßœ¿øæNê¾²õñ¢ÏZÙæüËpî î¤ÆpéûÃ;©+øü¸~?uóÐóþ#{gÍ·<®øYß§Ïßék*ó±ªO=?}àç„ówṯÁùŸ‰Ÿ_=#þÝß¾‰³úÙ^‘¯Ÿÿ¢‡žÏ&<è¤3ÈeۇÁƒÙˆºéšî©ô„ñÍB¦Ö:f4Â!ÐÈ ÑñúÒÅ»ž7ÍŠkšš˜¶züçoû¦íö½YÎvÂÍŽíæµµá«û{™‹Nû¬ýø²‘éÁ*WÊà0+öª] ”#`'ÛpÏÔ÷®ìë3¦zû Æf &æ@ ÓËsCÛd^W_HøåÎ…=A$‰S¤o±ž²›’îKGš¼i9Fã îÈÀòí>J©/4]l2<ü#Ñ÷Â1Ýc)Й~ä> 퉎Ý÷M.¢åd@3R4Ü1²i ƤÒ7Ú8þ¼-rÁCÀ¤Ò‡{A Ah¢m—¤® t½a83}).¢>PQœÙ–taº»›x0` »ÊÓ_¸Þ Œ3’ûj$ûkZÿþÈa´\ø2\!ÌO sOäDÍqDàE¾…J C Y7·@Ï ”Ó—W~c†Âõàá $íÏl° \‚á]Ës:öƇÑ!™þŸ·ÁMÀ$ôÌÀB0x„÷äDÛ™®ý‰zÂ2]º/iP(Ó‹B15çîè{sÓ mð!˜O¿Jä2™v§ù¸Ùª l þs¡¹#˜<3Ï!fÚó§^Ø}‡œb+:ùÐ÷&4,b» ãlºAh‡\H=pw0È$rU\D\Ùô­±Ø­7{=š´Gžæ˜áò¹œ 0}bÁÝåY Mªy‹æQ©«‘Ðç¶"AÆ„T)–ºäkp<¤Jp-PgAÍt›-±ÑÚ.ÕT[ ×ö9Nh4d‚3;WL€‰£/%ŽjÉb(LôjQˆ¨°§cÐëL¾“ }b0¨'01?Òóz#„Xu-ÚÃó¦oÁá‘… !uØ À6"' —®p-g„ël–[ñãÅfxÚ캗ª_$‰1+<œ-7³a˜}‰cF oœÂÓfïöeOÔZÏÄÓZ§Skõž-‚<ŒÖA»€½1‘ËœýßûkÇͳfïšù´Ùk5º]`b È‹Z§×¬_žÕ:ââ²sÑî6r¢+åmÜ’¿àŒdå©âh:€!9°ëèKZÒ&£’«lÃH¥¿¸Çlº•Ü“’I3Á‘°‡]¬˜ùX…*m¢uB²µZ¥Zç`5Q»&×ÍIß·!CBµZù‚Q<„"°[ƒ0еöÄÈ;A*Ez˜¡®t®%+‰~Ü9œ?¥š!VÕ1‹Éî¦ÙÇI*eàÔ–"õW¾*{|T/\‡bDÉ@Cl#™aeŒ :+ÒÝå2°Be7°9Q¡ýã³CVfãbP˜Ù>ºBµ12°È'({‚8#Ö„psÍìA B¥ÊÖÏ•8ï:TžT^f^½v]|è‰ÆÃâñáX|ø‰¸¯³>tăzžUªäK†‘?ÀšÉHÃbˆ#ˆK¿äxÜè4NEüFÛ¹W¾?“wHp9#½,’÷KÀ†Tì¿›{œƒÕ8™ƒËüЍéhˆË)ø¥-?ìâ‚koý0y•ÄayF!}ÞOmwàÍX¯ÙXœs×Ây†¯&à _LCšz¹EÿKÈMîÐE>×Y*yÀ;ohl%°ÀKéN亷Aò ²¨ ÁVïAaì‚~FÁzÀ"ÅdÄ#–Ó9õ|rzÄ$m<Ãâ  Rš±ÕÐzi%%­”,­ŒÒ é:(’ËÞk”·­hn >•í«ŒXHë÷¢…-½€¹BBCXY/¢ªD$sÎ8`Ÿˆ34E7ôa„¡„ÂÀIÐb·q ¯YT)Ýp©vè@Æ— ëAWdO,ä´œ>‘·ƒCÃdPƒA+é `dx ¦"a!ŸŒY`Ìjš²j2¤"aÁH†,2äÙN(ã=1èv›- …d%q˜Ö¯ÄÄ d&ðì«Mc/m\VdÉ+dªOÇ .B^cr®¢YHŽ|bd1­_E¨âh=¤¢dá#JämHäW¶œ­G«n‡vÀh…tÏÜ? Û!2R1}&ÝQ8Þ¦HUHöÿbžÁJéãvû¬Qk­+*2“¿h0X9Ýlõ²L±¨˜ìòŃUҭ˳³õHŠ<Åd,©šî4jŠÛ!•é }Üì‰n¯Ól=^§¨QLN…Å2ã¦Ûõ^#Qñ ˜œGŠå´ùtûøÝF½'š'V¯yÚÜd E†brò(j2é. ´}JÙºÛøµËF«Þ€ÏëÁ7ŠÉ風¸a@öƒ"ãù¤qÚl5NÄñ³õàŠ.Ådº]Œbú8!¬›®9¢Êb=®bN)ÙJy B!w¤I•£ ù°N„%Tâë)ZR¬*%;IÉX*hAOñEÇö‚ãJɾS*,-t¥«ÕÍé¥Tؼ¸/¥»€.X†+>–’½²¤øh@¡áûÞ­¦-)Z–’ý±D´,¥yèöª±¤¸YJöÄq³´MÕXªl‡XeÄxÕcÞ²n,)v–’SD逅¯ ©;ø:à¶â£t°ŒC%#Çñ%\Öã*’–“IZÎk\X¼Ónn@++&–“™X64Zñ‹DÁ²¢_9Ù™ËÞܺ>ÃMD[¾çÎ'´±ó©ÚÿoÉh(XP×zÊ>Ëñîçr»ÇG}1¸»ƒÛ2Ôh@SbŒ€¬z?•&+v i Ø x— FåMÀt¸xÞHÝóÃ2È"`À»`ºhŽ7S½Þî³®Ùg)Ö·GX0€Q‡2y?-W´éÈ£f7öµ ¢;•–=ä©Ò`D÷¼yÞ ]FÚ`Ô{—Q z”ÞÏ•ó‡¼ÒèŠúyW-¿ Šk(«§@»Ñ¼Ë‚kNà)­ó ñÄ !óÀÈrq ˜£; ÊÑ‚óM£pÀo–ɉw=˜¢0òÙ|>O0¼©D–%ƒ`a›•ò ÷G@;Ü¢’ø®…©Ñò5}µ ¸ìh˜÷˜sá蓜¯yÿ/·OûÖ›o>”/Ƀ}¸“é•ñË×ÊÔ}IEP¬WŠ{$hlOìV8dÑöòÏ¥¥b1¥û©iq „ñ…²h fbŠÜ‡1F…îÆR/38 ØÊâ͘nScß\8ž…hÍó‹v§‡%Tã}þkî;é{N°šñàDRåKiE´,»˜z°ÂÀ‘“ݸ[\%³E…]V’µ¨4ƒ‰±‰#=¨£¯TÏ-ó(9Ž ŒÔšŒëò cd.s¸0­·Iæ®Y¸K»h¾âõ²3p$Èe.©™L×qó):4ÄaUrm6Z$2{§tÄñ–̤¾Çèn 9*×A`˶…{“U tH5›q3ÑJ x¤YÅ®ŠKJ6ò›¬QXYæ2ç@Yô(, hJìà€Áí(´.óðtέK %ç°ÅY9ÕÀ\Õâ4ð0À¸¹*íKþ–cL¼0 Ô׺dSRÓךZçÑà©¶k9ÈSއªçe>g®¡²2µTéî@nøå Å€Àæë¦~±¨%iâËœW*® î´§ÛëÕHq”1"Ç25GÍ:KêÁtæJ,Ñm´BT÷å8ô+l@ŽwnôÜ«Œ:ôŠAµÀ……ÏõcßÑÒ Ø"G¤0¹€îJ)§öí‚ÆŽ\þ°‡Xø‰¨ºÂy}Æ«7|¿¬_™ömG¨k1÷ ’ZW†í!¯ÇñÃÇð!”ÀIœ{?¼ w|2ÎÒóXoᣱv ¤'SULK r°Ä<«`u¾5Õr”+®*¹ˆ"°ü´‹, ÑÐ÷¦¾M *"Ê‚¸Àd‹¥ùrÍ@Q’Vˆ’¾ÌI£5p2 £û‰VÇ{•Ä$²ÆÜ ©è%Æ!\´¸sd'Ö†h×>6ñr¦yAuàØÔ791@¨W©8ö륤7U›TäyÌK¼Ëo"ÿPœÜø°6(ú#&TÊ[±X‘k u'•eÍ ÖÀÕªÿò`ê2«h‘µ¬iÕz!¾öÔö£·¦@ÕÁ8a@ëš0–)„ë…Ìûçg!m—vBñÿ  d´éˆMUûõê0öf#Ï—ÌÇîKð_jÍUþÏîÇýšÊ«— @` 3ÿ—×dÏ ÍÕÖ“fºðsŸâd؈N®Ôlh²]ò.¶šÔäzZTFUþý˺ ­ñ\‡Ñ+ 7’™\ÀÜÓ®”4Ðë³Ø(¬ÛÐR·yœ™vfЪ˜0´ã’ÄÂ\Éf€éޱ֛ µ¾Ï9J”ëZÉf™äœr„ŸN—ÿƼœíÏ—÷š‚{ôTnPåD,ý*:f,£ÎqN`mñ¶ÊEf_ 1 •íÌ:IÁö÷N)™_,kn´$æ;¼=‘8cÜ3˜‹ò%M©l´û²Tǹ¥Äo!§²¸“pé6…a:•^CtoPYZê.© ¬ ÿ•Pÿ“¸ÐlƒüGean}kùeÌU ë ʪo—3ÏyT b–éÐ¥¸›6Gˆª-sMªÑBçD“ÝDO¨Ä¸€EBRc·ƒt1q}6II˜‰BºåÙƒ7îzz?šRW‚»^Hæz£Ý&ÉV¢“¾ßÉwá£Z´Ÿ„t©^j_`f:Q%¼‘iêÍ.±¦hk½Û dˆÌÎS‹¸“Ì$*¨/Í.iÖeÈ(!ÃüJgn®)Úo.Ë8ËúXîì£ÍÅd¤Þi‘s-³¢Fæš3»lÁ„œ»ý3èM± ].= ŠZÍL¤SʈSQò'Uô‡s•‡jtŠRœ® -âý°G 2¬´ÿ×Y;n¨åÓsòŠè´›Æ¹¥ijŠ>À®™ÊIAÏ:=¨Eå}͓ҧìXaöZpa2×DîfU ±f’ô\õõ*‰So.’pטu‚øžrà.Óô¨áÉd±êùß–ùîäé?;›©nì¼Ã‰Óph}e())ÀObR?»ßaQWxst(ø§ãÄøÇHÎUbȺÌBQ~O{Ú¾ýãO•ñ1e8~ÈvŒ>v/Š·{ÑÖ-Û¯®E{©‘NS† Ü0µN‰®WjMWuß, ñ¼#ó>+n6[ޤDv tºu]6Nh}a‰Åý^‡ŠÑ;íÖ²ÖzšÈÙÀb7‰J˵Zm”|ðë˵h¡MõܹV ¶÷„®Y©xŠ9þÆ©Ä ïuæçi*pÑY&ÅöåhB8 ÛrrÃê‘2Ú)¿ÆLOÑ2kwÚ#ü÷D-Ê÷!)x—P6oÎ=öÆþ†ù JĤŸ-}%; 'Û42ÙŒæk¦ò>Ñ‘ù¶³L}ED¡ <ß쥆Çg‚!]ô i¶'[¦¡>‡Çº YQ+¢*”¹T,¿{SÕÁXã I›ÜH…ûÂúH—ÓMë Ÿ›íãI·ÓæƒÕFs‰6%:köz²4P«$¬6•ËìTm¡fvÚäFÚ똩'“‰ª1Uä]#$Š´ù æRA¬ ÝÅ,O]•·dsg¯Rþ‹*:ÒÛ(:6£¢©›ñºtÐÔœvoä;› 9ê3óÍHèâb8ë<ÿc™å¦Ÿ¤µQU”sÛ¬ÒŸ´øëél®Gî‹fö‹EùBg8Õ›mqWP.IFíñ‰Ê~¾Àáò½â äQAÒ*9,²ªQÒX²?So©j£N£Ð¨Z¾'+þÙœÁÄ çá¢ê]qWP›[̃N ²„†¡YK ˜Ü†Åcõ…q%ªsšt½q´Z+Z£z‡’"ä4¹ŽF´ µ>wÛ¬\áý,µ¬ gzCê4Œˆó(ïRÌ‚ß3ÊO§ 6•cæ³ñ'7ο´ËE§„Ÿ“$§Œ Ÿ‹îdÊU½ žèù3Éí¬ w*:ù>ß±*»_jãüÏ]€zŽláõge´ŸvGYéM-'qƒ~¿=á)ºOb±m+ï*N,¯^åL4ÝíÿIûx‡TÎVöHšìRê´ät¢¡¡ÀÔöùtJZ|ªŸ¢-§É˜È;櫓kì³|„žíŒ&v>ƒÏj ù=N|KãÓû‘¾ýèég4yá6jà=¢[FnÅ?‡èŸýsœþiÞZÆ¿ ús‰þ™£búgöV–hÌÏ-#õè9ÑÈDtK} )ñçLt­Œ ö¥¾œu^O’F+ʾ¼¸Hy.ÎEׂ³‘]–_Zl9x}6y+º¶ÝœÚlÄš{zÓžñæIêšëĆçèñý“·²èÖ$e%©å$CPsSN›i&ÓI:ö1ç XAª’6y°Á H÷p¶b{¢““ÓÓ㇟ÆÓ•³†¨BGŽ%^¼VX5îRü\_Æã‘<áqO…?ZLçéë:¾¶™PMƒ $¢oÀ‡ ¶Í¸ßêQ93ÿ ÑÂw(e»s¼ƒ¥€ôTûÙ.3Ÿb¾#ë7݉IÙëwÛÑf9´˜#Ýq]Eóx]^á219¨94Æ×«çxì¯d«¡sœª§û—§ú>ew0—]š¥ ü޲¥6 NåÚ±Ú¶Ù­ÆX‡²¢ÙézãàáÝãtHjÆ£’Ô°03&Ã΃_4ËŽFÑîNÌûù…A¹¶ÇÃ5*ýTÎe×F¾ýi¯AŒ™! М’…u;o+ (KbV2ÛŸŸ×Y5ÒóG›ûÇc¡(Áq?pó>“UÑs0ά駕ic­³èyîÚ.ÿù’ÿ\Úí?žó/$øÝÓFô™cmX;0³Þ´édI°Sâ´™›G£Ñ,ÔB™È—5ØÎÚUfù£¡5Íf†Ås=•Š!ÓY¯ãÐx¼#Ú_æC2'´‹·ù‹ ©@dá !÷^1£–´Ám$½TóxSÊYT…Y±|aÚŸ›Ã.… ×uLˆˆ‚0^OÔ1bC ³DÕ./Gú|a²rdöz’ºM™|1§!‘XyÛâ’ÊdxÀ4‘§f¥3›Ö±ïÈÔžŠ®ÝcÏÜÅ êæèÅ~»kµTr¡œ‚ÉÏͺI‘òl¨MµˆNa£gl2|@Nà•Þ@“dõ`U%íZT9x`ßÓ8XsvïÖØ#’åXT’O-ãn[¥,Ù¥÷'ni~Y–ÞÓì¥àoÛF¶lÙº¥¬æt@”,ÖG˜†< Õ:]QF“•ˆØ>ÀV“•ªóÊ+ðÓ²(×è´!¥¨0&Ñ‘Ýù”&è&õÀ¸C™p-É™E*ŸhCeJ~¢ •×m(ßà#Ð$î„YãÏ”ïYü™òÅŸ1ÛWy=hldD·íÈ0sKÂ[Ž~{ »l”($ñrZW_Ð3U/ÏPˆh¼Åf¿Fì5FܶJ7o Ê0ÐC=5cŽyÿQ¶"†àKãgY>Û|ȉw"3,61Z Ðls†´Eæ¥Ë¶íÙ?÷¹œ˜Ö(MÅ&2ï’RªEú­Åæ"ÑÉŠÄj¿ãh²˜ ‹ÚŸ;WÛM:¥¸•vlû|>Õ²7ª2¥âNŒÕÈrÈ Ÿ²D'XÄåw“ž Ws$n--Ätô6ã[aBŠ6NVJk.a /AF¡ÀÛüa«ÂT‚<²8ÎÿNp)#=+†Ë¡ïvFõpÂZ’°NÉgŽygJ¬už£eMÚÅPÅfë«eTöTõbZ­¬¸9½æÀ@Â¥Å-Zžó bBa‚m–F¨í“.fÌ¡uGåÃNUJ;³ÇN^e»‹©jÛ±&Q ë2„š¹'í§Š†Ê6"=:’’Ïg £ËP¥Ç“¢Í òâdk²¦~/1™¶]-ÚkÊüÓÜ0mj`/U¬O¡õË€V€Þ‘°^õÜ2oúƒNižIàΔ‰ƒ©F§F¦N×2^ 1÷¸É™)”Ô i5éHÙëèÐ ®Û “´yŒÒ#¢Ž‘S-0§àMS™±u¶ÓF2Ÿ|SÔ‹=«Ä—c—†D34ç #ý.) ˆjŠF/NÓþ¢Wn›×ÅB|‹ ’j¤&N–.ìÂñ­E Cëu™¶Õ4ÜλJOÉP /Kjyá·92¦êdkQYU=:Ä`Øûñ<5NØ‚Ò’ÆØê›ê¾¹º@53r™U§•AÊØÕJYZÊ”³†| ù”{;ª‘8[œo8§-?œZb"‡Y•ØFÖN9cæ¹æ’HµIB &‡œx¸ó žFöà o$JC¹³<2•z«˜õ±ý‚o?g§ïà-kƒH¦ºÂ«†rCµXèÉA]@¨|Z¼ò{w-ÙíÊ\>EÂûéªQðÄd`ÓYJ“ÔÛžùtâ$dEôÞ]u9õK=ûdO ø`™ÓQ*_ÅQ jtºþîùY¹b]Á#|¾02ìÎ:~¼‚UÜ–´ØÑ±¸XŸBoÍØ·œ¢Ü.%jÁÄJ-Èú‘•ï¢|WxÁ,ìk32Ó¿é3‡,JIXÃ9ޤ¦ á³:(Ê•±‡Z¹Æ,LÎøà†^õ6žZtXé™nDsÇ;f/=êÀD&N\øÿ”F¤bè´8’OgJiE¸þ‡ö‘¦éÙjSíäŒì¸vÊŽ¿¤©› “Y îØš…;ýå^Å IÙª"ÏÏ{„âõ¤x íÔ=†Ù½ýc¨ëH\ölÅ_³”zL—ÖVþ=\Žî›Hùßµh§ St ·\e‰VˆYÕeÁ³!î-zÓìŒõð0wlmº5ùDvÁì4¶óšLysËÏH…z–4³Õì¯k, ¤;@±bFŽè¼ÔzdIjN JN°Õ£ôzÛó|︓¬cjÈ<©/ ѤÆôjɬFÛÑðEGß‹¸6Ët\¢cø• ‹š\&â@dñÛCØÀæA4Hw(Ð˹¢NÝùD©–¯Õ5ÍìóÙ°µS7у6Ï6,ÉH“Åvl4ðý¶Û½M5vi4ü7…!g³³B_ _ñÀÒ´¤åƒN {WoµíÈg”DeÙAËÞ9ŸÊúø YçuûkË›ßó¤…‚Œhä¿ ŠÔHG °!³9"€ô»w­´9gŽÖÙrΪ¤Ö—óÒ 9‡ÇëÌxn¥}$P­'_Ÿ²vEÜÇ­n¥HÖ=%,Ó?’aCÚ&1›rP‹ÆE_ˆåŸÔÙøÝ"¨.Ij6k¦ú&ˆq;™EQ%—°K±òĨ¿8BqOtÉ¢3ÏÆ#Cf¤Q˜BÀgý¬Òó Q1;¬‘€uÜéZÓ¢ŒÊÓéöå™Bgš¡„ÎúF¬Z-&ÈE¥™ï5šVÓW¬I]°Úõ§›ÌPD ƒfM“Ûmª5xßw€ñ®•åÃÏÄcwÅœÛ-ëúÝ¥NJƒM•fÅWt†…äF_ÍWAlóeýÚ쨦7x‡+Ã;T«3Ëó/>'-5ã1a!vÉò^õLãNnùݤ®‘mÎ"5¡½ŠŒÏ¢p¢jhªêÄ ±ôF|®ÔØ+û…iŠ÷ò¢ô®'CªGƒuËN|G· ‰ý*µËó)²–¶õ†Bæ¤å C¶S§‹îaÑ=b:/Ïq:àãðÙ¸~ìDÜmH𠌪8ÔÌä²§Ocµ-\Ú&u75š2²faå@fûÌM¸¶øj³öÑSøØãКD8Ñ{Bܱ*Y°•_˜\òcJNJ%žžT2Ó<á$aÑÈûC–y”â4!ÛñX´HË¿-©«t‚Ù“=2/œ÷¸›çÔhÅ—`¤Orh¦j+%¹áâE1‹:Z;Ùm+1ÌÞÑlÖrRY@ÞQŒí©ª4¬v‰¶…Ù&uÚ×2ÎÌäSJEÁ›¤‘p˜#ËwµLCzJÀçD¡®‡Î|ŠB§öl­±Þ[ôìÖÈÎÊ1¤±¨‚CŠ¥†–tžþJRsÔº –ïHŸê9r&ëh{.ÇÐË*e© %1¬ê0ãm ÈxdlËÑ¢CAdRu.ã¬Í• ±­’ô`—wÎElQâÁå³ãv$·ž£eÆžØlî›\{jÆû„jÞmŽÔƒy!QVÑÑ:|¥d"2²c j«–”ýTùï Y=hšóÌÙ`b 3ܹX>´H=LŸùâ 6Ûçà=õž ㆙Ô_¦µ˜6Ó‰¹´-ÿ Èv¬ÄT¥ œ=Ò‰8Èú[ÞÜxB.öÛó‰ç6Àm¦ÖWùyc¤­±Mˆ&±Âluf*’ª¿F=^¢¨ z·j±ÉôúvÖ6½?—ôXòêP…–¼«äÒÞ2­Ú{Yß(*ÙFœ.¸3PxÐjÄ$™{bÃl*£¬Dm¯måÆ_YÛêÎ~Û 4PWå:iz •»ÕÜ’NTÝÂA è¸T•E R ù˜rGæDÞy¯ãsUV=ðÁ¬´ß; cã™@Aƒ÷û k¦â‡iy¢;1ϧý·+‡,nt"›2{Ød騩aÕ÷~¢Ø[ÅÕ"Í»}]µèB3za l?)›Îæñi?CUùÅ@AOºŠfL†ª´|ãÙYò~S7ÄÈyóÉ‘‘ÛEíÖY‘íA®©­¿2"â¥ÓŸÆ…hÁr0!hØŠŠÈgÊlcŒPIÄ{#+/1}YMjc%¯UÙD„8Ø ”= o¹ñ­„채’YP0¡üX›zdá†Ñ¹°.G1 XfKT©nÂw1ù${eg<ØnžìÑ.¾D»£]sR€ÐZÚ¥$ÏÆAN‚ktrݵ5Q&Äž+'¤ÚÎ7ZFžvËêuU,Ý;Å0Úæ<¸5üÄ0¨òà.öÞ3[›z¨© /a×lò«%‘Ô[3SqéXÕÈÃ’†e©E¡È¤Ý÷N³~kQ¼8›Ì÷™Ój+ajYí­¾X­Çdf¹Ë±Äõ“Lüªt‰–©­Ù5S̲S0Ý4ºBiÏ–Ý})ƺc!¶~Q©7k­:ŸhâΨ¼·ÓÙ¹ó:.±|bQO5fPr•>‘Bô Êw–% ^–hÇòjl:üêl^ƒgìNl-–(À3/=cäcx1uÅ6¶Ê™™“jßj¡´¸Ã'×ÈCxyæ*¬oâ½`­°.?¬Ò–ÒpÆjd¡/‘v¶Œh#á…=*eæ²—ÓüãÕ kÿÁ]„1Êîû#"7$ÜWÜ)ñ1+Ú¡¤c"7ôü• 0š^ò­c’Â;ÙQÑù  ¹U¦¨ûÚÇ"ÃP÷Û+¢µ<v/G‘ˆBc–;$zJÜãL1 9[m¢sâõ Þ`ÆÀ„]ûƒ³ â–E‡Ì­Ž,—%Š ¤jMMNNÒ$ð_ãï ÓÙ䲑4†—§Yá³:ÝÔú½‘`Ñs5O.ÅdßÀ‘4¨ô 'KoŠ&O.íîÏÕ¢›1L’òT·j°|I¬x³.æó޹娙ôdUÉÄB ý¦Ôs>Јýʽ¨ÆŠ˜bºZe/Ç7eqÀT¦OŒÊ7«øÂÌl½¯nnæºW “Fá5NâO¹³ÊV*©8Ðð•¬äÆÍ«øÄBBjž~LGô¬©Mrâž’M-¹×ÆËÂͶůP¸~4ïÍ¥hcµ±M‘Ôe$¢Ú—9\^ëåNž»M¬Çu^LŒ ~ÄucYKÇ–mJ8?/¿Õm~“ž[ìࢻùÑYÍ%Áb [›è€+éuêÇžÞž|Y´á«$¹ ∠AÞÄÖ^' ι},sUñÀ[h©àü·T™ÞhÀ8Ûs“n”Õ/õà®ÉaÏdYBÙ¤åÍÄBÐÖ“øÇ^9ìyäí,O»¸Y^¬,G3©"»'¢-.ЈcSjèУƒ‰1¬T£y£Nʾ§Ù…áR gÚì¦&8JÝŽU¬Õ*ª7jƒŠ‘z£Êvçʲ,7{n† —ã´-ñYœdcÊu\ô–¨²è…Ä.“s®¤,¨•UвÔH%n[!^ ÃÉi9oQ3Ö¦³BÎe!yzqœÌ'¶‡¡‚øD™rš¥s`‰ÏÈ±ë† †Ú ´ô¶¯<žz°ÍÆh,Í*n¯/þŒÄ—Ž¢²DI™u:P•¾hÜÉA©ÓíÌÍ9ÿ`ŒÍ½Ï$íÂa©P(Ëhd$2^N‡Ð7£‡ö4ë²5Kð4:`‘À‰V)aU}áH:¶]²õEÝUN¾ôÒá²Yg“OÙ?Í•ÞÍgþÅ‘ëÊã…Ëáêìà²É0{ÍìÓ“:·,CNÆï#ž<âÞ™%Þl”I©AxdLID±òA =}RÞØ?M€¢‡Q YD8_#wØx¤í¨yùDB3›ÊJ½²ša\¤vPGG°®¤.´岉Ë,Ÿ€9îøÙ1Ѝ3Š!Â/æ uƒ5Q®¬¹¸ ls*¨&Ò~© @œ·ÒÔÄó‘ö‰:™*¤Ú'“ùe#âü!ò6ÅÑÚ]Æ6Øjë€×Œñe¡qµ&øº‰6jQöåuŽÃåÛ2]!KϲêÂfCýâç¶FeŒ³ÝFVÖHO£Mo»ühÁÜȺûØ#7ÍEl>,ÛéÖd ®kÞøíøkì¾SC»¡sc·½Ümžèå´X!EÆ3aØ&9o Qœb€j«ðÒÐÛsÉÒ°‡·¥X_;¼º”Þ³†k\¨ÜÈšBîç[ºwc;9Ôà˜=¯œv:ä DSžuÄïr!7ó„Ê«¦OÈ®4ÒP=¬s²ê,Òu£s]YðŽ Ÿalðëänû‡õZò‘¾Ñ%›p@çÅ'ìaGõ¡¨†¼Ü9Â)$×·ì]\QpBdX×,uŠâÛZ–µÃ† ÑB2¿0¢aÔ¬bï¿ZôQäÆÜdbGÉ)æ³* Yc=ᯙ›ÍT¡(³r¡Ój˜@”†Ñë,C猌ÂÍY8Ž•,æ’„Ìͺ ZÍ(è%çíTž0º2[Ñ„.uRa zþ‘‡e¥8$¶s°>J¤PFU=Úh-K^æü©áƒ-úŠ”[†“8Úm¦êïÈ~K Š=î#±ÙFÖ]R‡¸ÐB:¢ìÓ³VT©Þo©¡; ‰úS\…|…«ÑGêýž*T£Ú‹ÉÞØ™¤¨*=˜¾ívfûi¯Mk’…žFÓv™*'2G\šë³ùzàw©¹¯X©§ÖÝ·c3Æd&Ò¡4iÍ.G.Æ»Î8–a–l^™¨>¨ØÍ&â6Ÿ§“½@á^&Ÿ:Vµô„,%ÈOȪ'2ª49ÛÄ+fã£ï`$äxkÖ\®£k¶m}4¹ÆO4&F”í\BWfÈ D&`9ÿðÈ #Üê VÝÝe'¹Lø¬>W?áÍ=ˆsCV#äÚ2ZAòQ£6‡-1¹‚ø¢©±¬¹›š™:x`:ڹ󺨼{ò†©MÚ~nšË)N9ÙÑm$Æ$ig¤^Oz½hû¬—ÎlÜ­D[¯Žî$_Öi4x•l¶Ò‹[¯‰î¤"AÛ(­Q¢R ðƒñîN§Eß«a?søÈ$æç°—ìî×¼}ðµj|_5*ûW,ùß» «P“¸m†üS‰Æð«Žf HyWøX¥rT¶ßÞA*Ï\óªJ˜‚¢);QRã-›U¾kÐwF“öDìNsÏS—«y«Û‘8¥?ûwFå'Œóõ>OÑì½ú^ˆði󤚵[?aqçz0D)Ä'ˆþª×H{Ÿ3áãué.É™¸Äô„,ñ÷øòšÒSúž´+ù¼™fß…"Õ ¶&væ[srf WÍüéq¡úšf,|tÝz¤©šcÄlVoèÀDN o½‘’´ÞO=#}>-Kõ¸ÝTÖî)¾é\º‘4.bÙa蘒:25ùDÖJ,­z6ûÔ/—‹!J½¹©æÏ‘µ~–ב¢ª÷¡ Å ²85‰$ýRú¢j}ª&ïH8^³y yKØvÄœÖñÁ$ËF×-5·‡éꉑ¨¹Ÿc’“aêO%N]‘؎螅奊8ÈL`Øè'zrü©jtµ¯`󊪞H)&,˜3É™óhÃl%]ü"k,Ž7겓^á=U¤¥x‘Žomˆ7=¾(V§j59-`&¢cÍånC·w-6/i§¥ûi¼´¤1.X•šE¢yƒžP½j.h"=’mX¸ífÃõ¼X‰îJ³ M7Ú²ÉÑ“Eš«`8Én­|€•ajs‚ÙÑ]-Ùl¢ Ë µšåpTú–HÄåhޱ_ówæ oËäA æ)Ïe³¬Ë“‹K¤eôöeä?=9ƒÚÊžÊù®lwÎØ2öŸî}¶´É:#†3‡—ß—­6€'±>5Û³ ÆÔʯ§1ÐÔ`VøaÉlEV€†jõaS÷.EZ;7%ma{’¶X­p×¢ñyð8˜ì¹žsþ:tѰÏS±aØxë›æOš·³Ä,Oùsã£cãϨªµäwÆœvêñ€ºý<ïN=SÎŽ ‰wUù¢îਈ«ýE÷ý¹oøê«{}pÐO]Ϭ]Þ6Í/š@~BIÔÖ,ŠÊÙbªV‹Ah‰—ˆÒ©é"eI,„¾a"Üèê±2[ ¸x±þö´‡vëis©9.ïSe;È:ÍÜs'™òRªÚV1_ïc7‚;ôÜA‚YÉàŽ0šµžd®VöGÏÔŠz|fÌö_‘¬Àì“ÄYg¶½K'ôZ¦élÂjz };CZr´Ò uIä%žv^•¡Yè’µ\ n—.ÕD¶–'ÑØi%üUìöŠ÷:B‹¼‹ðD×1¼³¬ ƒÑòQy<º.Ú†v7~U˨ÁuàæÁ¸ÎŒM"Í®hts0ØãÂ`ï{BìhóhdóVÖ̘ހt Q*”É…›ÇòïTƒŸàKNy”–?ªã>œÚCµªkê]QY8œ0›#ü·Kts`5Ǹ † SH ‡Éµ3ŒŸåYwJugïâ~¬w4pºùlzß mŸæ¿b­LÒù2†T€Kð × øûƒs»‚Â\S<jJ½´9×MF¼ êÚÁ?ùªIeÖD=7yôy(ÊÍ=¯þöK$:VR¹4a [Hd†‡Ó™¯µûÐw“¬¸ô¸PÏ'c‘Hm"wvXfºÆS:»GQJI8‘½"T¶•:dáÙÄ=¶ˆïÌJ¬bllìZT|½l6‹X¨CR·hnî¤jíÓµâ’Ê9qàrŠ[Å*1eQº¤¼¥À>dr£†}”›Õa±ŠLG=ÿ #Ø‘õj±u`Èû¨JH‚â€XN¨}áÒäi 0aŸ\´—¹n<ÏzCc{OYmÊ_•£žiÓRñ~Ô¤é.¨¹eæsŒµ¼Ý|bȬ*5>?ßmÎÇ=3nÖªÔ0g–SÈq6”JôÇn˜O´sé2®¨hv.h$|;ìŽAuuPÕ-\ï¢@¯H­´¬ ÊÁÎþÈtȸjck•ç”f&DD]C£D–#”±!n{Êów§)2e¼/úAõÉlö9ñÀnd+ÇM¦æ[{u7Üͱêú2,¯i]Ñ"øeµ_7¯È £NrÞH­¯ ’¢h=§ÒM–üÙ©†t„C–÷Œ‘îld0ÕjBA6ÊæeZÔ¤z¦C˜—#3°wT+}A¬AÚ#´Ök-&·WÛ0);ïù¸iÎ…TD’Y碋‹ê‹cÀM1·Mö.P're€§L8`Š*þMýs‘ÐH_ÞªÕÔÕ$M¯ŸÇð©CGÕšsõ¬DáÞýQÐõ#óÄŒ¾áÒ Ç¶H Ïœ’Q¥…;ŸÉÊvZ…†E³6Ó XRj4=ŽÜæO’¬ø6¯ùwÔºc G;šË)ÝRŠ‹Â•9´ç¹6ÛÆüZŽnRK2@]Y+¤^]f°šíž])Bôø¤¤àmM-ÝêxW{ÅïÕjÄämWuÞ™î©ëÅXÅ¢Ú3câYW5È}«•)'h· æG4†êÎÖo.½–íL™±sì½Ç³:YLZz ç˜ áè5öDï=Ññ‰ª¨†5Wzðf&ZØÕœÂ.!ï²üzr烿ÛI8¹¼VV ê†'PCôô9;‹ˆÙÛ‡yºŠöTe÷‘½G£™§šŒf«Tèæãû2i%¢§Ñî$õc‘½›ÌøÓ2èU~Óuž‘Ž´ãè¨OÖˆëá´'©ÀÌë¹>åˆðtnªÒ¸í>9²O³ÝÍÓ%ì 3Gr«ÃÌ*>Ï4’*UNâT§®Ç› ]|»ˆØ‹H´y¬é‹ç£Ê‘S7Mž­L<šsÄgÏp4v¥ªQdáû$?éËÛ:³‰à¥‹•.z:¥]â]²½ìu^ÁîÙgë%œ‰9’6¼b£YOô8TlÔÅw™Š`g5éB¾Ò8îåX >=÷¥f9P7†¯ ³aæ…_7Ê”?Oâ(v ±É¡À&߯žÚÇù©ÜfŠŒÄ„9ª’_ŠÎº­Ç¯f>R&O\[^–nÊéùFä"+ å.×ÀÌmF³MkýHItÉPg…a5ÄxPËô®üô=£íµkÄ ‚øq?d¿{Q²gLþu“¶[ïÅ&Ó!CÀ6¬÷h‹0UUÒÅŽ»Ô §Îió‚ ÙBä1c%Áóî"ùŒjKéf›XqíD"âcOYáí´·ü›õ½õÒIÚ¿T Š+&Xw* ,µDj6¬²ý ïT¶©†`P£Ð‰\ª‹¾Ðc,rŸÀf9V5'üLŒÁnó}¥JØEª´vSv§¬»ËrÝP[ ÆË-WMÃUZIqVã—yKP'wÕ‹ñdæ»5£¶ÀiEA½!RöÉH8 VÒGÖd“ D¨ã0zÞîA (;4+ócàÝ'׳^“|…•q'Ml†BšÙþKhl£ŸàIäïNêOthw³ /ë SÕ!οò‰®z]±„«N—Ü›“ËTæ<«Ýí^º›˜$ÛÔ˜•™–Û ê‚M¶‹x©õ—F"ã¯é wyHE¦ v"¹ã.ð&-bªL(éû#Ó“G§€ÒÝ7y škÅóìZË,ž‹gO7´ hKUe=ã^˜PDÓ”í¸<'­Lƒ­W`Gý1b6bl­.Ø«Ÿ˜¦MÉEDiUmqróÊZØ»àl3¥kaxQ’oaf¶^>åoÙ0 ÅR]ïl1nˆ—ÝÆv¹S³y×–ãc ~ÈÎmáî(+…ÞºÖ1g±IF€Iºè<Ù0!rè› S¬ßG/‚ͶaŸü›nwd)[­ryl2NJÛ“1pyiݵÜZ ‚'‰ÔÚM‡•ëDXÐ]ÑcNV—Ùì{ÜY/[‘m²èݪ_¸?~[94é[¬ƒ¿Åø#²HÞk6´YWoìuz± °ï\9:äd§;ˆpìyêJ6R™}mHÄ p`}8oî æ-¶n±¿¼HHßÎŒí`mÛ¢5¬f²—àìîd¥›5…ÈP²š r³=‹6:ï¦b®2–Ü©žûÊôˆ ä‘iY…n¯K]4,Q鱆5fc'”9»‹¬Wâ_O¡|¼W¾Ò®`¹›IÏlåÀ;M¬vʤʸïZÑV÷|>Êm(Ú ³Q­«$г¹|†žê.i2JÒý@¯û .x7ÛrßFR¶r:æwœTdvRï>$EÙ²¿{ÅØ­?ÕgE›>ïJ•nåÕ%Xc§=bÒÇ`y³DÔ,Ü4ö¾ Ê(aVɦFÑNº±ŸqÒŽ L茦¶-&&Þ×ðz\Ì8Ú#·æž°ZLCýÅH[oS·GéÔÏRw/;K2G*•f $AO%æ §™Ø€FL …¡$‘ê¾èÞí²Üàô€ãn³t”$õVÆ– »ífõ™£Ò0 w„ZåׄÔI{§öMF›ç¬*©ßVOb9wO˜b’)ˆ¨‡y{w‹ß’ñŠª†È÷RN5š‹ØëÛÅ6´\·#³Wþ±NíŸ=qؼ*†BžÏQ %Ù„ Ρ¢;¶n¹jÛUÛ¯ÚŠ¦4¯¼J«,^«!à2“¡ÉBSùÎЃ2?ØNÆX] ¨·í5 k/KR>ˆpáŸC›1w &Õ†UÌë{tëŒ\d¥þ¢®9¯–i·…ý¾†ç.]ܪѩñÓn3ÈJÜVëÊ"‘š Î_lÀ]‘)ø¹ÞàËD 5Q<óŦ›¬3ƒgÝÐc[6ë®Äwެ`âÞy ô„ö6³Ø)ZëÖ¸f†Ã€ÚW˜†r.ÎüÊ’e1t”>Ê’¾ÍÇdú`ÊÎ;& FèK95%dJXé"Ëß²ð¡=£°k ßOŸöµ™=S_wI#7ާí1j“H+–RÈP Ìõ ]ó¾sb7¯ŽÊá\ä™ÇÞ] ê^êC³äI3–Œ‚ýQ•yÄq±Ù’ÌV-CŃÓh5ú]«þbv$¬ë8%”š*מΠÇã&b ]3Ñ`ó< ü $ŒUu_®Yûæ|ŽÎrÌcó{Ù»NÂÙ} &™8€Ü·á3ß1Ç ±Õ\¡À½-&’4(v¾Š}Aè-ì/6êtÿ^ˆÍI»2 ÞeùNÐn" Üã ›Ìí/òÐ1™™c¶Ô;5úåÕ1^\‘ºqÝÄ«(ðÞ ¡½S- ¬[ºñ¶g7ç‰b(Ó©-é6L®VÜUþÉè^e óvÑïe´Tô§o‡_‘MÀW,‡6ñÃÞd÷¿Ï`[LF^ˆîŒf±p…Â$Û9QUÂVpÕÉŸ*Z­ÕÎP?DaWöAÏoŠN~:[åfxŠ9¼ªPF'™º›ŽäPÒUFô"åÐß ‡"BnŽì£¹È¡S3ÜÂeÎþbã6hrQ¢Ÿö<·ïYãŽæ¸0¯ªdÔ#Euäþe雈Yd?L%&»Æ×™a§Ï¡t,ºeË­.¹Kg(ÝÝ2æžÑW ’o½Õ:Ð ¹õ¥,M¬vÉ4ó’{¡¼›‚ŸÓ &IÙNßB|êêÜëbkŸAÓö4çv^íß7=yYyh¨0Ía/M”K4Õ‡¸³9¸Ô+΢³Ô›ÁP¨¸F±/nÿÓDz>8xà(»[¹bË≪oçŒD“¬ê\-•W®–ŠˆÓ,y5ÒvðWf ÂÔM¿jšÕ-NÜhæ£Öʼnç\E5)U=H›YånfÔi¸õ-Y.—‰ÖÍxfñ¹Xf“™¥àö²·<2tWègà?ïÆƒlEœ¦÷s¾ûþœY]…ˆÙ.”B¡Ô=Üò³;/·4Ü´ƒ]ž³õ)pý¦õϾß3Æí{ÈvE*nß…ä€S{I·JR:H ãj¯Yy¤BܰQ~Þyž(Hq`< b í?|4š«š?§Æ #Ø÷L€¡òP”mèJ5k©Wwû6ѳ|~ƒØ=>H×ãRû‚ª Ž‹Ø(Jj Gr=¶ßÌϾ˜˜ëKŠLE‚#UiRòŒF•uà³G“öTG¢_€²c_§Y$Z±Ovz¼sÊRE"Šì‚^Ù±ÒÂÈõéØðifôÙ¼Öì“Î>B8;çP˜\‡³Ó´SO¸Š¼ h°«ÅdCÂÊ©›ŒÉÐq¹†c¡¸˜Ì/ôÄ•”dv¬5ãé[PJ%J‡£Êfì¶—^Ç_ +nî·ëu2»FF•6ÛÌ»¤I匾_ÆÈÒ§*5gLL@¬àëH³,ÊG0¿ª7·óœ+è0ÖmJ]Ý]%0|ÓÍžÕ e66¹™À“%К9ðjM Ÿeƒªš…V·Êo3æ¶*;OÖP1cfLH½õú):³2¡Zz¬ %&Éx)/•¹ VÜ4ˆÃ¥sÊu*¡¶« ÛÚk¼æÄŒêqc*ÙÈ8=ÃufÛi•B®´À=³U™±¡ Ì,%éÐ[¢}µ»Sv§ÏS-„ƒ…°Ä÷QD§vŸŽ*TøîÉÃâñ_2Ôê´™°jòO‰yŸh˜É ¨ã.ÆñF‡]ðLËŒ‘zzƒ5¾²š0sÏ Úë»ý¼r™x§sÙ5bÑ:]káTìäæhÑ®ou¼~,knÚsúlýÆ3âg-X˜(¶÷4*pS¢Ð»Ä]\Æ„‘·m ­b9SúФ`\ÄA‰$°åëK~ûJ™±Ùd–eVзƒÈáP%ïbüBtª³£ ˜¦6Ó„¬ýÀ•=1NÌŒ09©é7Ç»UT˜)Št¾:+¥œ‚ ¶­:—¹¾¶Xèå˜e7Óò³|“ÚbyÜåZk4á‚+wº:ìJ½sº¶Õêà .ÏZr*¼Õê7²¾ÇuÈhW«A&VøY¨@’Bž€!î9ƒ&x@=x« £ÞÂ~e ãþ²’gܱH´£^ ¶kÕý²UÊy8æFÜmDöðƒO¿è­;‰ º.˜—œ}¨qVb£ØSÿ2¶ôìîl/°ŒF/e½Ó-¯¹éJ$>«I((9»ÒÎE |A%Ú¹µv.jhø‹º"çËq*á U!´_:ËÅ[&Û¼‡ï=Ô‹{N}FZèÒ±z•ªš‹ø@”Z?¦ô1vvD?·ôÄ"M3*#­Åáªçù+½sxRµÎfS/:ˆ°ž’¥~KÅš˜oÆ8Õ,{kð¨˜[ŽÊvÂó¢ÕìÙd.š[‚¹hŠ…úˆ€¶ÌƳjLÎ÷¼“ÌÔÍ8f ³g¯-V"Ÿ©–]L?µ3öi_•"§ãIóDT.v3ŠÅÈ7ÈšVoÚÅê¥Fd´)-±ãyŽ‘züÊ~ÓÌØ.ˆ+X;çÙjÌÄÁðÚ Eÿ“+ l®¤Ð W¹¸£^:A›(:Vw#ËY™4´©‘%ó?æ² ©nör^¯P ­2Y>+ A>}²ŒßZ à^Ò’wz3;郻(Í8 d†™ âaðͧm|ÄÅÝ Ì\÷ žéäa÷èªL¶,«©zq—f¥G:élÙw›f[û¥8ÍyïÕb-ÚŽ?›¦J€GЬ‘€‰4êxÂΜ´!±QhI ±a¬åꟶyŽSræý Ù”í½®=¾ê<098ÁÑ\zÉq¦AY|®ˆ`££rØ|Áø³×OZíÔ>6p{6„ѤǷÑ%r}¶Þíï2f »±¼iØ ‡hr¼$DŸC©Ùâø½*kF¨á€$²¼T &AJ4j(wEóèéÔ£-Ć‚¾M†¦bÏ¥ ¶ jè^l¹A5"ê¬cc²¤NN›=cµ‚ê´~µ´ºÖJÝ6UÚÕâJ‘øÊi.‰ÜÖܹ»oÜaXoGæ=ó}ŽÎÉa¦ÕTŽö´Šò†¨äHIHωΰÄw²f ê³/Üm· \’)™#Ù`Ìv»’Ñ`3~¿Ã´³x)’Q ÝÁLƒD…›t¶X•÷ɪ¢i¶<ìô|bÒosÍ*êb¾Î4'38Ô’Û›Â2I\$BÙ ÆxVƒ¾ðÐ6,7h¢Ó¶nckiê2 ‰ÕÓ…ýF4|E*ë[ ¤Æþyïk1¡šÁÒh6ÕXh!é3D¨JÓöoÑ:ž]V7হrÖ\ ­\v…¶Çóc•áˆõ ò$"kfe¤ÈtH5@BjdþÓÌaÍY­¾ÿz÷8ݹ™ÒÕ/hs2G©«ôéDÂa«¢¼1_H°ŠžwI¸HŽ»d^x—_ûw‚Ó´¥O}©=eœŽÊƒêÅ rûŒÄ‰ìئ0}¶Åóìã:ô€«]¦PÝ¥^«Oì3ÊC×X‡·fó0:V‹dcÂÉx©»<;Úñ§LfÆo8Mí©Ð%M)Ýr‹•]å9:,Žl&¹$œ>Q(Ê •›I`§EM]-7M¼u=‰·­'ñöõ$Þ±bb4Ë1èè>‚lڵąÍH×Y#Üš2í–– üh¶ÒúêŠ9nŽë›XÍÀ‚Û~—bâˆBI¹2_{›Ý¡Tþã9B#?µGEt£i2{°Ö¯ÓÕ}e +öh]sÒº o♲¢žž¶Ë”¢éÖ@$gy"O²ükjŒ%Û˜E«\ ÏÍĺrºÛšl2æ ŸƒÙÒûó-šûÌ–rk]hPÖŠù@i~bÔþª Y$žÊÁîK^oZ›m?`:Ë€"ÚZÎóĨbÎî¤ÎØíݤ>lÆO—ipÞ‘eõ)¶Ÿ ee¼-ŽØA;„˜"hÄi[I¾>ÔãTr@A» XzzÄ>7穂핾+Ü“&¾'ì2´Ï¯T‘µòzÅ™Ö5³÷#‡‚­ŸûÅßù¹ Õ"m{Ý`fIÐóe¾VN~ƃqd…ž]µ2«ŒÇT#äÖΰ¶þp)Û9v@lY+HÙ›ågFÕ·Ìϳ@Ó%–öˆÅ ML$L”ÐZ¹Ì»&“iþkfþ màðxËÆAÚ0jIjõw¼%éZh¶Ùw?{_µI‰wT&2ÔÇÈ%THnÍsÉÙ™Â_.÷’¯oúŒnŽ6‰:“·Sš&q—q'W£-·É—ÖµHWʹ®,AlÉWx½ÂËúÛ“%N”Cu’ÞóÉ“­&™”ËÄ2ñl²x³ nÆ­*™puú³-s^­LqFGF mgöJ3Ñnî´KçpŸm zŠ®{ÏáQP™F-š$V‡nˆ7;³áa=Þ›zS6ÇôÂ뱓˜CH˜à40«› èS`x-2c°\ö}jRL¼%Nvhß‘é£SX3'\úþ©þWF¹>ãî‚¥ûKt¦úÚ[`_ä‡esŒ“6[ÍºŽ°)|ÆÁzŽ©ÉÉÉ£Ô¼£{÷ÏT½û¦vÓ¨¸¥‡ Ì(ùo·âº&2Å:Uy.³!;=¥3–ù”¹Iz˶[ ‹¥š­½\ÎÑ—Ô¶4Áàb¤®Ùv•ÛˆQeWf€ããqÒŠycN´õ$Û³êѪa⃆õàúA~8¹äŸ/07I=oÈk#c¨'gÊ=¹IÈ×cÈ;ýù9i´ÈØ£%ˆb&‹Š=IÎÙYÔª(4°p®^pÙálÒ¦Þ²ë‹hª6zC¯‚0i<²¯©4a—Çš¾§~þq¸Ì6[V¹ …_ÎRZþ²pCY!ù=ae)‡Adåʬw³8“ºbó[MV¦øÛ›î”iÁþ!åïRú*Û‡•“9õJ •9¼ÌX]Só:Kûjå<É,Ód¦Ó»ÙðÔÐ<™¼3¡·³··z¢Vƒ¼ÎCt¼îóʼÕnâ•Rñ“•AugêœñJd9ULK¼û†œÿ«²*؈8¥²ˆ®.µœp@a›cíæ48 X©»{Îð-b‘—iß$hÎñHí#ÒÀûSµ|Sá2 M º½BˆÒt³'9U£‰VWþäjÝ`ˆu€¯1vn”Œûü·?,F£h‚õ3b›± U‡¬"W82­åæ³UÊ]%ÞÍ ^«ÈuÑJÊ…p$ËS¼rNj'€j©´ð£r,aÂMÚcdÚ3T‹Æ{üƬšdWƒÖ­ßp³d÷¢WVƒ“û¹8]HŒw¹cçm‚#¾*@=¸€½¶ÅœDpS!™‰ytØGì,m¯YSöjÑœñØ õ\b® {Ov8#߈˾E6É6l-®d¾OÖ´F0xd–š¥–ÙþÔ ÐT´ÙÈMÐÀÚÀX´ Oªªš–\ $sþ‚Ã&­šIØÏFß. íäÞræé:Ž-é9ÞŽ4_= hƒ)Šs`µN,MT  ¬™û†½îÈsj}q8îu„¶ª/ÿ]RÒÊTïe¹oïnu³U/[Ò æ!î ¶#1‡‘9Ý$L<‡gUoz™²é—qžë†qÙ$ÃëšØ¥lD8+5ã>Ë*§½ìÜ4}N,°¯ ‹ÏvR÷Ø{ã 9¶aÈÍnϹO·î8šmuäb^3šê›+b¿ŽtÁÌó2g9Þ\d¸FWý˜»l)¡R"Šœ ´D¢ÈuÊØÖ«]V<•äŽP~·©ª~YQM68“ýˆVhÉÎwÁ¼’b•ïÅ “k‰ï䤾-ÙçHìQk’.tɉL" RnÌ…ª F3ŒØôb¶‰%’t0¡¼°û¡•3&ÏHÚ;¦7e¥<¿#©o:8aÄe»£»gÙ×&GŽbM›1Òƒƒ“6$a=éý]fZS:N™Ÿ·û‹3›''ðaf¶uÃ-·zº±™ƒGoœ|j…"èÝá¡¡Jîïq´1ÚrrËÜ­ž-64L¤é£‡ONO˜©Dñ,§ª˜?G®—6ºxÇ!+ÌÍËöҗŧ½ƒ“ߣ£gä0ðè™sçÆTfÐ[>ª6Ϥ¶öê6Û6#÷Ü0s‚à€Yš°Š‡>›+dvÌÏg«-Òrf™´y{%ôŸ}Ë1qk|‹þ¼a½E•ý)³~E-ÙBl#I #clÓûÊ-ñ°Ÿì¶·cU]‰Æ;Þ¿4ð°ï-Ó2fèIãK ‘~²(!å©qùáuEFæ½Tгkz™ ´åz#Í;s‚½àÿ£¡l«[}k·²uÌÀ’pX¬3µ ¾YY@:X_‡€¤æ7|ˆ–¹•µHJÒäÚðne²·àÍÆãýª™;~ÅèöxÈRx:¹T„$1¿´æJ|HLŽojÓ³"?"{mc !jt¦SÊ;N7Ü¢¸Có[Õdà6Õ¡wì.5ãFFEÆ,ãG¤¼üÝ¡žœW°óqEyç˯q¹`'¤*d+<Èüm …ûÛ¥Š*æOlSÜÆAÛ×%KãùËÂmj…ä÷d›¢m8’;7¦ 2ëߦΤ¶þ6%]à*–Û¦$¿MiʵmSnöy…Œùù`›²›uf{Àö‚=`ûJ{@°×¾ ¬›fo?‡4{w?iõFÈÊŒ#Ò¤ÙøðÕh÷þCæÏ™&A8i> ëx“ºù85¾Ãüy¤ BÐMã–ýbfïÕæï›’4±ù3ÁRÉ«Ûoø^ù «¦ÑI¬WoT‰¤ãL/R¾k:±g!jem5 QŒ †Nލk0íñ¾ž ãžÂÄ&¤’ÔHŒ=?9ñ«¬×8á@I›KŒ2—æëä5k™+!R§[`wú8Mê qc´ß¦_^QxoÚó¶4ï«âƒÍÿO$ìbm —Û˽qt£AÕØÛñîÇÄL8§í—¤¶pz'¯Å‰ã=÷íÖT@Å}mNxñU#~r´mތݱ:½×{ySˆy¿7Gï¯ôÒÍôd+½Z±‰’6¿$y˜LðJþÚRÒƒšH¹§2.ÇÈ›A¶ì¤ku"$lÒÒJé±zN˜1iX¦F„h¯W2ÄJºÄgHB6Ä””«ó>iÓª˜xÇ&_ žOÜ€™ ·4‹M¢¢8UQšŠÅžW‰ ÃQ‘ ³>6mÝÃщN÷fßäγb£Íw~CМÚ#ÚZkòÄw{‚`ô¨»zÕD«ƒ©ö3w~O.tª$õÿg“Ða‡ªF*«”µ¿ÓÖTtÀ,ð™R;€>kjN̲çÌF Ø%j¥½#3Hd“¿MC­ÏË¥ž#¥Èž9e¾ã%Ø‹;§MÍæl&R¸P\oä씋±„nè/ò|>QëÖI1K$Ç\µ–o‡F1~« 1­‡'÷Ï`·£©¡Æ—l(Ë:°¸ÁÇ÷ÔcS%íuº–Éî6ÃË /§´^e¤ãÜ{`†x» ëbºÝk6´vŽ2Î/ݲåo͸ÊTÈ0©S{|5i GCÞ5ªÈ÷Yγ*Çâ»bîtPâ3³±rUðm^¤öyÆÕ=ÌÖi½g›÷ Ê†GͰ«•º)àO©À•µ(n49¹p¨•ˆSð£ÑPȸš¯Ë ñà^^‹6">34ào0N±JföÑU¸žØ<Þ¶ßÒ²6O1GN‹:³·ÉÍ=±¸šäŒ®)˜ 6Ö~—éÕ…5m>¯0:cóXV e/ÏUî¥Ó.{Ó½¾¬$ÉãI›Á÷åP®h™8ò ¢ê·ÅÑû;“£͘Zº¼9ª¾oo·³â1q™¬¸1þ‹\ƒâ—jFKÇ¥ÓÍK¸ïǶë«ö GƒÞªÝМ mSa®ƒ4ÞqÄ“qsdM®é‘w1›Ý†xPmÁl{A§ñœQN›DGecfÛ‹e³?s³éK†,:¤š@ľ7%0›ç®`²`wþ˜Ó0!6éµÕV¬ÉAò®Îƒ€\xù¨Zª¶¢âle£ °§^®6œpîpÓJ©ÂÈ©`Üü«ˆÅ¢ ÊbošBYkw3ýµÿ4O8K-{0_-…†¶{ŸØ\àÅþ¥¼¢$,nP½±—Ú»äÄñ7¶Š´åFé"™ŽiøœÈ:¸»ŠY¶CͦT•£;¼s ¯#'OAƒÜf¬ÝJ'B|y7w=Õñ)˜µž×B¼p\t¬"WR²›_ѱq>Á‘èð±Ö©yGml»qÖ£x5êÚ.±0Û=Q5õ Îηvº˜ôXlµgùjÂg®Ž‹Û–§Êv—±«#×mêhÍ „büÞ$¯®âœiJ•ÊC69"UÑ3¢8ôLV½¸#næâ,»aI•„ve!ñ´£zñ¨—ï®E%ùòRW>¯º]Qæ[*-÷%Ñù]z UïôÉ[5uT_'9~žÆ|U*¥¦fÑãÒ¥¸ÞtLs(?^–†afiº^»8>Œ¸?Î6{R†1'ÓL ¬‹¥ ¿îkÙ¼P\)Ån¡»¼uòÒÉõçhªVpœf›)ì3)pê¹ÛMzÒ j ÊçÔëÞÂñ)%RUc¿ðÚ$X$é"äö~/%¶M4¥}s™ysë¨Ú\6¢´yìšk¶Úã 5ú]`IŒ8ß+6PËæª„Å>G¸ëjü/qm5—!‰àߤ¢j°iú×öO¶_Lð0=û½ ¾ÒI(VO|ôLnúÀþCªKa-Î-c[n͇÷3M§WdYÍÑ &êÑ‘’ã%ª¼¾—Ì^oaÝ|1º÷/µK:ØÄk6‹ÌÈê¼6 j§hÒÚ][Ê«Ñເ½àŒ-w)¹‘å´óz6ÞSÁ˜3º¯^Œr]ƺ_Ïõßðâ6aîó Džví„KµF<ÛQͯ¨&¼(|¾ÐI+•‰u‘Λš¢ã˜ÚzU¶‘¡7­«vfØ­¦G–ý\ÑÌ+_Gu9ìdÒ¶vînw¯ÈI”Tž?}íU‰3ÀÀBK­!¤N×ÄJ”ša©z¶tX‰ ö¿dœnû¯ÓuÒ}"¶â:‹²Ýèëúæb•U¡Fe#¤Sežœ™ ;!1/på¦ÑQù°bÎü6" ¼Aþù4=ƒHÍÞ´d„‡°\x£Ó¦”o2n†þXå<Ûá%–sõ5$"Ú¯.ˆÊÁcáÙÛhÕì¼÷ÖUˆâî³²—÷CU^_ôÊéÅó5‡‹'þ$ç fñiR=rÆÎêcÆcÙ_4ÓlœGOTZm:äç%!s_–ŒU{ªj)7û•þú·‰ÉÊ=ÍÕ'õ¤—ÖX—ôž­BÃ#a’½L3å< åŽ\3´ } ãæzám4'ÿ¡Åø˜´ÔDrŸåÈîê¤jœ‚¼:I@J"€yoçO­!‡{QÆÜFŠë™Hx¶R™[Lïk囩ۊH~Uu~N èuœ=‰Gþ•™wÇzÑ&ž¤&%vEš¶lÙR”2gæîqRI·H@1’µv¨¸¹F)5;ÓI"q4}†÷s!ÈÀ&Wuç X)ƒç³Ìsl}A“¤þ:ƾ]Žm„ì¡A:§0 TJ¸¹2ª’XûÔ\~ÅýlÄ1&ö·W9hõ%S-™—é:òNOs<·Z%;‚£Ó]¼0ùä%‹#³HèK6ì&ã.½rϲA>RÞë‘Âjæ±=é1[1èHÇCMbhøV‰LVL‡tEÉí·m ·¦õíÛ.‘<°Óh®k¥ŒDë^+gq%äýâŒ]¤Hf|ò,¢íÖ%N¢aªXåêJ³js¸.Ì€Þã5×nžh-»ºi3Ù ÐøšZZ%¦ïBà¤Ö„bj, Þ_d¾‡ÙÅ‚5HgÈdzi`çœJë&†e/tÄôÍúHnì”"wyŒÙëIIL7ÍÒÁlAºÀ<2€ÍØÔ|óžÔ A0lѲšÔXÌzÉQn¶\9Ö¤;øúv#dÞe²9^¿´Ó:.R•_ï´Z"?€$ܨ}éß—¢ÓŠôž²ÓÎwß¡˜… !]h¶–X-Í÷ù±Ž“ó5K Âÿ‘ý‘¶˜£ï‰â4Ô°RkuîþsAïUŒ­•'ň(ƒtŽeõD4õHUˆnI‹SÍ5OG­·â ?ß É$åF¼A·» ƒ¼xi Ðáves4É›ÚÞz{84 "Ï#6ì½Á_ã51[ñµµ—e³&Ë2ÉX3+JÄÆf’ÊššÙ䦛Mû¥>[›eµDŽ<”y‡efžòP)Ý­½mJ7ÆÊg‰Ås¬$Zòé¼9b1[²Ûà Ìçúãb×IÂ÷ØS­ÕlFmŠ"Åöï=[³¼y™6 ~´Ë÷ô¡Ê¤ÖR€¨¶®‹ OËSIšr;@oïµ”®37,YÛ ¡Sƒ²·£­ãNßé0ñpí²ã!ìbÃé¥]ùî“%Ê.J–e®²ei””·u¼f[†¸9àRÔ‚ëìÍ:—‹Õ Ê@Xk¹+’)‚a?¬Ñ5D9 c°LF­É GR1fA±'7Ñûº*u/ãs–¤­üÀ)tdÌ0a”š4¿†Ÿ²¡’ø%/–ŒøsòdªD1› Ðï‘ë±Ù?1ªèŸô¥Ù‰2†]kÕØyS9¹€[àW•û5‰Ý–¨z¦š©)F޵ÑA§fò6XŸ7ʤ¦¯6Kò !¤â´¼Yfq“ÖίД\E‰\µBvÙº ÑjòÌTÍZª:"©½PuôO{£jÈë)«n=°DkêׂÖ‚Št符û¦½Ø5¸¦ª¯lÌÜ0ª“Þ¬OvÕ'3*·$B›U»z¼€%ü‚,*aûÒ"iÔ452¦"Ý”Èû÷ñóŒõ³KË9ínvÅ`z`Ú3pÙ3Ïœ§oñlænÎâÙ8ãafh}w/g%!“…·õèWò˾˜‹Qäêu_Öê2119=½÷rH]ŸòKÌ[Å•ÞqF•^ÏÄ’*ÛNt;¨m¯©ƒ—Üo¡ùÒÎ þY:4}ÏÖ•ýñxhttæÆIÚl”Ó¢÷Ð;9øÞ ³°гiÙ®yòÛš VÞ¡éÜl áºyjß¾hïøÔ>ê1ŒdÉäVÌï\tš;“{&÷un4;õ†jÒªÖ½ÉmÀ&œnñ:å”sÙïÜ6Ê“…çD¿Ù…f|©NÝ%‹ì“¿WYR׈Ÿ¸)éj®$­h±R£}YŒ}m¡´TùÃr:Ñhºcê×OPtðÉG!~‰5»ë÷ ñ¨‘û\«& Ÿ¾Hë²ZÐe¦Ú?Æ–DµXžÕ3—ÏÓ˜VñV•»ÇÄ@¸ÒÙNŸŽÃ˳õÚP0i&"´ƒt‡ ûHfz3¯@0A9yŠJ|PË6ƒßØ}VF‹ã¼ó¸¶„zU:Û&ˆ=srñjñ¶–ôkqZË‚©éƒ{&ƒÑ¬jˆÄ8è5{¬›u ÍÍø¶Ú`™³=ôÌ‘5^۱̔æò[J`6¹I‹M:ÈáÉ`ÈjÑ”l6ø$‘*¡?¦ñ‰ ë!B»e­d#´ˆˆ-GtñLƒã˃֠6…K=j€=w³®~¬ÙÃbn:«,sêªã›V!¡™D—}.‰£›”X'L§ßê5ë íäÙ}ë4•Z£­Ð’¹dU§ž\uïÍ\kWm†¤#eÐWÖd<±®Š¯¢]ø‰ø¤¨Å30Y±t­…Î÷è¶çEgÂ&~Çî.Ι‰C4ÛÚzµF²-&žÉh¢1õyxçÝtð¢&rªLõ’4••ƒ PtÃ$(è©uñˆ×'Vþi»Ñ¯‹‡€ï Ë»ˆœƒÐŠ›/‡Háµ°Éûí,‡÷öaǾ¡ÙÛ½Ükz*ð'¹T‡šÍcùdE2™nÎj£|l­ÍRqÜ“ëDgiY#³4Èh­ï‹Æª?7},YŠV)µE7gÚ7õ¹µ‡x+Cš­ð4.ûŠVTip©ô×nâãÆ$GD »O3#]ô|†9ƒ,¡Ò£6ÿ_šìYžögS;Çiµ ;Z¦ñ/Oˆý ‹Îʯ6µ‹Þ‘* `cPN_Ì­éäN4<–ÉðW}¶ŽöZA§I ’è o·¼qXy¹ÃºSO[!VJ5U@õ;‘Ùß3} †*ÃÓ” ,BsÒu~ dÖ öþmšû¥K&‹´æ”XP5…^vÜ^XKó{©/F$ñ <3W”ûßÀ¥Ϊ¨lW쬡ùîyþH¦l1Õ8N;VlºÖZÁYs˼ÃâödÖõJrCAÅURã˜Í»€±Ïà·$xØ\+ž×øezŒz}åÈcIÊ jQ_vfa m¥CdçzÅfâj´ÉR4Wœýš­Tºî!ª™"{QŒšípÆÖïOr×ÞµöÂZëd5|ÍÎÅ€Ô—±¥ÇriJ­yœ2+ÀvK5×ÊEË}ÙHëÔ8[žõËkkSË®øD©&æŠ}åèJ• YxÏžOÎi:+וù˜¢j&©Ìd9 ü–ëg^2¡5ˆÙÊM®AHÌ쳌ª ½}[Îfm‰×•ž‰ /…³Kº!m΋œL‹Ž.nqÖm…kS/·hò~Ì#)÷— 7ë:Þu™®Ð¡>ñ¬]ÊDkgZ|9÷Å÷t«Ù°~£½GÞºŸ¯Nö‚ó wR]´¢¬.aÎÕE!“HC ›Au3™ø<¾=A„ºÄx'0É3ä®K² ¿%mc+«É^Áx¥|溹§¨<î÷ˆô¹wdºóÐvö©»k.½éÏ 4kZªÔ’Ú*Ü–#±6Þ1ÇHö*Å–÷ݦ «¦÷•rÑ5æU$¥éSÞÝÝ9 Ù¾š70Û«rNf¤›U÷UÀ YÝš-Éž2›mK_vìÆÖºÎpBƒ“b¢N¯g‹ î&ó\ÝÊK•¢ž6¯'.°1;ިёâø4n.(Çé§æ¸ÇêGeæÁSЉ 0êˆæ|Ò–Ì|f£]0Gx…³-%µªg2šmsúîqS/uBjÅMèªð@¾Þc8›þÔÆÀä3wW2…Ç"O¦ïÖ óDeíÌT®+¬Róå“—üz»8šÕ;|å4Xèl·i»Áõ#½)xHÉ-È2™ÇEƒRU¦Õß Ék¼"…TgFÆ@µÏv XÅš3 %(÷v/I5%ŠP[žAËRÒe K4pìð=ÙUdÍAÔ1WÒ`òx³KêÑGŸ0öÛìcN}-1z(#Ñ뱿4Ûu™øP&¶’ ›#W/üaG1'T2­ž8B®CE’ueÌh«ãº1–ÐâSŽªÆëÑÓÙ¨†4'¥·LÈ@LO©¨IÐ&š®:iOU.‘«P§k“Øû³|›Ö¨t òm5%âîá zv#Ù¦w­*«¡ÊÄ@¾föŠ4rp¼ÀbK8‘®¨AȨ¼M´/£(ŒÙòYÏFv; ÷¨íßÁÕç^b ¿(EÌ»Z¤¸¾ÉœËT†[NŽn2"=ÞÕP”q`¼›–*¶‘/NÄd«u¹öEtYóäÒò­-\æÙ™h¬6{Ïœj 4SçÊìp6%é߈F«Hé^`9Ô{à¿Ç ¸ˆYëÜ«Â|gŸùoÛeÊ4o Si¾óS[¢kŽÊ3í±›7gÏ›´yÅ)ðì“Ì›¼sÙûqƒÚ9U^øÔÏÁò^E=ž2SSGP½ä>•¥ôSsî®'áx"vN´}"V5„µÚ VYìxû)ÍMÈqÎmÖì]ž•–+;Ù¤(!}s<¿³ÔËNüŠ7çøžÒaKo¼"½Uû´‚o­q }ð^âs±:¹Œ*Óæ¯µ±mµ1΂ÿÜJQ]\p‹g²aíg¢â»ÂE.%“hLÇfÈ7ã j¤°ˆ×m’.m-GeÎw·nº6ÕÐ/D¹”˜KÖâæÙé¹C$:¢¶~Dàéhäô0Xí°ºÄ²,2Ç0êÎæ¼ú«¬”:rðÀ¾§]*A^‘*u¼‡«Ù`c†œDFb=Ë!Y$SÛä™ceª0úÚ^rå)å„I,ÔÈÙá ·(Xú3/I‡ÆŸÄIY‹¹¢ò e(w´¸ ’æ*EYc¯¨L—©«u" ­™%XdL;m>ÞÃhÐTâ­T¹ß©À´Gáµ~p-afµêý¹DÉáq#É×Eà6Ò¿Ópñ‰Ö\\ç(‚-S<5e@ÞÁ¦1#@10Æz£R‹Ñ™áËZ] ±ùÕ)yOµ˜³`úF­“~Lôò꺕èÏ;Ҧǰ—^í©f£›Eº":åÎÀró}h}ÚM*Ålü„X¤$á.XǧâtÁ–{Z°çs0r•ÔˆÔ‹ø§¸4÷/ÊH¥[o‡Ì¥ ·²ÜãÌÞÅÏÑËzíªLþÕ;˜"Èx»-ý[Ü ¬QTaŠŒË ª§›d®¥ô=ò¤83zˆ+~¸»ulà‹x6ð½ÉNÃ=0¨Rß Þ¢Gï0‹BÁåÖu6[kmä÷µóŠÕîÖÄF´ÙÓ4SÔPG¸Ý0WÝ»˜U¾’2[¾féêivgê.T¥AÌy¯#ç¶ÅcŽ igÙ¯¨Œœ½¹¶ÔÉËù}¶yÒn´ÌLËK{F›hŠ$Ï…ÆÅR"›pIT!›Ña"wˆMM±›’%Lë0Þì6¢ÊF"&Õhãø´:¨ûœ½i™­[ØQNrYº†¼çØ %§=ÈÈâ²ÉÇŽFÔùÊu–=˜zBãQû²*Õùß)¤DÍm ©#Ý"Å¢3WIõ$îE—ƒ"æV;¥ÉX! úîòdkQ¢£ŽÑuktýÁâ :¦¢Øelk;±´S.ˆœ^±32' 6 “ÙmòeÃçÜ ©ò©è„1Ó3úýÄØiœˆ¦Ûq½>Ét‘g,E9¦å⢺!žæÃkëû¯üÙ)ÐúÂiœG6>ò~—ˆ<ÞnÀnÄW(™"íon£Ü}£õ+®ðرn}”4k4ó†kLZH Պͱ#EÜëÑ݇ØäDw±¬¡žøŒ=*ôeñmKÃֲ̄z1l"iPRßÜ÷Fã(«ð¤ãN•˹ÿV4M–"T… °€‹BK¤‹Ø^!MÞ¼·áùMC›Ñ5†ŒÉ0sÿÏ;ú‹Á[êqÄJõ÷0ÚäS !`q‘ÂÌ$.>·&“åûNv÷2õýN&Œ¹V¦ñgжžé;¯+ïž¼aê@9¦7¡Ÿò‘c‘(ºã6ÚÆFЃ#õzÒëEÛ· Ù¸[ÙzÍKvX1‹ÊVz‰RÇTš€µôx¬ïîtZôõîƒ÷MŽ௉Ý.ÏŒñßfþÐU+æU³‡VËCÁ5±Þ÷“ŽìŸ<<>3¹'º#®lÆ–UÿõÊÖá;ñÜ¿mJ³õ¿½#)¸r±ª’»_&å5qãÁ)zÇä“óÎòåÉ{Êeiœæï˜EM0mu³UôŒc»ŠÚQ¢ˆØ¸ÒÞÐkÄ*É”ßP'êåhayi¡ÙN…pvÕGâAb1—ãü‘+¨ ¡îJáÌ*Â4iÌ™{9‡ù ³v‹ºg–7ãXsùÉ]ªä4kµQ´Ë˜K…¼Í>ªp:Z“ ÍÔœ¶Õz½Þ1!âé&6mjÔ.Ì$°¸Ø»fÜmQœ4áµÄµ‰»U”¥¯½'<³¬@i%s]Ûa¡pKjÒ@T·Ç„›Äs…å‘‹6@k¼Œó$mɼeë†Enw€;Ôam(/®â)ªœvŽNÒWæ>^Î<©¢LóFİ3Ê…p°¿&ëôÉû½<¹¸žG"¦rQ42:¶j—_*gh2ÕtAÐŒ­Ÿ{_$©.GðuAhÄí´æ&ð¡|'TÆOÅ,x:Œ“ÍW•†AeÐf)•%PÀQóŨqUIyßyíRwÔêæ|õÜ‚ ”8lúE|—Èð°å;Î)mä¸ÉF;p×ôȪ6œÌ¥bIÒ¥/ÜOÜ$¹qÙIr‹œ NbH_Õ…=·<Žj®¥ñÜ=åî’÷’ÌÒ$?AþZAMhMÑí ½ÜT–.jâ*RÕ½ß}ÃPa¥’^~j@»m¯mÚ_4ü„†|èMºrœ­µ,ðáì‹ÃÁ’‰¨¨K9ñÜ#0ž`Ò0C—£µ¬Mâ<ÏÌ ®h¬,1ñyVŒšx²žX#ö{{åFHj‘ ?b¯–&Ú:‹N™×À–:ºeOÙ2Þ'²Ô‘;žŸï6ç™5äõU<{døt¹{cHaÏ»ÍÈ c[ÓãZÿb®/©”r%ÚÍQ7új°V½™X°JöñÁw…XÝS‚ƒM¢•sJdŽ@¾˜'R‡Jg¬§0%Dîí’IÍ—]þˆ(cèiBÃ1Ý•‡ÆjbÒ€ˆÐãi{†}lɰY2,måÄâ›``Ý\5@\~»ã$=Št5´Í{ƒŽø‚äå¡íA†Þƒþ{-ŽÝÊ(1AèSy(ºÒ¥àX-ɼø*Ë™2*_Þv—4&h&c – ZI9Œaµ¥|QŽ®öòòn}¿Þ¾*G°±“Ú w9óþÉ™ñòÌ4˜Dµ†6òäæça{6+i®øjPY D]«Ñl‡[^Q×Esq+%ßu*mfbßr²‚?î±Q“La^* N4E”© Ít>M5ò+–²›¾}åH;]í%×"ª= $sæ×»Ê'ÃŒíŠLJMXy. K„ªëÉRœt]¨9¥!å6õxÆÀÐJR?–É÷„`#2*Êß´³^Æ]¥<1õ1‡rµ²4XZgX®%Ñà¶h@Ý•§×Ó(á’öñÝÓÞ_¢ˆ!†Û.l Ä„®†…ôg}dô ìA£õ0â(ßUÕoÍ…Q²½5Œ…O4žUû;}S—Ñ*´°Oc‡}ÁYŸU+û,r†C3²±t‚G¦$f ›ñk—XéEçŽÉëú`…£?`ðuÐLþØeÞÔéªÿa×ü ;SÓ&cG£v+è2ãB/óÛº¯x‘! Zt1Ojþñ²ÚX•±àÎ4—o™i#—@ѪN"]ž%Ѫ0= \z|¨7ÓÕ0.Õ«â¤z¦Úªà 'XÝ}½‰¾¦²¬N±éI²­eæ-OÓNM6Àa; ú[ÏLÙF »›[8öÙÔ¹o/P%ÖÏØ•°êB`Ÿl×÷¾ï—t–=4 ÓoÉຠñH3wå"ih-„Å‘õ ‹¾OsÙÝ´`ìÐùÌMóbÏ›e%—|ÒaÇ\p&ÞÆ›F“µw|ßô¤‡}ÓjVädë pÚ¶a>Œ¯©§7--~ÁxóÊ `Uù; ³¥î¼ùP\'Š:i&õa>ச<¬ÑZLÞDº[CRb½7‹Î¹HÅ’º{qMŸš)c–OÜîÕʇüMë –S±½xhµJÕ˜?äÉÞ¾½N†N%æDDOB:==‚ãó~2–›Õ<Ñ„TfF<'>²MRw”ÉËÊ\`ıŸÕŒ&¯ó©:âÅ Ë×ÞP™žj¦0LÒ ª²ÈÞ#âìj°ÍÒõjBP­ÏÉUµíœÉU5§@³!ΉºÒÔYµ$qõÝŠ#Íh4M«ÊÎØêË&üÎöÛˆÚ%z؈¤ôê©vk8³å[!·ïË*) H˜Km'e;Gæ™82—©ÅÓCŽý+•Øš´Ýôn´ñïÕªf6æ¬ÂÖª“ßBsð°ë …ß¡!‹è«‰$öh&‘åyα>%gLG*K©œnÙwTRmj]Ío]ŠÌµòAcJhN1Åùì89Ò³òTÎîÅ{…oòD– ˜fÔòà Ð¿½Ÿ:G±852’Ò>sšHòˆ³I“Ô·¦Tb±³¬é]vF—Ý´g||?¸õ€yrYÙòÔ «uŠ×åbw/ú›Ųkã©%µÎ83·6¶j¨­Z„Ø0æ¼y£oå‹Ä0Ò¸‹ÆBçeÒ´j–ü7¢e·‹Ñèåt©7¦S—ñM£¢Þðõº Åò[´W¦½w=4SU“ŠOÛÔ¥kBµ~5e&]½9ôd; =%• tœY ÛáFíTýÌÌXzÆ*cÆù’ˆ¡Í´Zæ›]aÖ{éÐf dÏ3c“à­†zü‹?O7Ÿ}p_Dü‡ùJ¿à ¤Þ¤oä/| ‘rŒÕ>ü‡‘hÜÆaÿÙ ½ž9ÅÏu™×=…N¨½²j‘õkEü\ ÕD’ù*ŠÖ¦)Z·þch½ ¡µk@ˆ `YEÈ4.¨7­Bdè(QØ]ƒSîç¥#i)mzË­»ŠT++éVäÙZ•+Ñÿ.í Ç€¦FèG|âÁ¹sW™h¬U{$(17évÜ]¦‘¬ÂàUŸ&öæ¢ È#Ó¥t Žbù«U£œ¨U •ûŽÂ&ÈA?ÄHטpgøÒ¼Y'é ‹š\ðÚl3Ò{ƒ«Þ%‰V‘£PvÑEÄóó¾¸Aµ'ƒL—‚úÚåH2µcÏŠ„¢ú°V6Öe¾iU?0÷n•WE¼å>c6/"‹õ~J&’+_œšÙnÌ)°äKÝ@kž‚ü,ö¾¥¹¨U3`vF¤>2!°eVúí6¨–â•û4&ëÎð–«Ãåùµb…{Ø}/0‚°IUJ—=5»_ª$ovLíº'įüBf(û˜íœº n;)Š{TÓѨ֦S¿Ëµ‹UR·}9c8%“Ÿ¹®œÆ2f ¯Œ‘ˆo‹ŽªëXcûfÍû!wvê,¶©¢kÖä7¼(¹³A8Lǫ‚H,¤(­a5A¯ðdÖy#f³ %‡Ub‹Áãz%c9³âÖ°”¢Z6–‰³\àžgÞÈ ¬ÚyZqgkj± Ó²³Ä×ÜùS¡áˆsþUÛ9tÍI’•òc>CƱt‡–f7d™¬ŒÓPø…áŽô³e±Ü +rZʼ°[~†ç–=Z#4˜ó»É–~¬³]ëç»Î€ñ:3ÎK'Òꌗ&\3ßµÒ‘VÆkœ×šX¯õñ^«²Påb{²gLzj"HŸÛ>+…Ï"SyÌØã󉼪ÁˆèðgãˆÞ‰ »?FNÒ°6¦ã9 ëXçgLÔ.°æ÷dW÷DL½pæÂºÈ5ºz!Øb³ë´¥¤té­›$“Âl_D`3ŸVsÍ=2½3*ו ³LùT˜¿¹Vãõ9ެÉmîR>ð=«:£;Œ¢ú2-á²]ÑÌ5kþ¢e¤=ú€Žá›>HHJæÌ&L«ÙGåw³_óé«íÞ‹áŸË‘sU/õ=4ŒåGÌ^[Y· ›«ŒºX§½ÆÎÔ‘@g¼­¡X¸ÖŠ„4Ë¡ýv¶–=òÞl'Ký–q·±¹îÜ 6¨ÙíyšY¨60ÆQŸ6UÕTϵ±ÚUµrÙ7à=Àö¸<“]ùf7­ë-àsÂvsŒ—R®\*Ö£ž;¥µ†Á«ÛçÌ‚Y.r>3ÊÓeíõ’5ÏŒQL¼Lœ¥Q]©ZÈS'§MR†’_ [ú+C‚ìüÛ¡S LMÞ¶«y2–Û<>WÊêÒˆ dZ‹&¬+o¾€X]Aù¼Dù¢zèéàù9iXG8ÆxÙ†$`oÃeß¿gÑ0TþZ' 2%inÎpnP½†‘H€?9üqãþµÃ%Îå»–ýÔŒW`v*Ì•ÝÁfã+d2ã õJ–åEoó„V?8cCgh©šG–áÉK,^ò(3eûXÙÀSzãAà¡«‚Ÿ­È +´›4škÈQ‰›ù´1xfÁ"âëQqœß1ÔÊZ¯¤aQ4³yð ±ì:är<ߌük 9\„ö™wçe{üM&óÆS¡§ljdîj’åíëëI“µª¿;½pmÞdÏÚæ¨‘H]µ‡Ä §FAx|o-/þZ‘8lE•­ÃÑt ¬îu‘hVý­Že ‡“$•áæ)ÈñwÚrÓnâã M@GÙ\Ä“\Rå?gI(‘?ëøs+þÂ6HÌOà2pËyË€p´›šAðœX!9˜Ih¤;zOß°Ñ:|ñ,kQÏ=žwÃó3‘éx;ÒÛà13Z±ŠÒÖçÚ«'Í$c¸çbyQ÷ÌWÇõ_# Î,4óí6,Öd5Õ{•\ó-PmÓŠÕLÕŸÖœ=/•)•ur±>·9i9ñö¸å„~:ôÔ‰Í`Ø&¥òVˆ`Õxbî*~Üó]-óiXò5–ùÇäb‰çêi¹k…­0+¶ª\ܚʩ­µí[j[¯9 )b…§ ZZà= [Téuû$/Q»ìbS-¬;ã.:Rîñ~oÖ†:ö^Hû`b±žˆTJ´Ñdí˜HIψR‡†Ñ$uûmQw“[NyÂH{̹d¹/îKš™É|»ãóSQäÕ¦SQØI EàÇàtáñÒb•Ãʘղ´eâäI‘eùÊFw ß–±¯­ìDÇ{Y­Nüô |?÷àƒä$žw%«Vr×FUV,Â0BM­>l;̨+o‚XLP¿‹z¯$ c]ðð1 ãàR0,Ö1!8&®­ VàbpqõÍ"âf [LؘÈ]B͆ |FŸh”@“ëR ÖÀP'3ªâ(1’MB™®FñhŽÚPøßxžˆúº²7öPZ¯q³A{¯åÃoª>G»¡¯k ×ó®ÂÕ ¤a—;ŧh%&÷‘©Ñ~Úe}ª ÌfĘk™) ¨í v"޼·hUè<×ß N޶#Sfmtzÿ¡=¶lô妭üp­¼µF“¾Eñsœ›þ ¯j0h?†5¾¿{]5¯JGQÁtŠKL %™~Ú罇B¹›GZZ6‡@êÎ÷U4Ôfê%m¯G¨ Ú”Ó-G·ÖðY¢=×˜×æ>˜q+ôü 'ø&À'Œ¦Ë)fȶ­nº£O·ôé"M\|a¤µ8\õBµIožßgÜóL³¡4ê‹ä#ÎÒ‹ÅVÎ7Ü-GÊÈïBÉhtŽ„î;4QøÕ Ïlc“¦½ÀQkSÉ,K:*€aÒHz錬Z£ÄÔÍxŸÒq¡19-ƒb¿Âàœv£ú Ze jesS¢1†HÚv~>D¬äÍ~0úPkN 3® õßLâl…Dù5Ϫ|Í ö2YÉ€x¨.EG9ÎN­"óØËе3sõr͈"mD“(‹öiO–"Ãã ¬oŽ™lNKíª=T g:©:ïN þÊ~¦j*eâJQÿ4i2¸è1L(¤ïØþã°_z™Ú@¢d‚8ÕÐJ|¢%z¶ÌÖ ;2¤I·ß$µ ™¥hç·-^Þ—4cDŽ¥ö¡Ù`Ëmò$㫬Ä|eM¼³µ¸Á²"yÐý)/G£éÊRU²RU?Kj…ïÅ:(æöÀÚ빘&Õ>ã‹¥ˆ|òÞnîõ˜Np™óNÍÌ·#¦&` GE§iÛ»dÍ„ ™m?0LÖ¯ÚDJ(2Gõ+Í©7–XbílC Rdr9˜g¥[f‘4šÄžéà¸S½šœµÎ›ÄÊ0ÁLY3¯]Y·Yí†J\Îewuý%ÌN÷“๲ŠŸ©¹^¢`öÇ^¬?5$A3éÑ])–oUw?d™3k#[hH\Y¦–™äÍ­¢@6À”ÝhÕVß—³__ÌÖÕ]£¼¬‹dC8˜°@ÂÄPøãÞ]Ó^l6&LETET£íêÿ¢÷àÐY+‘“Ť§r2Yì/z¯³‰g¯•÷‰+ ë‹|Õ[š$IÝd1¼v6¹#5]£Ç6ÕÑùd-wC÷LÕg–¤gŒ%@ÃÀÊyLÔle £!éùî¹lÚT:¤iìÝ-jEÒ&“í8HÁÂúÝ´éÇœ ¤j† â†Æ1惒ŠèÍCæZ^_™£>4vh8BN¶~±½ÙEV²íy—ØJ1Cb¾˜‰V`? [¢×ÄVT÷Üa(ÃÉvcäàÜÈ„±\YŒ»ÇøŠJšD—è$Ùðš¼Ì$ GF³jUö%×Èû©è¬tÿ¦Š²`nðë€Qûn d’bþrªι×q²Sˆ¦3²Zż‹Ú&‚9¥ÂèD¦‹†£æHO]{Ú#ùŠa Ö[_Uëñ¬V7,ÅД ÓNßà^|²µ‚[I»øì¾¤+·söÊÜÜãÌïp™ìÕ4î&™™$N%Ih9Î{pÌ/Û5 Ç Bg’Àáb7qbÆ’‹òDYé§zheÞ4¡·|þÄÏÙ?ø²gZ”cX³ÎëDæ“‹Ç¡F&ì«D¿È,c˜rè—~"V¿=„Š 0•Õö ó­gK€Ù¿}Jšµâ‡Ó+=´šEý.²FGÞ¦,Ý“Úsm&ƒ{öí;:~hʼYx”m~ž«‰ÈXÇ{l ¥ŸÐvçº-AJ¦=ú#ŽáNëØŸ‹6²L¡l‚ò(‰äBnû¾9Z¿nK4°àC¹‚ùx,(Üs!\ö!¯lÍ"[>ÛžX›AÍ4&;Ƽżg,wÖÖIƒ,æ<|ŠnmzŠh=F :ìl´àì‚"£Éµ•åg ö5R“ \aªƒŸüd[—ÝÏuÆê§ Ùå8¾ Ùí½g~6¥6Óë®hk)”_Ô­æÇ-ú(cA”oCþ=,é(4)Zõ­é‚·r6FÃ+d`hÉJY¸þL­Ò`S¥ÄÆ%=ç­f)rt‚ÆÄDâå`MŽuEg 4Iø)¡¦ÚæžL0l*[B‘N"ôÈó·uîËí&,I :¬DNĺ¬LXÁÚ3¯ÑìÉ,F¡N§À*‘±Éë69qèRü“%Ð~2Dhs|»›r=lΜ™-4βzÜŒJØ.Í´Û¨gT:BÖ½~››ªîÒ¼üˆ²VJBø1kb“г—²a}Þ“.³ëlÐæ~³‘ÂuXÍk5+c˜©²žÈ¤æŠ¥ns‘z‰UhæÀ3Wçâî¡C˜$’é#‡(óQ”#f”Æ,†#!RŠØ*öY#4ÌB„qPiS¶Çƒ°îSÏ››iŠA'¼9îéi”{{#®™+†W bÞ\Ûfï InG'“.s‰ãöoÛqþ¹Š: T«C1sûKÑ-c;nUE¦À³¾„µÇæh\ý0@1¥M£CÅÈðtÌÔåâîfEw*ѾitXµA< %+²–6ú—fsõ~XðÙåÑw[žî-üRé6²SÅÌ X1l(â…BN(ºC÷MZÚše3uåð.ÎÁF¢Òì[æÇn»RYÚr½zzá‡*\Y ‡ïк^g¿ÚerâÂ)'ÉȲ5‘áªãej£ÇSD†[ƒUqqþ&ÊŠ)Hë[kO5röÚ+°Hg»±A¸¡‚WWb¿ŠŠâôOÝ¿/ûJ' ÷æÖRzûLÒk5¯#'“a´"/F³%ÏE.÷0*äÄ,;üD´N&ÿÂZ™˜U8!AÙäI?Îƒä„ ÌlHÊqcSg‘[4¿ßŒÛåνÃGǽeVßp }Ù™áR–ë ¦G5æ<0v꣎Äç±UàŠ±ÃLZPµLl—•0Ç"tóƒÕßúQžM­ÓAgÊRTŠ™žÌ/ðn{‚NÈÐ ÎÊØ¬st!ÖiKØ/WÁìÜ9ÍV¿rÍÐ96Ó¡¯w•‡„3§«ƒx>–[¿Š–ýƒÇðé%å!óˆW˜8Ú¸QÓш9N¦m wåU©˜L†))±IHú#Jv§a[½Í‰ Ÿ+æÂ“"U¹Ì­f·™eA›Ñ©‰ÓV9-E_ö)›¯7‹²&‰z&`ƒÖÄm«4ÛnVy—hì5ÕTÀ‘ðŒæÃÚpm'fÙÒ–›a¤xÓ[›k¤6ZäÉ2ÛãýÎìq¾ÃƒUi¼Óø/è¶2€êix–¹þ°kÇV¨Ýþò8'%°((D+MË+áÕ—æbjû½›‰|ŒÜ÷inÁMÔ;QŒShæ4ñ §8œÌéHåxÖµ¦EºTth;æ{2HŸÈ¹ˆI±ÜÚ`BÚšaRóh$# ‚"1N"ÏÙ|ñ.÷'H* ai‰AÜ›1Rçš+soSÆ™´…Â4‹ªÑâ°í=söIêÛ± )¢aÙ=uC4eÎ6**s»†I"-ÿ°ÕHò ðÕ’KqýX5µÇæ8Ø×ÖÍÍ'õf¨êm¿ÀÙÄ8ÔòÖ}+p¬S¾ uÑ1˜'+ äg)“B~Öª1Ä;‚¯ :š²ÎáZÛ^šH×K§:Nƒ SöLÖAP7x'Ú¼D÷XÒm¦U9sÑÛ0U«bïmÅóÃYΙª\‘ß¼ŠˆqÞbÙ@~êoð¨sA® ùjx˜{m\bA€!Zß{^qòÉAG)$}Q³V®}ÚH[ž?×$0`‘ft5‰ ®/}…X Æ8þÿº ï;«¾piñ CCVâ¸Ôú\^WéhÝ–öÐÚŠô½Ä“Ov¾b5$OÐÚÎ舗ÇJ™H‚a‰x­€ý=Ä*ªJ&·rI¬N¡<‡‚Yµ7ÀxàoÌ}¿A>³î·xõñ$]qz^ç&g6Go4Iñÿº„WC6_‹µ” ¸OYVÓ—ë{™?¿¤ä"Ñó¹Í'>GÒ¡N›3¿«²áf*š„(»¤¬¨@VíNÆ®Ý0Jò4²7Z‘Ü™Ï/2*i…ðżÚÊŒe¹ÚÈïg£›g7K »)l‘Íàœnˆçvãº6uj°[žU}êŠ4‚fÂÿZÁÎeëbPh˜§Ëù0…ȶ–Ää GV¯³µÑéû¡Z{^ˆ¨.½ät—^sƒ…æ6,T“ÕδNæ§ðø‡òÁ.«=[j[†ï¸Ó{U4êP“ŠþÖ­5g­!(QHQ¸4_öËüXqIJ]ÃéWUù n¨ÐÊÛS"Éãøª'Eší½ƒÑ/®ËÙj 8»‚DÁ«ë‘ÜçH Ùó¿—"’£ë c¤L‡±7°÷dPÆ?·îzäEÀÎBö~s ™MN`ê£ã¢*XCʬϳHìšÒÆ›UèÂx¹i  )¹¡ÎÓê Ô[è6ml¹‚"¬‘Úô.ssÈo®Ù·„ÙåÈZ;¨}ëÔäääQ"ÿG÷îç0uî‹}S»ùÚAº_oÔ¢=æÝð%kÚ©'Æ2ATÂiÚ_ÔçÅ‘dŽ_(s“ô–m·‹ª­½XÎÐÙ‚¸«Ž1~sÕ(­Ç­Ùv•ÕÈ÷Cî%#•´saŸ¢+åÀó«!s\¦\½¹nóä’¥êÔÄìAFrV¤\q$É¿Þ /ïÁÇ4&ÖûH†ºÛœ£C{8 .”[Š vîÊŒç10Û”K6kÃe»‘ðZ‹9˜e7eáо#ÓG§ð=ÈbA´ê€ÿÕqëî¼ÂÕCʸnû¡æÃ2sþæÖðéµúéT›eïe1šÂ—û“¶ÿ­sz m‹´7V›êô†öK·IqšÅ…›’t£–74dìÅ*ô®áD%ZyfÛkÎÖt朘ʗ ÛÄé^¤{wõêo¥b”h©sÂfQQgyÝ÷0¶!%Š çê)QÔx$I›¦™%6t0È©UîY™ÿõ„ì¾L6rÁÄnÈ}^Y İ`üƒ$Ì_džeP¥½X7²%îré°™ŠîµÝ_¤ÏÑǓÝÁavø]íÙ–ž°eÐ.Ò¿Fó–ða6O¿pdAgVÉk^ñËqÅDÅåØLV,Ð|$ãä\4#}󹦟†ÛwG«6Qé˜+`~ îJ+¨£­X::ÊǺ²›'éâO>©ë‰¶»%4¦œc™$ëLÇÈ’n-£¶ÊË^ëvù²Q“æû#;C¹ÿü$|-ßñ¬¬p@&±þG•Ø ùÀL/]c¦—æs-È6í´:H8A;—vý ^C²h¥$­n6I¶´Â\S™M8•ò%ÓžuS¾¼#)+õÈ‘âÔñ'bdGwy£'¼Õ‰_Ú:EÌÏnž“9Á-òzR¦­ ‹? †byá‘&¼$ÏÖÒÓ°ì •Š”qÅUãW›¡ZIž£¡÷ý*(Šlz7aœ£ÂYSX­±2ër—_ƒ|wΉ²si5SÀÂôçFuEË6/Ü•×#ÝÝkÅ;ß<"»ä=r5ˆ¼„Nótwfg gتg“*Xµºúi^äÙv(ÅÙå;]pÍ2ÆkÁ½»Â´éÉoÄpFü ;†©l©«¥Ð#$86) úøjžmc9ÆØË±–áüi÷æp¨ã®îå‘lVTh7‚—Ó¦ØJÑ÷óú·w“ ×=±n­ä]ß¶Õ¾YE`ñj¨ Mó;ÙNÛ]à–ÐÆ¯E+a6¾-T[í62픘ªbÕY‹öyÑ›xùA ¸›âxK pÏ;ÜБéhêoÃXš±’^AŸ„ãiªv[—ê$Ù”²…ÙɪîÈt BOM¹fÕ°®—L]Rãc@uʈ¹*gCéÅvFÓð×? GÅ#Wz¬Ý|ãª\(GùÌ%],¶ »q$žÌAÄ¡[i%ŸÜôÔÝ߸ûòÎGÖ‘1¤tLÏŠxÖQ銙k›LJ½§ü6Ùɦ¯‚A9sÁÌTS7ci)%ª/5ø8JÎ˲a¾i±¼­NÜÌ™¥BdôÌ4YË&ê8ò¦öÆÏšÞõ.6 KíŒÖõ'Á ÛiaIæûdÝ9ÛêÔÑPK€–Zt¸YoòñavjùƱÆl51*´¶u¨çaâ,ÕFK{M!X\—ªÄ]õ$»ÜèUjÑŽÚÕ^Õ©ßú·;èÜz¡‹iu89µË”OŽ(œ¬™´Cÿþ\+Hx î© ?y _~õlµ¶²KIV<­Œä:i«QŸzg)áÕDCÆQ9_5çCÔ ’è(HPßøö «Ÿö™yóB·†u¶WºèÛ4´{«bi]ØÎÔoÿ6‘jLyªÓNÆc¯¨ÙA»ñºT·ÅóV˜"âäÄ^xöÙe®„‘•¤À ‰¾^ð1¯­û‡=äQ0´™§~ð*[æ ¨>Ãçz´&$‘åñ9˜ç@远c²õïÄ®—Ê Ù@Of(Ï–G×jl£Ì´Ñ K¤ÐÄÜýÖ<ÙëÆn€5ˆ±„TËúïË`o²FÓ‹¯>EL•KoÆiÒÔ»oâ– ‘{ 67g\[eæ†Î­6&B@ =÷»bZ(Sަ`Æý/¤„â’®ÇãÖj‹âðåâ`,ÅîÞY]?¤0è±››=m7/ @Ö±Œ\cï±ì&ÿêr°IÞîœ0ô²q<Æ”rw)èÁjsDÃ’žrûÒiéìjx½Q,1û¨‚ÂwÔã¥x–eÑš^W£)yÂJ8³ƒLP§¥WO‚÷8’psn.©'j,ÀצÐ×°Õ‹äÞ÷àZ»Z¹¼»Ÿ´z#ÈivÌÑþ*_T£Ýû™?gX>  “ºùx$ëŽ÷xæÊ1óçÔøóç ÝxiÁ‰÷lÂéƒWn¿Ò¦å y-óñH;¡Ûz¼/fö^íþž˜I(°¾DôÏÿ»ýöˆêÕÙ-g×t…<ñÔIíE‹4£díŽ1I#¶ê5 ÉvÊ]´Óf) V”•¤†¥£&!2¿%Mѹ8iqHº6—èo*DE)¦Jò¤¡†œ“%¦1ìÑ2í·é—WÞ›ö¢žš÷¹JáOǬWx¥Y›¯ùÅ Œ‰Ç¬Ã£j®`„lÜ3] ˜¨ ŽLÊ%@\==uà U<ÆýÃ.:íý±B0ý9ê:¥B%8‹\%P‘Ìá%«Õt\¶Y^½ÌNDµ#ÔûÚ9 ×Å¡ÖÂê½1¨®|ÓºV× ¹›i6¨öTrîÊÍTµz¹×¼Ò6ÒÛ^ó^Üè=Ï=¼kÅt¹²†îˆVTm a†rïF騍ÂjB¾ö’xs'Ÿknì SµišÕ÷ŽîÛ3~¨×Á³¢« k/g“¨¨€¼Îëüd”"ùI§óòOݦ-q&‚{^\üi~ƒV9j?A{ºw7ˆyCä sµÐôvºˆßu—'"÷ó®hw¯.5*Ë”$Ø ÿ>°à&E‰¨‹Ñ§?HLp{©ç7¨8£ß=yøè‘S78¸gÒ´6ðu•{†Mz‰òÂ?šÀêÊé8N)O ³ê«ê°îÓÌì4:½\º*=oö[õœädtr [¿ ½J ÈqÀ5‡·†Êzõpv Þé^f"74tÇÅïæ)qñ»™·W"ÇeŠ`ó@Ïg{@o³ÕZý^WþzTaö²ÍQè©êƄݣG22éx§7+ÐðìÙù_*žñÙ²ØxjBGgÆoàä\R~ ì¢{¤Qü¤.I]j¼*N¨ŒÄ¶Ê”ʤ^û¤¢yQüòf•LªÌëgsZ­šõwlbeûèÜM­C˜R3ã»÷MžÃɈü«L­ í:©UÑ»k§VÁÛgsZ­’ñwlR…Ýsî¦ÔÌä¾É™É§L¨;EX±Jhd24[JôäFa.<¨h™x„Fs.3‹læ\¨HZeÒ…‰×9ë _^û´ _?›ónµœ¿c/ÓCçnæÝ4µgòàà©W0M¬Rq•bÓ­srdß[û¼°ožÍ)±B¦ß±ÙàºäÜM*ãÜígúy•‰¤]çä)zwí(xûlN¢U2þŽM¤°{ÎÝdºáðø¡ ¹ïA$8XuïñÒ®{ëÉ¿»žÇ{ûìn<+füÜwüî9—ÛÎôÔÙã É¨Å;ÁÀ#m³ªóŽSå¼®V4Çnûgû,s~ ç0+ ¯šv´¨î`ýº ÄÅïå5ûþ{&<ã*ïŸ0œàIË9èñÀ [ú™jy‡ÎXÍ[¨à]Qíz¯Òò^:0¨ãU%ðÙ8pÈ)\‡<{ìÕ2Êè3>…0J`—ÂZÙöPd†ª+(²W°Mõq2'UޏšÌ盽ñ”V{%8ìr“.7yÙ½(Ì­ŸšiöDgq6i7Ñ{kÖ› ºÙ&fPÕæ„È8",rŸêØ´+lt!…°ÄàÎüÛE[]þí•^Îìë'Ro»´¬ºU:‚™ÝWÈ£xWÌÓÐìf¸jžaËyºšË±<ä7‹è GGv¡…/³…rTÔ¡âÍx(ØÝ;ñHBHuÎ.0çµg væ9ÐÞ®5:99ckµ†U—yc]kOfqk]«ä°–Eé"Ìds–âª9ñ‚\[Îë^–ƒV¥[”™‚WZšÁÊÌŽ[Ÿÿ{–ç#F”fòðt!Ã~—©31Zà µ‰×»1òÚʾ½¶…¹âÛk[”fUÚ,îÉ‚\!“3_‹«ez.–¡-sí+ÐÁÿÆÅç–µó¬­::ô"+Õ ±ºÃçâ…(ö­v†Jž`rÊ–`¨û¢ ¢Kȱhõ xÑú¯šXt–³´øÁªë*(`uÍÀl‹WÚzr_YA#M ç¾4ý¬ëgü‚¨©ý“kÒ3g WŸ8™7Ö?Š38“‰”Íi8Ðõ™¯ÏötZ5ûs=­Šô~¶ÎéÌRåßÔÓ'÷ΰƒ»Ÿ<91Mí™<03µwŠ.nʵ– äU 1!@_Ù|¸IæíÇ›ø>c;Œo*jJúS`)½ýàÔžÜCÍ^îÎÙf^á/)A’š¯mÈ;ÚÇ2îø$!?-ضüµþÖ›ãð.“ä†kñyŠÎùŽhã&q˜ñlsžzÿÐVÓšÑ¸ÜÐìMà‚ñB£¿T1د§*>¹F#ÑH€š‘Ý“k „íämS_J ÖçíhÝî4¬ttšX û%D†©:tv^áѶQ×ùÇë+nå^qÝà—vyª†²ªˆ™#Pitª!ûÐ<ÙîW›£qN.q>Iº6Z ¹n°C`ѽËS JÍæ¢çNË‘jôÊgérçàE˜+3•2‘„>’Ó£æ³ûìPåOâYÖ[pÁS2Qr+’"áÅ6ù7³ÿ‡¹5Øo{¢>gƧ@5Ñáà¨!E~á:0‡¢5ùJÂH›— j`Q +®•X Éb‘WʉˆR]gkZDyü:¬e(C7 ·sG4ÕNzrƒS6Mñ$ì ûoÑ*è¬ðv@Ù†²oŠçšçfkº«œÍ;¿ÉTò[·œhRL,ÌbXÑÌÒL¿¾ë¥éô2 Fƒ…ìsaB̸é[Æ)šSûM÷ºÁ+î¤a©UÆãºÁ½™­+¾æˆpfì‹ó‘Šx”.HvéÚ‹Ëܧ–+ñÒâýV¯–ŵ«T†æ…õ¡â+ÖôÇ»õÔ;àÍ[^ïvãåJøBG¿¾åV®Ñ;ÓÙÓ ·¯ H†$™è2Ù¤ù¶øiÂÊÖpƒº·ÜZ²ºûØAÌ,ÅÌ!ÕÆh ‡T]ø’uxÅ Êz¢@ÚÞ¸êµVÚÎÕÀVák…ù**Ÿ¢²„I¼†…qYì+Ý"g ¯ŸÓr¦ÔJ¯‹¶ä í®Á“csdÀ¬àc&Ú`®Á›"gÆ=Ø –ì»eYza)7G®Ašf:Ÿ&lÊzBWº“7YCC–,* R@t¯Mh솣žË ‘48ebœ¦9À9J·fŠ…@¡ïÝó莱hk´íN ÏOÖË”‰au+§Æj[kÛNs(˜$ ½#åîßßi†oøöj Bvœ£‘4ű/&áð ßSl»+57D;&laÅøù©»B˜ÃïWÌL4EÎ$”‡F X=ó¨ràà ¿¢#ŠÁMƒ>¡@”#‰‚¶¸x¬\ +r©w{ÊrT7a£—¹ïF8‘òôäLtp/—8=ù}G&LLÒgŠ™KP­‘ƧþVB«–LNĶgM‹Ùf=¦Yôøé<)¥°ãQMå”H‰Í ŒSDÌébív4qÅt?ñü*í¹ä’/×JÕ HÅ€]UbFÃKµÓxN[a¯è)©Eº"ôzî¹9šA›ìmÙ9hI…ez9·ø¦¾«)ìË,ÇÈý#ô[ï÷D»Ÿ¦›Gø×]Ã蚨Ea” ÙåL`ÑSéûé²á¨v‹q½Û¡.1fåòŠ„! 8++›MÍ⥥„ÃTÌ„ ´6ø×\ÉŽE”[˜µèFª.5‰²ä-Ó»µlß²@.×é ©¡,<‰XSÅ4ÀÒv¹Š¤Ýñk„.ï`K ôˆl3é]*]ÿæÓ$ÕÍFzS¯ï(î§J:)iÄh^í‚ãœoóu0A(^*²48î mª­¸.{†Ìn0±v®P¿H¼l¢J¥{£ÖÊégx?o“V§e†ÜL·9®1Ñðò²Æ;Áè2ã×ëÍÔv-×¾ÕÒke?æó„Æj¢úéÖæ¢?ÇíåZœ¶ÇøNxZJûÕ,´ÿ‹š(i³J.œm{wçä:ÄÔ^÷Y˜€ÛÁÔP¦ ÑÂV2¿@s(`…±Rµd7GÒa¯]°¼Þç2N7E48`n *mÆmíMÔ -g×N>â¹Ñ|â5¤Ø1äÍ…‡v(d Ý„ÐMÂÐóè󩆆ÿPºn¢†»@n”è"¶Ÿrdø óC¬xøº Ú7Ê*YçÓ›ÝqG’Å”ÞÑM?ü\/>°_âg3uáL‡56 ç¤/WެbÒ ÷¤Í5¿<3ÛҺϚ° ºé•tžéàÑ0ÇtAî'£%ÉãÈ/Û2<úrœì’¿ð³B©˜µöºêOçÂlKù)Ò›R;£\¯iv<„&4*`gžcà)Þ$•&¬'˜Š„¸5æ5¬ û¯ÝÁ‰T.’Yb>I†×”é}+ýP¿R,ÙUó°Yÿ†OUrùzE®Ú.¯¢‚ k©A cÓcm`.š1•áYDvÜY`“{(VgYÇb'óuI•„‚÷»ÌOÓŽ*Áî8½.ëFŸ%J®šŽIÖPJEæÝæKú…v8ç'n MËZrg²7?S4»[-µ“RBùš5Êë³Ê”ƒÉEÕu ÍAéÛÕ2e™DiÇÆé»VÊrÌPªš¨ÏF,ïÇŽ&ÖñÏÈõœm´¢™™:~½8¾3•§mµ“Ÿ6F6¢GQh]û"·Ç¾È­ò^Ôi¹Ï ä2ø—{‘Ø×,­pÁJîž^›9#—³gFITF¬xb…ÐÕ™ø·Ÿ¿s“¹þd¯L¯ñƔ—´W]®à.R\‰Ñ±AÄ˸{ù@¬2'Kþ­}¬a-‰ÛØ™ÈÛKWä•Y†¢"4òÿ vÖHÒz?5—ÚQh9½n³îÄ]ÃsyüÉ‚á¡=¡åiþMqûd`l«0‚ùb $,b,yYtéZDŸ#“[R&ªY.Fv³…¦6—4|¦†ÜXÊVÕÜ1tÌ&kU#±Ò%$ͦÈÈö‚O!«õn2Ûôtót÷u/ø1aœ ¢ö¶í.ïW‹4c¹FÔ5ÖòN‘­˜à”é•$aB1¤Úº¨¼ZùvF4¤‡Ê¤³âÑó –}Œ@f¨(‰™ahNtO2O§ó2M\Ø<§…7©û#šÄ¼¼»C¡¬ûd™Ïð‹TëÃeÑ…—==rûLL5ñ×Ýæ\æ[G!è>EÜþ9Œ‰}Jêäâ‡Ó+=<ÒN>.³Lrg Xþ¬"ºØ³ü0é]ÀM¸žwš…ž&Ó9´fß*N°RA,åE(äØÛoBéEYó„ÖêJžÕSï¼Rj I‰…ì6`,ÝÝrijœi¤lÒe=ê]¯RWÒ, ^¼Asz\^†úºÑ‡f:TA.lSnÕèÜ`¶4c¤ã5T™ÃFc&Ð ð…VRâ°l¼:þ55b΂Ò˼‘.u7ƒ:꥜#X£ràæ>ÔÎìmøåÕËW¦®p¢BÍ-Mò†;´Z¬r»Ù¼<‘mzCCWÓœ¯óÒ׉\%Êco f"ìKÓFa›!=¦CDOÁ:/JI´( gnØC¤‰‹Tº˜JÕ¢ìâmN ´vi¯cæ¬#рꄙ,WIµå2¦4¨}›Ò‚ÕOXYxýÑ趨²@[«ª 1ØdBO{ƒs®i‰Öß‘—NÞ=‹þhôë<„$›dw UØR¯Ò2›‘½ÓMæ“vÜBIA£}ã3!DBÝ_ñÅÄ4Ú…ƒ"¼ƒ¶˜K»Yæ!’i3“æ.ÿNíÆméÓ±_K= ëOá›9æôþ¸Ï‹_ªe»DÁ„ÍÔ>²JJ&%ªÆ²ºns„®LíQGuˆæ’‰RCT®©\v€ÍÊðM¤¦×^¥–jÓFI7•ªÌm£‰†½ç¬¯¸b¤•ÌŽb$Gã´Mq³k ;ÞÚÛŸ •ò]eØ“Ý+>[š6ç­­þÞÇæÙ¤ž¥¨aîÓ4HgRà*ˆlg ²1ÒGg`møJ š¹’⹦ö$”Õ[M²ó3²s(åê÷vC9|<Õ`¢$Ö ˆCH8Ýœ§tÑšú!ÿ67²¸ÁôBx£¸#T±¼R $æÛÌ8¡¨;ømûcz2LhŠhWÅk ­Mñ^“^ÆôÚ€´aã5mà ›òRîíë¶øï»;G6óûúim塳Mz?£¹´hdnèÆ³¤`1sLt?UY ;wJ»~¯ðàì!×ðíuÎÛ\ɼx”¾ÖÑá'tÔ²‘.ì6rÉ7o^×ƆNu<.BjšÒÓãasó‚6:­/ f[ౘäß–QI‡kåòd·Û ø¤‘hº &g’–I¯lø&áX›œÞcžä䓈)u˜õû&m‰í­¦æŸ&j«Æù5M N²­Ô#‚h·sb˜¹KºaD.pðw@ŽÖ?t¬fª^Äm±Å •wüŠJ†oº#¬,c–R:©zmɘ¥€E 3 #ÄØ¦‡\øJeXºA9ºÌCŸ£¡ZèÞŒnlsP)iô5Þmþã+L y*YñH“ßÍu Çì›9:yøðÁÃì^V-oã &€r´[ešˆÎR?]¸gm(®Âs÷¡-{¾Ù›ˆé¸{Áι]_SE›Ã—(››—Ò#=5È̦¼±z6n¿ÂØžß’k:§[5¥"$úÄdNÌ'À¥~+öN‹¹$‘·ô^“‰h`-)RJrâ[<ü¬x¨†ù1Qå†êðýÚ^ñ×·LÏŒO<›ô¡™oÍm)3Ž·ˆLo$¬k¶HT• BìÞ@_‘ú2v¦0.³ÀÑwhƒ]ˬrÖŸ±&ã›vI'‘„h~¼Dl™³þÀŸrO‘£Z©'ÝÚ*¨V‚¶­$õTÜV çel.T±¹×—8E¶/@º ÙÈèú^ÙP°s´´Úlæ$ª;ž7 éÔΙ&Í2ݱØz‚X„=ÍEž±¥ì ÿÚŽç»XùmYél#!y`¶Ï©Ý»(óÀ k²¤Å9Vóû[ªžFÕº ›kZå*òMA…Xº&33¶šâ ¾%7>üd{–vÆî„‰>B ¤e#7âþ·º]šý§j\ÏÐvÜ¡ÃÖp´øj`ÛÚ Qƒ{OMŒhW5"X''ÚfYÕF¹~¼‹Ó•Ñ´[×K–:˜Ë•S§ÃüÂLF¦¨´?k^¥Û‹ûmš¶[ÆpæÂ"jT¶£B‘ËzD󥥸ñLé:‰Æ.UF:Ðô˜Ñ'Ýåz›(øãr­ö ùzÿ¡=˜GϘMÚÏhò†ZkžlF#{¢‘‰(™ŠjQw®>6¶ãª‘´½¸Ä5)耱ùŠ’œv:2½oÎSšÒiÊãÖ:®º±l¶ÑÔþCÏø³Ôz¥J¼ðúØóU笵|võ¥%™¢þ— ‘p‘QÿÞtn¢Çsn:È=~Ú³z0Ø2T§Ž“î)í¥,8ŸÓ~á¢\ ëÙ:j¡HD•,ƨAË`>O: dõ·Hr*TŸö%c·«7cò¡¡!Ý~›‡ÀL73x-™º›Ž «Ì¯2Åãè¦1™ªi¤+%¬#õH+¡-AÇÛKÅ9Ij´uKuË–-¶T^ÔŸL™ÑâŒPå:[ÛZÞÕ–rÔÄM^¨ÉµS™ÍGÎ.Š—õ¨ŽÏ¿•öŽuk¿†"eÝðÆ"놥%Kìuj¬¦/¾šŒ™œþü‚ì1u¾.yÿú.9UhqJ/bT'ofˆZbÆBfÙ¼2A+è ¿¥Ie‰‘é• ûG­Ž¾ÅOTÞ€¦I´´°•o»5š˜˜š™©E{¨ä‰Îâb¿m7ãÍž8i„쫲YñA<¸‹¶ž;WNO G$2·xMP_bHÍîq¢#{÷_5Šc²ºAi”eA<µ†ét5Þ – M”YZ` ƒÓ²ŽLöÑA¬² O£á*èɆ;®ºklÛ6Ì&ì½qZO rG7MMMÕ¶ÓêßM'M»;cµèà"ZÚY¬F  Ñ¡¸{ ²Z ¨E“5º°ÙnÇø=mÝ:võ–èÈôx…gƒƒhìš«¯©¡·Þ»:ðéÀ‘(èÂÝ|ÓÞ¤ÞTî›}f=}‹Ž½+Û16 w£³ß½å[¶ÝŠn™î´bô„ýW^}õÕcÑ^,J:K9Ä7ÝNt”Ó@›Ž¤Í¤l’QjaUÊy Üö[)¼- ¸C5pÏ íN«3¿ü£À’pÀ~46ݦ¤ÝxÏGtVTÁ6n£2vh7cPÇ/Åt^FßèÆs|"Ñ/¹€6ç·‡›5¡Õúü¨n‹”g+nÏ÷é&Ð:YËo½:‡ÓB3¯áf^ykt‘̪fŽÎÙ™ÝÔ‡üS‹ÆÅ½àxùžÎΩòè•ÉÉI7{é•©é=0M¤CPжJ´cxg´íšmwEÛÇvT£½ÍY*u+•zUa©Okö[Iô´X‹å¢˜á·,„žt;mú{'¯k·ªo&=S{žÏh°/™ÙzM4Möí^§t¢ÃÅ­E¿îTIxNPåvªÃĶÛ'éÖÖÄ|ò :<Í[i-ºüË_y›knüÔ¶ó'¢Z4ꛘ±J“Ô†5¦›‰þvA»ÓŒn ¤“*pX«Nÿ8uÚîZ4ÿ1(8ºéÊ™hìé[«nóÛ–­m¸ÆÐ•FiGµ³wñªq–:ªÁÐÿ¶¦ÞëÇlHu-NØ{pâàþhÓ5Û¢CDd›Ôv"Û°ðƶo¿ c t×UÄux$°V˜xS®&Ÿ ôLŸä©X–Ça#DºÐ˜£–ºq’BŒöõL¹i˜xIŒEW_…Mck´åÊè*ìc ´»o‹1[iöƒÆX’…O<Þ!^îSz †²'Êk¯´$¥ì1³±wl¡»M½O¹|ß²þûðCã7LFÑeûç#®» p8 ¼xðà¥À÷|øSà#À7oß1T*]\\| ø6°ñ{K¥M@x"ð$`øú¿þÃgÿáÓûðÇ>ýaúçýŸ~ϧßùÖw¾ñ­§ßúÎϾòù¯|öóçŸÿÊâÆ<ìÂ…?¿£\Úò䇕&ž|a)J—œwþ îsÛèƒÐÔó7Èszväü ôø¢ûÜF/æ¾û†sy¨ËyÇù/˜xòÅ¥‹9ße/_}‚,Júùzß—ƒoüOQéÁþ;HŒ§¿¾t©<­i«¥ï‘O®ž@=Q Rm)ù9l1mвc ôxÿ £ó€ûœ/s¡Z0h´€E  t€%àÙ@HÞù2Ohn¼XçÍ_Õ¹Acÿ_þp¾y‚ þÝÿð•µ=ù®|š08Ù—ýÁ;ƒŸ˜Ÿû>¸tŸÇoˆ¿¡´áÁ4Äøð¤%ú|ß’}‚t¡‡£t^é&à¿ÿ»(«ÿÿçëÏy6œGkòfà.à“ÀnÐß§”JM`4&~Ø º ø#à÷=¸Tz?ðõ‡”Jß^óÐRéðÆ‡•Jo^ðpìÀFÐ¥MÀc/(•|Û¯Ä?³ü?ÖöáL(Êÿ¶úsßJi¾±õ²¿/ñªw4àbÚo͘Ç:æ p'ð1à/Olz`©4 l®Ú@xöÃyr±Žó0°¸x"ð$`xp+ðµ/þíg>ñ‘O|æŸùÄgÞý·ã×[ßüÖ×þíËžû²výéõ‚Vèîc‹7–îÛúço¸ÀíÎÞ·õ÷Sz†=Õ{\z„·^^zÆù/ˆñ«tIn羜^ÔÇv¿}6P¬‹lº+)é#J·RºGäöå‡\°ðç·Ï!WªKéæö`åè{cyóùþK>£ô?`~37ðèlmð†VÈ´6¬æcÍ8ý pøœð÷ÀÕ•J/¾ ìd©ôãÀyÂþü>pÑ£Á¿\ú˜Révà3ÀV0Ïþ¸èÐà×€ÿ&[*ýÈc3»öú¾u¾1ðÉ=Îúì~ø®T'ó³aHòé ÙÓ:|&px‹@è?¼ x9ð à•À«t¾¼ø!à-À[_~ø5à×ÿ|•Ö:ðuàÁ˜[a~š¸õRéáÒÌ”¹wá…´ž0‡€mÀ?~òÃïûðo½å·^ÿ–ßzË'ßG^Dÿœ¤ïæíw~ó"^Sç?ÌãÉ3k”âç'6K)ªüÞ«ê½wýæ »7Ÿç½½´P*ýO‰òRöÐÁ¥( yèù/(züû½ÿÎÙ¢jÒ–}ÈšÚ²‘úy;°ƒÖ

|ø[àï.Zóà‹Ày 5÷¹hà¸ã›nᨯö#ãõÕ‡/é³å‡¯güÿ{…YöÝÿ=lMmy<õ÷}ûçCÀEÀ#G[mÀv`p%pÕE²?\ìŽ77Onž , pð"àÅÀK€ï~xÙE²Ç¼x%ðsÀÏ_t®Æÿ³¬6þÍ Ö3þ_zĽyü;XÛøSÿð‹À/¿ |øKàÀ¿ÿüð5àëÀ7.¾à[À· À\\<xðhà   Œ{€'Oö=Rx‹ÀAà6àØ#ÏÕøè¢ÕÆÿû.ZÏøüÂ{óøßráÚÆŸú»,KÀ³;çÏ^ ¼x=ðàÀ›)üà›Ÿ~x7ð;À{€ßþø,ð9àóÀwÿüP¹áQÂSÞ¸/ð8 zÔ¹ÿw>jµñ¿îQëjå½wüoxäÚÆŸúûRà2à ÀFà)À>`?0Ì ÀmÀ1 õ(‘Ú@x9ð à•À«€~x3ðÀOï~x7ðàwß{”ȼø ðÙG«ñÿéǬ6þÃYÏøÿò£ïÍã¿íÑkêïÏŸþøð5àëÀ7€‡ Ÿ‡\\øh‘ÿ < Øì®®v»€)àÉÀS€Ðæ€ nS²,?¼ìÑçjüè’ÕÆÿ‚KÖ3þ¯¿øÞ<þ»xmãOýýràÀ¯Þ¼xðàÀoï~x÷£Eîð»À_ŸþøàsÀçÿJXS€G. <ˆ#ºƒË€Ëë'>æ\ÿs·ÚøoxÜzÆÿ¥½7ÿ»¶ñ§þ~0ì&§Ož¤@è'€“ÀòcDßsðàGׯ^¼ øqàÝÀïï>|øði௿yŒèŒ> |¸ø¯Çœ«ñ_¸tµñÿçh=ãßîÍãÿµÍåÇSÿ7ð?@ 4cðà¡ÀÀ+€*0Œ[€±‹EÏ· ØßŽ7ÏŽÏ–Û;€;çÏ»Xt…/^¼xÓÅçjüg._mü?yÙzÆÿ™—Ý›Çÿo/]ÛøSÿ8ðfà§€Ÿ~øà?Þ ¼øCàÀ/ýî¾üð%àŸ¾|øðì­< ½öÂKDGüHàQÀv`Ç%çjüŸô„ÕÆÿ}_Ïø?ùñ÷æñÿÓË×6þÔßWW;]Àn`ØÜ <8 ÄÀ,PW½~˜^¼xðbàû^ ×õÃÀ/oÞ ü2ð+À¯^"g¿¼ ø0ð§—Ðøà=xûϼýôϼýg>ùžO¾ì=/ëÒ?ø&¶ßdG·ºiµÑýµkÝâ^—R®Üx®ÇüRW:Ó|ò}J߬{üßõ„µ?õ÷G€?þøðIàSÀ__¾|ø&ð-àÛ—ÈyÎÝÀ¯ñ(àÑÀc€Ç.<¸x"ð$`70ìy¬œ ínfúcÏÕúäðj3ä•õ¬ÿË*÷æõÿs›Ö6þÔß   , = ü ðjà‡€×§€Ó•s¼»€~xðvà7€w¿ ¼x?ð‡ÀgÏŸþø{à Àþ¸/x–û=î\ÿ}¯Xmü_¶y=ãÿ Í÷æñ?5¼¶ñÿƒ'¢ßß| ø¾¨Tú-àrðÏ>TÁí¼ø°{Ë›€¯{° þ$ð0ЛãÀŸ;@%_|¸óp øð(¬˜¹ÊJ6`küð3ødðµOX£ÑIðaYŸIuÖøAøÜ÷¡X^(•߿҆8_Î/¦õö=Àý. <¸¸Ø \ \\ÿ8™/OÆg·ÏŽu ÜÜäý#À]À¯^üØãdνxð›Ào=î\­ÿ¯TW[ÿýêzÖÿ·W 'ßýõÿ¼+Ö¶þ©¿ßü6ð»Àï |ø$ðïÀ_¾\ùÍÇ ø6ðŸÀ…øxà‘À£€K€Ç£À` x2ð`p8Є֦6ЉÎÕøº¶ÚøÇµõŒÿFîÍãldmãOý½<8œ^ ¼x=ð6àíÀoïÞ üf$ûû€ßþøðIàSÀgϰoœÜ¸¸x,——]*{Ìã'OÆ/=Wãÿ-«ÿþ-ëÿ?½7ÿÍ£kêïÝÀ0<x&px° ÜÜÜ <xžò/^¼xðãÀ›Ÿ~xðvà7€ |øsà£À_\*¼ÅÇ¿þøKÏÕø¿}ëjãÍÖõŒÿïŒÝ›ÇblmãOýýUàkÀ·€oß ïÀ'MÀ0°¸â2áG€0<x °Øb`¨Ïîž <xðBå)_ ¼x3ð—«ñóöÕÆÿ Û×3þ¿¸íÞ<þ£ÛÖ6þÔß? üð³ÀÏoÞüðaàO|ø‹ËDø8ð—À¿ÿ|øðMà[À#!< x4° Øì®®®¹\d‰]ÀµÀÍÀS/?WãÿÊ+Wÿ‡^¹žñ¿kǽyü³cmãOýý4àéÀ­À3çwÏ~x-ð:àÇ€7oTùïÇ7ï~x7ð;Àïþøðqà_¯ÿüðUàk—‹ ù à›ÀÃ!G>âñçjüO^½Úøÿ×Uëÿ^uoÿû¯­-§þ¾¸x p1pp9ðxà:àzà‰À8°˜x¼Èý“À^ f:Ðà6àùÀ €?¼x#ðãÀ›Ÿx¼è~ øià=Àï>þ\cçjãÿ׬güÛ×Ü›Çÿ?®^ÛøSÿðûÀ¾üðïÀž>(<ô ¢ïy8ð`ØŒ[Iÿ\ ÌG€›€°<HÐWÑ à$p 8ý„s5þ‡®]mü?¶k=ãÿô]÷æñÿÌε?õ÷w¯^üðËÀ¯>üð!àO€?Aô|þ ø'àŸþøwà?€‡oÄü.jÀ(°Ø l¶o]!ª\¦7ž«ñ¿öúÕÆÿ÷®[Ïøï½îÞ<þ|íÚÆŸú{8ÜÜ $ÀmÀ1àÅÀK€—?¼ x¹êw_ ¼ øyà€_Þü2ð+À;€w¿ ü9ðQà/€ |b£èˆ?üðuàÏÕøWž´ÚøÿÒ×3þ[Ÿxoÿw\¿¶ñ§þþ&ð-ànà¿€ ›J¥ó€û—"àRà²M¢×<ðàIÀ8°˜ö7€ƒÀ! nŽ‹@èèÙÀ³.ð*à7«ñÄîÕÆÿuãëÿÇŽß›Çÿ§ž´¶ñ§þ~5ðCÀ)à4ð‹À[€·ïÞü!ðAà€?Þ$ç9|˜Æ øðeàŸ€¾|ø&ð-àaìÀ#€ ‹€GVäLèÑÀc€+«*çjüK{Vÿ—L¬gü¿wâÞ<þ¯Þ½¶ñ§þ¾¸¸¸ØL{£À³€¨  Y‘s¼y`xðbà%ÀK—/N?Üü ð«À¯oÞüð€wï> üEå\ÿ?M®6þÏž\Ïø}…ùôÝÿ;ö¬müçt JÃ¥Ò“þ¸ð ÐhàJ²ðÀ—€/ß~¸V*Ý8†9\¾ søëí¥Òçw”J·^‰9ôóÀÕE~xØ5gûtóøOÿ÷üÁáqp@»ÆÁAðßù—{ú!ø¹ßƒKß»±ô€½Ä–~^‰"”6l¿_üâóßÇÐzûðqà“À§€¿>|øðmà?ÿþø/€ó€K€Ç"àràñ@6À`¸¸˜Ò9÷`0, Ÿ«õÿ‰V[ÿ·Þ°žõÿù½÷æõ?¿wmëŸú;nÚ@XnîN?ܼxðúa¡oÞ¼øMà·€wï~øð'À‡/ÿ@c |ø'àŸ‡…Öü+ðà›K¥n>WãÿÞ©ÕÆjj=ãÿáïÍã?}ãÚÆŸú» 5ÓÀ‡|øðuàÁØ<x8ðà‚+d¸x$° Øì®v»€}À~à0, p h‹ºÏt€%àÀ+¯Ð9ðö_xý/¼ìõ¿ðzò.ýƒobû7º¿ú”ÕFwÇSÖ3º¿õä³;º—ºñ:øäû–¾x&à%9»ãÿÄ'¯©µO ¾~ðƒÀk€SÀ/¿¼x/ð>àýÀ€t…ðþø/àKÀ—¾|x„ûç———O6›ªÂ[ ›I`oõ\­ÿ7ì_m†\º=3äg÷Ý›×ÿûÖÔ–ÇSßÜìöÏŽÏ–Û;€;çÏ« ?øà…À7?¼øiàg€÷|øðyào¿¾|±*<å?V…¯\mÜëO-Q̯8¸Úø—®gü_sàÞ<þXS[.£~'~ hM`˜ö€Ÿols<|÷zü ìz"þ~øà-À[ßÇþ4!ßt€0 >d ¨‚·ÚüŸ}à±Î~õ{ðHôù%ÀkŽ”J¿\ò4Ì¿[P.0Ü´€% ,~äDàî£hpŸg¡­À,Р üð~`w º¼ ¸û«wÿí_}õÿ>z÷Gïþü÷øïwî~çÝo¿ûgßtþã/äË?ðþ£˜NÏ;ðw.¦S6ÆÓ£Ýgc·ÿL€Ÿ}¼[ú^I? ùü}åù/и•þ[.å#ùíåMÇù÷SŸ™åÁ÷¹í>‡ÌÀ¸F÷¹í›¯{Ú®ïõ¦ãMá¬ÈÆ–ÔˆQ»H&» x×ÎRé·Ï#»J¥>ð€NMž¶ûÀ?_'óàM:6<àfÌ`7ðýÀ‡€?Û lRàׯ |øðyàa/*•.ùbì/À;_Z*} ø{à À_½ªT:ï5˜gÀNàWNÇøÚ—ïþ»»?u÷Çø¿à¿OÝý¡»ß{÷o¾÷mïÅôçÏãÏÝýÓo~ÛßðÚ7¼Ï_é-; N–3rÜ–þù÷裉ï¼ïŸñïøª—š¨¾<ê¾×Iëšbè™aŠùŒ‰µõ!;nE£»úœÆÝ̆D‹ßu;ÖÇs°Þ€?>|øð?À†;A €‡—W;[Ÿ Z€1ðùç—J¯ÀØ¿ý2^×1«û^´A Žàg0{ðúTçL>›óà>øGÿÃßù>]*þ9_e¸—æ<ïëþ:ñd$ŽŸ¹ýœ÷LÀÈ}÷Å“ûýÍIà‡?¶c}~xÔK@瀸ø-àåÈú/•uHëoôûK¥k¾ÿ,Fƒåš/ú>sO?|Üÿðgþ‡úÞéøÕÒýð8÷€½e‡ê<¼T~ÿý7¼ù~>rÞ÷˜ñ‘fd/ÄLbÜÈžïÆ2Lû°RøùA™ÏÍ|~ˆÉña4nOGÛ€—oþðQà/€¿ª?€gÀŸÿì|öàpøqà€É—cOðŠRéÀ+VbW×øá kKö¹‚ Îî‡Á…~òž~(þ1cxAnåεûÐgškŸÚpþý1×οÿ3}÷‘4>CÀ-À]ÀÛjØ/.Ä; LOž ¼óU²÷~øWà¿€ ^]*=ã‡J¥¯ýìÅ›€×¾&Cÿmà‡€Þ›?Déïý;0ÙÙý`X·³iº™Èï 9úQz4ËÏweðN.vÏNœžêãÀ_:¹¼xë”J¿|xË]àå^[*]ù:ðѯ/•žòìý@ Ì¿ ¼pòMgA†9»ê¸³+_ÃXg’µ÷£Ü€Óbÿ¿˜Æõ¯2ãšËÀÀ ‹0®®žŽ77ÏžÄÀ,·wσùpp9ðx T2æÈ° sâš7ɹù'J¥§/^<ê§ñ>p1p p=0<8ù¤žÜü8ð³ôÝÏá3ð)àÓÀ_\õ‹ÈØ ì^| øæ—¾ð‰/|ÿ}ÿ{WôäW¾DÞeþyWô…]>Hа'ENÆ{f^Î+âóW9cb Ϧ)gÒäï §õø|àûWü#ðOÀ}~yO¶ûC@ x ð£ÀO>|xø›K¥K€ïRà8ð†7¯Y»µÆe;8ƒøaduÜ㊞ µ 2ÈýxÜ~iHþ~¨~¶kÞ§¦qùCàï€ûa½mëüÌOBfÿ)Œ/ÖÙÛ±¦J?9XøY7¿¡kçGßYŒê¯ÿ v¾_Çú{;äùßÀoàÀÿöw€ojï< úϳKÿ²zv³þî×ÍûñÎìø_Lã÷7Àg€Ï÷ÁXÞ8v{€ãÀI`¸ø1àç?þ xÍ[! 1æÃ<°$Àû¼üm˜3À~̇ƒï¹Aóâ ð à5Àk—ÿ&þN§OŸ> |xêo!oàq¿y |ø'àŸº¿S*=xð|àŸoç½tx0ðàÉÀ> 6Ð^¼xáïâoà­ÀÛ€·ßó{¥ÒW¿ôéO|ô>ä?ü%Þç¾°Ýßþ¿xa%Êîö„/ØAŠö lÁרß_оüðôÙ6õÚ¸Œ6¾þ½Ç÷alÿ°TúeHÇ¿¼ØþGè#`ê±÷³ÀÏ¿ ¼øà“Àßÿløøàð‡Î©vû´Qgbö}/ûàý`Ýsì/ ÍihÁÅ4¿xð(à1@ó÷K¥cÀpXýRéRà2àõÿŸ~ øià˜ú#7'^üð‹ÀÛ€·Ÿþˆ06`øeþ41'.ý0x3à%À+€W¯Þüð1àÀ-Z*Õ^¼ øà]À×ÿ®ÿèðbà‡BÐù$ð7Àç[ÿmž¼xÕGK¥üè°ð1Р |ûëßþ‡¯Ë?ô›ð©¯ëúø)ü'_[’}„ÿ?üî¯ãÛ•ù±ô̵óþ£x-¯D)V¢ †v8jRÚKëñéÀì‡dþþO@×þÄÇ!ôßCÑGÆ´¯~x/ð×À7€2úm p3ð"àuÀÛþÂõéßw£?¯ú8æÏ_ž…-ÿì2÷8·ïÔ‡3©uæGe@K.¦ynÆf°˜öÏ^ü ð:àsÀK?‰¹¼x7ð;À{€»û|ªTº/ð=À`?p¸Øö×¥Ò`/°¨Ç€°ü<ðà’¿)•~ÿ3˜cÀ?_¢Ï‚^ ~ x#ðÀOï> œÿ9Ð3à©À3€—ï>|øKàÀ•Ÿž< ˜žìžt€»ÿåî¼û¯óß_ >t÷ïþºý¬úÿ™×üfëÿ»F‹–òÚäÇ5ÈŠ{i=þÔ'd|€cÀ÷¯Þü2ðnàw?> ü ðàq…1æ€ï~øpÿO—J#À÷ÏÞ |¸ß_ŸÙ¼ÿÿÃ`u\lð‡{œÁsû®| Ÿ!]ß/¾³óºŸû.Xÿ¹Ÿ®IZsû€Û€EàµÀoŸ>œ‡5x?à"àÑÀ€QàZà0pè¯~x£®_³þNc=}ào϶íÛ`¾çgðúpû øýñǽh^<†èÜ+€Þ ü p)ÆiØ \ܼ xÐß^ö7|¸xð߃®ÆÀÓ:ÐÞüðçÀ'€OŸþ8ÿ Èx,p=°8Þü.ðWÀç€ÿ6|<+p ðN,ƒß®þÞþø<|¼@¦÷ù'ȯÀ ûÿ3æ1p׿@nRt㋯çm^ ü7ð ~èÿ;øFàKÀ·6¨Áó€¯÷û*Ê~ØþuÔx;ðàîoðÿèý«ÿ…_¹GŸ_Û¥ŒEÇ÷¥ÿO£5ùzôý¢?/üGéÇ«µÿí·ãÚ_wi?QÝ®}ó<í“/i_P?P|Sû€Ú? Æåáß,•ÞªþX¯üÏÿ‹˜®ÿmBšpÉ{t|tŒ6ê8ý’ŽÕ%:^o"¯ƒ»±ç¯^ ¼’ó×ÿ7öàÀGÿO©t phM`ø!à.à·€÷ÿüÏÿÐU€JO^¼غaCé ðà‡·ï&ÎÛP:,/~x3ð“À/¿¼øà߀›î³¡´ü3p7pã}7”nnnþâ~x,ßCéàùÀKï~Øsþ†Ò“ú÷n(5€9àa@^_Ëý÷¥»¿p÷çîþ(ðA†ù·ø¿ÏiÚÏýþÝ4 ÎvçÆÍV–øV[Ó‹÷Ÿ}¤!>RÈR ]ÿû^©ãújÏë½qüG ‚ñxðûèÿ¡O'Ðç£ï†€GnBÞï{6€Hl(mîLï>üðVôã=ž»ÁVèå¿Å®ñCpŒÿÿà üapk¬[¸˜?°·«þŸd½ÕxÁGÓ¸ü2æõÓˆßÀŸ¥ò†Ò¥Àààçç=hCi/pð3ÞP:ô ¥‡ÉO» [êŽêãcŒÆ”²UDeL/¤ˆeðþBjýêVŒí…"#±%‘½¤"ò£Jc¦á'¸c® åJ+¢ª£~Ær¬ÀJDã*¾|ŸÏ y¬/&5"ÄpÀ/õ~ú±ÀûƈԈÝÆ ©‹é§e(Šíá›îü›_WhéÁÓn)29þ×Bæc0bQ (1@tà „!%Y×]‹©ë|)ëzÖ"oqETAWlÃ5L"KK¨ñˆ+©®×I¬?7ÌxÿuÍÿ׿˜¡¥ïÿä!ÿe½6Ä&¡8‚"e¨ (Òø@‚Q¼,ý({Ú ÃfìAÙòä,:¢+¼1šžÍX¬Æzl®H_ Ç‹8ÜF›Jü º£Ü0÷£2í r ÛP¤ Ÿžð¯ÊgC0²WSDQlƒ?æV'§± «qÝMÝõsºëêxN~p¯î ãu]¸anÚè¡ ¿îcT–+öqy÷çc®×Z9ëÙŽ¦çxæ½A­-h$óQƱZc<"`ý"\±§«¹…ÈCŒËÙ«±¯¤Åº†ç`ÜÁgˆ7ÖÃŽxÿÇA­cÞðíÿ¿¬™02äÿ-/'™ü󫬿ÒÄà! ;²Ærœ€ùÕ C«ª97–ü‡i(G>Õª¡ˆÚ²Ý¬EÌë“8‡X$Ô1‹ÿëùUÌkS̆ ñ—í_nËv¡Äî8Nà\mE\B'b6®˜_ì€?vjñÍWŸ~Š£J"²"Πt#Ú tFwôÇìA¡¦¼Žr°Ç´is€#ÃÐÿ²¯ÙŒýrÌÄj¬ÇÞæŠDRà줈ï0Ãá8Š“ˆhÁ6àSEìj©ˆwZ±§Ò­d¿Në£Åh½´ˆû!é]ºˆû©!©ûwùíJ]Ÿ¡“ç!{xrÅÒžZ7¨döÝlú}~ômn.u™®-DÚÝôÓyÓ§3½¯ÄKìÿ5’ù¨ƒõGЍ€¾XS¨RW½p:4®ÇºÅZœ©—óÅÄx Ö£uCâ¯Å6 §q9Ó¿Äçßîÿý“³!CþËxLÀ äiB kp›ªùÙÒ(·á2ìÈ¿*˜BÞ}Hn¹´PókŧjŽýŽD”üLƒàƒ²äÝÇ-_QüŸ;¯ç†ÊlÈ)-Õ61}>g{ßZá8Ó†¶ºûÎpÇFú=ËÀÕÐ 1+ƒ«r™ô08 Û/ÿ7º3𯌿Üþ•Ç2â¾áˆB4RðñvÔ‰÷Q 1õà Éxˆåmé;¶UëÌñ¯¨Opúšþfv¢`-Ž¢Q.英pîŠ8 ¥;u í{ð;à‚ˆÁŸðp¦Nb3~E Î#Ï7ŠÈ‹:øuÑ ½áwÌÂløÂŸôdŸ_ œá‚w¾e‡†hèô­QŸ!í˜ãÙHã£=÷SèÇ@9^ŽLÕ— ÿ /È1Ó-¹é½OÚ'xÊíK™Ÿ`$Ö!Y:*¢*zbbaõ%±GsŒÂ  ñ±n‚ž˜Œ5_¥×iĺ]∾]þ?mÿ_IᩎÿÈxÌ ×.uSÄErÍüY¥å“Ì¥¼ZõÖrÆ+¢u¦7û.ôÓ¿£Îô¡ïß> úd¿`±¬ˆ~„¹Ø ¿Á/ þ/ñŠï7­2äԮ̙ñüõømÙU$¡&ñ¬GbÚMжÄ×ñ#}Oì1K° ž8Œ8ƒsˆAêE+´AìÇ!Dàõe¿SáŽÅðį؎êÔ§:péÏ{b ¦#Çqçåk1?ÂS¨ƒ3q”zx'…Ô¿6è€ÎƒÓëh1´ùÐÝÒ]ƒ|TŸõã…ôÉLÇkº³º0ýT°¿WÚº§nÕe]Æ6ÚRÛmñ~‚w•˜|—¿¿Dfwi*óñ’Qn1†'"lCiÛQõÐ#°`3Œþj¡#¾ÁhŒC ®ãþB¥á¬o¬þvðÊ fçÈX¬C® ìE|Š6/øà,þ—‘Џ›(=оúbÂPs´"†a%ö 6äW­1j®½ Å¿#þ†vo¾q¥ÿ†iðB ŒWD Á,xã4²M þ¨‚Žè…>ØŠDd™H»‰˜_ü6Ñ,îÉ?¥IáÚÛÂc fÑUëô÷î)7"«œ*;ÀÑ4þv2öãÍâ‚øEã0¸m×bè§Åñâ$âïÆ¶þÈ6YÙaò¨ù܇2S¥°Â!„!f±OßÙôPiu »ˆBîŸÙF']9¶_?n÷œ/ÇíLÍŸ3uŽÛWý8U?ºÎ8ç‰Ïœú}Øǫ̃öšJÔog ÛôL¾Ë{Ü÷|Åósiý„|Fý|tÎLßÑìUK½‹Ü]d˜ÕWåR²”ÙõEr~%Ë,IJœ1qï×öØé¦Æ¶¼Óú5…¾ÕT–›F;?8"v3Ø×Ã\áê߯‘j\Cÿe“¦è¹oXcr3—X0 =}ëÌ{úrÏ/c«PLÆe4:¸+â Œt·œ‹½æ)b Âç+"ë–Ã!ŒXH¿Þ‹èGàúbET]¢ˆà¥ä>6,£€"+Ìê€åÝ0“µùw÷^láŸúÔ–ßÇtPLë@&5ÄN¶§ï¢lá„¶‹IpÃdxÃ~Ø-fc6ÀÙKK° Þ´¨‰ŽèŽá‹DÜÃ}èk ï]‚îª.Ž1JÿxDÿ˜6'j¿~ÒhŒÒ–JÐù'¤ÍÒód~†Ös] ïè?ÁõŸN2`»ž|‡3¦c'¢‘‚üÄ«ò5¦†x–±Û¬®ÛÖkväD /u}Ëu½ÈǺ´÷V×ýÛ”uùo~ü_Öívø Q¸ˆé[é¿ã:î!ÈGDZtÛcxblüè; 0Š£J¢*j¢ òw^ßÁëXŠeøÊŸm6º¢Ží¦]À„ýŠ˜ŠyX„¥X‰ÕØŒí8€¢¼J¡4c\1n˜…ÙðÇâDñÔGÔÃÇhŽ´KïnêâåÔ)ýã‘}úÑO?ÓÇ‹Q磽ý2ô ÊULú¾»BËC9%s­uÏ–òœ=´AE‚žü(ñÓÞù%íïÈØfrý_™ˆ±7ñÝâ“ëÛ¾Šxç7E”û]_!fb|±ÕÐN`\1 :<@Þ0EƒŠc>Va-¶ :<À#8e»ƒê¨„ÁðÇn`‚ÓˆÁyÄbÔ1ELD0"p‘¨®ˆq7‘ŠðŽ`8BQït)í¬m§.:4ÚP¾|?mo0m¯Ðx–ÙED2Ô´þ=òåò­‚a[ó”û­e~E^âesP›+&àg,Á/ðCN"v‡QC±‘H<¤Æ¼ša¨OãNˆY[`ù>o@›üJ æCf-†ÉñûÃÄ ­1¾Ø‹ÈAž~„!‰¡j>Ëœ•9)óMæ…ÍqúŒˆÂÀHÚŒ“ŠhE}Â8D¿ýÎï) &‡£M2Ãäæãfƒþoý4²êŽÞ=ÏçÞ¯ÝûYÊb˜2¹þW¶_±ˆPc(ãw±JÇÀ›Pþí,¾À×èŒøßc\Ñ›Ø÷Å:lÂø"á8ÓZý8‚£Z©@‚Ÿ‚ƒ§qYO3ÿ¬"†áÖ9>WŒ"FbþyE,D®XöCP¶°¿ÀçDUTÃçèŒ.¨ò?öMP µñÜ‹ ¨x‘¶>žeРݱõ²~ßà¶ñ];ÌÆÄk‰—™¢Ù׿¨Ò&£tþrvxûðæo«iç}œn?yûŸ» ‹ n!ý£|‡vVÓõφòí¡Í3éÿ;9hë:ÖÚº.÷`:pÂWè‹1˜ÅØ _„á²!¦pÆráÊ7'Ü7®«&5ü–ÅWÞ€‚Éßóx±¿ÚhÈcÜÒ´Î?yö®wñؼ6G†Ì† Çe<¦c6Á~ÁiÄ 6—hPÝ1»‡G¨§ˆX@„"eþ$÷1ó°±¾í ¼²‚Ùù?2¶lãÊ z¼é¶¯þeuÛw gp\¡=‡ÛUúðÂøëŠ˜rƒ~AÛéDÚ~ìÄn!=‰muÒ ˆý«Ï¾7&ÿe|e<«bˆÿ×èIWÓã}‡X?DmâÝÃáŠ_‰½7rçB‰j=¨N¬k #:ã"®à²Þ¤_†ö˜€°›à|‹mlnS7Q ;q+™ŸKQDAÔÅH¬BÃTö]p ùï(¢:`$ÜŒÜwù<¨ŒÂ8LEÝ{Šh€ÈûìË ï_¼†•HNºw幤Sqa‡ÒÆä½i“~²Èc²~ÚO_öË0êW~fGgó§÷ç´ÂïõMßn}Þ:ôívt[ ïËý4,Eÿl(;SÿF¸\*}i}‰¹žvk-ö›É|,ˆRp€cRzÜÚáÝ[j<&b-h±‘1ù“°»0˜ø ÁXC\< âD ŠÞ{Ñíþ}_Ë‹™´4)–î e²ÿ/c2s°º?:?«°›Pòq}Èöÿm6 +±3ùmÛ° S­¬ÄÑ,ò·[‰X\À=¸f·îx–{^šüÏLÎy´üg˜žûš&¿ú¹{î7–Ãù<9ŒÎò–õgVŠ®ÔbªSDâüì0î¨K¼¢#ùˆ½3ïò ¾UÒëÁìjüÛ£;–á¼Q}(I=°Gy4D34ÇL­ŽÌÇ,Ãr¬6b¶Â;àcÇŸˆGÖV"Jã}4@CtAW8ã{ôÁ4ÜM¾ÊÇ%Ÿ%‡&ï ݺ‹ç¸(ùïnòÖÐ XÁã]“‘…°-èrÁµ&-­|Lû6?¯Y9m)“ïüi—Ï:ïìñ\ùSf÷|ö¿dØ–˜{ÐÀ][ç˵u½I[ÇþÚº•ë5›¶>jëQ®;x ¡8‚TÜA}k+1±–ïž|õ•b §_yÁäQjƒÉY›úJñ7wõÍØ.äÎ0GûMEd,e¬‘„ØwÈUÄáàŸÛJìG òX‰*pD |„ºØ×J„á(Î#WQÖÆJTBetC/ôÆ#äÈg%¬QÑ-áö®•¸„N¶ü úcæa>Î#6­Da=Qs±Ëp‹ 1 ¬…Ma+Q ?#ùòÙäèÈ£ûLþýö«I1yuräQý´Ñ<µ,ô,3ù‰îÎÁ¼žMO?ã9=úüåyföóúw•Ï™4´>Orܰá£Ø—ÏI»XˆE83¸ëÿcïNr¾ÿŽûåh•iÜW!Çr¥CÎÄfd#e“;’6Jø«æfiî1G¶Ä&rßwfÊQcnZI-±ú¿ý«çIþf¶ð~WÏó}ŽJŸï÷óù~Ÿã÷Ó—Ä;°Âçø³±ÑØ…ƒÈ†%ýÆ »q— òúÖ ¾XÛx µ\Q0“Ëñðg\b ?Ç0ãò.”VÆ¢7|0˰På=n‡#"¿Ã¬Œ2~§a®©Ær¹²ÒKÍ•_f—¯ofCíibµFáÉ·©Å6wjñBû•ã2 îEØ8lX‘k;£o9%'Ë95i(I>5AC4Á(,¨ ä\9ÏNCT%òDeæyXPùåú¶ñ¿ôù¹.Ä",Æ·ØŠhA²PœÖƒš¢-l1Ÿ" ±‹ñ 6ã;lÇNdA"þ;±w«sðªÒÇ0¬:5~5é7ˆÁ=<Ä#XÖ¢ncVmIlÀø;pçðJÖ¡ÿaÎÕå:œ‡e=æ¬õ¹ŒËHÃ#X4DWôÀ¦F’x·1ýµ ÿ/,Ä&s~bqוw0¨ü»xÍÛÿÇ•Œ³•]À*çªi¨®Î»ƒ¼±Âfÿàþ¿åñ¸—¿¿‰êïßÀ„l´0–„'¢q×q M$Ñ ¾8„Ç0¯ÆßnXa* |/L2Õæ€"kh<ÿ/ÇbâQœqçV]ƒ³p@5A¿†$Za¦c¶âÜFƦ Ü1 ¾5•1왪±kfö â^øTç­›ÚG¾žÝü[ÏüåÎ Ôžÿ“cRÑý1³0çð“74¯¥äß~Såá¥Ø‡ßð;ê‘{‡Â A˜Y[ÉÕ‰Hªýzû· kÜþGüå˜Ü¨­ÔÉ`ÌÂ\ü„ó¨HÍœ€%u•:*×Ð,4¯§ÔR7lE4bqe©§UÑ3°ßÖWê®ÚÁ6Õf*Eß(üó¼¯Ù/ZxC}{~ìåìPUŽIT}eÞã LG8Vc7nà&ê6”Äg؃½H†#s¥q”9ÓfœSÍJ£#æbÂq ñëÿ· k©o/9&©x„Ìs‡a"‚1»‰2îÉ\w[SÆusIèZJ¢ŒÐ^˜ˆì@ÌZP° °ixû–oÐÜOíOûÆüÖÏ+Öò:&ý-˜»Á8¿‡š°hªÄ=»q·pÑ u–øC0˜,ƬÇvœF~ýÉVôtQõ©+~’áÒNâc¤ í™[àN! Y0ë ‰:h ´AGtBwô€#¢°gqñH€›µ$FÀ#1 þÖ’²¯ÇŒ{Yªl_yúOÕo<½?úôŸë¾¼SÞǾQ¥àúnP¾5Þ3×~/{¬ßç½”oý×Yà…p$ X+Öh‹0ÜÄ-µ&ÞpAV`%nãê½/‰¾øs±u‰¡“•ÓPDYi×~¯¾ñœçŸ_Œ£òµß`ÚF£1>X•8…Ó¸€wÚ’Çá ÇX¬ƒãSB)Ô‚z£O;e,n§}þÿßlþün_0–ãá×^É•U;Ró±Û†9NÁЖu?ÞGGã[<€“$Fa6b ìYâ+œÂiÜG²ý«ÿoA‘þ[ú/×·LAVc Ö" 7p©x€4Hô=¼}”AET‚)j ê¡>` †"‹ð„¾¥K2°UúØIÔîLŸ¢x9cná7Øwc^LG ‚P®»$ŒQ Œ„" Xx\†A~Ê¡ªÂÝáQ°êÉ\¶èW Ã<,B'I˜ .rôüç!¿‘×O‰q‡âÔ žwž¬yÌðÛ¹ŸÏ?ãøß…?ì(Çò$ÑÃàŽù؇ýHLJÄfºƒ£ƒ¸«ŠUôà Ä#×`Õ…<‚œÀ]ÜC~p÷®¯]ýÁLú†ŽÿÿQÿ»«:‡<îÛ1Ð’~nFÿž‡ñ½˜¢ooI”ìøÇ÷ˆGyî‹ Ø‡‡H‡}_Æ'‚†ÃÈN?òA¿"Šÿÿi™ÐØ ä9ÕGXÀ #°…˜ï†qwé­Ä¿81/ÑG‰ñÃþœ£É‡’˜Š`ÌD¹’0ÇèÁ¬¾ ® ¡ƒO $&Ô/Iâs,A8¾A4ôfPcÐ>Tvp@OôÆ—XŒ¡O×gÉ·®ÜÊHÈ8¾KuúŽëVÍ>WY‰MÉðå”5Ey¥-ïx=ï(çù³å3VZÕËçÞK¹oak±BoSËÞyÇ’ó‰Ç‰×\÷iÜ&ﭲ׈|Ù?ß÷|Þq…ž±þ³Çãxc¢±©hL|ÍÑ“0KpJûåÄ{Îã"*÷NèŠ%ØŠëxï#I”ýè Z÷©åýk…Þ­ð†Úc^æüÕÑý̽@ÈK=ÿç^£öþ9.­1“ð9Ná,âpz™ç¡ 1³± ×Qqq‡1›‘‚ê®ÔÔBm À@WísEÖÐxýWŽ…V ¿à]9wVrx¾Æ/¸ý%Ñ~˜‚©øÑØŽÝx‚ÖŸ0„æâ"–C´ñ/²†FüåX´Ä@,Ãr¬@"h8”z€‹ÍØ‚Ë0p£FÃ#± ‘ø•‡±Fƒ z 'úÓÆ¿Èñ—c‚C8‚Tsg†ÉðÅ6ü€$˜xG8¡z#3ŠãÐNž@ Á|ìÇû”9ä§ÚøYC#þr,c$Æ`,Æa-Öa î£þgä¸`¢q7P{„$êÂ!ˆÅ^ìÃï¨êI€ záOmü‹¬¡9°qø b$ë: FBq g‰÷G1?@;´ÇTÆQœ…þhÖ˜™ˆÁ¼7F`1Fÿ"khÄ_ŽÅ,Å!ÜÁ=Œ•„5Æb'p :ã¸6„9øë±%Ƴf‡>ÚÈ}¼¨^ÚøYC#þr,¢3&à+G2RP}‚$úc¦b?.#%&JÂ^ðÆ$ø ÑØáM_A‚8omü‹¬¡9%'1ÀLG và²P݇Ûà ¬ÆO–„)ª£\Ѓ± —`âË}à€¡˜‹|µñ/²†FüåXÜ¡Ÿ$J¡&`"‘„GxŒšþÄ_b>`!Öb=.á nÀ4€¾oø gð,¦hã_d ÍúO,šbÆ`Î# ¸ˆòS%Q¦ŒåˆÅ$£úç’pFfàŽáZ!‰6_(¯ôT½  ënþâ–ÆVàõŸ§¯ËìÜÀ¤£ý4ItÀÄ`'Ätj>ì0 ‰k((‰²0†5†Á;ßë=ÞAÌ gHÿ`MÚ†FãeÞÿ“ûò—±ù56X£3F`=n£x0ó<8cÆ#9h}÷ÑŸ>TƒþÓúô#U?:½œ~µRWñÉ*I ÇÄ`öã(Žá Î" HA*J¬f‹Z¨Ž°Á ¸Âþ@<’Ði$º¡?\1O2ÓòNÉi™r[íºÌ;™I|=—{ùø³N»Tw|îû÷5õWÞX¢‚Gh³€üïmyæ~däÛºÉcRo)sxt€ lá‰Q˜ˆ#(ñ•$úÀ °÷Ñ!œëá‚ìÆÜA2ê.ã?Wâ"Eh×EÖÐXÿɱh |{¸Š_“ÐSpLJ’ŒG+LÄ8Šc8‰SË•ñš¼‚qÄx½†òŒ¿NذJ÷¿Ðx™÷¥Øžî L?/æjŸÿݠʣûUùó¬*oÊ9³¤*WÚ¨räÓü¸Ž<èò ó†uÌñ×K¢ù·’°„Är6ŒQ Mñ¦mxíæ}÷ò7Ô«ð·j»ïyµßº°ã?hÖúçìÎ ßû¿äš6 A˜ƒp¬Â¬E½µ’h‚V°ƒœ±_cÖ⎣&ý¢.n#zô‘Ò˜Œ©Ø}8 #úNyüJ¿ùCÕwb¿cžÅc‘†L¸meí ?,ÅJ\ÝÎ}c¨K;é—±äžÝ’¸€x$àï!Oí•ÄrDì#/¡äIÔÁ¬G÷ƒ’‚±‡ø?Ãðˆ$êcüŽ<}oiÞ.]ÔN·r?×÷t.ò¥ƒ{wìÝ‘¥yÊ·ÇzSå}ôÖ ('*ä~•kqîyaïý÷ÿâ Ë•òß¿à þ@Ìí1óq Ùh±‰o†å8ƒltÛLýÀ·8ŽTŽ”D[ G8Î"Å·³-Ú:Pd Í÷‹rh‰vhWÌÅ<¬Dª/Ø16{À}áápÄ|§Œß³¥ŒÕK¸‚ÐÖÆþùWûA­Àó¿r<œ± ÇQc91‘¸…'ø%Ȼ݄%ØBâv%/[üHÝG|£äéê\­ð+ˆýߨÿ·‘ÆüOŽÉœ]J ˆUjçE\Âe\A’aNý5ôºïg®{jè1XRCWb5ô1æ&_P?·Âü(ýÍ`yôuøüÚÞÈßÌFá;UVk¨¶Üý‚—~Æñ?å9Î d¨âd¡ŠSs´@K´Æûhƒ¶°-ìÐ èG8¡z£\ÐOÒŸÜ¿­œããâËQΔ=j7µ­¼rÌ‹®Õ„ggQl$¼ôtžÉA?ïVQV÷Sùy×ôɽßݱm…(ýô6¹Åõê3PÕ\°²¥*έTq¶RÅYŽ­½*¾r,5â©¶Ÿ—i¨ÇJí‰Ó—¹›ZCma÷ÿºÉ£½¸‰x—uß@y¯¯z&¢Ò´'9•§éˆªu›Õ’rsB©F¢i¨‡Žiäióê‘IíjDŽÖ«©WÒ,ôëâµP;RˆŠ‘§¥J0 ¥~h··lsd=h'†ªZzj·%%ÍÐ )ø ­´(–Ò›óïŠé§ÈßA‡5«ÐÂV¤4áb±ŽrW+¾§_stäŸÒA×HñS‡ wŒ‹b¤pã’¼¥S¾ñ”ODÉ”o Y¹–pr?±éØÁn—7?t0{ăž9bš¡RÖìrïÚXOŒ¬–âËuîìäèPJ¿ ¿(Õ¥³¿©N{.7Ó£þ‰8œåq½lĦ“Æ·…ÐNÝí‡\ºtscr¨¨ié‡û ºyóîͱ'O^Ø»÷d@Àâ„„«ÑÑû×­û±mÛ!999B»i··h;}Õ:Œ3Ã!žNN]m=G[´jÚŒ¶ng1.†µ…N»ŽÎ¶×¼3Ǭ•áˆ6Õ6ßOMÍIÜäè’Z&&î ÖM†ÞÙÅ9¬Qµ³#̳Œ#n|ït781óXvªV‘·Üãoz&ÎiY%{ø™»‰£úu{rÉã뇾:¹NŒ¿í1¾í]³Àß9/¹¸íJ¬U•zóÃS¶Š¿=)ÂÚ0qÁžß/e;–.ÑÕÍÝp^ëô1¦>ææö›[§œtó¶ýꃆC3[Þ’ÙÄ sYTæ)ëÔé}Z,,«;Ðmíämöç'öÛ³í磱‘/ÛZ.œ«ûñÚÉ]‚“tÓMî¸Ç9oonwÿàUƒ²õîLþRçðIçÖÙ{õ©Ût×§ÿœ¸ólßU[\µ¥Yå ?¶Y-T/¶è}‡ìðþ¦e\+{Æõëâ’u8ËZï×µ¿îï0.ùAê»~?:®5/>«Ë6óq–f³&,ñ¶©ezù‹ ZV<Äpa‡5ï§ÿ—¼;§j]ø¾6JD†¤±4’$Ê”d.sQ™3„]"C”ÊÔ\¢9IÍ¦Ò J£Ð@KG¥A†Óáþ_»ÎéœïÞçžÓ}îó~ß×òü,¶½÷íµÖÞûÿêéuh ß-öBó%Ú!Cñ»y/y‹{§"vÝ;øz¿_Ò ©“eÔ®•ªZÝ\o/Tð‰obœ]ª™›Ç©£:‰Ns÷. UqpzÆ£ca¶xï|[‹II•Wïœošë»ëF„YÅ–oâ\'_ãr³)¿dDGq¯V§ÄÉûëŽY¦è¬/7$e@cóݼ¦|Æs¶žëci•›å‘ÄóÜ&gV·¾¸lu¸¤&ÏÕ ¯:N·˜EÏSd7èD¦X—1:nfé6)W6Õï\¼ÈÙ¥y„²Î”¢Û:â²s‡þ8A”Ŧ…ƒŸ¦9LêáêNf%š†uëª ÷|0̈ÔlÈëè©ãQfT?krÍ!… ¿{ÓêVTí9g*)•à0y¤¶îÿÈÆÊãÍ *g ç zÖÅ[Åûül…Ðê}ýÅ¥Ž=L§VZSŒµþ5‰Mn÷½qœ”ßÝÇ34ÙK‘|<\·MÒW!wõÛ•ÍÔÍY <[/7×™=è8*A¼Š7§ÿà°']ü­²FÛ8¯.H)Ò¨šzDGo­BcÆöùQ*‰+{öá“sUQÕZ~µ²‹}÷InºÓv‡Ï<°Jý­ªZ¶·ž‡ñð¢¨Þ á‚vçY NgÞ»-sq±‹oÔí¡–‹:ßÊö÷”ļØåiY?/.£ZI»%>®ÏÖO$J8õKV÷A•QÝôϳℂ•·Ï+Íàs¹>u{¯T¼b®D\¯SŽ·” »QİûWº™>ACî´i3ÆÍ`‰IóxÐǺi­ÙÉ÷öÊ`‹Ž{c"s²Ï·L+²ë¹as¸!ßg’¢©Œ —XûàŸóšn±52 ¹+<¿fµæð²°îMmñò=Yj ´²­ëó'u8¨¨( 3»Î8hœÕh}Ï]š{šg×’Z3“œ‡µ¸;­P°öÝ¿´6«AÃäzt¼qßü2é¢-½é»e²£C n~(½ÕýNm®aÄ¢ô°Âæ"Ãá›·¶Ù®÷Íu8ž©gÖ’>SüV³ÆÊ3\kRЦocË'+=í¹î¶$?$ùAl®*Ÿ`øÝ ’ª´Då @ù¹Ù’Š¥þ?xo8_Ì+¬:ýêôãÓºZ½kÓŸ>:öõÙ&±¬„³çü|º÷·µ6œHäÙn|ç×ZíNƒ§oË©(n?WÝùªPõžâ*?&õzš_¥í›í¼¡ÜwU'¶òå ¼¡î7?øÝ¾Ìó ö¢öÝ1;”ÅvÙ³Æ{ ¾˜¬ØªÑÖ–]xLç©éÞ+®ï¼ç²AÄ(ö3ÞêGtW,þ!eÓÑé—£ÙCöÕM´zµ¯ËkâþêÞÒƒ™:—üãž)ÔÏw«O)ZT&˜ÿιâøqÃMÎYö";Ýê _ÍsxZªš˜dÖÌÝ(ºž§t²½Òñ±éÞÙy¼å²K“Ú¤KM“: Œjâ=­]¹' % ìhݬ‘%˜YþƒKE:«>ÐQÊ¡$ðöìð­ £üõεT»”Z–Ò3¿3¿jJ¼Jµµì¿'e—Ò’Œƒcv̉=[ä¶ó˜î–ëv8Üg“*{S,‚‰nŒwœšn¡i ¬uD¨vuPÇ¥ }™ ·á̯eÝmMÊiËeŠkw>àµpçщdRþ)ìpo\cÐØŸ;Jb_ì­ªQôÝÞ²lò븀ç&J5bï³rÆ)½Šè}yég½9Œâá'51vöíÓb\ gmöSíÞ¯«æ¹Ì:³øÚǸ¢3§uRªÖ^,Þ)›Û¼.³HTfÑÎÝ­éSÔ5ö'5.É«ÒR Ú0U瀟Ì%×s£^–©–ÉžiyŸôI9íe¸~Ä8ÄœWºŒ<.fT(ȳ6ÉzzCnÍßèœûµAñnì"+ÝØæ]³ïyÆÃÊâ½v{'¼ªó)¿”W¸hÝ‘W•»Æf;/nbß8¹±ï”„³µü™¤ñw')Ä)½jš™£5?ã—c­´Õ…j›OþÜŸ>ÄU<Û©Øô~|’xQÈs³¦c† åšw¯ÚÿbZÞ¶¹Ü¾)âiíÂi‹™ N÷ÄùÎz)£3¡±q×tÒÞj6GI½I¿.þY„µóÇØÉ·ü<Â=C&·X{æ;Œœöæ¬7‰2ì+Û¶®Ð—päŽ9¼ÖËh;ûõ¿ñ3¸: jER­b*œFÇ¥¹kÌw¨X¦2ÞdëúÖ^Ëú[~ÅKwîq]åZn®ð~ÓËÇSíW+ê\Ñkæåò¬'%ÒxÞ‰å˜fþu‹oùì￲' èÒ¾—ê}KúùŠ<Ä>f»µ™nn—r&CÆÄÀ\?[Ïe}#óe<ò,åe­¡=÷D¶¬gN0ó2†’Q÷H/ ‘™åŒ3ÁJˆüz e>0RbÜ6ã‡ka ÷§{Tû—÷ôφd_ß™Ëä¿öGAãÃèâ³+6ŸYŠ`²Yäë)øÎ?ñøŽlªó?Ùù ÜÚ›ÎÆÃû»÷Íú/>DrÇß²ç—á²á¾¸Ü×óÀed³—<°&߯Äu\q ·?|í™öŸw]Üÿ¢m[ÍüçaÈ?;ä÷‚àÌ,ÀF»1ªŒ£ŒÏÓð¡ÌÌd¾ÇèYÌ÷M¿ÇèiÌ÷M~sñýEOg¾ÇhUæ{ŒžÁ|ѤÈ~ÑêÌ÷M­ Q¦X¨E«Ð+HT£©$ªÑÔ Õhj‰j4µ‚D5šZA¢M­ Q¦V¨FS+HT£)$jÑÓé$ªÑÔ Õhj‰j4µ‚D5šZA¢M­ Q¦V¨FS+HT£©$ªÑ µhUz‰j4µ‚D5šZA¢M­ Q¦V¨FS+HT£©$ªÑÔ Õhj‰j4Å‚D-z½‚D5šZA¢M­ Q¦V¨FS+HT£©$ªÑÔ Õhj‰j4µ‚D5šbA¢­F¯ Q¦V¨FS+HT£©$ªÑÔ Õhj‰j4µ‚D5šZA¢M­ Q¦X¨E«Ó+HT£©$ªÑÔ Õhj‰=x‰vÿ|'ü¸K‘Ñ|#"y¶ðü~É`#÷5Î¥d @-æ÷)¹x˜ß¦$Ó:ðÌ!Û²Ž%Â0—Yøôy"À/“ýá›H†·c6•›gÖË®b’±yÂ#Ä㸥¡~ÆZ3ÙŸ‘%I›2ÄE^ªÃ—ýùšºSßR¡ トò$¦{Š*3Šì†¾ƒí’~¾£‚üÙìàˆà o~Ö,4Ÿz/ïîùYóŸ˜oÚ^š:ÍÜÔ¡$;qål…u-/ýýœó¦ú?îI¯=b›*—x,UN'Ê‹oJ²Ø®GbÄmGð0‹šµCxÒ”d}ž(žè˜Ž—Ï_{vÝûxòè§¶“/W}l¿s «îbèûº§o“Õ¢.Ö·¤sK½p¨bc¶Þž†XË! תÖH–¯Øp¡Ük(_RجKøw>xèåï¹Jm½SadŒÉý! ‡Ú»´ÖÔÕXØË=²6¬}楎ª2y‘SÃ9/Xq±Ï;æð?\b©‘\+&7£ºrXÿ¤„®†)L™¥Ú\#9é_Þ=\®œwücRù)' Ý‘–‹ÉN%‡†Ì…HÄ rˆ—á>Îqd°/†s*á|Á''ˆÂpƒ@æyü2Ÿ‡H2œÉKFƒ4È€,È<(À Š0ÆÃ˜“à˜ S€Ì)IŽ3yy&/Vä©KNdR¹I%uŒ”òVMÞ¸4@È ª dŽÙ  s@!'*çùg†`Æ`¦0惘ƒsÑ ÈÜ—6°‚-ØÁ"X KÀÀœòtdp…¥àä)Hf ñ„2Ãx™Çwø2dn†ñ6,‡ ™3…aV™8#VA0„@(„1œ×—pˆ€5°"a¬‡ ѱal†-°¶™t9ãa$@"ì†=°öÁ~8á$ÁaH†#Gá¤B‡tÈ€ Yp²!NÁi8gᜇ yPáÁe¸WáÃu(R¸7¡ nÁm¸wá܇rxP UðÁcxÕPOáÔBÔCƒšÎÄ:/ ™áü‰—Ÿ ^A+´1œyÛÎ4ÈoΟz ïΤßd®d2G8ù+7dºón†3z/üd®m2Qr ÌWŠ'? ¸€x`kà%žá%/Ï,2Ñ#žÿ0@†y…á #@FÂ(I‚Ñ 2 r  0Æ‚"Œƒñ0&Â$ø&ÃP‚©  Ó@¦ƒ*Ì5P‡™0 4@´@t`6虚Væ‚>€!1˜€)̃ù`æ`–`Ö` `!Ø‚,ò»ìÁÁ ȼQ.à KÁ ÜÁ<áGðoðeà ~àlX+ VB Á*†…0X ák`-D²È[2žÿ°¢XœÙb â`#l‚Ͱ¶Â6Ø;`'ÄÃ.H€DØ {`/ìƒýpÂ!H‚à G ŽÂ1H…48é' ²à$dCœ‚ÓpÎÂ98 ò   .Â%(RB®ÀU¸ÅpJ nÀM(ƒ[pîÀ]¸÷¡@TB<„Gðž@5ÔÀSxµPõÐÐÏá4ÃKø Zà´Bü íðÞ@¼…wð>@'|„.è†è…_àü },Î<Ì俯¿¿Ÿ knàA0xað?.)‚0 „@D@†ƒŒq £@$A Fƒ4È€,È<(À Š0ÆÃ˜þð+¶óÏ”qùtAyQÅÚf€¨ÃL˜~  Z  :0tôR=˜ ú`†`Æ`¦0惘ƒX‚Xsqö㬂-ØÁ"X KÀÀœÀ\À–‚¸ƒxÂàÞàË>gâ±®6¾_+ VBàçë¬Â:B Â`5„Ã.ξ\‹u$é.l|2rh>þX 4†¿¾ˆã£ÿóBzá`rÂ0œ÷V†S¥~[„c§n‹—»ÎR!Ù¢œËôÑ€Zз-üx÷êÿjù÷·àüœZgÎ×vxôh^úƒ£ ô+ýðWIä“NüwòÉ¢ÄpÆTh>ÈtC¦åÀ±ðý7·üã"ŽwpÒÃIöW£´?,;|'ì÷/ûÿëŸ9£!Ïø‡VòHg~þÅõ__Hþ—ÇNÆ "[×¹°¸/ÓŠÚ–?‘T˜ßò¿¬¿¾= {Àw õ~Ûò-ÇŸ,bŸ×,42ÝòÏGâï.¢x%c&2^úËçÃéédáþœk‚³Îs Õÿ½Eôÿ—±Y^ÿ?¯‰ÿëã¿/㯌ÿÈõæ0ÿzüG~nòyýÿuaq†ÿß¼°°w¸ù9çþŸŸû䘛y»°W²=å,ÙÁ–loÿ@9_owSÈÌÆ2Àc¥‡ k 7Ûà,úýzJ×û{ßÖÄÒºÙ$$Ô„nA]”(H‘¦  ‚ØP@,è½j„‘$A/ˆŠb{ï\»^Ô+6l ˆ€Š^Ć¥©X°ñff7°4…ëÿ¿÷½ïû7ßÎΞ=sΙ3gfÎÌNÌl±šþ'fµJ³Õ'm9 #©PìŽÅ«–½°ÝŸs@íÖóïŠYùÆ iF7ʽ»0‹WÇX°"@GÒäy'v™wêæœSO fÏè• ýK÷eЬç©Î÷Õ¬NÅ϶¿nXXê1%¿WŒ~"ü² *¿[A¿Þ)âNó\LÝ ¢¹â}G¹'—èçñgÞË+ŠußRÔ;–?dˆ`§™Ãwëpt}Õá—÷fýqèóÃ?RϾ¨Jÿ’qóã—Œªôªso.\À­-YÙ£p¾[÷·Ë/Dl+^©p+ì“sMs¸àá"_å3Ë„–ëô¬ûæPU½Öf¤Q¹ë•5»k¦IXFë ">kE—”[¸£ 8eÀ…+,mUN­Ðþ@{mÔŸ¥‡´=ƒTȸÊ9”ju l<Ú4ô‡ïÓNÿÂþA‘ gc¨Õ¢¶*•ÛáP‘éH¿¥µÃTh#¡}lkþ@‹7'ã°ÍŸƒ8†11%…¶÷F )þ¡8Ûš¿È¿›/ÈÍet­ð†è(‹³¦ \±î.“i»ãln‡í„Áƒ…‘:J‚™ÒÏêi Å¢š«#ŽëÕVä?\m_ÊSÜn¿Þ#iñª7²Ð›!•*~Æ•[WžÝº,¢›Ó´kÆm}«·Pj?ÔŸ™ÒuÈÜȵÉåÅ…5Ö;û2^´wêŽKÝ,Û¹Uëç»Å\sÞBͯëG…¬ó³øjC¶ìû¨â~õñ¬K'M¿eFÀ¨^¯Î×–mQÕ¹äRIja¯C…±³Ýã#£Ož˜±ùóU‹©“î$;qØšE–+ºŸÚØWyŠö±@¾ÊZƒÃ®ÅÎë¯ì·zƒi…áN+“œÞDö‹ãœ–%ŒÚ§þ2]ÝÖ|ÜØÁË.%wù~(dÌ>g[K<«ãîL¿Áz½ÓÔãì5ºG¢ñ¡´õS ïF+®pvs>?oBŸœ‡ãgíüëó ?½Ü…;&=Ñ 8›~eçªÚ¡ƒ\OŽöW^0;G{àÄI&¥ƒ]’zeŸ7Öö>´wèEo5]ÈÉ7?(ëëwl‚ùK‘‘F+TýÍ|±l«ø•¯FÀå½³bÓ†öÝ3ÎëKÄ¡]¯·”Ú•½ÉÁ9rü--½o5Óôú?\-Í9\ã5¸ÂJûýÅ›¬ãÚœ•¢¼~¶OúæxGº†(‰#Öî›u g]¿ ç‡ú)Ø“=©O'ãÈˬ}™©¾:Ë®†ÜÊ{ëåyvrÿÕºÆÃ=Œ3'WJSEû¹¸äªGŽ …n•[sçæëe‘eGÄãŸMvÙ=åÑ a¦Gf:ÎJôúÐõqÕpN·õƒ ÏôYóþKT’qæ6ðÍ­Û_›ï¦iýaÁGåM½ÎîŠZ¶D²ùI”©·z¯qö[v"2øä¸¤U §uN®4Ðæ«æg¼úSçeîóýL¢´”÷á£îë§û÷4v¾¯–üÎÕæ¶å¼Òäé›G+ª¶8Øm|³Òá)×ÛÚBaËŽ^]o¾œtët춉›önß¶)ûòß9¹äDmÀw<Ð[™^uÆ$'®Xð‰}HoæïCö^ç9|ÈkM¿¯åQŸ.ÔìØ×íRAäå§‚?Œí2¼Ì«K/£;—ìøpkK¸Uz¿™ûßЏ¼xiN^lÏܼÍߺºTuèrYvchYÚ˜UAøÞ“/nN²|HUÉ…)^5™—Ç´óâ;ïà8i÷EaÆ›†?± Šö;²ðŸ“}òõ³Ò×uïn]ìR©?×ítõÑ w6Ê\Ÿoê{÷kJ—}ççÄŸ±o<áÅ@ßK‡GgîJÖß¹g‰¢é½%“>¹:~5hguNÕÌË~š…I?-×)}úóêäè2¡n¦Ñ¨‡õŒ°Úyì‹¿ôãÖ<Š0°ø+ó„ƒó&¯•›?.PÕ]¾•ëºbk¸Iü/g¡KÐÂÒ£“tâE¯ïoH‰çÞÒá‘©ÁÅ Wt6®»–;øLpIÕðr‰Ã÷€O'Js¿6oPq™äêw…¯{}½=ƒ‡¬ë|åO[»Œ8_Wϱ5D3*ëÛ‘gÇ|¾&·9ÐÅþ¹$…9D³"ƇUqqϲ ýOu ”,»_<{æ"Å™›^?Ó–$œþ®±¹ìŒá¾`›ô÷¡D¡tXÆÙ³;î-¸­ñ¬—õØï^ÇÜ{ºqœùUÏîZ{Ý7B¶ñz˜ñ’cÑ’½WVo{˜tv»ÕÛϧÒÜ‚Ë"÷G'lTžPWüþóÍ Š¿Â×åEUŒyš*~ûlaißOd9îÁ:vâyœòSVÏÌX÷þV•·bZ1~û;CÛW«4eÙÖ“æO¼ÈÃSN½z·w`†°.`Üñî‘#'Hô9}¸kótvñ¢¦ÛoölL~_¯ã[%¸Þq—7‘îV_×^¬>wŸ×ãIÌÛeý7-9×#]eÉMcÝ„^VvÿΙ×yk­bZõÝQ™ŠU÷bŒØÌJþàîæàõßi%œ êðFíà¤ØQw}ßæþe‰Uþñ!óâsS‡~ÝYSp^$T[•¿²û•G[çuÚÚÛólÒ2Ó O³ªÉâ>«öè HüMiPаKÜÙ3æ¶Ë\“ø4«Ojq÷èC¯½ØaÝ&N}ußöÉ`§´wüz‚ðê¹g¢2%‹Þ}—•^=a—yzxÉúM=tŸ¹”ÝÔÞ÷wÁÎwY‰ÎÇo{ »>îì*%+ÓìêyG*Tæ•t{uÔïÓ†Å'ß¾0‹>ÞËúÍÜoß™Ò)ºþ«Ö¦Ú&Í\Û—UüºÐú>ó*?U9waHì\œûþÇÄ3}kµ5JÔFàYOƒŽš‘Òé]FöØÔ7Ž >ú• ¿žð? KÿW/ãv_â(ÞûüôÌÎÕ£ŽŸxþÞË…i,ÒK†¿å?PÕÇ}+³Ð™8õVŸ‘§&-2Wà=V³|³¢ëŠÍqSÂ7Ç^ÌwZ ýÛçËE‡w¯LVÿ~8úBϒ©Ï鈵=V Û¥‘1Bòäë®·‹‡>Lýp¬WÎÓÓš/sì2–zô8Øi¬xn¬Žö³{“ó•†m_X}ßðµÈøúêðeó"ü’óµÞçŒ׊葜¹12åc²Za:q6¹ðËÜÁ·, ¿iGD~°´ÄrÏÉ™ˆ›¿%ë 7:øïħücöÊþªº]O›r‹›Ã3?ôôŸ{êÞ­©ìŽ>ï œ/ÌNì9馗ì5óðŒ‘ïÒ¹³{¨ìøg†Í⊠‡*}CâjŽª-¬è:›¸l»êÕÕûÞ•‡ k…¹}Ëúfþ%H—<¾Yl‘¸cÁ-AyEH¯Ñ¶½³Öî Ò¼¿ÛI'ãFáàÇÖ âÊ  ¼ðT s:áŒÀ`¦K‘ÛŸê©Ì¥Ï Mï'•8'kLÞëXU`ÿnh¿+IüååëÕçöxzÍqüœ3KÖܽ¶Ø7ey¿õ&vÃý-8Y_Þ¾éÐsÝ¡áý/íaxácuÓ s*=çô<ãduÿR^Jç‰ç>u°ç®{x¼G@Däí{‰•e^I‘WŸ¨Ÿ= øªŒ°sêñ¯3}%¯6ìZbý±fÁëÏûGØ–¬'ý«Çîš5ÿÓ­UÏFê§•k¼÷©ìÚÇGÇþ¬ÞyJÝfš¨úqà¼#ÌÎ/± œG„ã58_ø£ü-Úõ¶vŒ?ÿȯ¿îÁü§›“cø|:F:à<5Ì7†Êg3•œŸ…¾!8ï óƒtÀq t B?ÌŸGeýH\ÊQÊ"}Dð™›„ôžbY ˆ„Ãwé²Å~‡8-0ÿ`‡þ©–|p$æž¹‡¦#aÀxˆ¦~|Ê“ ŒOWy´ÆåÞèrïC޹ Œ‹Iø®è)çÌݺÐK¶¥„œõTàa¨ñ“©àÅ,œ”LÁE)`öº¤å×íŒyº¹»kaת‘Ó iÛPÕH„%ɦVB© ¿5ÌÆ8!…< ¢…R±@IÀ2”;c¡ß­B1< Oe y·¡}Å·YÖp–õgœ]ƒ„3êŸCº(ècÕX~žÙ¢e|8ºV×ãÅêù[PrJ’° Vãäôœ|>W@ÏÈßø¥ïôM.g+MÈÿ£bÎ?àÌó«š’ù1‘$ÐtcZõÒÁáBsj$5pÆ¥%jÚ‡ NO@e ·C8YÏ»¢ôf ù›Jõ8ëc ¾NÊ·q¹°•“ÁE©4Xy¸?("œÔ€—ß6}#5ÀHk¤†EUWJáýDI¨­Áû†7H™ónPóq* OqHJ¸‰æã$AÂ`L.óul¥Ò™³)‰@ÊILÇ(Fi®i$M$M³£IÓG4[( …JR"¡TAJ„>¤øt…Á>„o¨$ˆ@ZH„½D2©Y]o¤Š6¨g¤´ŒåÄ9)7RÓz7’‹N½T”õ@«ßHU›¦AÚ”dÉ÷ þöÈà±ÿÅÚk©¯ÆmÒ×ãÒúz&ŒX¦ŒÕ²¥÷©¾·•¾—êïÀwuX ØÎ̵,{MdëÞæ¾ÁêF­·¤…o£p’Î@[*AŸfœ‡yïãáêì:Œ´˜: vÚ§ N;PkíÀ:¸v¡>8I|ðm2y¬%ùjá/QÐQa*ô^ƒØ/Xä3Øæ«~]ÁiBMpò+Ìa£!‡nT@¯¾!‡aÁ¤ÕC™~Èç¤Ñ¬÷ù3ÞlØtÞ4QÎ$¬!gdGôt@.Ö?äÆKæGaËcQZ[4Í;Hj&”a>H½5ˆ©ƒk'p§ó ¦^Œºº–4V¹‰Æ+7Ñøx…¦)å:.¿o¬Ó;9ÎÌDû&¹ËuS‘ÆùiºáZK%ëDã|¼™‡ÙÉlQhp(XFµíî66–&æ€{8Í©Ò$% KU³‘ÞÂTúè×¼ðyå/Z/g&‡NŸ!¢Â4é}@k[‚¬E"ï°P±,B" rSoT“€¢®¨¬4‘¶Oç<Ñ¢ƒh0á Q Ö⮩çþ«šÂmŸfD+:3WqÛ¢[¹Ík £Y7Ww؃2òü l!6œf)Ô)l85n$±¹:‘²22ûïHì+£œå®Ô>‰™ª$³‚•Ú"±9Jt‰Á5–J¦CãÑÙc 1ɬ¯yÂI*#ûÖ"©’¡::åõÄÕ'¨§:ÈwAasÉü¸þ\jDi¡!Œn¡ ò˜dfmnN :£Žì>üõ¡QÔZ™À\|i¥kLåâËЦ×RKKÂÝœVà´1!D2o3Œ^O[¾’­C{Û>¾2o;D„-ñmøvÉWa°ÐO„ŒÐEÖ%A¶Žê/YËáiUo÷H´“âßQìŒ(†0£æÓG0^pruvïÂ=T"“xK¥J±µÐ“k¤¶þò”¾âFŸâêg5²)7Çq£‹¸0nsn5¦Õé'9ýе,Ui_Ý«êÌÄUÛR÷•UéüB¯¦¥„1hüšµ Å?®½[À:± Xå±–±hëvcýq9È{Þ #ùŦ)Cɵ3kW xCÁÝZ÷*Êb ÷9·BÁÝ´,šúâ´ðoT*’?¸ÆÓR ´hü‘ž"r-÷ɽ:¶MFŶh¤ÜàáùqþŠ\®pÕÕn(h)µG. Ü|Õ ¥ŸË¥–JE— „ÑåBsÙAB™·¿8دeŸ‰6‰€òOµì1ù±n{qèÔ˜!j L—F Y>>"_q°˜tA¡Îg3Ÿ…å7¢{’H¯Q;½Zxz#ºÈQ„ÑGMÔXÀ;$Ä„ n@éõ#½s­ç sÐSiÈ¡#•ƒžŠbóü°Æø~êçûýë¨ðL¥œÕ>ýûÈÞ¯¢Ên‹þudÓ% ½ý–J¦Ð¬^ÒkbkZñE+7àS§ðE+Óû”ã‚Maýý¹ÜšêA»¹@] G€pφFXÝsD:g…´PéåÏüˆ¿RZO¸Î70^{Jë¢>>"x1kðÌ“¾Qz?fïv÷Â2åOŽ7!L³QþŽÞÞ"©”j> _ÃOµL@YÈÆ-ˆ=e)Û¦ Mg놂4Éހά©VÔk ye¡ç&Žd²¯°49$œQ¯r]kü6œç5`2±Ã,§œ5”ó€õM®It k:ûØÅ,IñåvQÌåœ`ím'ÅûXçÅiœtÖ"ο¥®|x²9 ^Hæ¶b=ü(WÊRä¶âH–7‰õ‰#f½ú×[ƒ„ Ñ7pÍQj;Ŷ¬kJ÷XGÛIq-ëon9+„›Êú“ûo)&@gü7MG€t;´Â@1†sœí£¸@qGK)†S 8ý_ËXE¤˜ÍkÅ|µÎµöR|NmãÅpΩý{ŠÎt`+‚Àƒ» m§¸TŇmÆOQhÅÝøù þü ¶üm¶í·%0Ò8.jöMRþxÜ–ÏKçÌT §ÙVÒ§¿½Í>}#¶’wƒO_¹YëNa'Û rFÂè3òãÆ»™z"¯$êÔ€v¶pé6üô±àôaGÐÓ'ðƒq}ÌŒÅM°^েÁ¿nk+JÒ+Ÿƒ(£¨lO¯C¥•^‡*ÕëÈÔc%ðÛ”ƒJ}9÷ªÊc¯F?Öeþéft6ïuÜ¢R‘r…ßêY*A˜M®d³Kö|PóKoké=£´½?î‡X¨Óé ÇÈF#þ O 1Ð0èQ Í) O:é¹’ÏQÃþÓ(~àäG£ õ8ÚŒs' ®DÃß0»cFŒàʃ¶õFšJdC#‰P~¦NçÇ4H($¼Á€Z, – a˜'êR£#GÔïMe4ó3M ׌RÆxž íÑÔ šƒ”õyë~®©¦T*zÿÂþ›ýã–K¦¢%¤&@]p EÝemŒüÙÿë>²+ŸžŸ ʺ4ÉÏC8[D8I‚e@úx„͘)ò–¡Å ˜œ3Œ\m  °4¬vºÒ°ú…\ #_¯Ð>J6¢”qB˜BJ Bkøµ–ħÎiÀGPøÔ9jô:‡Œ}(h†(TjFÉ:‚ÚGŽåÉÕíãEE΋-ʺ6á…jfê§Âˆ0ØäÀµ8 R×£FHäHŌҽú5$äZ$Xò3í£5°­}­¦×LîN”¯ .}ñFtõ0ôÒ°mâu’¯c¡µä+]ÚGåFT’þ0ÓjBåQ¨Ø7‚€ÆT—7ÑkF®8‚R”¯Í‘¯=j5æ$5m†€1èŒ_¿µžžÜÚ5ôôd õÖVHà“pyOO¥ÅžžJ}OOSá2ß¼¥©˧ÛOº]ýYß4\Œ ð裮jÅ(ûóÅ*þí¤ØOe)ÿ xËOed›)n¹•¡ç ïés ëñj^©Jã”Í[z ó?§Æ'T—pK-LW*ÝÚ@ÝÚŒ…HBeÄ8‘4,P&µ¥,:ÔJXsaý í)ÑL[öZ“´°)¨+‡º*QWy¯§® ï7•hcÙ±°–Vð2p¼»G„T& ÂæÈØ¾8í ¥„‘;Eq¹ŒÈü™-¬7§×§Cþ~í;þÿÿîàa/™Ö ð;€2¦!¸Ñ#T>yÂ8Ô?X_啘ÚÁÃY£¨ –8áºÁK@°—JÏ0€Û´]âuÀ¾5`PøP‰§i+”ʃ–¨éWï€Ão6ä{ô˜5Kaj9Hç&\ÑN¡ …œ¾è}ù›Í¿¨çao™p?¸>Ø5ÔLs,ŸÇ¢èãa·9›Qì4o(÷u£÷¤¸Î×qh×!ÚÀú¼:/Ÿ ˜æ>à ù‡×èB¦9¨{| Ümîx FßüËñaíÁ†²‡x°L8HŽŠ,øµÊ>|›Õ}ƒ_ t'°ú ]åWr¿+RòuuUR‡X6ÕÌ ‚,&6LO¾ãÓ™Ó™òx +‰Š‡)³V0Ñ—%Õ±è©B5Ô!&5‡ -“BÍ¡ræR0xvÃÕh Æ©6€0VÓ]8êÐ>r½Á°Ý*L®r5|y>f.b` °Í'àÞ•0‹â‹Pº8.AáRž¹ó0F †ñU‘±VCa B>Ø=Œ ÷Ác ð0n,Š/Bi_@8Q¸¥_ŠÂe(\ŽÂ(\‰ÂU(\BÒ±…kQ¸…ëQ¸…Q¸ áߌâ[P¸…ÛP¸~yäp´X]±ó°=à^@^„»? Ýë0jg¥ËÏ^Ek(¼ŽÂ,f3ú Èýì¸hG;rO; »‰Þº‹¾H©¶\ªø ¸Edz³³ÑNq÷Šc`lÜÖîCJÉE¡"zJ~ŸB~U¤‚ ª(®†B –âê(„{²1Ñ®d DPúhü¼ßt>ÁáÕµ ØbÃ?K=çp(ßó~…q¨ù—P<…—Qx…WQx …×Q˜…›‡ÉàyšØ ܼ¢¼.wð\ŠåâX ëêò@ʈº[8\…—nV€»_°B„á6Îï…awðõ@†x’}]]‚ßCðû^‡ë½gÁí61GæA#6Õ'&¼ eþ‘ÁÀ†!È›Žƒ!¼b’x>1_s¡ŠT1åöså¶Ÿ<ØæÓ±jÉûl€ˆ˜òÑ-˜•Õ ìÆ:ìĉ˜<ÜTž^ê¶Ù¸q#Ö€ïJãëk…A”V[¬Hκ¾XÓ|­¬¬ÐõÁƒˆWWWìÕ«WÍÒÉéƒ8 -€Bìüù󭦃Ï0_’>¸ámk鬶Ôa[ên |_ Xm¸£™Õf´Áj£l˜ð˱}<¸³/iûMl?,â`!`\ (hM¢Yôá}w"µ8Öz^Z`…÷g1>›l ˆ¶?]©Xk4¨P4´·ýùÓ깃\Ç‘ Œ¡(GB^å÷$6¼þžÄȬ¿'±²êïIÌÓf>x„P:®‡ÀÒaÔÇ;#K…Y—{cÉxL X:аhѰhаðiXø°ýd°`½Ç«³YPó¸h³w8 P@pfµ7‹Ü ö˜bµükWùId_’Ü$"‡Áôpe ¬ñæñë0åj¸—÷<(YÀƒõm¦r¢šl¯É–úh Õ©6±Ž¿¿%[+¸µ<ÄÃHbäi¹³x˜:EÍ%åúÞ)v…ÍÃT«=ÑÝ®ú †ä t { O|Äpñ!…2ø%2!•EÀï‘÷ò ÷úÔ[‡Q¿L“—!ä î†,çŒIq¶p?ä•sæYÀTnOX'Œ×”'ø2Nñ´ÁIžOãZåI.#Y’ªzˆ¼%Á>D üJÕÓ_*—„…Êüå7b_yJ¡k½TQ~*ˆg¢8«^:¤÷ë–K‡ÕŠtdÙí“Ît^cºB ¿©t Žs¤t"8)²ÔÂ-­ÁXÛÃÓ¢“N…pÛÃO´A«n2.'žÝ ñ)å»9í$ž“§ÖœxX)ñùˆøÁÞ ñ:õ$C¤ŒFän•|…Ö4³Ýäü<­æäCô\œÀÛI>Þˆü¢FäÄȇB=““?»Ì wcÕ®å Ã]’îctÝ/ò¿'Xè#ùÁLÈ(¿]Ð=bz¢áò&eD@BshµHÓ¨®ea?‹Ã%Mc»¹i„rüMšÐñ,šiä6˜Æ4>q(Áíî•«‡` Åä3g“â4.,UÀ­¼°8à)YXdG›ì`Ê îœcXKfR ŸÇ„÷;ºk¥à`{JÇtdœIÙ‚Zšm=Œ*“Û†d· £ÙËVØÍü°¯øˆßœ]ˆˆƒ…!=†à­° 'q(v a¬)ßÚÌpF3à Õ.•#=’a¸q;è1\Š]‡>¼ŒC¡4f48_Pjɲ{@4ëÕš^Ìgÿš “”ðÝj'U[²g 8)èÿ?š*ø× õæ’’×% /h‡äòê7Ÿ‡¤ükR+Іµ1F§%3ªHIíjãç6+'ì1Ë™æ´Â´ÿŠiX'›3 !ÿÔÉ¢6³ Ù«o[`ÐjÛ[•õ¨…ùõ¶¥’ ÿÒA>œ–w©½ÄÃiØÖ ²­±aNµ5W\…lk’°ºá ò¯d`[€ÑÚ•†¶þeLý88_ þ5‹2úo'–#d\%úû F“‚†Ë Ê ¡ !eòθî®Y:®¤ëႲ¼Ö7“» ö¥Mçcêü<¸Æ{ †…o/ÿâ}9âáÇššƒÑ§|¦|x°ç]úBÍ¢A»r?®Ö|ü(÷ÅÂOÁÕwòÔî›;ž ;uaã é#çb•õ7òZw¼ï“??>^¬ï‘ÿ5 뜋ÆV…µüÍn×}îïßb ÚÅ_ŧ“^Yõσ^ÇzMy»ázBqFmIÆÇŠÊÓ£¿Tœ~X9¥lKÕ°hYÕ¥×ߎ½%.ýL©ßþÕ|_—MU3SÓþ/ÿüëñÇÞi ÿ5Q#]¶z†7ñ5Û­ÈgÅb9–uvüر˜~v„ÒKL†ßÁîàw¹ŒLì5ã÷U¬s’zˆÙ#ûó=ôB2®ü›“§\¤ò’È0À¦0¾ÅYV©eÚ1ÎbºølæÚ˜åëOU\x'øítÇ”‹8°òM%«s³ŸôÞÝÇÌ»cfÿÙ‡óµL:Ø|Úö¹j~—s¹oÆ,);öø†Må÷‹«»Øÿ)+Zm|Oe´çN¸ËÝÂ…S¿òOÑØ3¼<ßÓqB| qòPÉgg·²ƒáwŠˆÒÁÙω8‹ÙN—ÞŸNÜû-ó¸‡fYznIÆçºÙ¼­›¯d_œh>àÕIN'뫚üÔiý?\ÿγúʼnÚò7 ¢L¶mKâù\}áW°ßå±x„"G«¿æŠšn‘ݯGGÜz!9ÀõdŸŒ:²/Ä÷ñÇCß'Ü(fÔ<é–¬cˆ{YðrŽ|™ºxüîÚÛ>qÂ]¡IîFE#÷˜g?Ó¿ò3·+µ±Œ1(ø ¹¯ãÝ›‹§ö\àê´°çgë6{ÔnöÌ)N¨°Û•¶ü÷;»Tº¾:Ð{ùƒGRKgŸº$7Ü"gú¸;žÕçâTËçŠÊ¦—ÎåØÅ¼½ê(ìš–¿½ß‚zÓ×>|Q¤²ißÀ„{3“î%G}LÞtfÄŒc?zå2¯3ÓöŠfØXZñpu¡â •Îغ£4¬ËÐïŠiŠ÷„.]›8اàðû·:6%¤©÷¼ß/sÕîÒ“ú%VÆ·»—zw÷Ë>vó¥ëKmfúŒ$£Ñ)ËþØq;Í܉ǯ;§ÃŒÖ|T…McÛó>õ¤&+?E;½ys¦gÙâp³«ŸOfL<úlÙû33&Nº¤ý:ìòÖÄ¢ Ÿz ýïú[&­LÛÕ{ò´±ÛÂßWŸ=˜—]5£Ëó§sn¥GGóªçjžãæ© {ÕÃ#u@Z¯¥ûs‚±§Lú·§fmö„ˆðSÖ2í%—/eï?¿åhÊ ÝÖÙÅBÓäÍZz}ò'Ý6½µßm‘åãɉ›. ÞTtñ"þE[ÕtóžË«k_^Ÿœâãøj¿Îs¯â²}E“ÊŸÇ~]>ÔÁæt䥀ӑ‡Þh½69Ÿ­î1µçÛ‚Ô>†Õ¿í`¦<òŸœ`©¼]çzì¸Kˇÿöîªvñø™A–V{Ù•YJ’HÑF²E(JRRö}ß*Zо—¥´YB¥DˆÚD+Ñ‚d˾ÓÂÿ{F^Õ-îÿÞûÞûþîùý>Wï|ç<çœçyÎsfæÌ<³\Œ½WjûÏ„È{Á‘«Ô ŒF®Z\àxº:þoÜÒ‚{µ‚F5^“3OIÖ®ª¿#°VçZš¸a|ȲçÁ˘2œhÿþÎ?8R÷™ ƒŠÁ³6‰ã³$¼â“W+Î|b¶.ˆQÅAÛ{ ·•?o~ûÄÉ â“3C’GZ 9òè)δ~ÖÆåãž%^3k©÷™SêË>2ð‰¾KZþàÞ,>µÒ¢¹xªÆ‰QKŠ9}ÀÚÑpEwÌö}—žLyž;F!)ÄÚ‘)N:þ€ª9S\¹áòŽ$ÕYW$ã„xãâÎ§ÜØd}ÊÂu‡µõ)ëQ×ÒÂNëí×·ÑÖ<-©Ù shëbÍý'm5<š¨éü”ûÓ™õ†+^×ìÕ9Ú»)®foÊ ;I͈ù»OÈw9º5ù‚ç µ—Íûª:6…í²æ´U)BÝIU""gºŽ7W1g([í(”­-£ÊáÈ^&Jñ9[§6³íD©”t¥^óºó µƒOêÄ.Ô;ÈÜb›`YÄ‚­8»H¯×znŸÀƯ©EKOïWó’sÿUGŽÜ‡¢SÅQwÚlœr…Þ[Ƹ¹¸C?rþŽËü¡òó#ä‡ïù|¶\¯M#1]¬¨/AYBíÁëYfÇ[XSú˜q W(וEQÓï.•–Ú4;<õB‹ï蘷úg—Mß¼³aE\õ®èQ£œ”ö2•:ÒòðPÛ†ãQ|:Ë´¿?jé¯'µÐ¨³šÂî;ާj¡ð÷Ñ_“ÖvO Êl0;1O¡'F(qáˆö% Kd?OýØu)¹¼OduÉÚÞ›YÞÝ 1Er%Ïôm˜nî®û:¾ht‰¾òv¡ëiùyÍ-˳Ÿ+¦_nôͲRóuÓÜÖAå//¥ZñI–Þ’ß½hY¾gBÄŒêô(ÎøÍ7¾ôΦ^>0þsaÀÊ䦵r¶>s®HÍYO4Ýô²çšæ±ãèȺ'T¹Œ ¢u }TÕ£_ˆÚ`Ös&Vi^Ê9]{y=ÞŒœn²Ê~ŸM°}±ü–O›‹^ͨô-8¼k7óîìZ£î¿rÙjv[ƒ‚V ì¢ÍsœxuÏwH¹$syá£ÒZ~—œÙÂtÊ”°¥Õ©4,Lpå(sÓ²°0óº«'¬rXö¬UÎñû‚)D‘TõñÔ7ѬšJk5X5Ç>pªºaY¿>Aý‚Õs¯ÏŽŸ‚üÄ”O>¼$ü®õÙ.+ñ§÷Þª§Ï:iöNôغqrÇÙ³2Ý«÷xÇ…Ýxæþ5³^vnû¡2ùZ›ûDyáÆÈÓ…‘Oï0lÛÖiîînï-‘œôðBCm˜Šw·ß*w>Žù»m”Í·ª»5Þßàá]7¦M‘µÞ=Ûç•Ö‹Ê«±™ëVLXq>¢Ö ½×ïëÆÌÓ=ãY=ž}ÜßófµB”ÿ;áÍ×ÜrÇò_K¤ï{œÿ*8vÅ-™úÇ¿hŷƆU¶(˜]R×µd‹=ØYn+jx,c½{WvMùÝ¡ñÕfíf²2'sVMái\žÂààt—5…Ùø@C® Gª_ Îj§C;'¦8ím»`91ò}«D®‚S\„guZ—†Ö¨¦‰kÙ]!ól±¿ÚL¶Mê*áG§V_{gÆûznœëü»ç–¥ž qms©m©­x^±ZÁ«Æ@Ô¦ òÊÁ´õõ®Ÿ¹?kصBÔráÙ¶Šà¯#t´Äëo=>ÙÐr|ù4óUìñãõ¬’w'³WÛ5ÒÐÏ_ qÅo†çÓÌÕR•zLÙ«ù ×ËdJS²âFîå6ånHœ*vdƒ©ÓâÐ×{TÄg¬hz ½þYF¼Ö ÎÕ'‚ÒWî¯Zô©ª]Ë]&âÑB‰WÉù*.#œêNu58ÎúÙSFÙÆEújµ~Åìó#{n²’Ý»^ßD%¼MÑ!mŸé…¼ø‡çÎL}™zÈ",b›g Í‘3jË%V-ßS3{â¶d]«(¾€èžÏוºøŽÍŒòì®ÿÊ6åÞSNÏ3ÇtL—Õ=Þm»¿cóuo¶%±gùUd÷ò†º®š¡xî~@í{Kå°±žc½:W<.ß[Ø vøqùyeá£òÁÁ§ì’(·ƒ¹G:5_9sÔAPpž¢ïñK§Ç'¨Œßm:#D6הщ·‘Ÿ²»8¦OªÂ\¥:ÐQíeè±È¼³SÆd u¯hZ²zM ÿ›×D¹¥õ9¾yq‡­_‰ØtÇðè[§JMº(’ÄØÀ>ëPÑ ¶MíÒ3­_—x>¦Çm¨‘Äp­~uŠ`zf©aLŽØµ¦Û.†U¹Å{ ª8c}Ï_¸4¦}ççˆæªI;‹ÊÖóŒ;7²Ì+}óŤ~Ü|%ójkR /̯U®é O»í®>û«æ£,Û8ç7ù¦:©nš’4ÃÄßÏœñè‰Ú´9E{ëßef& 'ìeødéÀ¶Ô )åp­teÉý¤fOJûÊJ‹­öêV&lSOUx9åÍñú䜩|Ú{ ªÏ¼°Á/ºê™Fȶ32ïŒíV3ð?O{*g¦¤(Ô&‘±z?ß²‚>Î*BÏÚÜb7æ­Ú½9÷óf“ŽM¹kM^NÒ*{1ë~3‹×Нû|ßœl}ÃBbâ2¯'ÇŒ~uáæÇmyïøv}5òy:žU^ü²ô­»µN íŠ`‰á¨«°[½ÃºE=éjÒÒúY÷…´ªÙnéT+§Žš$îôìÞ=ÎÚÍÌ×ïÖõdšÈ=Ú•t´ELJ¾|ÅH»PGm «€¬Ç÷´‚^ûÝH‘x™µv¬€±·GòÅÊTCõÚοÎû Ùc²ç)¯¯{h·A×ʼ1»óýÊů½åuÙÃb•~Ígv‰ŸâšK; Ž¿Øp‚NÍûMvKwÏ ÞXãÌSwÛäéeŸ;*F;û®™pyν ºØª•¬ +ç#,Pò:FåÀ#ž+ÅÇ}WÉÞèâµ[ñ|q©WH3÷Ë%ö“Çñí?œàsqVDƬ ä8SÓ9IÛN_û²ôÒåË}š5§ÔǾœÙyrµÏŒ̠ç‡:Åù"¿îIÓS1b~Yù¹ŠÂ7V^Ë­Çßq®CÍô5eÒ2E.a'/¦ömN~m?önºa!¯±Éüd3¹)™‡ý–§M*JÌuÙÕÙÑÜÉž˜iÝ¥%u#âë$«£SV]ÖÔi=ì²ùžUϼ¹œis7/>¥ðša÷ýJÿºâ'˪6™[¦}1©Ò¯\ h(ógÊIÉ0]m+ñ·]zÑû–®n4Nk:%•ôºèÓ {ŽpþÛn’ovö׎Ê× •–hô5jXw÷ü7’ÅÜ·xó½y¹©HXºbÙÅ,O|01÷µO,HI³yøWºÛ5›s|·ôGÛX޾|*ëÆöX!#,«¿¬™O³®Uén“åÛ][š”ź=££¦Ô$I²Øýýíã†ú‚»®ù=¼ö®k–á§CA~'µ—–÷7>bzN(£È49È #б~Úù{αobŸdR]”SyrSͯ&yŠgv¬¯3¯{~^Ño¥ƒƒÊ:&“µr])/ÖK/’¹ö5Èàõüðùûž«ñßÝñÁ~rÆP?×Ë_ÇêÙ¨e¿týܹ<‡T©™‘‡¦6¼èâéÚZ‘s=×ûëå+Ÿr¼:ÚYvŒ Û{¡ÍkŽß“›¹LpJ›mcœ'âsöÜE]Þš…ü~Sêö•V9Å0[ôõ£ûŽOîI^‹Ž‘^°ãaשH寧Åû.¼þ|öi•ÊÙ #µÐ1ì[=_­åw* Í¥”fñ9‹3‹ý´q©¿¶¸¿pUnV9ç—— ½ñsR|£f7Úì«Ð X¡î»—ïzÑ£>½¾ q=ÙæÚ¾,pÒ xòß?~ÆžÒõí+l2ªN*ôÚ¼hZ”;aƒ7C‹µÃ%\þ&w÷–óm}%Ý!Ñ3¬ü^v_½f²Ç.µªiÁ,µö™£7åˆ÷mmŠ¢ìvúÞg¶ÖÇüVWxß'ÃGН¤;SäsR½nu]«Z2Ç?£ÇLØfU³Ê» ï=Aù—’5ºy“ý÷p„7‹ß^;¿Âsa÷*É/W ¸hoú´F²Ñ¿½”û±ŸIŽÊëÖ˜¦íUCÎq+‰ŠñÙp›Ÿå°{·Ÿ¡KåÒ¥k¾šé*vø|Ý?ÆaÎî©i¡ÛV¬—Zä·Í–¥h‰;k™É›¢ÛM¢y"2Þï·|wO&›ûN[çên×J³DÒlï2·5«QŸ1÷,©Ëp èÞ°x~÷4ß}ª«ÞyŸnyÜ|4¾ûb§ÚMYÖ´È‚JÍÔ¸Y[›YÄ»7\Ìψ[û$9O+#ÃøŠtt«¨Q^qÞÛGžÇ•Ï ^ ¥ï™X?’¡Ô˜÷ó«ä|^ÛÖócDûD¯nH›•“r¿áaWÛÞoÕŽ„ÐRo爫»úïÍŽ=t_ý‘Gu»LtŠÕ#[kï\¡{­J'—Z±©H´îdþpÔã²_ÙM¯¤Õ‹#”lœ¬­RÜùN¼Ðù…í"ƒ$ûô«›×?RÏ;<Ë-4ïœ÷£ Ÿi™–]‘^±aœ§Yƒ fmIy;ƱzÎû׬^ µ9®Lp˜´×±nÚG~í·á)ÌÉÇ©òëêj¾¼]ÛBÿ)[@ˆ£Uj× M«uÆšVëﮚP-¿p}ø¼•¹±+8ò/–½H9sÑõ¥ËØí“nr¨˜> í>_˜œ\[|ÙU&J¯èÃx?†‡Å{rK8Âbì–¶Þ`-2|Ê3ç1×ü°â6ùÊ'K#¼Xïœ)V(ÍËzù=+§“~ìÑ(UµÝ-J¹u2ùÓÊ- …)ëºN_"u¹ælX ÿƒ•©Õ‡Bo´~\sx±Ï°e—•—¤v²É$éTŸßuåÁ±ó5Í•¶Z´ÎåXútNZE¸–uØÉ^£[Ú™6wçˆI^Òa¥×ï\›«r¯äðÜLêÆ¦¯€Ô7ÏÛÒ½½{£/môŸéËu®$ÏôNcddÀâÒö œFÛUç1 wäP¼yn³ä\Ápë}ÊvÜŽZû Lï­@z\åÍØ¬ú‘w¢êB¥ç³©¾¹ùÅ„ªÇÍ“¥¯S¾Ú:êùd—ØÂíŽq׿ˆ|TÅÖ¹ßÕßÿü>]ÍP“¥“Žæî¸tÁ=ÂçÕVÞêê(«;ÅÙ¯B£zùÒ—~¹ŸÙá´…cÊÑ-óÇ>¶­ß~™ŸíäÈ“ñ>íã¿'s½jÅ%ãøü…åQyúä¯IæL¬èªž¼8䥕O\…{ð‚¼•sÎ ?w翽ͣYwñø:uÁI­~纅O¾­x~jáè,Ó/’i‰žœï‹L'|žü±‰Ïeæ»,.'÷ÕBáîʆÛ6½Qñ¶ë½)V§"¼Vbí?S]]‡›uÒ«)X›'áìÚíöNWýMÿÓI½¢A}ž/ƒ“®<ì!}³qQƈZƒ;Tû®Þ.°Þfõ<’A?ª*Ïeþ•Þ–{W5ýømÙûôRÇIô ¾mR²îmYT.­|Ê!kòŽçeaîS7<©ËÒ~¿T*tÙ‚7‹mwIM_áõṑ®ù‘ˆÃ\n’÷Æ,Ôoo×^öµ•‹-vÚ#½œêýûU‡èÝoPNZSáŸàß(åÌ5U¢o»ÛËyÒ›Ò^$Wn™­0wÁ=ûÖÓû>‹Æî›+;1_"MhФe¬ÓÙ{NñMÙ~=x«°µ}™è4ýG«“BdXó¼9mYt;åbŠoñxÿÉÕ\ÎkU‚ßðH‡W~ŒHÖ»~…ÙP_+ÝzÊŽöOv;ó·—jg×/Šz[Ë ­q‚Òþ@~ÔN„²<Û$[){NàøS#/QÌò;BdO¨še+d»gËdŠ•qd›e LbÛKI¤„Qrµ[²,’3†«·Õ4³öüªû¸Î°R‰ÿÈèÜ2ÑTö±}EEñRvî;'L Ò?EõŽ©Xè)Ùÿ†­Òô§bÑ‹?.ä?µæã]¥Ø‘g™ùÏ Ý¥T3È®Ë"ºK;ÅÅ⦆ù{X»†±JîZÔ`¼Éu¼ ¶)×níùö’·­.f]œ¾xłВkSb‚—«¥‹,±žÐÈ1Ê„›qtÐê¥A<7•J?7†Éªïß,zs¦@cO×Û‘]™Ÿ=«ßÍ™M-Üêf.?už³Ao•_×”óò—±Rê¨íxŸöÕe·NlÚvLPö½ùÁ™'Ží”MÜ–iÎç;ªs[R¶š#SnèasÃõ ›)ŠÄžO¹ÇeËŒ•ßi}Ê wvä_Épå­9g*s=a`ÎWÏÌ|K´yV7Ej]ß}Ý"7JÅ}×xX(ì«óÞñFàƒíÞĤCGóšn—.<•§·9°#FŽsúy¿ØOæµÂA}ò3F7õôq0dÝ µ¿~sÇÆkí}ŸØâ†‡­°Zân—¤9{Ëɦ¹lö”ëy.Xç”2v1P[[{ªÆ§u8ú¶6§5?O y17àÞM©ÙaWV\ŒvzðYÌ…MW£Š¯;·¼˜9%®Âkÿu±6µõbÛˆN:¿×&ìÕÆ+%¢lﳕ¨MŠ—+Ù}ìY¤œ…ø#í‹á—ãî÷™§[œíÕ}d©ËÎΘÞöþ"›°[sCDÜ<öœÞÆV縬û4W Bñzù>—ž÷µ‰5«¦,Î÷µLkqàÊ›È f]ÒOÕÏ8ÌÐç•n0Ã<£»ûžÛ×ËÎïН‹Í/žÊżà´ù'Zƒ±-\wdÛ$»[EÖ§{ãëK/ï[fΖpºE¶hþÑÞ;s¶”Ͼã÷ttù;ì¬Î¼ee'%ŽÛ} Fáâ¹f¶i…Ö2û7©fp„¥bOwÛìÞqviû‘yL·\›T¨çÊÜiá­MɼZ$½öšPáñ=S8?- mš`¦Ÿ¥°áú¾Ósî<¼äp/ÞÐÝ BóuMg[lbþ›s.J¼gJ66^êhJÙ¼'ùüK§³ÒÅNe+MåŠ>2.x'ùoÖ³’f=^¡ëvÝÞ¼ˆ/+ŽžU´` ÎRèµçþns¬%{3ÄÏšÆZEÞ4ün·'†FMÌòùBμýKÕ£]ö‘K ¼1wA„’¿At|û¨+AlãîÿÔÛëéý×¢?(÷_~cú›oFüÿý¢"AýöyÊþÛoWôÝüLŸÆ·ë´3ˆ(×âþ à1ícä´Öû{×ï†u±ê߀Áï?Ò>-O^Åþ{ׯJ |&ÿ_Rÿÿß¿éʺ?¾ÿßä¼8RhŸÍd¤ô_tEùö{¾”þ9T(ý•£ôÿ~ËJÿ%Ýï§E×^Úe½³¥¥½ˆÁ&þûɃKSFD]FÄh½È"/Kq5‡õ›É)5im¶Feð›_äß¶$~ów7 m[ÉÛïþ ë?€É}ùyörû:¸9o¶t&ï¥mû"ËëÜl]EYºl¶²§ý4È?o!²Èa½9é$ñ‹Ÿ¤5Ž }«EèÛ,q°wu!Üamƒ©ß¢q´‘+YaiçHþÈÁ;<ðÃ4‹í,,73&èj‘å:»[:»üð ²¾[÷`øß^³«.(ØØ-æ¥wÇ”Ó Áx§Ë“;“{Äçëí&|8ùêÔßMkÏdÎ)ëÉ¢ µxps=ªîŠLkúrºT­§ãvé˜ýVµ"jFïn?ª!­pÏÑ—#¬3ÂN„—„óy¼R ²d©õÊ"w=(“Žßò/™WÛÙ^äxõ¥µÐ.W«Ök¡¶'…“ÔÏ$Üøp刾ã¼33Fw·åÈ®ÙÀ·og}cˆcܧ4¡Õ隇m™Oä[JNN–wX׺ºéÖ¡èTvoµ÷+Ù¶ï² [èé{Šw¹akÔ|Ó£i{—éåOWñÙÕâ&7©i¥Ðój?ÿ´=Kî—»Zè:Õ‡çs_¾¾ÎxÿöZÿvKÙ“‚[ýÆDeÚ46ÈÝcòÄÚã»,»Jò‹×™­MÓG‡O{ßžà£Ç*È`ã4*qùÔUí£Tõ¶…ªn¬Qaz²|jWôãVÑ]ΗïqÔ4TÃAƒùœRÑ=‰"ÆÝ2o÷X}™ã¹Úã ¤ù^‰n ßåf{XÓËVú#OФ÷Ó¼:­[wý9#åxt„%L>­›kpÅuš±ä{öŒÍU ,=%Æä%4òŒâ«¼©«MË%Æt‰ñ혜{*’újÌÔLÇœÓê\ã{+®*h”^2 /²Ø4)§d™¨S‰wøB‹æ¼’É^¥Š_’».ªÜ™̱¥°âБ©ç®½\µÞA=#ÚUøô³É—æ¨ÝØX|ÿC•ËI~Îö’åÎç®ê=¼Ú‰b\ZqѾvü¢‡.‘)Õ^â,ºkŠC*ŪõÆf¾ÔºßÚqµ‹&³_Èèl5‘=:ó lµìvŽöù{ÄË>žÓ]þ¡^¸òÀîç™®ùïÍkWên™kºXÍBâ*Sâ&íÖc½÷ƒÂææÇ:My\¡°yc¬<«mºÈã‹NOî}¸$‡ñÜÝíöU­êŽ7ÏZïŽqí°à)0ÖdÒº6îhGÞ”Q´ÌøÎz«¾Ê®²þ™¦ÞÊC.â³ÏoÞ¦Öþâ,_µ~Ø­Äù,ú»Ùø¸*X~eñŸ-ç™ÕéÿØ/áxÒù9¾*ÚÍÛçŽõ–N{weUŸBcÝæGÝÞ|]¥B=ÏoJ4­oõ¼ÓègYZ6#ªÔ¸4ó«o‚ïአ<å&‹¤¨[‚C§_³i,”®­­]“gÑ™ýQ+ûcÝö+‚F îžlw2…{™O¥&/mz5u¥®„È¥S5³>ð„,qŸò*JT+W00^øáô/ Y¦KN(gÕõ í4%;>iï¥øû…»×Mz¥þѺyžq…]Þ”ÖBmõ—>ݱgk»·ù!»i­3ª|ÖdóT¼2S§8ÉJùÎ5˜~ðÆ*­Sn{õ²F[¯KMÚv!ÒPQäXb×ê/´Ö3ŒÙ=VQ¾÷Ø{ÛU/[T "zo(U~”kŸwÒŽZ]0-Z@]¢š1E§ìËž J=ûŸ©Ñ—¿8´©!yýú3 ïdû <œ¥-¾Y.þ­Bæä„5/G>»Ÿ™üe®áþ›Ú‡æQëxü²íbE󌖗ܗ2t.dŸ”¯>òµ‘¾ÀÔ\^jÏz‘Îîj»ž ‹÷¦â3M³[ÅWå|]]P´fùã©6ò[R$šÎ˜L;ÑÂà<ãØx­ޱÖã?ð¯]gϪ°ô׺=Úï&ÝQPéXw0ïå¸ûõ5êU æx6éXœÜVð`qÀ4弓y‰]zúþ‚Ã=)½"‘ò’­®sžáYñ¥±¢—̶ð)Ì_µ~žqÞe..·yüÎ<3"gsÌ\*UwÐñxÎN ¶®—cveßÙuzÜÙ‹e}¿˜zÎ)åë_b6­¼4o°°(­Àº[ê»9ã«zdÔû>šÏTð ±½iíÍ Ûnµ'LÑTXÐ#>ýܺ5!Óœ¼¢®t©f×p«1h\#i/^çá–6§£Ìí¡qÇb˜Å&v}è4n¸?á”çŠê}é°å™«¥÷zÎIîP·‹«»ºUém^á²YuÎˬ¦n½ÆÑ3eúþ¾Í*Æb:ÌKYJs“йgª.º1} ÿéâÒÓ·…„›”7oÚði^ãá'öMâ¥ñÎ×%?-Z4?îÆÆ&í›möíÞO=*S½uÞÅöšÝŒyÕæä6ÚÅßÏvÉå‹r!k_>ß«çÿprN页ԵzºÆÆÚœë–ÌîUÕ¶¾¦9¼P)gFíÙíN(‡4æ,û! ~NO’ÍyO~ù¼…gBûg¹…´Úô–>œ²FÿKâΆðÕ…þ’ËL§åŒoÙ{{º_`ûf^“Ë—b>ñOmœ:ïuçY¾a”·É'0+Ϲ©ãÁµCiOÜü&Çe-¡‚ºq1m1Ÿ,î•Hô2,Rì L˜š:ûp¡„ÿ´c“Î׳ò%zöšÏ7~Øÿtɧàtn‡»û§ØrìzÞÂ"%ÕšœvªºU‘⻉+!HÇ·Œµ×.b±:ç ~áN•‹fÆoþXÞø™!ÆEÇéL¬‡{ÀÔéOzR¯Ü8o_•°¨ïXvâÙ€7¾ó_O]wBÕRy´JRÙžg4WÝ]j²M?ìLŒ¿tV•ÎöÛÖ‚ÂUÝ·­Õ2šNgû¼;ä8פbÖ•~œ·kG{d0Þ™(+¡¤°¥CÙ³üµVƒÁx³‰¦cæ„õS×Ò_ꬽóeþ¾KÉÛÚÃØõ¦ž™åp¦c‰æ´-9|æ=pÑþP3rdÜýUãô÷\4èo3:ñAtDÊò­ëyœô¼.,ðXøÖÝc?xLÝjñå.û~‹[ŽúýÊÖÛÓÇÏJXlééÄø9»û«ÜÕð Æ×ÜÝt ¶¾UŽ g)VÉ47Е]ÙÖ~ã°ñ—'ñ¦^Ó_¼y>2ñãI¡1ªX²­n©û½`ÊébâY˜V½,„wëÞ ›£3y¶¦›žOí‘Yߥ½-Åmí>×›ÜW¯Û¾Ù|W°*àôIeå©~‚磮s$ŒÞ²«pcÒrC©Œ¢éG[ϱiòª´ ~Ó}BLóLfšø†3—úw)gØï*­ûÁqí‘Î’Ç:ÍÞbµ'Úٟ˱Õ<©ömóˆ¯IzïÙS/gQás2|6o@g[mÐ|Ùà>áÃa/cÈo$/þõÂз'>zõÜÈgÛJÄËbi_ý&_aŠ9c‚mÖrÞr[Úœ ®´×¿6xU¼¯n­À¯tmi3#\O›i Ê~*[‡èŸ5a3K–¡ôO¯á)ñ'Vù‚Úƒö2Ć6Ã~˜%ß.Ù„G¸ŽØIrª§¿§Ù!·òÛvêt‚/!Éù{ÉÛà¿è7úíßqSÅÿ·ôQñwpž 8BÞù²%úßJO,ÔO¬Õ 0®Ã_; VFp‚¢J~ÛÑä»X ëhŠ=Ú< ¼èï#Ä(lâÄÈ%LçÙf‚ëì\BUœ|·kË–…š"Ä2 b5Ë3M*±ÿiDPie Y¶­ljÙ”Á²=Q6ù­I”2× +@މ ´rõ‡,w&­\†þr©?–K~1²¿ÜþBùPãßQ¦<­LÆþ2~¬†þ2b Q.¹¡+&Z™+†,“œEŽ‹`"ØÄ,‘‹,O,’è¯rKuˆ´Ru†,UVê”Êôc©Lß¶’§+yÐw˜iå©YÞlZyÌ(oÄå ˆ% ­„%C– H+%0ÿXóB¶w+Ö¿£¾æÐÊaE9,?–ÃÂE»¥‹]ý-˃s“šjkßiüõÇ{~ä½–ÄF”ëF;Šz´wŽ×a äÿ:âÔ!‚ýq ½·LÞŒˆÍªm}Éd_þ£”Qß½ /òÓQ'B($x;B¾pAaøƒ-±Ž¼›J{ßs*a£ÚÞw‹üæÕå2ÓÊ!´°Ï.´õS¿Õˆ±5ÔŠ¿ß×РàdÁœ Š kÜ BÕ£¼ÇKÙP/ŒVÀáƒÇÂ$-ð„ýpä}±üp쀬o¸!þ(R¡ dbh‚>¬kا žÃ ¨©@dðAi öÂ!ˆ‚X¼õ #q2Ô]ÐS8W¡ dp¢4„­Àƒ¦,†•à©ðÞ@|nœTWïÄèJ!(Œà<€rø£CÑŸ`(ƒ9x@Â[˜†m‚`¸¸g ȃø=8ÃìÃq³í~çéC¨op«#8îÁaì…;P õÀpÏe&ƒhƒØÂ8 gáäA3pC¿…åàî÷à0Gß}X¥'p^?‰rÂQ§ O¡OÁ¦Óh§h—PGÏ _ñq퇳æEÇ ø ס:u“„>2x²ý2Æg࿊ ìSÂ?• ¼Òpœd 2Ѳpv½…ú„,¿çE°ôŽ7°€ Wá1èÊ]œG@LÀ,¡2g'Í%ˆÙ wûôýfÀîGØn¸ o¡ FçáxcØÇ!îÃx_£<<›X€gOÐîÏPO`;àÄC"dB6Àxä´“ÂÏqž‚°2 ˜_à|Ë!.B10½Äq‚…è?` vp n@1”µ^àƒÉ sA ÁöÂaˆ€»°«Ç*Á¾¾Æ>¼E_y‡~WŽûAñ=Æ$Ø\ãÜ?`[ñäùHúW5λà]C½P‹~ýçI°¯C€W=Η ߈6‹&ôÑfôÉÛm'al;¶ Â:b^'¶@-LíÆ± ·{ÐÇ?ÄÂÏ8W}!Và10úŠ}ï%È7¿ 0Ãb¸%}ä³Ô'ž¥'R)„ #þÂSòã§LBtÀbà%PGPˆ% ç˜)„^-Žc£9  :’Bá¥Ç‹±¢äÇáq` a¹Pœì‚æÀZƒ|¨! aká$'…‡s0†‹BÈ€$ClåÆc  *y(Ä ¸‚çB((Ä Ðƒx,‚ÂŽ@1° a]pF Sq°) ! 3! r¡ ´D)„/ÄÿDì'xƒøÂ°˜D!R&SˆóâØox½À;¯²!^ÂÒ©Â\áøJP?Øâ’bö4 ¡(M!VÊb3PßðÊ ¾‹…[ˆb™I!6ÂøjòÂÎÁk7‹B°Ãq qb@o6…TÄöB”@70ÏA{.ÂK­„:†3PÜÊ‚´ç¢ÁuÚj€>¶¶ãÕæ,5 ±iÚ"Rˆ(H…&ZD!œà ˆ-¦‹`;dÀ °QGýi ŸÂë¥Â~…=¹À¢…Ç€,ÌuX Nïà#ùm´¸ÀYx\:b1xÂx ºb:l€cPT= 14À "á&¼ƒ^^N!À‚3ð^À. a`H!V€-„Qˆx[±’BHšPˆS¥0Æ”B(ì…X¼Ǩ¶q-…H3§×a×£Ÿ[¢ Á~…Hߌ²­)„8ÁA¸ )ðÚAÜýÎà xL¶Øvƒ¹  pîÂX; 1 fƒ1¬oðƒ;P]ð¤ì± p.@%Ô‚˜…XË!á ¼÷°É‘B4@ ˆ:Qe°…ýp®A9(8S7ˆ‚,¨†±.Ø6XëÝѰ ¡8=pLƒ ì…$(&O¬dÀ6‚ \†&`ð¸[à0\ƒëÀàòÀ<` <‚‰>hgH‡¾b*H‚ xùcÌ Àã¶`?¶á˜vàBÿ€ƒ= Œ1¼Áp;ÆXð„Ø8àÚNô=Ú…m&…QˆKðt7…`܃ÇÁðØ‹ã’ö¡= ~?úö7Q{u ã`b;ÀŽÃS{ ÷Ãf8•ÀyœB,„ '±í iPŽñ)‚BìŒÄ8…Ð QèW` » ò¡¸N¡|°€PH‡WÐì§1Ã`ŒF[/0žÅvŸ£8zV ‡t¸ ã.Pˆ) ±Xwê rà9´%Pˆ‘I86.ᘀjh€i—)Ä*p„8á÷ ¾ÂÌ+§ÁÌ`-Bt\Å9'Û˜J!D€óŽk8¹P ½ œŽqöÂ}Xžö"ã+C,¸‰ñÊ@2 ã-ŒÉFÁð‡@8' Rà&BðßBßW8 /  ¦ÝF_up8¹ÐSî =p‡k À|c¸€7l ðËÁ1“K!äîaü}€í|„>Eà˜‡10ç¨l;|É'ØFè–§hçghS†)0–Â*°ØÇá"\ƒ|¨¦ç(, r  ¦¾@ ¾Ï€ó%êÔÀŽÁS(ƒ&h…[…Š0^ÃÂW‹Ñ ±ûÓ^SMЂ`6à¡°âá ¤ÀC(wÐcß`_AÌa d@%ôÁÜ·86á4Ü<è€Iï°O‡ Ê€«ÈÁ,PP)ÃøÅð*`r9ê¶½GÛA"|À¹¸cOÚ¶õé 9ðú`D žO7ˆ€$È‚Ìàøˆ¶€-pî˜]‡c¶Bd€s=Ö;áLÎÕ c±Þ&Œ;-hwØ·ZQ·mØw8qB(£õÙ…ý¸n÷°»cdÀŽO?ã8ûŠú‚rèÿ^<¿€#g!®À x ÕÀÔ‡ñæƒ삳p!C't A%ÀÒ  šÉë*aëà(ƒx €…J%XA ¶Â6ƒk7!zAžJ¸A6äÃ[(ƒrðg¤fLT¢u2f*Q¯@›…Jx‚7C$œ‡WÀÇŠtà(d@LbÃv@ÄB|®‘Tb#X#ƒ»¡”FQ 0S(M%Z  ˜ÇP A˜2àGàŒ‹õÁÕqØv*±ŽÀm,É2A À^AôÂ,.*a)P•PÓ¸©Ä2ð…{ðdy¨Ät°„8 x© À ¼ Ši<!r îÛ*1‚ öÀ5(‡Zàã£F`^à ~à!Гø©ÄdXæ að^BÌ@ûÃJØà$Ü&è‚©‚Tb¸ÁP(…2¨3!*± Bá ¼„Bà¦îp^@!|‚™"X/XÂ5H,¨NQ*ÁZ°ŽC<$ÂUОˆ¾Þ p²¡ ªaÊ$*a·à64‚Ž•pDH‚0f2ú¨ÁA8-Ð’âh+ð€]»Aw •¸.íF%¤¨#ŒMpˆ‚thƒIÒ¨Gˆ„‹mЋe¨Äpƒ(FYô˜ û¡j`ÜtÔADè…0uŽ8áL‘£z°öÁUh€Fhá™8öÀ ¼!Î@ èQ pO8) - ½ã¬/ðPpZŸJœ…Bx ¼¨GЄp *}ú6(‚xÁV(€gð^‹!Æ-à0¸•Àk„òA¶ÃNH‚f1FLSX– ¥PcVâ8Gˆ‚SPÀ¶ cøA l­© _@Ñm–pr :@Þmk NC4<‡vè€N˜¶õ ³À’à2¼…‘k¨Ä<°{H„KP̨„‚6è‚1ì…{ðšAh-úø€/\‡4(As, z°ôa;ì„},ëP0 ÖÃa¸ 9ÀhA%F€4؃8ƒ \€X¸ ±û F)P U0yÆн·át¿%öa9€)…çðˆ8Wƒ9ì…}PO¡æX¡½AæÁ¸á°mB…p Ø7S )˜pîÁG¨‡‘ÖTBœ!Jà Plp?,3Ø1×`„-Æ?`ƒy  °îÕõ Ó@Ü!ò šAÄçb0…-pÞB)Œp  Á <Á ¼á*¤ÀM ±}°vA <f'´)¬‡`ØéП@Äø‚?œƒ à‚qD@Œ`%˜C$¼AW<Ôa„4ø£Ü0Þƒ ¸ƒD@ôÀg˜èŽòà†#p.@¼wPÂX?x‚7DÁSø Ó=©Ä p'8…P %ð¸½0Ö€0˜ÃiÈ‚[Ð"ÞTbì€ðA+(úàÜsAöÁ~¸9ð^AÌó¥ó!2 ?´,¸— 8ü1Ž‚¨ÂFðð%ÿ€~ˆ¾ ó@4Àâ ˜¶ À pWÈ€>ÞŠs˜Áyx ã·¡ŸA(„ÁE(…2 aXû`?\‚JŒã¬`„B&Üüöq X úàgá$ÀÓoGa‡I ²°ôÀ¶ÃØOá#L؉º‡y  …!8>ÃPwð¾À†=·Á:÷á¸Ùåàù0¬oð… È–ƒho˜ `!ØxÀqÏOÀ .B4ÀüøŒ ²á|„F˜ru ka;¼©£¨Sð†d¨‡à=†qVB <„Gð˜ã|áäC<Æèã'QÀŽó(\„ ¸ à”@ 0G`|†°ü!b#±?§Ð§Ñ¢ñüñ Îy äÇyø@Ä`¬† 8YP_à+ˆŸC{À!8 o fÇëQ8 O¡–]@@<äA3LˆÁq›!žÁs`ŠE›(€ ̃µpÁhX‡ó!è€1l‚Íà Y°ú"Îëg°½ðª€!ÇDBˆ&¡N@áÔÀø #.aŸ`œ€tÈ€{P ïaúÔ!¬ë«Ø¸#®á¼’‚6¹Žm’Tôxoá”A#ÈÞÀkŒt¬´2Ð`q&Úäob?À4 c,ÎF]ÜÂy docÝ ò0 fƒ"(2,‚ŰôaÂJ8F~Јü Ú޾×ÿ¿Ìˆ?+#þá2Y†YnìÙ\bð6ÔrÄOË­ þ¦Ìÿ½ŒøeöçÕÙ¯×÷Ï-÷×ÈúëlêŸ µ>zFÏ~ÎÆýœQ3ö!–ãü7g\ÿàr¥}ø¿’Ñë쯑 ÕçÿŒì¯Ô'þJûN?ŽèÙÿOöœoY&ÊÙ7ß-7ø|—üvÅŸ›§0‰PiyÿPË‘ßêøWd£D†Î(CdÔ!2†!2Æ!2¦!²¿Éþ™}g"c"c"c"9D6jˆlôÙ˜!²±Cdã†È؇È8†È8“ý3mÄ5DÆ=DÆóˬÿ#ûõpÇùí¥[à·å¨Çrä·—£gôìß‘õ÷OrÜ®’ß–\î_Ÿý»×GÏè=ûû2âOÈèuMÏè=£gÿ ÙT*“-#ïÿy9F‘ÁåÈoÿÞ~,“ž fd ¼ò«là}”_eï£ü*c"xåǬÿ5¹Üp¯ÈYn?÷—ï³2Éõ W&9»Ã÷ÙX‘ßgã†ÉêóWÙ@}þ*¨Ï_eõùsÆ>Ͱ±-c†XŽc˜ìwer ±CìÇû7T •ñ ±œ¿Ï¨£Ÿ1 däÌ¿Ê(CdÔ!2†!2Æ_gÔõClç®!¶óñÖ5u`ÿ~—ý¦Ý©û÷»l`œøU6bˆlà}Ó_eï›þ«ú÷ýŒ{ˆc…{ˆc…{ˆc…ûO8V†Ê¸†Ø?®!ökˆýãbÿ¸†Ø?®ß÷ Zö›>AË~Ó'hÙïú™ ¼—þ«là½ô_eï¥ÿ*x/ýïo‡þë@uýÍ·Ûàu™7ßfë¼ýXfÓwY =û¯Í†j÷¿V6x½c¸¾KÎ5pûyßÿ³ÙൗŸ÷áçåÈY¬oôŒžÑ3zöÏdƒ×Õ†{ˆSôlølð=ˆáꓜ½žý_Êß ®mÉYéÙÿzÖß_È×”ÃõrÖÌÿ\Ö¿äëÛá¶“œÅsðöûl¨åèÙï²þv ßK®ÈYQé=£gôŒžÑ3zFÏèÙÿRÖÿ\‘¼¶4ìsÅNâ»Ûﳡ–ûó²q?gÔþ¬ÿzÕÀõ¿o¾Ý¯W±~›~àöóúø¾Ë~Þ÷M6xýa¸m!gǧgôìß› ^[®’¿®@ÏèÙ¿7¼þ0\ÿ$ƒžý3Ù൉áêšüU“Á=û¿ ^·®ÝÉ_¡¼Ñ³_gƒïëWŸä¯ô ÞèÙ_?¼2\Û’¿ž4x£gôì¿1¼&5Üñ@þº=û_Èß{®O¿Ò6xû3²þm!?G=ܶ¿7xû}6Ôrÿh6ÔúþÝÛòWÊÚü¬ûpíGþ:=£gôŒžÑ³¿bÖ?–"†ËÉ_%¼ýû3V‘¡3ÊÙÀ5©_eßIûUÆ8DÆ4D6ð´ÿtýU²¿Z_¢gôŒžÑ3zFÏþÚÙàÜ7äýC-Gþª9=£gôì1ëGÎÉ<Üë8Ißß—ùïÈXD†Î(Cd¯ã~• ¼ŽûU6ð:îWÙÀë¸_e¯ã~• Ì-ò«l`n‘M žÈû‡ZÎh;=ûó²þv ï®<öf?ݬÿÈcl¸ý‹=ôû2éÙ*ëo?r®ýøOÒ3zößõ?ï!ob¸ç=LÑ¿/“žýU³q?g?üFÎÀs¾o¾Ý¿kr)ŽB3pû¹OäüÌ~®3úvþyÙÐû0ø=¢áúÙÚ+¿/óûì]n Ï“ÇpÛB¤þ¾LzFÏè=ûÿÉéõBÏèÙÉ?~< ¾ÏG»ˆåÔ ~¿¾ï³¡–:|¯k¸mé|òûm¡gô쯔 Õwéýú_ ¾Ÿ<Ür´è÷eÒ3zFÏèÙg6xÍf¸1R¡ô'¨Fò?†©— ÷¿¯kzöß” Î;2Ü{œ3kèÙŸ— ÎI2\;¸Ôÿ½Ùà|Õ™Ø0˜ÿ§²q?g?\Ëbü–}óí6x-ëH…fðF–IüQfÜßdcÿ"Ùàu’_ïÃàrW»ÿÞlðzÇpeföü'³Á1k¸í¬ûúcÆ,2tF"øœÜ¯²k¦¿Êú௲ÏÉý*øœÜ¯²ÏÉý*øœÜ¯²ßàúU6ð\¿Ê~ƒëWÙ¨ßdCµ=£gôŒžýwdƒÏ݆;3SÿHéÙ_"ªþJ½ýèÙg6ø:u¸ñó(ûïzFÏèÙ_# ¤× =û›lp¾ØáÆù|¿ïKôìψj‡´èmû¯Îçæî8ú(øû2éÙÀí¯“ÑÛèwÙàü»ÃõùTÑß×5=£gôŒžým68—ópã˩ߗIÏè=£gÿª,ðÌèõIÏèÙ_5ü­†ážkó¾•VP̯˜÷;o Šy¿ó¦ ˜÷;o Š+$æýΛ‚bÞï¼ùëÕ™5^*Í£%ÿ24§ùÆ-ΙÏã‹ùb¾˜/æ‹ùb7³®9eäúלÕ+ræóÅ|±¿n¬LÞ˜ùÛæóÅþؘï8ü/ÅlÞXŒäúNÞkbi“ˆØ±Üב¹žù<ׯZÞù¬‰ ŽÙ?…l§²Lã÷-Ó#NûÐ2`®¾9ÿ?ÆrP;š9ŸìíÏíþ9–Ñ|ŒH7ÌÂlÄ?.²cEº +º!~¼È½Šø’y²¦`¾CÕ SbÐ#0SÞ›hÊW¨<É”h…{ß0eTží.jÿ¾ÿÂ-yc~9»•/V$W,–?œ ©HÇ“]A\@lÔÞk×W\¼yn’/VÌa>õœòwˆå݇¼±köXÑ\1õ/ÇYË=–/Vâß³y®‰©mÉÙNÏu×÷GÅœr–{ßÓòä,W=!1´Íò£°m™ãSÛRÆêx·³&BîÜ¢·3Drb¹ó’;v#ÛyÝ}(S`LŸÃTøÛÔó¯dêxÖË¥X·áIð@y‘ð ,ƒ‰–aP%ö±²È)L®"Òšƒs ªŠDT9„ÞÕÉG ‘ÍHa9$æ,®Åy°¶Hp‘˜]W¤+¼„iõE¢nyýÙ€’ E2o¹£‘ÈW˜œÀ¹4Idí,‘V°y;E’޲ü3"Û/Š” 4äÿjr6Ìš]xœhÈã )9ÓâÏRw!íwòêaCÖaÈÂ_ ™`ÊÌŠ¦|ÒÄ”ŒSêw3峦$½`Jú>SîÙÏù˜8ƒ1IHF †bRáÆp<‚G1i`d4Ò‘Ç U"cð8ÆbÆc&b¦à db*¦a:²ðæc!c ^À2¬Äj°»²¯áulÃ¼ÝØ‹ƒx¤D>ÀIœÆ§øê ê5¬Z¨HáÔ ²8¶}9Få¢E:Ų]E®ôdç:˜Æß¸ÞEOäú÷×Ý™äaÛºHä¶"; Rëµq’õ¾ý"²ª˜!Û+’ɱÕÐsцtmcH\gC‚ï6dð3’¼˜Ä&Ì×HÜßIH¥†¼ó¢! ×òõf~¿eÈ¥ýü>nÈ' IÿÄSŸRâ¼!•Ù‘iþ\k‹™r:Дà SžªlJZ Sj×6åT]SÖ40ewcSâ#MÙÐÜ”½·›r.Þ”NLip¯)A÷›ò@/S\½©‹¾¦ø4¥ÇSš5Åo¸)GF°üÑô¹fÏkJ ®Ó3Mé6åÎ3¥ÑBSV-5eÜ*æ]oJ‘Wù½•åí·ê¬y€A‰É˜'A Ë,ÌÆÓ˜ƒ¹˜‡gð,H‡,¥.KñD÷'V×ç$ÜÇ8Q6äd„¥DZ¡5D&ã dbVãG”¹‰ç‚P.ôD2†bܘ…Ý8…3øgáWZ¤ÂH4Ã=€q˜ˆI˜‚å8†áG\ÄeTäÐíÐу‘¹˜g±ÛpW­®e¹¡&:¡b† ‹±Û±oà4.¢l9rŠò¨ˆHt@"úca žÅF¼Ž-؆“ ®÷¨Ž¨‰Ü7ÅŒÄ\lÇ8“ø¿¢l0¹@4Eº£F"ð`!–cÞÂ^ìÇ—¸ˆ²œ÷‚Q‰¶x x}03°k°ëñ.>¸ŒŸð ªp]­ƒÖˆE[Ä£Ü˜Ž™˜…,lÀœÆ§8‹ÏáÏu¹:¢Ñ·£5Ä(<…¹˜‡ùxÇñ.â~B%®íMÑ]ÐÝ‘‚¹Ø€×°›ñ!LÆÕ*[c‚š¨XôÂH¤#,ÄÂaÁQ\@ c‰zh€†h„Žxéð` Æâ9lÀ!ÆÅTf,âBš¡9îC:æàÌWãlÅQœÇ¸€‹(ÏX¦6Z¡ b‡ÞƒùXˆEx;ñ=J2ö)2(‡PÜ…¤ÂG…5؇8h›Î!˜ëk„!è‰I˜Œ'°qà>Äe˜Œ½ª!5Q±èŠ‚$¤`:Vböa?àk\Fc¸ ¨ˆÊh†x<„Þ胾,¬ÃËØ€Wqãg\ůPƒåh€8´C{tÀŒDæ`.žÁfÄøßàJ1®üe[©ñ%* у0I˜Šؽ؇·ñ—ÖB]ÔÃ-h‡^‰tdÀƒ…x gpŸá ´güÚ}Q}$Çn,ÅAœÂ=ÜÃÝœ]~\®ÖTÊtïìì ºîì¬Y|ÿdžo›ÿ÷÷++3¨ùìlZ뙢ےրAßÁV·N*úî5¨f‚³³< ‹Î7õãžË•˜År^ñRý©þ½eg«i³ÅãñÈ%uW]ZÌóÜÇð¨ØùbÞ™ ––"çÕýxiñ;‹þ{ñóÞ{ðÜ?Ü èùÔ«Eíé¹o’rößÕ²„A` <¯vA ºË衵5p-&~EÔM{ë"†^wÙó~öVdgw£-%½¤§$KoqIB%JÂù/B"óÄšñ×h~‡ ÏsIS"á< - Êœ.½Üü15WSâQùbüM­-‚¸óvæŸ/g;]…lgX!ÛYÐ|ÞílVÈv†JIbíe°¸é[[¡–fG¬¹BõXsE3]É\Ë‹dj;BùÝÌ1íQ1§H¨c$Ì1îq9F"#N{ªŽ¥SÄ)¡Ž9sÌÁµGáÚˆSÂs昃0Ç„9æ Ì1aŽ9sÌA¸cÂspÇ„;æ Ü1áŽ9wÌA¸cÂsàrÌË1.ǸsàrÌË1.ǸsàrÌË1Ž9ðž« Š8å Â1Ž9ˆpÌA„c"sᘃÇD:æ Ò1‘Ž9ˆtÌA¤c"s阃HÇD:æ Ò1QŽ9ˆrÌA”cÔ•·%c‡‚ôrP‚1Ö×u,µoy’QÕÔh‘È;D¦¹¹!M91^ä;¬ž*Òi63-yaµÈÚÜ íf̳Ÿ›­¸(RüŠH ¸ö”0d~Áͽ!C ]Ëô†Ì‹4äæÖ†l‰7¤ç]†4mÈÝ ytº!Ëg{Ƣϲn…!»ÑK½ª¹Ñ‹ï2ç˜!‘2îŒ!á_’ú!K¿5$óCaÅeC^þÉÓW 9`ÊÔ²¦dT1åT5SÖÔ4ů‘);››2üNSZŽ2åÓLS§™âZbÊ«¬7aErE¬!žã©7ZÔ;/j|§ÆnêÍDõf#ÃÕõ¿©ÿåK}ŒÙ~ÍMì×½$åQA¬!­°VF±Þ«Šjb u¹/—±†¼Üû ÷®Â¡‘ºb½‰Sj\ª†Ã Á!“FhŒÛÐD¬÷“B†p¨7n#‰(ÑïR‘"ÍÑB¬ú¸­ÐZÔ Y¤ Ôx¶-âJBÚ¡=îDtD'tFtÅú9T/VÕ±$²C+ÙÀMl`+œC ¾L ~Kýý‚ýÔàPj°ô"‘W¨Á­Ô࿨Á&Ôà jðsj°õW E©ÁƒÔàjp 5J z¨Á‰Ôà Ô`#jð058lA >B >M n¥ëSƒå©Á7©¿÷A V§ýß3d5؉\E v§'Pƒ»¨ÁÔß2¬¡7Sƒ—¨Á¨ÁÙÔà$jðSjð%jP}ÅæAjðî¦t¦¦GQƒñÔ`†]ƒÙÙ*Ãþ’±øžjÅ¨Æ 3þò½²ôü¢ç±{Á:6ÆîÓ±Çé•¡×SÇÆÚ±¸wTlœ·çªÉÆÛ½÷»ï&6Áž/8½2±‰vìÂz›d÷ªU±Éö”ƒ?ªMoŠ«S4„Þvï›io3_¦ÝÛò³šrª=_ŸŸÔ2§Ù±kÔvN·c%{Ö`Êvl×Q5å“v¬ê1Õ›iÇ­V½YvìÀKÕ™o¶Ýk4p±,ï|z[žòÆÞSó=m÷:í¡7ÇKW±¹voôgj«çÙ½Ì({Æû^ÅæÛ=¿ùjžµ{·Àî-Õ{´Ð»áj)‹ìÞìQ*Ÿ‹íÞýËTì9oïCÕ[b÷vÍRË\êíé}xÞîm9¯¶åïÞQ±½Kù@õ–y{)j}Ëí^\¬Ú²vï„>î+[U·ëWÕ[eçÚ/[õVÛ½ WÕúÖØ½ º·ÖîKªHoÝkÙB­}½w™:ö’­c/Û½]ªÞïúz©Þ+vïþ+jí¯Ú½ùº÷š½Ì-ºê6ÚûpåI•¥MÞµÏT½ÍÞ­ÖÕóºw™Ô¶lñæL÷¶Ú±ýUo›» çÛnÇ2õ‘Þa÷âô3n§Ý[ºJeâ {¾q{TïM;Öó’êí²{ïŸU½ÝÞ5¬T½=Þ)_ª-9(ë°Ù¶ {Åz3ZQo0¯¶©7ûÔ›xßX²ÈÉúŸ‡-ÉÇ-ß4¤óû†|uÔ·Nrmæ\ö±aÊñ"¦ 4åo%M™\Ù”¡œ³žªjÊcœ·6‡˜²„sלº¦Œ©Çõ3Ü”‡\¦TÌ0%'˜róDS.l²ßlJY£ z¼né¤" Û·˜Rs»¥"ðm3á#|†v;,w¡ŸÍ{½6źb[/Ñ‹êÖO·þº Ðm1Ý×m Ý–Ôm nKéö&Ý–ÖmÝ–ÕK.§é6X·åu[AG+ê¶’n+ë¶ŠnoÖmUÝVÓmuÝÖÐmˆnkê¶–nkë¶Žnëê¶žnëëÖz]ªnêöVÝ6Òm¨ÞžÆº½M·MtÛT·aºÒm¸n]ºÐm¤n›é6Z/­¥~Ü\·-t{»n[é¶µncõ”1úqݶÕm¼nãt{‡nÛé¶½n×Ò*›ðöà M}Œ"Ë¦ÞÆVk8dû…ƒXº˜%˜E9lI=néJuw§ºÏQÝoSÝ¡T÷'T÷ ª;™ê¾›êžJu§ºçQÝc©îm!¦¼HuϧºÇSÝiTwªûf*ÛîTw ª;€J. TF5[_*9 Ã0£m¨î[¨\ZØúÛŽãS|i뾃‘¨-Å–4ÊȪ¦­Ñ¨‘k4ÊuªŠ­Ñ¨ñ_ÞÆº› ©®GCW£ª<#‰(¨ ôŽF[èj3t­å¶áo±v}©ºŠç±ª©Ü£ÑbdÕ˜©¡gø°¤æ©½û'IHm­,Y{ëmãu§Û¶ºÍõ÷‡)[:LŸoúÜÿ&ß”êG­Åû:€3ä>Ûª3¬º¿ˆáx#Ž <Žñ˜ Ö8oŠXŽRL€dx0Sñ4Ö›Ö?M­?°^Äú'¨½ÿÌôQ|€6*àQ?ëƒí0ð‡+h.%©ÜÈÆ9ûCOêÃNÁ7Y¯©ûñ˸Š.õìurÊ¿Šç9í¯´?Øy Q\ÚbÖ`?âgøsi¨„êH‚_⻆ÖkN­ÑëVëÞ¿ïÿ³wP^–éÃøŸA¤A¤‘T@” ‘ni‘Ai¤AiII¥»;¥»»ARòýÌäàÙw÷ÿ®«¿óÛÝó9Ιù~ŸçŽë¾î{†™ç¢> ø”üÀsŽ2щE\–³Šì7¹8Ä1Npš3\æ ·¹ÃCñœ£PTbññI@"ó*ÉHK:²““¼äãb:fÅã¸mí,émeÙx¼§,mèL7úÒÄq«ø’“\`²Ø|âÖ„¦4§éDgºÐ“^|M_0Œd S™Î f2‹Å,a9+XÍö±Ÿãœà W¹ÁMns‡°ccx†(vL¨É†ÙBJ|û@"ºÑ““ŽçyȳùÝ—ÞÔtÀmÀôdÈ%IäçI%A½Æ®SIZ©FMêÒϘÄæ2Ÿ,eëXÏV¶±æ'8ÉÎr•kÜà&xLˆ¤J$"“X$ IHJjÒ‘jÔá*?“·PøÏã RŒ¸R`BÒ’ž d$9(Cy†1’¹,ã&wù…L•Úg]¢Í nç]'L†0‚Ð÷ÌIHEFrÒ¾ d0CÃwŒg³˜Íb–²‚•¬á2?“¡„*‰J9ᲊ ,úÀë¹ÃCê”¶FiHcšó9ÃÉXƳõC¹‘_ÊšN—“S)V>JQ†|Ï V²†Á‚`8³XÀ-îóöÇN¼4§ ÃɦrŒ3$©¨ýä&?»ÙO¥JAPšÔ¡}ÌPÆ1•´•Å-™ÉFŠP‹º|\ElЕÞ\âgbU$ªæþÌf!«k3ù‰Â5|‡F)>¢MhGgör˜Ì5Å=èËãZb·¶½•8ä¡kØDtm,^ýDó-£µùF!ny€—‰{.|j­P¢i|ÈD¦ñM3ïc9Â)Îs‰y$²ÙÈsÓ—¡Ôoe¿¢íè@7f³]á![‡ÿYsZÒš6t¤]èNoú0€Œ`$ßµÿ¥³ãœä g¹ÌnòLgbø¼J2^iës$$IHJrRš4d%o’—y-óYÆrV±š-le;;8ÀAŽrŒÓœá2W¸Ë/ìì`\ØË¾á@öoM‡9 Á)cwñÀ&¶ßa)e©L;¾¢}Êx6°ãœ'A/}åDoûÙûèù(HaŠQ‘ªtþÚ\0Œq¤îg}PŒ”¢U©CÊþb—‹\å:÷x@„â—¸T$ö©3Ø™ˆÆ|Æ*6²‰í\⩆JR–4¥-Ǧ2“ÍìàwH8Ôü’‚×(Ey>¢ -hËpÆ2ŽIleÏ~c¯'ééLzÑ—AŒ¤Ì×d+{9Ä1ò”¿(NiªP`´õ@¤Ñáÿ¦ó"qèþó sXÄŽp”Ì(Ÿ3t†û2‘i,c ëØÉQNé‡ ˆFtⓊ´L™ãLMӹ΄Îsާ ùb¾sS™E¤ò 1‰K+:²Ÿè¾ÐxP‘ù$Òb×#)©IKfÎp‰K¬Þ[f\èJ¶³—x˽—‚¥%ÙÆNöqœQ+䪭”ãºÊÐRµ¾qs8dÆ:ãI—õÚÉÎ öZl4ÿ´§ùŠ›äR†1–iÌb6+ØÄvvp€S\ä7yÄ3›ÅÏ“‰ìä å¨DeêÓ™îô ?ß0š1|Ï,°åáu·˜/a«9ç,I·oZÓ‘wvˆA>¦rØO iÃ× a5›9ËU®q—`§>‘—INÒ’‹¢¼O *RŸ&|J[zÑþŒckYÇÎp‘K< ê.k˜¼Jr“B”åc*Ҁƴ¥ ÝéÁ0Fò=?2—y¬g{8ÂINqƒÛ„î·Ä&‰IB SœÔgóH¸Ç˜Ž¬ä¤0Å)͇Tàc*Óˆ|A¾a Ó˜Ã"Vp#çç¹Ê³{}G^&3¹(@IÊQ…:4¦9mÁ8Æ3y,ã×HºO?Ã8¶³—õûÙØ Í ¶±›¤½Ötç…CÆB”¥.hFNq‡D?l]ðoñ¨ÎH¦ñ˜HGÜ›÷˜Ç2qœ„õ1§9Ë5nñ€ùÇ'9OØïØÁq>9éüÊ-BO™:é´üF3ÆŽÁL ÚYcÊgtæ6‘Îé7=yD´ór]i~ÁÇ\à]”c¸É3—äOº’íŠv1›¥T¿ê> a4±®Ù»øäºñc8Syþ†=^Œ úMç¾f½nÉ_œç2‘o;‘—bÌc ÙïÈG¼EÞ¦KYC»îÏ¿Xçtà ¾as˜Oê{¾—à Ó–t¿oýóÁ{$uÊWDz¬ÍÃþP-$(N›gB‚^Lg«YÇz¶1$ˆÌsÄ 1)HEVòQ€†4£X¤à>Œ|ÌKQB‚ø¼É;´¦#ùŸ 1$ZH0‚¹/„ËÉÝ×(À»”¤ Ó™Ë"–³‹ƒ\à2W¸Iª!Ák¤'¥(KCZѯÈ(Æ1‘é,d+8Ç îrŸGD~1$ˆF ^".ÉÈHÊS…ZÔ¦ íé—t£ýÀ·Lb:?°˜uld‡‰3$ˆÉKÄ!iÉI^òSœrT õèÅîÄ ^ä^x)$x™ä¤#Ùxü¼OjЈ¶t¦7Ħ2ƒY,`!›9Àq®ú²±"6 x•d¤$5ÉE>jÒ„6´§ƒÍTæ±”ì&bl}"6IiA7ú0šóÜ$eÜ 3ýÁ>.P>žød-›y%¾8¥ ½YÊnr‡ ´ä¤"5ÈLN PB¼GIÊRŽj4¦9]èÃp¾c*3™Ír6±•ìc?¸Ë#¢% ñYÈI^òQˆ"¼Oy*S•´¤5_Ñ—aLàG汉­ìç(ǸÈ/‰B‚èÄ#5ÉE>Þâ=Êó1U¨Em>ç+z3œé,f%«XÏF~b;»ØÃaÎr™«Ü'bb9ˆ—IB:rP€¢T¢*õhÆ4–’<‰õB9*3ƒ¹,fkÙÌöq†Ë< RR÷#)y ä¦ EèÂ`¦±Œ-ìd?G9ÆINs‰Û<àQ^u}^!ÈEAJRŽ4f “˜šLäÝ!A JQލÊtfñJJñ̦1‡Å¬e §¹D„Tò qHH"Òƒ¼¼GyjÓ–´£=Ì7Œ`,ã˜Ëj6q€KÜ#Hm‰J4b“¸$# éÈA RƒF´âKú2„)Lg!kˆ”Æu˜ÅB¤•ßYÆZp’Óaà(‘Î:eÃÙÌNÎp™¤¯‰y*S“,§jú ‹XAùŒ^ÃáL!Á)ªe šÒžî¬a3[ØÉ.rœSœæ"x6‹|Orrñ)Cyªò%=èË &1,d=Û8ÂyîðˆÈYíÄ ©HK²ñ:…)CEêÓŽžô£?ƒÂF2–ñLe.‹YÊFv³ã\â ·É&x…Äd%;oe û=Aý¥¥©@UêÐŒvtà+¾e“™Åó;9ÈŽrŽ \çÙ×/’€]Ù½–Š9ÄõiJÒœÖ=©J#Z3‘é,c-ëØÂVvsžK\æ‰K#¯‘™¼A~Þ {he(K5Ó‚/éËHÆ3ƒ9Ìc[ÙÎnr(WøC0!·þò1INr’‹7ÈË;ä]ŠSšJÔ ŸÒ–tcƒÎ$f³Œµà0ç¸È%îr<Ö+/›¤T~C~¡1ŸÓš®tg0c™Él–²œ-le;;ØGŽ¼Æ’f´d(#ÍD&ó³˜Ënq”Óœã"÷ÉgìˆLfrŸbt¥7c˜DœüÎ7$#)IÍWô¤}¸Ê- ½%¾©Î'4¦ã˜Ì6ö°£€±ä G9Æ)Nsž \á*7¹Ã}ð˜àm9—H£íé@gºð%_уžô£?ÃÅ&2Ìá'vqŽK\å· Þ{¼D2Ò“‡·(F)JS…z4¤=øšþ b"S™Á<Ö³‡Cœàç¹Änòˆg šb’$¼FvrP€¢a«@jÑŠ¶ôá[ÆócÁð¿iXÆrVò|!×%)©^ØÚá6‰_DœòVQ÷àcjq“G$+f‘Kg^">©yäå=ÊSj|BÒœVtä zч~ôç[Æ1ƒ™Ïj¶±}œâ*×¹Ë3¥¬ib—dåuÞ e(GeêÑœ–´§ ]éÆ@3‚±Lf* XÄJÖ²…fˆê~¨´¥3«ËÚÿ )oìùð#cA]s„ÓŒ«|OÁŠÖe©@uêð|%ý"ïP¢”¡³YÆ>Žq«l«lÿ'{ý'cUóBJ±€¬d-/Uóý èÊ§Õ ›ØÁAs„“œâ¹LÞæœRTe%ëÙÁ.ºÖ´_0Y$©mP—–´¡›ÙÁ!ŽðyóC7zóU]ñÂðOì;lc7ïÖ“k)ÃÇLd2«ÙÁI®s“û<&r}ë‘ôd'S4¦5íèD7ú1” Lc.K‰ÜÀ\˜$'¯‘…¬äæ-Þ¡ ïR—†4¢)ŸÓž|Á@†0† Ìa‹YÁV¶s“ÛÜã1ÚïˆA\’“žœä£ïóU©A=êó)Mùœö|IWº3žI,d)W¸I¤F¾¯a ÙÀ&v±‡ý¡lcù–:4¤)ŸÓ… b£™ÀYns—û< ¤‰þñQˆN<’œôd'E(AY*Ó¶´§_Еî|M?2Šïøž™,b5[ØÅANáS¹˜ôde8˜Ät氈Ŭe8ÃÏ„=ù."1ˆÍ+$'#YÈC!JQŽÏéÂ@¾e˜È4¦³„uà §¹JègÚK4â–t¼N>Jó!U¨N-jÓ˜&´ %èÈt¦F óICь洦-]éEð ß2ªEøé¦ò#ËYÁjÖ³‘MüÄv^ûÜŒ2T`{ØÇ~Žs‚Sœæ,ç¸ÂmòˆÇ„=U0„(¤&ïS†šÔ¦1MÈ`†1œ Ld2S˜ÁÌfs™Ç‰ÖÚÂy.p‹ÛÜçaO5 !Ï™ç¶H4b‡¸Ä# ø€ª|N+zó5ýèÏ`†0ŒáŒdß1–ñLà{&³€ul`#϶µž‰J4âð ñIÀ«$#©IÓ6üoJ3‘¹møßöílgü9ÔY¬ÚŵHJZ R„w)IyªP›Oø’nô /CÅ"–²Œ•ldxîKí#)ÉHÇkd"3Ùxœä!/ù(F*Q™ú,akØÀVvq‡‡Ìë*VYÕÍ×ÈÒÝ5)G*R%¬"jûEù€¶|Á æp‹G$ëi§]éÁ¾g2ÓXÎ*Nr†=½íÛüÂöÌôd¢õÍD¾g*ú„ý ¤>r½Ÿ÷‘¢¿ù& ¯‘‰œT  °²– ld/YËa|ÃXvp”8CälŠQ’šÔ£%øŠŒa23˜Ã 4e)GUªQ‹ÚÔåЦ|FÚÓ‰/ÂPF2бŒc S™É,æ±€Å,a%«XËMîQd¸v1›%\ã‹FX£<àå‘â„7iE;±Šõlãg8ÇE®q‡ˆ£¬’“¬ä¢e¨@%ªP‹ft £˜ÇjöpŠ£]‹Œd§ å©G'ðÓ˜Í*¶rŒ‹<$Ò9™d¼Î¢8Õ©Cæïô™Vtd:³9Î9"?$#-µiHŠqÖéÉD ÚRs¼9¤/ƒ™ÁLæ°ˆ%,gG8Ái.s‡_x@” !A,‘‚T¤ç#*²™³<&ÂÄàE^! ÉHvbL2Ž”æ#z}oì¸Ä/”ž,>>ÅMiA[ÚÓƒA e8Ä1nr—ˆ+ /¤á5²œä¢oS£8%)E>¦"•©I-šÒ’V´¦kÙÀ&vpŒ3œã&w¸Ç}BW™;bó ÉÉJnÞ /å¨N-Ð’ötä+2’ÑŒc)+XŶ²ŸSœå¢•©BujЀ†|JSšÓ‚¶´£=ø’¯èdž0”QŒfãùžÉLc:s˜Ë"³Œå¬eÛø‰Ýìå9ÆqÎ’f³õGòÐŒ6tc©·Ø³(K*R•[íYLd ?0›5lb3?±›ý<"d›qd7{8É).s…[?…?3çîñ¶ë#/ï0g¤&¹y‹·)L-êÑ‚V;°¿„KüÌ îðüN±°3ìyrÉÉDòR€"åC>¡èJo0aŒf“˜Í2V²– lbÇ8Ã9nr—û< Â.ù›8Ä%¯óyÉOU>£9­iGgºÐŒb ™ÉV°žà0'¹Î}²Ûx˜¤¤ã5rP€‚¦$¥ø˜Ú|B}šÑœ|Í ¾a8#ùžÉÌÞöl9‰ìå8gX±Gì°‘„ìu† 5ÝÂ>ÞçKªýâ‘|L†Î=|IoÖ°“Í!eøˆ Ô¦!-éÀ—ôe ƒÃwLf>KÙÌv³$‡´jÔ¡.ŸÑŒfS™É,²œµ¬gG9Á.q™ëD<¬¯Ä!!‰IGvrñ&ùy›w)OeªÒ€&|FsÚÒƒ¾ôg$3˜Ë|r€ÃáW¹A„#ÚB$â—Ĥåur’w)EY*Rf´ 5ƒÊ0Æ3YÌ2V²‰Íìá8§8Ë5®sŸçZ#¼L<’“† T¤U©Æ'Ô£å™wÖóÛÙË=B[k¤$5™ÈL6^çMòò(DaŠó%)Ei>¤å©BUêRŸF4¦-é@G¾ 3ÝèN?ú3˜!|Ë0Æ2މLb2S˜Î ³„e,g«ÙÌv³‡ýà8'¸ÈU®ó3÷¸O„!Á3D"2Ñx¼ÈK¼L’‚”¤& YÉFrRŒâ|H9>¦"Õ©AmêPŸ4¢1ÍiA;ÚÓéDøsÔúЗA fwNÙcˆxZ[ÉI^ÞãCZÐŽAgŒ'QÎê³XÈvöqŽ‹\â2׸Ã/Ü#äœï=èt^[h|A;iIú0ÁŒe&óYÈJ¶³œ ÆEçÞäm òU©M]šÓ>ôe(c™ÌTf³ô’9çgž¹,–ÉC?FóàŠ{]u Q‰´¢-“XNœk攬d§>8ÄQ¶_·6¹Â-¢ý,8Í9"ݰ¿ç–uJWú0ÿ¶8eÉsGþà3:ñ€w݇SùEî¦7_Ó— b(ß0š1Œgß3™©LãÇ_Ÿ­öl³Å,£ë=×dç}s@ÕÆ™–´'¬RdzDä9¢•h¼H,’”Ô¤#yìä&yÉG~Þ¢0E(AI>¤ å(O%*S•jÔ¤ iDS>£%­iG{¾ 3=èÉ2Œ‘Œf cÇT¦1ƒ†=ËY’¹Ìc!‹XÅjÖ³Mlf;9ò0ü¹…§8Í%?’ ÈG!2ˆÁ gcÇd¦ð#3YÀÂGaOñ²W²•ìã§8Ëunq—g[ïÄäe^%ÉB>Þå}JQOÎXV°ž½!Zöä¤Ð .‰INZ^ ž3öD Ðà=JSލBSZÑšö|EzÒþ g£ÃD&1E¬dØÆNvq”cœäç¹À%~æ6wxDDäy^$‰IK2’¼¼CQJPŠJ´§3˜ÇVvsƒG„†º>qIN2ñÅxŸ©NÑ”±Lá'vrˆ3œã‘#h3/‘Ĥ!/oñ.¥)C•°'#Ñ”|AO3”ï˜ÉV°–mìâ8§8Í%®pƒ…Ïx-Ó#†ó9Êy’G Ò1–i<&bäÐ ù©JšÐ’®ôä{~`>‹YÂr~b''¹ÀsÏ…1HIZJQžZ|B=šÒŽ/ù–Ñ|Ï4¶²ƒcœá7¹GÅõy‰×ÉÏû|H*P‘êÔ  hÊgt¢+½Ì· cã™ÈT~`ËXÎ6²‰-ìdÇ9ËEnsŸ‡<÷¼þ“L¼A^òó>åè@ú3˜ÑLa ÙÆŽp–óÜ ˆD :¯äd#yÈOQÞ§. èÅ&1ƒlç(gî-4ˆM*2P‚² à[Žs…›Üç!Ͼ ΉJ4ⓈWIN2’ƒÜ¡8¥¨DMêшf´å+zÓA g,Ñ£ë+©ÉÎf²‘íÜ'4†¯“‘7x›ªÔa3¸GÈ‹ÚL,–°Š‹1CƒëDˆ¼L|j½"fiÌç´¥_Ñ•îô¡?#ÃwLa*Ó˜Á沊lgYè oP¢¼Ki>¤,¨Ì'4¤-ùœV´¡_ð5ý” ü¹»‡û8ÂY.r‰[Üæ.’ÈUD'q‰G|’Œäd&;¹)ÈÔ俀ù¬` kÙÆOì`/9Ã.r“[Üæ.xLÔ¡ALb“”ÞYô‡¡Œa<˜ÁÌd. YÃ6²“]ìf/‡9ÂE®s‹¬ÖJ¹˜Bg6‹ØÁ>jç´v8Æ.rÐ\âžJÔ¤C©˜[îáòÈù¤$#Ùéņ0†éÌakÙÈ.sž \æˆò†uÆËÄ'‰IFz²S€·)DŠQš TçšÑ†Î|M?ðß³€åç·yHì7Å)HKz²Q”’4¦)ŸÓ…/鯖³òÍð€ØÌNös‡Ð¼òY)KEêш/èÎP†óóXÇöpœ“œ'R>qD<’‚t¼Ff²’‹Ü¼ÅÛ¥å¨D Є¦|Ά1–ï™Îlæ°Š lc‡8ÌÎrž+üÌCBòë3Ï•hDçeb“Œ4¤''o’b¼G êÑ”ftä ºÐŸa¬b8ÎiÎs“à-1Ì Ä".ñHJ2ÒŽã#*P•ZÔ§ŸÑœ6´£;CÉRÖ±—œâ<7¹Oüò ™ÈM~ÞåC>æW¹EèÛöL:Ó…/éJ¾f/½cMœ´Œâ;ösˆ¨½†WˆOÁ°B”Ô¥1U [óÄ.â:Ô¢ÆzvðUQ9–!Œæ;fð#KYÎVÎpƒ[„¾+&ILR2‘—‚~7üYÔSåÅć9Åyîò°xhðÌ{æç‰Jt¶°—³üÌ]b¾oÉÈ”¡ XÌ Ê—ð9êÓ‚|E†1‰),gØÁ~Nq†óÜá¡%µ‹d¤$-Y)HI>  U©A'z1‰YÀb–°‘â Wø™[Ü&B)çV¢‘žt¦+ÝèÃwL`³˜ÏR–³—œäx‰¸$& )HEz:Ñô£?#ÏD&1•ƒæ§9Ã%â”vm⑊Ԥ%ÈHNr‘Íìä ?“øC¯%=ÉK! Sš2”£èÆ`F0–ILgs™ÏR–³™³Üä‘ÊÈ$!=™ÈÃ;¤%¨H Ñ„ÏhIG:Ñ…Þ|ËLæ°ˆ­üÄNÎpƒgË:““—‰O2‘•b|@#ÚðuóÀ`†0–q´úµø{:2©ƒÎtf°—}à '9ÅÎr‘K\æ ·¸Í]~á {``‘‰BŽ®æü¼M_ú1ˆÁ g#śݼ–·y‡(My>âùîÖ=ÑxØÄ! HDbR2ìu=½ŽX¼Ä[ E)͇|DF2ŠñLà~¤[o¹žôâkú1“YÌc> XÈ–²–õlg×ù™_¸Çc‚>rˆÌsD%щA,^" IAJÒ“ä&ù)LŠQœ”ä#*P½Ox݉º|B³ár mh˘)ò˜Äd¦0“Y,b1ËXÎ:Ö³™-ìf‡9Â9Îs‘K\åwù…G<&ÂT9ž(D%:1x‘˜Ä&q‰GB‘Œ”¤%?ü¨Ìa.óYÀJV±Žõlb3{ÙÇ)Nsž \æ xÈc‚™Ö%‰ÌsD%1x‘WˆKB‘œ¤& ÈL6^§í¥)ÍhN[ÚÑžt¦ ÝéÅ×ôeÂPF1†qŒg Sù™ÅlöqŒK\!ãBqÂv.,·T\âÜ@þ¥úDqJ0<â™eb•¸”Z¡Ÿ,d9+ØDÆ•á2ÿ*˯²ñ:9ÈInòð6…(E™•áOçŽ$ Âß)Áoü½ïùK±þâ:¿Õ†?Ú–´ ÿJÏýïxþ^f?þÖuÿYmûG¯û{ÅÿÞëÿuï?£-aëô÷Îïïyý?êöëßí÷ÎÍ“~ÿ#yó?ÅocéßÝ–ÿúßç¿ñ÷_ÿõ_ÿõŸç·g»?zÆùkgÖ¿ç¾ÿ bÿÞ3Þ“vü»îÿ_Û“øøËÏ?‰™tîþ;ßÿ3ý«rÒÿTdlÿó¿Wø×µìϺÓ?kžŸÌÕŸÑÆÿÍ~;ž±þÊçÿÒ¹W¬¿â¯]÷ïiÇñGúðgù½?cýOi÷ŸåÏžÓ?âÏîß5FÄ=þoëo|ügøÅÇŸÏÿ‰þÌñüO÷ŽÉ?kìÿ mOþË=ìŸù3Œ?ÚöÿÄCûí>ùÜ¿»ÿÛÏ%ˉ¿ÿ™þÝ#þ?ÁŸ½Zž¼æ_™IÿY÷ù{îÿïüÍ™ÿ?qá7=‘¿<#þös¿íÕÿ+*þy=úGü½qû_ÿõïö{"û™ÿOè¯ÿ}*üÿ¡AØÿž! }Д»Éƒà!RAÄTApåµ ¸Ís™‚ “rÁLÞÌ…(L1Jò¥)G:±…í¤É)Kjñ ˆðFDã%2ç‚d)9 „×^¯Áƒ‚ù›æa5Ê+ü¦ùûE}ŽÚÔ'æ»Að2¥¨ÊV³—£Ü$(5i@gz2—…$-éhJkQä½ ôkòG„¾{8B×AÐÍl#zÉ x‘ÏhÁLÎp¥žÖ*R£¼JicÂe\‡{å‚à>UËA5v}ûH]1^£A¥ hN¦ÊîAº±”••Ãk|ärÝ ¸^÷imíÈ u›"cÃJ¥&ƹIxÝì-äp³§µ³ÃêfG!6qHN š¶ ‚Ï[=­•½°],c{GcMîNæ†;AõÎOkBçí¡=žÖ€þ[5ŸôÔFŠÒ‘.Ìe9zù%ûˆô ‚TýžÖfžÈäÁOk3?©Éœeˆ÷yZ{ùIå'µ•ÿ²frXmäÊ'F=­uœã» ÈG„±bŽjム Y&Á$šlœÈ25²ÓrF´á èócŒ`?Ø3Û¼p‘;³ÃkwŸ^Û8î¼ðÚʼn<­=¼i©÷,}ZsxÔ ý%úJsE6rò ÃI²Ê:¤(ïq›D^m~ID²ßÔNºVûù’ÄÜèºôÞ˜ÀTV³‘ÜäyasÄ iħ¿©ý[e‹¸ã…­^Gаx»8&×ãûkÍߪLg+XÅOìà§~­ù{oGxÛOSÛöI-Û'µhŸÔ }ƒ·~S[vÜ~1³?¼fìÑ_kÆøµFlF Pø×± ~S6¬ækmörˆ—A¼¿R»µ3½G ×'µ[ÿU5[ŸÔjý½5ZŸÔd­rGþ%ö]ïcÛ=±Éùûæ&¬Žêƒ öàiíÔ"c!‹8ÌbF âGxZKõgyñÙ 6iÈBYªÐ™^üÀs†eC‚ÕT‹Ôa;xû¹ Oj§ö|!$öÂÓZ¨a5N[ǯm::Fx-Óƒ1Âk™ÞŒ^«4oQêÅð£Gx@hÌ ¯Æ ¯:$fxÍÐD±žÖ ­Lu.rõ¥ðƒƨ—ÃkpöŽ^kslÜðÚš[ã=­ù¤Vf:9aH5axMÊ~ æ[¢$rO†0,QxÍǤ¤$mâ§5ïp?Ix Æ!LbjÒðZŠÉFÎWÃk&.&jò &Ϥ ¢Ñ‰.)þïZ‰ËXÃNñˆÐTÆžâìfªðÚ„iÆç©ÃkNJûל“9$X™ùi À'5ÿ®rƒÈYô—lä¤-]ØÏajg êqˆc< Èö´V^c>c<ßg{Zó.¬¶Ý«¯?­Qw“üÂC’å ÒÑ‘.DËí=t¦+c™˜ûi ·'5ÕžÔN{R+íI ®ul#Ñ;îûNxͬžÌd.ï4†ÃkX #cá +{Ø_8¼Uí¢OkO=©5õ¤¶Ô:6{ZSê/kDï…Ï’…ìT¦_Òƒ¹,â 7Hù¾þSžJ|IO°”³\âå!A< P˜´a:³8Æ)BK†y•”¡8#ùŽ¥¬ä'xDh© 1É(@!jR·ÔÓšL£K‡“9Y>$(ýÑÓZJ»ØûÑÓÚIOj…Õ2JPíi-£ ÕC‚l¨!—а–qcgm1A‡:^Güº!AŠºá5†¾®^[èsëY?ìæ`½§5„žÔzRèIM ƒ­ÿ´&ГZ@Ojÿ¬aKƒ§5wV³ž&Ìi£ð:‹=­SªqHP†tægþ{wÓÙ6püžÓ"Ä’Vk)!m©ŠJ‰ %ö U”JKÓˆ •MÄNR’”Æ*µd»K-õPZÏ…‡ ^ž¡¶ŠÅyÔñÇ]'FOÆ^Œßd¬Äȼ•ÙŸ¢ ãF/FÞ›¨Ê8Ý&·ãV^G­#,!*:Ú'ÀñØÜ&ófÞ7_÷rlJ”O/Ÿðä¨è¨dµÜõ9®÷Ííè–˜ç7 1U.{ /%¦Ä$ öé3<6Á'491!F¿6  ™ã~ tNNLI˜êÓ}àÀØèŸW“°¼¹‚ŸCVÿþº?Ó~<ê…OmŽûéiCÃCÔý¬áY3}vÙÌýkîss+ÇÏûŽÑÊÍ|½y¬ê*ñ"JÄŠ8‘*Å "Y¼ÅÖ%;–%ˆþ,!ü÷ó(†ßÄ9ù‰<*†Íq¯œ‡»¾hñ×6ºŽÎuÖÂ`Ö–*’XßóüŒpü˜cÅ ¤²ö8ÖÃ=?Í6Ä󬿯+qxLrB|LBªOXbÜ°ÔØÄ„Çzleäú8·9Æ=;ä> ­æé˜kæíAc/ßu>Uô’sÍ<¾æÜî›#œG‡9Z]¿Oµ´™¯i£›÷ÍyùJç‘^îÜ­KØ_ó·-£?1V¨íuî¿|ÛÿÍþã°ùÙ{g÷Ù{'‘0U÷Ôùò]> ðpŽMØsîï™ã1ó9¸çñÜ >CqÓfr.E|.çÖ\Ý'ç'4˜ÅçÚÎsdÿ›ô9²ïÍÊ9²¿Í9Tç|S7Oö°é‘'{׌˓=k6åÉÞ4¿çÉž4 ß—=h*Ε½ZÄ|>ÛÙo9ù²÷Ê®|Ùså§|Ùc¥jì±ò|ì­^ {©L(½T d/•ݲ—ÊùÙK¥~¡ì¡Q({¨¤Ê*Å…²wÊÁBÙ;åR¡ìâQ${§Ô+’½SBŠtï”˸Y¤{¦ì¡…º7ŠÙ%Ëóž!–p –ü{O“ùÈ_¢{—˜=I~Ç¢•|GD…Õ|ßÄ÷k8žktO‘õy98Šãøbß6èž“>bßbȶs‹îá±ûqaüƒíE=<ƒPtF.fc? |+ßɶêÞ}·ñ]%X‹¬Ù&œÇOx~;ó#13w° ;do‹‚²—Å?°_ì=+üЭq7>ѽ#œ= œ½ìdß Âwê Ξ Î Î^ f„:ز‡ï{dσãøùǾ‡8ލ{˜ã…\¼‡ù(@ Öa;vã[œ>,kàÿ†²G8†GdûވƠ#ºf½³6}ãÌ„!⨮9ÿÖÕ5ã5â5áµßÍï'ŽÉÚí5¿–µÛƒ¿‘5Û[â¾ÃË'm¢çI]«ýA5Ú?ÀZ4ü–c†.èú­¬ÁžŠtLVµÔ¯«Zêž§tÍtgmô…X‚/p·ð'ê&öi]³ÜY£ÜY“ܬ=îµgùN‹“8‡ó¸tVÖоƒ‰?ñÝ °Û°{pÀ¥†´ý"û¯!éÈÄ,„×eò×pׯ0§ðÏ«ÄAíkÌø]g>`𠾿¡ÜMæÐMYc¹3®áöm]ûجÑë{OÖè}ùž¬‰›„lä` >ÀlÂAÇRùÓ…®yë¬]{½Ô}û}²±³Öp4ÞÂ\áG\‚§aˆGÑí‘wƒ\|Œ]ø !2D9##0NÕðuÖî݃ÏË☪Ù€H$¨š½•Ê×e{QޘººV¬³ì Á'؃ øÞOÂÝОb_¢+zb2‰w±ÅX†5ø §ð ®¡ùÓ†h‹X„k¸‰áõˆåRcÖY;¶:¡‹±ûñîá¹g˜s8ó,ù€M É54ò峇ð3†5b¾ã¥ç Ñ#1»±~y_˜Œ©(Âr”`#|ýXF`4 PŒoq­žçX"sð ~Å£þ¼4EsôA_LÄ$,Ær\Âuø°D »ñ9z6aŽ6Ñ5rµoŸ dNa Ò±+p§àdˆÊˆER‘†•(Ñ”ç  Ç3ðEK´i*ëéö°Ë:º§í²Žnr3Y?÷&žjnˆ.õr+¶`¾¡9Z·urgá3ìÓ-9â}b-6Ã'„厑(@±K]Ùk¸…­˜“hƒ[麲Îz²¿áOŒm͹Y˜ÚZ×kuÖa}‘Ø„­mþ½®j˶¬q϶㸠K{ö‡ª[jÖ+ÍéÀû3k”vâ÷ø¤ëýõ;u;; ¹ÈÃw¸Œ»3'‘iª^ç|UŸó…s6BÐÓ‹|,|E×ÙtÖÓŒëÁqî!ëgšµ3ç¡ ‡¬‘iÖÇtÖÄÜÆg ~Äe<Ö‹}‹æÁHL@2qß BoCxõ–µ#Ÿì-kDöÃ",ÁGØ…»(EÍpŽ+zá5|Œân¢þ«ì;ôC4b8бà.¼úð¹…pôA2ÆbÖ£fÛƒnè‰tdb3>Æ'"x“0™ÈB6R1Sñ.r0 Ó13‘‹Y˜÷0yxs1ó±ù(@!аÅX„ÅX‚¥X†åX•ø«°%XƒµX‡õø°›°a îñ]ÇÉ}Ó·]ÿ5—Ǿ86߯–WîÑè¹;«;˜×þ¶ìóZ­º^ks\‹’×h“Ô5*ó±y¬`ª y­Ø¼Î¶YÈk²;„¼–ûªá×~¿2ö%qÿ5^„Ƥ&'&ÄF7Hñ u_ÿ³výÔŒ™Â;2ÇyXWñ÷ëÃ=ùW^6c·çQR¿CxÇîÛŠn÷mÅÚ†&Ìsœñ€mp>×¼oÎHÑ˱® ,üù7€»üëuM˜Mæ8ÅR¼&.ñwŒ“,Å p‰÷˜co)žÿ_¯ ÞŽq¤…xÁ¢¹K¼ÚŽ1ÅR¼f.ñª:ÆxKñì.ñuŒƒ,Å v‰÷ˆcŒ²¯©K²OçG°Êõ–âéüVù±ÊR<Á*?–ZЧó#XåG‘¥x:?‚U~̳OçG°ÊÙ–âéüVù1ÍR<v•Ùâ5qÉ»Ê Kñt~ØU~ŒµOç‡]åÇKñt~ØU~ µOç‡]åÇKñt~ØU~ÄXЧóîò#ÒR<v•–âéü°«ü³OçGÊ®â¸äGÊPKñt~©ühk)žÎ •-,ÅÓù¤ò£©¥x:?‚T~'Šmƒí0c1 q_£eCt@ Ò°%X‡ø¢}4û}ùÈÇfìÄ ÜA¿†ˆÁtÌÂm܃w Û„0D /ÞB–à2®ÀhˆJèˆNèx,@1Ê 2DLÄdìÅ!Á9x6DMtAæÇò:|…Søî â[†ðB[tB FáÎÁbˆ²hPD"Ó‹Xm8ˆ qlÚ #:# ™˜]8€ñ†xÑ}ñÒ0k°p×p ¾ †ðG4‘ŽÉx<‘}‹.èQØŠí8[’!A{„¡‹±ÛpWP~¨!*#ƒxdb*vcŒdž‡'Qb+®ã7sy y>xQˆCVà~FP*9†Î膑Ù˜‹8„Kø*3DU„¢+Æc ò±à у‘€(Áiü€Ÿp># ñ,"ð&¦"EXƒïq¥¨œfˆV耥(ÁIœEõ‘ìøÀQŠ…XŽ“8…«(Å £È9„#³1¶ÑìûѺânìÃÃ78‹[¸‹6cؘˆ,ØÆ¢ ’Šø7qÞã ñ4Ú¢#<'0ÿÑÑ}1X‰-ø×Pw"ǽÑÃ0Û° "|‰h,ÅJÀaÔÌ`[Ðoâ]ÌÆ*¬Å9œÇCo“ëðCôD8ÞG>Öb.ã*Nâý Ã0Ó±;a›ÌþA"0oc5Öâ0Ž¡^&¹ «>¡è>ŠaÈDN¦îù#.à"®à‰,ÎÕÈžÂù§"#1‘3 1cŽÉÈFû\ÎGHÄ0ŒÂìÇa”ŸÅûÄlÂUÜF»ÙC¤#»°¾ïñ^i8Ìes8N‹‰Øˆ-x"íÆëˆD2qß ÂûœŸ‚6…±œÇ2œ)&Ç ±¿QO¡ü„ˆÄ@d"K° ŸâsœÇ%ˆÅ†x у0y(Ä|Ûö š¡%`0J°Gñ5lKÙ.tCÆ"«±q7pµ—‘ÛèW‡$bŽãª/7D-tA8úc º­àµx o Éq(ÄR|õyâU†X†ÓøðÊ®æ\>è‡",ÃAA½C4BtG Ò°p¿ã.^ÃüÇÛxÓ°«°»±±ýCæ.á*þ…28£úmbžn’ý ý>µÖ'Pö tsssssssssssssssssû_bVø}PÕ^C8köž'ÄyøŸ³9„(‘Êpå¢Rû;©­‡o †(VY†Ew”É6„7Œ)†¨;Úa ¦X¿®¦®­=Äû²æÁ{˹ܼýw·µ÷_×þ|,ª‰ŒÒÒÒ´¦3jŠÒ*÷ÿ˜Õ#JK?ôCõÿð»K]®=Üä»;ÿþ›Ò*^â̵wö±qU·w{ö}>Çö9uÚ«iÓÂåb×¥Uc Mã6š@hz¶×.Mì8upCH.¡¡ȪJ $õ ™À|üa"µ2…PE(ª"%X.è'¥üAüÅ{»{»³{³·¹=+4b'šÜÍÍÍo÷í¾yóÞyfgÛƒâä;»ñꎭè4>¿­„W·és/–$‡'/¹@¾ª"xñ,ýÒÃÀ^iÿYeõë';xí^Yÿù‡ãO=É«{±þÛþòþI?¯nhÏþ»îßxáe^ÝV…W½ñì}ß\,¯7Hð覯|8õƒ7År®K~½ñÛkæ.'êxÌÇwö&¦¦žMòêÖ}fø“¼ø¯nmço[¿qïἺÅÛÞlûÛ™îí¼ºéžS;~qêG+xu?nœ~ìÈ÷Ç>Ä«ûÇGV¶7¸WáÕýÎûÞÓßm<Ê««\wç¡6–½Ê«£‰5›J£åCç…Š¡“ Uoˆà:/xwa9…åÍ­.ØÒJOÔÄæ¿Ìê¢DÑíRÝ.Dt»ÌaÑ-Ï€* 1äVCnD ¹ ˆçhù"œh 6œ «•`}~ÖçGXŸ_†yæ]˜ À^0Êg×\ª›KØ\*EŠFØk¦g'ÃÂe*,\†°pY¢^ «°+a„] )êX¥ «DàXe¢¦«UXºaéê"DMÖª°d-Â’µEŠ«S±:Æê¬EÕXX“G…5yÖä±5;ˆ……$؈¨ÂFD„ˆÓAl—LCNªÊÛò h 3ëùî%V›·XÝK°*o?°%ªY°%ªY°-ªY?È'ªcw»{3Û]k¦2›Jä놾GR¹nä{Œ¡ï‘\` Š™ »²+ „ft€&æe%#¨ ‰y@ÍÈÒf)"—BnTb^ïF%ЍPâ’åVH>)…]rdN"¥¨K¦°KŽÌi$CŠãÙi´‡–AZX¦eˆ–AZ˜¡ ´8:ÿ 1ûÀ†˜Æ‘.=++tiéÒ³±”CŒ£ü,5”C ã—¹&÷NòÂ8äe®iÔ 5ŽŠŽ\n$Ó`šº¦LS ¹<9ŽW[O¯0ÐÞŠ¡óÿ‘è /ÒÞ–5z…=ŽAV~móð kÝ% +Éc¢yn…𲃬rÛ¢Þ*·-² Aa€éyð1Ëp+ sYø6˜ex,e!³«È¢š]½,¢¥,|kË2¼–²ð,ËðYÊBvU‘Eµ«zYü Ã\Ù,£ÁBF¾[ÄÈaÇ¡-ع°%ª]‡Öôìì8´;¶DµëКžÝ’:´Ž; |S+ð’÷~Ÿ óûæ÷>Ü_ ¨ÃÊÅ2. îGƒêyŒ‘1,|¸,WƒåÈ,/|¸o‰¨²´DÑ)|¸V©ç­BF´ªðá~¦FeÌÔ c¦¦ðá~|¹*ËørdŒ/ç ÷w¸9Ñ“üCóË­d-å_nuJF¿õ*—„B…¢.º$n5“Ô,ê¦ L‡ñ@Ö΢ŒqT(* jÕß¿ iÛ$ª¿_òëR«8C0Šº7îùà¼fÖ&Ð=œ×áü`ôÐ5¤>¢ E=tÝцÏÌi†mmøÌœY’ƒô豺°*ÉÄ•T í˜ÓÔj¬$…e6ÈÅŠ4[…¢^¥÷MÎjÚF½orV‡.3E{x&À E}4JâÐÑ$ã%¿s‡Ž&=>œïË9„e…¢~e0Qb¸Ì­Ê`’º¦;DÄòYï—íú.Åwx}Á¼kó}†ÂL.¹ J×VÝ„BM.ß;(ÌäZGiÖ&—n"‹êjrùÃa&×:J³6¹4Ð+²¨½a9ªa9 ì(0¥k,Ìrº‚^T0À²©R‚™…kIeóð]˜{iÄG!ÿyÙˆüxç%Ã(j;ÉøÑµYÁÒ¹0ù~ò÷"þ†Éålþ¹–‚:¦u¶EåGwEˆÊõlÚ^3séü¹6¿¨ÎŸkí‹jgšŒã<8ÎÃMí<8 ì(°£ÀŽSrø¾ÙP`W,”¦ƒ\ÏL[³~`+ž1ë¶â³>`;ž1ë¶D5ë¶D5ë¶E5ë7Êîšÿ˜íLãÒ3þÿ¦q]ˆBž_¥Ì”ÍüW©t.ª¸!ž´?ěœU öDý_¯J äh# :n(Ó:@¶LëíØ2­YdË´6-Ó:;¶LkµÒw´F-ÓúA¶LkÙ2­±&ѺA¶Lk÷Ø2­×cË´Ž’-ÓH¶Lk7Ù2­=dË´~“-Ó:P¶Lë-Ùrþí‹IÕPXÒZDðîÍ_‡­Â ð«Ç_…ß‚ŸG¾§o9£ž†G{ Ö,ÿ \žƒKç`ôuèè~ >îù3ìþÔ;ð’÷2Lm˜‚£LCCý»ø;Œ¼qá*œÙtžø7ì8< ‹Íî´ ŽOÉyd¤ÅE‹]è=¥ì«õl·Ÿ ISzš©cS¥> ûÔç¤ï“>õƒ–äoÑ+y/²‘gßÓ„®‡ªÉ©¯[ôˆ‚ÛóÜ!ˆáÇé,GAÀ6è½ÒN–1iÏÊ/á+íuI»_îÃúõÈAoOt .ŸWP'…1n9¤é¿­ð ¶éÚàc+¥£—z=%Ó£úñøíR›»×Jm|ž€ ˆ‚Çcœ—õïhïÍ©íÆ °a½Üέ´3;–¾]VZ€{½’„†£åJ¸[îƒ'¤§ÛÓëü¬•ymàD2ç…iìwþ°¡{cªcheå²îÓáp@WÀïwP AßðЄ)Ñø©K9ÛÝaí¤BRŸD< gáØ±È:º…µx·ÐEy7\ÊÅ$­u°áøºOþK938™Ô"¹Cþ =dµAÞõGû£f™Œ¥†ÒâbDyçÞ–Ý!¦ìNA«¹ÚP+àç1ìÑ1xTÚK¡SÚO!­¨ù´_BtcݧñÝAI‡cðÖ÷J;4ð];²%²³DM â5b D-bŸ b}Ï)ˆö)Ì%˜K1Ó¿æ2Ìå˜Ã˜+0G0Wb^†¹Jšy£’K²{ñ*lF;õ¤uCŠHöUKÖ-P@Þßh©R¡Ç_êt3ß ‹î™á È}yB®ÚH~þÃ=ý½z»žŽmîêêéÜÛÞÛ¿;ö@oçm¶-ÍA~x+}†I£½gëãMðþ=g–ò^;iiÓPKôŒë.u£ë¶a ¶EsnaccOriginalMaterial.docPKLŒ05Ú‘‰ñ|  ¶8aEsnacc.docPK€éResnacc-ng-1.8.1/licenseq.txt000066400000000000000000000003711302010526100157120ustar00rootroot00000000000000See discussion @ http://www.imc.org/imc-sfl/mail-archive/msg00498.html Summary here: The SNACC compiler is GPLv2 The SNACC library is public domain Therefore, any compiler enhancements MUST be GPL Any library enhancements SHOULD be public domain esnacc-ng-1.8.1/m4/000077500000000000000000000000001302010526100136655ustar00rootroot00000000000000esnacc-ng-1.8.1/m4/.gitignore000066400000000000000000000000771302010526100156610ustar00rootroot00000000000000libtool.m4 ltoptions.m4 ltsugar.m4 ltversion.m4 lt~obsolete.m4 esnacc-ng-1.8.1/m4/ax_code_coverage.m4000066400000000000000000000156661302010526100174220ustar00rootroot00000000000000# SYNOPSIS # # AX_CODE_COVERAGE() # # DESCRIPTION # # Defines CODE_COVERAGE_CFLAGS and CODE_COVERAGE_LDFLAGS which should be # included in the CFLAGS and LIBS/LDFLAGS variables of every build target # (program or library) which should be built with code coverage support. # Also defines CODE_COVERAGE_RULES which should be substituted in your # Makefile; and $enable_code_coverage which can be used in subsequent # configure output. CODE_COVERAGE_ENABLED is defined and substituted, and # corresponds to the value of the --enable-code-coverage option, which # defaults to being disabled. # # Note that all optimisation flags in CFLAGS must be disabled when code # coverage is enabled. # # Usage example: # configure.ac: # AX_CODE_COVERAGE # # Makefile.am: # @CODE_COVERAGE_RULES@ # my_program_LIBS = … $(CODE_COVERAGE_LDFLAGS) … # my_program_CFLAGS = … $(CODE_COVERAGE_CFLAGS) … # # This results in a “check-code-coverage†rule being added to any Makefile.am # which includes “@CODE_COVERAGE_RULES@†(assuming the module has been # configured with --enable-code-coverage). Running `make check-code-coverage` # in that directory will run the module’s test suite (`make check`) and build # a code coverage report detailing the code which was touched, then print the # URI for the report. # # LICENSE # # Copyright © 2012, 2014 Philip Withnall # Copyright © 2012 Xan Lopez # Copyright © 2012 Christian Persch # Copyright © 2012 Paolo Borelli # Copyright © 2012 Dan Winship # # Derived from Makefile.decl in GLib, originally licenced under LGPLv2.1+. # This file is licenced under LGPLv2.1+. #serial 1 AC_DEFUN([AX_CODE_COVERAGE],[ dnl Check for --enable-code-coverage AC_MSG_CHECKING([whether to build with code coverage support]) AC_ARG_ENABLE([code-coverage], AS_HELP_STRING([--enable-code-coverage], [Whether to enable code coverage support]),, enable_code_coverage=no) AM_CONDITIONAL([CODE_COVERAGE_ENABLED], [test x$enable_code_coverage = xyes]) AC_SUBST([CODE_COVERAGE_ENABLED], [$enable_code_coverage]) AC_MSG_RESULT($enable_code_coverage) AS_IF([ test "$enable_code_coverage" = "yes" ], [ dnl Check if gcc is being used AS_IF([ test "$GCC" = "no" ], [ AC_MSG_ERROR([not compiling with gcc, which is required for gcov code coverage]) ]) # List of supported lcov versions. lcov_version_list="1.6 1.7 1.8 1.9 1.10 1.11 1.12" AC_CHECK_PROG([LCOV], [lcov], [lcov]) AC_CHECK_PROG([GENHTML], [genhtml], [genhtml]) AS_IF([ test "$LCOV" ], [ AC_CACHE_CHECK([for lcov version], ax_cv_lcov_version, [ ax_cv_lcov_version=invalid lcov_version=`$LCOV -v 2>/dev/null | $SED -e 's/^.* //'` for lcov_check_version in $lcov_version_list; do if test "$lcov_version" = "$lcov_check_version"; then ax_cv_lcov_version="$lcov_check_version (ok)" fi done ]) ], [ lcov_msg="To enable code coverage reporting you must have one of the following lcov versions installed: $lcov_version_list" AC_MSG_ERROR([$lcov_msg]) ]) case $ax_cv_lcov_version in ""|invalid[)] lcov_msg="You must have one of the following versions of lcov: $lcov_version_list (found: $lcov_version)." AC_MSG_ERROR([$lcov_msg]) LCOV="exit 0;" ;; esac AS_IF([ test -z "$GENHTML" ], [ AC_MSG_ERROR([Could not find genhtml from the lcov package]) ]) dnl Build the code coverage flags CODE_COVERAGE_CFLAGS="-O0 -g -fprofile-arcs -ftest-coverage" CODE_COVERAGE_CXXFLAGS="-O0 -g -fprofile-arcs -ftest-coverage" CODE_COVERAGE_LDFLAGS="-lgcov" AC_SUBST([CODE_COVERAGE_CFLAGS]) AC_SUBST([CODE_COVERAGE_LDFLAGS]) ]) CODE_COVERAGE_RULES=' # Code coverage # # Optional: # - CODE_COVERAGE_DIRECTORY: Top-level directory for code coverage reporting. # (Default: $(top_builddir)) # - CODE_COVERAGE_OUTPUT_FILE: Filename and path for the .info file generated # by lcov for code coverage. (Default: # $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info) # - CODE_COVERAGE_OUTPUT_DIRECTORY: Directory for generated code coverage # reports to be created. (Default: # $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage) # - CODE_COVERAGE_LCOV_OPTIONS: Extra options to pass to the lcov instance. # (Default: empty) # - CODE_COVERAGE_GENHTML_OPTIONS: Extra options to pass to the genhtml # instance. (Default: empty) # - CODE_COVERAGE_IGNORE_PATTERN: Extra glob pattern of files to ignore # # The generated report will be titled using the $(PACKAGE_NAME) and # $(PACKAGE_VERSION). In order to add the current git hash to the title, # use the git-version-gen script, available online. # Optional variables CODE_COVERAGE_DIRECTORY ?= $(top_builddir) CODE_COVERAGE_OUTPUT_FILE ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info CODE_COVERAGE_OUTPUT_DIRECTORY ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage CODE_COVERAGE_LCOV_OPTIONS ?= CODE_COVERAGE_GENHTML_OPTIONS ?= CODE_COVERAGE_IGNORE_PATTERN ?= code_coverage_quiet = $(code_coverage_quiet_$(V)) # Use recursive makes in order to ignore errors during check check-code-coverage: ifeq ($(CODE_COVERAGE_ENABLED),yes) -$(MAKE) $(AM_MAKEFLAGS) -k check $(MAKE) $(AM_MAKEFLAGS) code-coverage-capture else @echo "Need to reconfigure with --enable-code-coverage" endif # Capture code coverage data code-coverage-capture: code-coverage-capture-hook ifeq ($(CODE_COVERAGE_ENABLED),yes) $(LCOV) $(code_coverage_quiet) --directory $(CODE_COVERAGE_DIRECTORY) --capture --output-file "$(CODE_COVERAGE_OUTPUT_FILE).tmp" --test-name "$(PACKAGE_NAME)-$(PACKAGE_VERSION)" --no-checksum --compat-libtool $(CODE_COVERAGE_LCOV_OPTIONS) $(LCOV) $(code_coverage_quiet) --directory $(CODE_COVERAGE_DIRECTORY) --remove "$(CODE_COVERAGE_OUTPUT_FILE).tmp" "/tmp/*" $(CODE_COVERAGE_IGNORE_PATTERN) --output-file "$(CODE_COVERAGE_OUTPUT_FILE)" -@rm -f $(CODE_COVERAGE_OUTPUT_FILE).tmp LANG=C $(GENHTML) $(code_coverage_quiet) --prefix $(CODE_COVERAGE_DIRECTORY) --output-directory "$(CODE_COVERAGE_OUTPUT_DIRECTORY)" --title "$(PACKAGE_NAME)-$(PACKAGE_VERSION) Code Coverage" --legend --show-details "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_GENHTML_OPTIONS) @echo "file://$(abs_builddir)/$(CODE_COVERAGE_OUTPUT_DIRECTORY)/index.html" else @echo "Need to reconfigure with --enable-code-coverage" endif # Hook rule executed before code-coverage-capture, overridable by the user code-coverage-capture-hook: ifeq ($(CODE_COVERAGE_ENABLED),yes) clean: code-coverage-clean code-coverage-clean: -$(LCOV) --directory $(top_builddir) -z -rm -rf $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_FILE).tmp $(CODE_COVERAGE_OUTPUT_DIRECTORY) -find . -name "*.gcda" -o -name "*.gcov" -delete endif GITIGNOREFILES ?= GITIGNOREFILES += $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_DIRECTORY) DISTCHECK_CONFIGURE_FLAGS ?= DISTCHECK_CONFIGURE_FLAGS += --disable-code-coverage .PHONY: check-code-coverage code-coverage-capture code-coverage-capture-hook code-coverage-clean ' AC_SUBST([CODE_COVERAGE_RULES]) m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([CODE_COVERAGE_RULES])]) ]) esnacc-ng-1.8.1/m4/ax_pthread.m4000066400000000000000000000505201302010526100162500ustar00rootroot00000000000000# =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_pthread.html # =========================================================================== # # SYNOPSIS # # AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) # # DESCRIPTION # # This macro figures out how to build C programs using POSIX threads. It # sets the PTHREAD_LIBS output variable to the threads library and linker # flags, and the PTHREAD_CFLAGS output variable to any special C compiler # flags that are needed. (The user can also force certain compiler # flags/libs to be tested by setting these environment variables.) # # Also sets PTHREAD_CC to any special C compiler that is needed for # multi-threaded programs (defaults to the value of CC otherwise). (This # is necessary on AIX to use the special cc_r compiler alias.) # # NOTE: You are assumed to not only compile your program with these flags, # but also to link with them as well. For example, you might link with # $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS # # If you are only building threaded programs, you may wish to use these # variables in your default LIBS, CFLAGS, and CC: # # LIBS="$PTHREAD_LIBS $LIBS" # CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # CC="$PTHREAD_CC" # # In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant # has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to # that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). # # Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the # PTHREAD_PRIO_INHERIT symbol is defined when compiling with # PTHREAD_CFLAGS. # # ACTION-IF-FOUND is a list of shell commands to run if a threads library # is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it # is not found. If ACTION-IF-FOUND is not specified, the default action # will define HAVE_PTHREAD. # # Please let the authors know if this macro fails on any platform, or if # you have any other suggestions or comments. This macro was based on work # by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help # from M. Frigo), as well as ac_pthread and hb_pthread macros posted by # Alejandro Forero Cuervo to the autoconf macro repository. We are also # grateful for the helpful feedback of numerous users. # # Updated for Autoconf 2.68 by Daniel Richard G. # # LICENSE # # Copyright (c) 2008 Steven G. Johnson # Copyright (c) 2011 Daniel Richard G. # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, either version 3 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 23 AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) AC_DEFUN([AX_PTHREAD], [ AC_REQUIRE([AC_CANONICAL_HOST]) AC_REQUIRE([AC_PROG_CC]) AC_REQUIRE([AC_PROG_SED]) AC_LANG_PUSH([C]) ax_pthread_ok=no # We used to check for pthread.h first, but this fails if pthread.h # requires special compiler flags (e.g. on Tru64 or Sequent). # It gets checked for in the link test anyway. # First of all, check if the user has set any of the PTHREAD_LIBS, # etcetera environment variables, and if threads linking works using # them: if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then ax_pthread_save_CC="$CC" ax_pthread_save_CFLAGS="$CFLAGS" ax_pthread_save_LIBS="$LIBS" AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"]) CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS]) AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes]) AC_MSG_RESULT([$ax_pthread_ok]) if test "x$ax_pthread_ok" = "xno"; then PTHREAD_LIBS="" PTHREAD_CFLAGS="" fi CC="$ax_pthread_save_CC" CFLAGS="$ax_pthread_save_CFLAGS" LIBS="$ax_pthread_save_LIBS" fi # We must check for the threads library under a number of different # names; the ordering is very important because some systems # (e.g. DEC) have both -lpthread and -lpthreads, where one of the # libraries is broken (non-POSIX). # Create a list of thread flags to try. Items starting with a "-" are # C compiler flags, and other items are library names, except for "none" # which indicates that we try without any flags at all, and "pthread-config" # which is a program returning the flags for the Pth emulation library. ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: # pthreads: AIX (must check this before -lpthread) # none: in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) # -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64 # (Note: HP C rejects this with "bad form for `-t' option") # -pthreads: Solaris/gcc (Note: HP C also rejects) # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it # doesn't hurt to check since this sometimes defines pthreads and # -D_REENTRANT too), HP C (must be checked before -lpthread, which # is present but should not be used directly; and before -mthreads, # because the compiler interprets this as "-mt" + "-hreads") # -mthreads: Mingw32/gcc, Lynx/gcc # pthread: Linux, etcetera # --thread-safe: KAI C++ # pthread-config: use pthread-config program (for GNU Pth library) case $host_os in freebsd*) # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) ax_pthread_flags="-kthread lthread $ax_pthread_flags" ;; hpux*) # From the cc(1) man page: "[-mt] Sets various -D flags to enable # multi-threading and also sets -lpthread." ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags" ;; openedition*) # IBM z/OS requires a feature-test macro to be defined in order to # enable POSIX threads at all, so give the user a hint if this is # not set. (We don't define these ourselves, as they can affect # other portions of the system API in unpredictable ways.) AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING], [ # if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS) AX_PTHREAD_ZOS_MISSING # endif ], [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])]) ;; solaris*) # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based # tests will erroneously succeed. (N.B.: The stubs are missing # pthread_cleanup_push, or rather a function called by this macro, # so we could check for that, but who knows whether they'll stub # that too in a future libc.) So we'll check first for the # standard Solaris way of linking pthreads (-mt -lpthread). ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags" ;; esac # GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) AS_IF([test "x$GCC" = "xyes"], [ax_pthread_flags="-pthread -pthreads $ax_pthread_flags"]) # The presence of a feature test macro requesting re-entrant function # definitions is, on some systems, a strong hint that pthreads support is # correctly enabled case $host_os in darwin* | hpux* | linux* | osf* | solaris*) ax_pthread_check_macro="_REENTRANT" ;; aix*) ax_pthread_check_macro="_THREAD_SAFE" ;; *) ax_pthread_check_macro="--" ;; esac AS_IF([test "x$ax_pthread_check_macro" = "x--"], [ax_pthread_check_cond=0], [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"]) # Are we compiling with Clang? AC_CACHE_CHECK([whether $CC is Clang], [ax_cv_PTHREAD_CLANG], [ax_cv_PTHREAD_CLANG=no # Note that Autoconf sets GCC=yes for Clang as well as GCC if test "x$GCC" = "xyes"; then AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG], [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ # if defined(__clang__) && defined(__llvm__) AX_PTHREAD_CC_IS_CLANG # endif ], [ax_cv_PTHREAD_CLANG=yes]) fi ]) ax_pthread_clang="$ax_cv_PTHREAD_CLANG" ax_pthread_clang_warning=no # Clang needs special handling, because older versions handle the -pthread # option in a rather... idiosyncratic way if test "x$ax_pthread_clang" = "xyes"; then # Clang takes -pthread; it has never supported any other flag # (Note 1: This will need to be revisited if a system that Clang # supports has POSIX threads in a separate library. This tends not # to be the way of modern systems, but it's conceivable.) # (Note 2: On some systems, notably Darwin, -pthread is not needed # to get POSIX threads support; the API is always present and # active. We could reasonably leave PTHREAD_CFLAGS empty. But # -pthread does define _REENTRANT, and while the Darwin headers # ignore this macro, third-party headers might not.) PTHREAD_CFLAGS="-pthread" PTHREAD_LIBS= ax_pthread_ok=yes # However, older versions of Clang make a point of warning the user # that, in an invocation where only linking and no compilation is # taking place, the -pthread option has no effect ("argument unused # during compilation"). They expect -pthread to be passed in only # when source code is being compiled. # # Problem is, this is at odds with the way Automake and most other # C build frameworks function, which is that the same flags used in # compilation (CFLAGS) are also used in linking. Many systems # supported by AX_PTHREAD require exactly this for POSIX threads # support, and in fact it is often not straightforward to specify a # flag that is used only in the compilation phase and not in # linking. Such a scenario is extremely rare in practice. # # Even though use of the -pthread flag in linking would only print # a warning, this can be a nuisance for well-run software projects # that build with -Werror. So if the active version of Clang has # this misfeature, we search for an option to squash it. AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread], [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG], [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown # Create an alternate version of $ac_link that compiles and # links in two steps (.c -> .o, .o -> exe) instead of one # (.c -> exe), because the warning occurs only in the second # step ax_pthread_save_ac_link="$ac_link" ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"` ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" ax_pthread_save_CFLAGS="$CFLAGS" for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do AS_IF([test "x$ax_pthread_try" = "xunknown"], [break]) CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" ac_link="$ax_pthread_save_ac_link" AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], [ac_link="$ax_pthread_2step_ac_link" AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], [break]) ]) done ac_link="$ax_pthread_save_ac_link" CFLAGS="$ax_pthread_save_CFLAGS" AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no]) ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" ]) case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in no | unknown) ;; *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; esac fi # $ax_pthread_clang = yes if test "x$ax_pthread_ok" = "xno"; then for ax_pthread_try_flag in $ax_pthread_flags; do case $ax_pthread_try_flag in none) AC_MSG_CHECKING([whether pthreads work without any flags]) ;; -mt,pthread) AC_MSG_CHECKING([whether pthreads work with -mt -lpthread]) PTHREAD_CFLAGS="-mt" PTHREAD_LIBS="-lpthread" ;; -*) AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag]) PTHREAD_CFLAGS="$ax_pthread_try_flag" ;; pthread-config) AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) AS_IF([test "x$ax_pthread_config" = "xno"], [continue]) PTHREAD_CFLAGS="`pthread-config --cflags`" PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" ;; *) AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag]) PTHREAD_LIBS="-l$ax_pthread_try_flag" ;; esac ax_pthread_save_CFLAGS="$CFLAGS" ax_pthread_save_LIBS="$LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" # Check for various functions. We must include pthread.h, # since some functions may be macros. (On the Sequent, we # need a special flag -Kthread to make this header compile.) # We check for pthread_join because it is in -lpthread on IRIX # while pthread_create is in libc. We check for pthread_attr_init # due to DEC craziness with -lpthreads. We check for # pthread_cleanup_push because it is one of the few pthread # functions on Solaris that doesn't have a non-functional libc stub. # We try pthread_create on general principles. AC_LINK_IFELSE([AC_LANG_PROGRAM([#include # if $ax_pthread_check_cond # error "$ax_pthread_check_macro must be defined" # endif static void routine(void *a) { a = 0; } static void *start_routine(void *a) { return a; }], [pthread_t th; pthread_attr_t attr; pthread_create(&th, 0, start_routine, 0); pthread_join(th, 0); pthread_attr_init(&attr); pthread_cleanup_push(routine, 0); pthread_cleanup_pop(0) /* ; */])], [ax_pthread_ok=yes], []) CFLAGS="$ax_pthread_save_CFLAGS" LIBS="$ax_pthread_save_LIBS" AC_MSG_RESULT([$ax_pthread_ok]) AS_IF([test "x$ax_pthread_ok" = "xyes"], [break]) PTHREAD_LIBS="" PTHREAD_CFLAGS="" done fi # Various other checks: if test "x$ax_pthread_ok" = "xyes"; then ax_pthread_save_CFLAGS="$CFLAGS" ax_pthread_save_LIBS="$LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. AC_CACHE_CHECK([for joinable pthread attribute], [ax_cv_PTHREAD_JOINABLE_ATTR], [ax_cv_PTHREAD_JOINABLE_ATTR=unknown for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], [int attr = $ax_pthread_attr; return attr /* ; */])], [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break], []) done ]) AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \ test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \ test "x$ax_pthread_joinable_attr_defined" != "xyes"], [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], [$ax_cv_PTHREAD_JOINABLE_ATTR], [Define to necessary symbol if this constant uses a non-standard name on your system.]) ax_pthread_joinable_attr_defined=yes ]) AC_CACHE_CHECK([whether more special flags are required for pthreads], [ax_cv_PTHREAD_SPECIAL_FLAGS], [ax_cv_PTHREAD_SPECIAL_FLAGS=no case $host_os in solaris*) ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" ;; esac ]) AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \ test "x$ax_pthread_special_flags_added" != "xyes"], [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS" ax_pthread_special_flags_added=yes]) AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], [ax_cv_PTHREAD_PRIO_INHERIT], [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[int i = PTHREAD_PRIO_INHERIT;]])], [ax_cv_PTHREAD_PRIO_INHERIT=yes], [ax_cv_PTHREAD_PRIO_INHERIT=no]) ]) AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \ test "x$ax_pthread_prio_inherit_defined" != "xyes"], [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.]) ax_pthread_prio_inherit_defined=yes ]) CFLAGS="$ax_pthread_save_CFLAGS" LIBS="$ax_pthread_save_LIBS" # More AIX lossage: compile with *_r variant if test "x$GCC" != "xyes"; then case $host_os in aix*) AS_CASE(["x/$CC"], [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], [#handle absolute path differently from PATH based program lookup AS_CASE(["x$CC"], [x/*], [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) ;; esac fi fi test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" AC_SUBST([PTHREAD_LIBS]) AC_SUBST([PTHREAD_CFLAGS]) AC_SUBST([PTHREAD_CC]) # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: if test "x$ax_pthread_ok" = "xyes"; then ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) : else ax_pthread_ok=no $2 fi AC_LANG_POP ])dnl AX_PTHREAD esnacc-ng-1.8.1/m4/warnings.m4000066400000000000000000000025141302010526100157610ustar00rootroot00000000000000# -*- autoconf -*- dnl Tries to enable -Wall -Wextra on systems which support it. AC_DEFUN([ESNACC_CHECK_WARNINGS], [AC_LANG_PUSH([C]) AC_MSG_CHECKING(for C-compiler all-warnings support with -Wall) old_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Wall" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])], AC_MSG_RESULT(yes), AC_MSG_RESULT(no) CFLAGS="$old_CFLAGS") AC_MSG_CHECKING(for C-compiler extra-warnings support with -Wextra) old_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Wextra" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])], AC_MSG_RESULT(yes), AC_MSG_RESULT(no) CFLAGS="$old_CFLAGS") AC_LANG_POP() AC_LANG_PUSH([C++]) AC_MSG_CHECKING(for C++-compiler all-warnings support with -Wall) old_CXXFLAGS="$CXXFLAGS" CXXFLAGS="$CXXFLAGS -Wall" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])], AC_MSG_RESULT(yes), AC_MSG_RESULT(no) CXXFLAGS="$old_CXXFLAGS") AC_MSG_CHECKING(for C++-compiler extra-warnings support with -Wextra) old_CXXFLAGS="$CXXFLAGS" CXXFLAGS="$CXXFLAGS -Wextra" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])], AC_MSG_RESULT(yes), AC_MSG_RESULT(no) CXXFLAGS="$old_CXXFLAGS") AC_LANG_POP() ]) esnacc-ng-1.8.1/m4/windows.m4000066400000000000000000000024321302010526100156220ustar00rootroot00000000000000# -*- autoconf -*- dnl Checks for WINDOWS. AC_DEFUN([ESNACC_CHECK_WIN32], [AC_CHECK_HEADER([windows.h], [WIN32=yes], [WIN32=no]) AM_CONDITIONAL([WIN32], [test "$WIN32" = yes]) if test "$WIN32" = yes; then AC_ARG_WITH([pthread], [AS_HELP_STRING([--with-pthread=DIR], [root of the pthread-win32 directory])], [ case "$withval" in "" | y | ye | yes | n | no) AC_MSG_ERROR([Invalid --with-pthread value]) ;; *) PTHREAD_WIN32_DIR=$withval/lib/x86 PTHREAD_WIN32_DIR_DLL=/$(echo ${withval} | ${SED} -e 's/://')/dll/x86 PTHREAD_WIN32_DIR_DLL_WIN_FORM=$withval/dll/x86 PTHREAD_INCLUDES=-I$withval/include PTHREAD_LDFLAGS=-L$PTHREAD_WIN32_DIR PTHREAD_LIBS="-lpthreadVC2" AC_SUBST([PTHREAD_WIN32_DIR_DLL_WIN_FORM]) AC_SUBST([PTHREAD_WIN32_DIR_DLL]) AC_SUBST([PTHREAD_INCLUDES]) AC_SUBST([PTHREAD_LDFLAGS]) AC_SUBST([PTHREAD_LIBS]) ;; esac ], [ AC_MSG_ERROR([pthread directory not specified]) ] ) AC_DEFINE([WIN32], [1], [Define to 1 when building for WINDOWS]) fi]) esnacc-ng-1.8.1/m4/xsltproc.m4000066400000000000000000000020071302010526100160040ustar00rootroot00000000000000# AC_CHECK_XSLTPROC # NOTE: The win32 check MUST have run before this. AC_DEFUN([AC_CHECK_XSLTPROC], [ AC_ARG_WITH(xsltproc, AS_HELP_STRING([--with-xsltproc[[[[[=PATH]]]]]], [Use the xsltproc binary at PATH.]), [ ac_with_xsltproc=$withval; ], [ ac_with_xsltproc=find; ]) if test "$ac_with_xsltproc" = "yes" -o "$ac_with_xsltproc" = "find"; then AC_PATH_PROGS(XSLTPROC,xsltproc) else if test "$ac_with_xsltproc" != "no"; then if test -x "$ac_with_xsltproc"; then XSLTPROC="$ac_with_xsltproc"; else AC_MSG_ERROR([Specified path $ac_with_xsltproc is not executable]) fi else if test "$WIN32" = "yes"; then AC_MSG_NOTICE([Disabling xsltproc check on windows.]) else AC_MSG_ERROR([Cannot disable the XSLTPROC check.]) fi fi fi ]) esnacc-ng-1.8.1/policy.h000066400000000000000000000005541302010526100150210ustar00rootroot00000000000000/* * file: policy.h * */ /* * enable the snacc compiler's Tcl interface generating code? * set it to 0 or 1. */ #ifndef NO_TCL #define NO_TCL 0 #endif /* * enable code for meta code generation? * the Tcl code needs it. */ #ifndef NO_META #define NO_META NO_TCL #endif /* * enable code for CORBA IDL generation? */ #ifndef IDL #define IDL 1 #endif esnacc-ng-1.8.1/redhat/000077500000000000000000000000001302010526100146145ustar00rootroot00000000000000esnacc-ng-1.8.1/redhat/.gitignore000066400000000000000000000000141302010526100165770ustar00rootroot00000000000000esnacc.spec esnacc-ng-1.8.1/redhat/automake.mk000066400000000000000000000012441302010526100167540ustar00rootroot00000000000000# Copyright (C) 2016 Aaron Conole # # Copying and distribution of this file, with or without modification, # are permitted in any medium without royalty provided the copyright # notice and this notice are preserved. This file is offered as-is, # without warranty of any kind. RPMBUILD_TOP ?= $(abs_top_builddir)/rpm/rpmbuild EXTRA_DIST += redhat/esnacc.spec.in \ redhat/esnacc.spec $(srcdir)/redhat/esnacc.spec: redhat/esnacc.spec.in rpm: dist redhat/esnacc.spec ${MKDIR_P} ${RPMBUILD_TOP}/SOURCES cp ${DIST_ARCHIVES} ${RPMBUILD_TOP}/SOURCES rpmbuild ${RPMBUILD_OPT} \ -D "_topdir ${RPMBUILD_TOP}" \ -bb $(srcdir)/redhat/esnacc.spec esnacc-ng-1.8.1/redhat/esnacc.spec.in000066400000000000000000000050521302010526100173330ustar00rootroot00000000000000# Spec file for Enhanced Sample Neufeld ASN.1 C Compiler # Copyright (C) 2016 Aaron Conole # # Copying and distribution of this file, with or without modification, # are permitted in any medium without royalty provided the copyright # notice and this notice are preserved. This file is offered as-is, # without warranty of any kind. # # If tests have to be skipped while building, specify the '--without check' # option. For example: # rpmbuild -bb --without check redhat/esnacc.spec %bcond_without check # some distros (e.g: RHEL-7) don't define _rundir macro yet # Fedora 15 onwards uses /run as _rundir %if 0%{!?_rundir:1} %define _rundir /run %endif Name: esnacc Summary: Enhanced Sample Neufeld ASN.1 C Compiler Group: System Environment/Libraries URL: http://esnacc.org/ Version: @VERSION@ Release: 1 License: Public Domain Source: http://esnacc.org/files/esnacc-%version.tar.gz BuildRequires: flex bison gcc-c++ libtool-ltdl libtool-ltdl-devel BuildRequires: autoconf automake libxslt Requires: libesnacc = %version-%release %description The Enhanced Sample Neufeld ASN.1 C Compiler software is used to compile Abstract Syntax Notation version one (ASN.1) syntax into various source languages. This package provides the actual esnacc compiler which generates the various language sources. %package -n libesnacc Summary: Enhanced Sample Neufeld ASN.1 C Compiler libraries Group: Development/Languages License: GPLv2 %description -n libesnacc The Enhanced Sample Neufeld ASN.1 C Compiler software is used to compile Abstract Syntax Notation version one (ASN.1) syntax into various source languages. This package provides the shared libraries used by applications which use the esnacc framework. %package devel Summary: Header files for %name Group: Development/Languages Requires: %name = %version-%release libesnacc = %version-%release %description devel Header files and static libraries for developing with %name %prep %setup -q %build %configure --enable-static make %{?_smp_mflags} CFLAGS='-Wall -O2 -DYYTEXT_POINTER -fPIC' %install make DESTDIR=%{buildroot} install %clean %files %_bindir/esnacc %_datadir/man/man1/esnacc.1.gz %files -n libesnacc %_libdir/lib*.so %_libdir/lib*.so.* %files devel %_includedir/c-lib/inc %_includedir/cxx-lib/inc %_includedir/snacc.h %_includedir/policy.h %_libdir/lib*.a %_libdir/lib*.la %{_libdir}/pkgconfig/libesnacc.pc %{_libdir}/pkgconfig/libesnaccxx.pc %changelog * Wed Nov 16 2016 Aaron Conole - 1.80-1 - Add missing policy.h * Tue Apr 26 2016 Aaron Conole - 1.80 - First build of esnacc RPM esnacc-ng-1.8.1/scan_script.sh000077500000000000000000000100511302010526100162110ustar00rootroot00000000000000#!/bin/bash set -e # Environment check echo -e "\033[33;1mNote: COVERITY_SCAN_PROJECT_NAME and COVERITY_SCAN_TOKEN are available on Project Settings page on scan.coverity.com\033[0m" [ -z "$COVERITY_SCAN_PROJECT_NAME" ] && echo "ERROR: COVERITY_SCAN_PROJECT_NAME must be set" && exit 1 [ -z "$COVERITY_SCAN_NOTIFICATION_EMAIL" ] && echo "ERROR: COVERITY_SCAN_NOTIFICATION_EMAIL must be set" && exit 1 [ -z "$COVERITY_SCAN_BRANCH_PATTERN" ] && echo "ERROR: COVERITY_SCAN_BRANCH_PATTERN must be set" && exit 1 [ -z "$COVERITY_SCAN_BUILD_COMMAND" ] && echo "ERROR: COVERITY_SCAN_BUILD_COMMAND must be set" && exit 1 [ -z "$COVERITY_SCAN_TOKEN" ] && echo "ERROR: COVERITY_SCAN_TOKEN must be set" && exit 1 PLATFORM=`uname` TOOL_ARCHIVE=/tmp/cov-analysis-${PLATFORM}.tgz TOOL_URL=https://scan.coverity.com/download/${PLATFORM} TOOL_BASE=/tmp/coverity-scan-analysis UPLOAD_URL="https://scan.coverity.com/builds" SCAN_URL="https://scan.coverity.com" # Do not run on pull requests if [ "${TRAVIS_PULL_REQUEST}" = "true" ]; then echo -e "\033[33;1mINFO: Skipping Coverity Analysis: branch is a pull request.\033[0m" exit 0 fi # Verify this branch should run IS_COVERITY_SCAN_BRANCH=`ruby -e "puts '${TRAVIS_BRANCH}' =~ /\\A$COVERITY_SCAN_BRANCH_PATTERN\\z/ ? 1 : 0"` if [ "$IS_COVERITY_SCAN_BRANCH" = "1" ]; then echo -e "\033[33;1mCoverity Scan configured to run on branch ${TRAVIS_BRANCH}\033[0m" else echo -e "\033[33;1mCoverity Scan NOT configured to run on branch ${TRAVIS_BRANCH}\033[0m" exit 1 fi # Verify upload is permitted permit=true AUTH_RES=`curl -s --form project="$COVERITY_SCAN_PROJECT_NAME" --form token="$COVERITY_SCAN_TOKEN" $SCAN_URL/api/upload_permitted` if [ "$AUTH_RES" = "Access denied" ]; then echo -e "\033[33;1mCoverity Scan API access denied. Check COVERITY_SCAN_PROJECT_NAME and COVERITY_SCAN_TOKEN.\033[0m" exit 1 else AUTH=`echo $AUTH_RES | ruby -e "require 'rubygems'; require 'json'; puts JSON[STDIN.read]['upload_permitted']"` if [ "$AUTH" = "true" ]; then echo -e "\033[33;1mCoverity Scan analysis authorized per quota.\033[0m" else WHEN=`echo $AUTH_RES | ruby -e "require 'rubygems'; require 'json'; puts JSON[STDIN.read]['next_upload_permitted_at']"` echo -e "\033[33;1mOops!Coverity Scan analysis engine NOT authorized until $WHEN.\033[0m" permit=false fi fi if [ "$permit" = true ]; then if [ ! -d $TOOL_BASE ]; then # Download Coverity Scan Analysis Tool if [ ! -e $TOOL_ARCHIVE ]; then echo -e "\033[33;1mDownloading Coverity Scan Analysis Tool...\033[0m" wget -nv -O $TOOL_ARCHIVE $TOOL_URL --post-data "project=$COVERITY_SCAN_PROJECT_NAME&token=$COVERITY_SCAN_TOKEN" fi # Extract Coverity Scan Analysis Tool echo -e "\033[33;1mExtracting Coverity Scan Analysis Tool...\033[0m" mkdir -p $TOOL_BASE pushd $TOOL_BASE tar xzf $TOOL_ARCHIVE popd fi TOOL_DIR=`find $TOOL_BASE -type d -name 'cov-analysis*'` export PATH=$TOOL_DIR/bin:$PATH # Build echo -e "\033[33;1mRunning Coverity Scan Analysis Tool...\033[0m" COV_BUILD_OPTIONS="" #COV_BUILD_OPTIONS="--return-emit-failures 8 --parse-error-threshold 85" RESULTS_DIR="cov-int" eval "${COVERITY_SCAN_BUILD_COMMAND_PREPEND}" COVERITY_UNSUPPORTED=1 cov-build --dir $RESULTS_DIR $COV_BUILD_OPTIONS $COVERITY_SCAN_BUILD_COMMAND cov-import-scm --dir $RESULTS_DIR --scm git --log $RESULTS_DIR/scm_log.txt 2>&1 # Upload results echo -e "\033[33;1mTarring Coverity Scan Analysis results...\033[0m" RESULTS_ARCHIVE=analysis-results.tgz tar czf $RESULTS_ARCHIVE $RESULTS_DIR SHA=`git rev-parse --short HEAD` echo -e "\033[33;1mUploading Coverity Scan Analysis results...\033[0m" response=$(curl \ --silent --write-out "\n%{http_code}\n" \ --form project=$COVERITY_SCAN_PROJECT_NAME \ --form token=$COVERITY_SCAN_TOKEN \ --form email=$COVERITY_SCAN_NOTIFICATION_EMAIL \ --form file=@$RESULTS_ARCHIVE \ --form version=$SHA \ --form description="Travis CI build" \ $UPLOAD_URL) status_code=$(echo "$response" | sed -n '$p') if [ "$status_code" != "201" ]; then TEXT=$(echo "$response" | sed '$d') echo -e "\033[33;1mCoverity Scan upload failed: $TEXT.\033[0m" exit 1 fi fi esnacc-ng-1.8.1/snacc.h000066400000000000000000000104321302010526100146050ustar00rootroot00000000000000/* * file: snacc.h * * INSERT_VDA_COMMENTS * * $Header: /baseline/SNACC/snacc.h,v 1.13 2004/03/22 20:04:00 gronej Exp $ * $Log: snacc.h,v $ * Revision 1.13 2004/03/22 20:04:00 gronej * took IBM references out of the code (to the best of our knowledge, we don't use any of it anymore) * * Revision 1.12 2003/12/17 19:05:02 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.11.2.1 2003/11/05 14:58:53 gronej * working PER code merged with esnacc_1_6 * * Revision 1.11 2003/02/21 12:13:16 leonberp * cleaned up project settings for 1.5 release * * Revision 1.10 2002/12/16 17:23:11 mcphersc * DISABLED TCL * * Revision 1.9 2002/12/13 17:43:43 mcphersc * Modified the defines for META and TCL for use with the configure script * * Revision 1.8 2002/12/13 17:31:56 mcphersc * Modified TCL/META defines * * Revision 1.7 2002/12/10 14:21:19 mcphersc * *** empty log message *** * * Revision 1.6 2002/12/10 13:41:10 mcphersc * Added undefine of TCL for compiler code only. * * Revision 1.5 2002/09/04 18:33:43 vracarl * got rid of c++ comments * * Revision 1.4 2002/05/10 16:25:43 leonberp * latest changes for release 2.2 * * Revision 1.3 2002/01/10 20:04:41 sfl * Updates to Unix ./configure script so that config.h is named * config_Used.h (similar to config_win32.h for windows). This allows the * run-time libs and includes to use a unique include, but still be * dynamically built for the individual platform. * * Revision 1.2 2000/10/24 14:54:37 rwc * Updated to remove high-level warnings (level 4 on MSVC++) for an easier build. * SOME warnings persist due to difficulty in modifying the SNACC compiler to * properly build clean source; also some files are built by Lex/Yacc. * * Revision 1.1.1.1 2000/08/21 20:35:45 leonberp * First CVS Version of SNACC. * * Revision 1.7 1997/04/07 13:13:18 wan * Made more C++ readable (credits to Steve Walker) * * Revision 1.6 1997/02/28 13:39:35 wan * Modifications collected for new version 1.3: Bug fixes, tk4.2. * * Revision 1.5 1997/02/15 20:38:48 rj * In member functions, return *this after calling abort() for stupid compilers that don't seem to know about volatile abort() (they would otherwise abort with an error). * * Revision 1.4 1995/07/24 15:06:52 rj * configure checks for mem* functions. define replacements using b* functions, if necessary. * */ #ifndef _SNACC_H_ #define _SNACC_H_ #define GLASS 1 #define KHO 1 #define memzero(p, len) memset(p, 0, len) #ifdef __cplusplus #ifdef VOLATILE_RETRUN # define RETURN_THIS_FOR_COMPILERS_WITHOUT_VOLATILE_FUNCTIONS return *this; #else # define RETURN_THIS_FOR_COMPILERS_WITHOUT_VOLATILE_FUNCTIONS #endif #if !BOOL_BUILTIN #ifndef true /* enum bool { false, true }; */ /* the above looks elegant, but leads to anachronisms (<, ==, !=, ... return value of type int, not enum bool), therefore: */ typedef int bool; enum { false, true }; #endif #endif #else /* !__cplusplus */ #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE 1 #endif #endif /* __cplusplus */ /* * Inspired by gdb 4.0, for better or worse... * (grabbed from Barry Brachman - MS) * * These macros munge C routine declarations such * that they work for ANSI or non-ANSI C compilers */ #ifndef __USE_NON_ANSI_C__ #define PROTO( X) X #define PARAMS( arglist, args) (args) #define NOPARAMS() (void) #define _AND_ , #define DOTS , ... #else /* __USE_ANSI_C__ */ #define PROTO( X) () #define PARAMS( arglist, args) arglist args; #define NOPARAMS() () #define _AND_ ; #define DOTS #define void char #endif /* __USE_ANSI_C__ */ #include "policy.h" #if COMPILER // If we have TCL on this system then add TCL to the compiler #if defined (HAVE_TCLNOT) #define TCL HAVE_TCL #define META 1 #endif #elif defined (ENABLE_TCL) && defined (HAVE_TCL) #define TCL 1; #define META 1; #endif #ifdef ENABLE_META #ifndef META #define META 1 #endif #endif #define COMMA , #define if_IBM_ENC( code) #ifdef META #define if_META( code) code #else #define if_META( code) #endif #if defined(TCL) && defined (META) #define if_TCL( code) code #else #define if_TCL( code) #endif #if __GNUC__ #define ESNACC_UNUSED __attribute__((__unused__)) #else #define ESNACC_UNUSED #endif #endif /* _SNACC_H_ */ esnacc-ng-1.8.1/tbl-example/000077500000000000000000000000001302010526100155575ustar00rootroot00000000000000esnacc-ng-1.8.1/tbl-example/example.c000066400000000000000000000145741302010526100173710ustar00rootroot00000000000000/* * file: .../tbl-example/example.c - decodes and prints a given BER * PersonnelRecord value and re-encodes it to the file * "p-rec.out.ber". This example would be similar to your user code in * that you run "mkchdr" to build a nicely named description of data * structure (PersonnelRecord in this case). The table tools deal with * the same data structure in a generic way and don't use/need mkchdr. * You must not change the output of mkchdr otherwise the table encoder * decoder, etc will not understand it. * * Mike Sample * * Copyright (C) 1993 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program and the associated libraries are distributed in the hope * that they will be useful, but WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License and GNU Library General * Public License for more details. * * $Header: /baseline/SNACC/tbl-example/example.c,v 1.2 2003/12/17 19:05:04 gronej Exp $ * $Log: example.c,v $ * Revision 1.2 2003/12/17 19:05:04 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.1.2.1 2003/11/05 14:58:57 gronej * working PER code merged with esnacc_1_6 * * Revision 1.1.1.1 2000/08/21 20:35:48 leonberp * First CVS Version of SNACC. * * Revision 1.1 1997/02/15 19:33:26 rj * first check-in * */ #include "tbl-incl.h" #include "exp-buf.h" #include "sbuf.h" #include "p-rec.h" /* include the file we made with mkchdr */ char *outputFileNameG = "p-rec.out.ber"; void Usage PARAMS ((prg), char *prg) { fprintf (stderr, "Usage: %s \n\n", prg); fprintf (stderr, "E.g. %s p-rec.tt p-rec.ber\n\n", prg); fprintf (stderr, "The BER values in the file list will be decoded, printed to stdout and then re-encoded to the file \"%s\"\n", outputFileNameG); } int main PARAMS ((argc, argv), int argc _AND_ char **argv) { char *tblFileName; char *berFileName; TBL *tbl; int i; char *fileData; unsigned long int fsize; PersonnelRecord *val; unsigned long int bytesDecoded; unsigned long int bytesEncoded; SBuf sb; /* use simple buffers for reading in (know sizes) */ ExpBuf *ebPtr; /* use expanding bufs for enc (usually don't know sizes)*/ GenBuf gb; FILE *outputFile; if (argc != 3) { Usage (argv[0]); return 1; } tblFileName = argv[1]; berFileName = argv[2]; /* init mem pool to hold decoded val */ InitNibbleMem (1024, 1024); /* read in and decode the type table */ tbl = LoadTblFile (tblFileName); if (tbl == NULL) return 1; fileData = LoadFile (berFileName, &fsize); if (fileData == NULL) return 1; SBufInstallData (&sb, fileData, fsize); PutSBufInGenBuf (&sb, &gb); fprintf (stdout, "\n\n-- decoded contents of BER PersonnelRecord file: \"%s\"--\n", berFileName); val = TblDecode (tbl, NULL, "PersonnelRecord", &gb, &bytesDecoded); if (val == NULL) fprintf (stdout, "-- Decoding error occured somewhere -- \n"); else TblPrintValue (tbl, NULL, "PersonnelRecord", stdout, val); fprintf (stdout, "\n\n -- decoded %d bytes for the above value --\n\n", bytesDecoded, berFileName); free (fileData); /* was malloc'd in LoadFile */ /* * process value here * (This is where the header file generated by mkchdr is * useful - you can access the decoded value in a standard * /easier way). * * Ok, well, the names "field0" etc aren't that nice * but what did you expect - they aren't named in the ASN.1 * spec so mkchdr just makes them up. To fix this, just * add field names to you ASN.1 spec - it will not change the * way the values are encoded - so you're not making it * incompatible with the original. (not including value notation) */ printf ("The following printout is an example of using the\n"); printf ("hdr file generated by mkchdr to access the data\n"); printf ("returned from the table decoder. Look in \"example.c\"\n\n"); printf ("***** JQ GUMBY & CO Database *****************************************\n"); printf ("Employee Name: %s %s %s\n", val->field0->givenName->octs, val->field0->initial->octs, val->field0->familyName->octs); printf ("Title: %s\n", val->title->octs); printf ("Employee Number: %d\n", *val->field1); printf ("Date of Hire: %s\n", val->dateOfHire->octs); printf ("Name of Spouse: %s %s %s\n", val->nameOfSpouse->givenName->octs, val->nameOfSpouse->initial->octs, val->nameOfSpouse->familyName->octs); printf ("Number of Children: %d\n", AsnListCount (val->children)); printf ("**********************************************************************\n\n"); /* * finished playing with the decoded value. * now re-encode the value. Using an expbuf to hold the encoded val * because they can grow and in general you can predict a values * encoded size (although we could assume that is would be close to * the same size as the one we read in at the beginning of this prg). * (note: the size of PersonnelRecord BER value we decoded may be * different from the size of the re-encoded version depending on * the use of indefinite or definite lengths. Both are valid BER.) */ fprintf (stdout, "now re-encoding the PersonnelRecord value to \"%s\"\n", outputFileNameG); ebPtr = ExpBufAllocBufAndData(); ExpBufResetInWriteRvsMode (ebPtr); /* set up to hold encoding (= writing) */ PutExpBufInGenBuf (ebPtr, &gb); if (TblEncode (tbl, NULL, "PersonnelRecord", &gb, val, &bytesEncoded) < 0) fprintf (stderr, "main: error encoding the PersonnelRecord\n"); /* copy ExpBuf data to file */ outputFile = fopen (outputFileNameG, "w"); if (outputFile == NULL) { fprintf (stderr, "error - could not open file \"%s\"\n", outputFileNameG); perror ("main: fopen:"); } ExpBufCopyToFile (ebPtr, outputFile); fclose (outputFile); /* free the encoded version */ ExpBufFreeBufAndDataList (ebPtr); return 0; } /* main */ esnacc-ng-1.8.1/tbl-example/p-rec.ber000066400000000000000000000002211302010526100172520ustar00rootroot00000000000000`ŽaJohnESmith The Big Cheese_†Ÿ¡ C19820104¢aMaryLSmith£A1aJamesRSmith  C195703101aLisaMSmith  C19610621esnacc-ng-1.8.1/tbl-example/readme000066400000000000000000000054141302010526100167430ustar00rootroot00000000000000(RCS control information is at the end of this file.) Table encoder/decoder example README - MS 93 ------------------------------------ This directory contains an example that shows: 1. the process of creating and using tables. 2. examples of decoding, printing, and encoding. To dive right in just type "make" in this directory. That will create the "example" executable (you should have previously installed the snacc and mkchdr progs and the table library). Then type: make check and see what happens. Look in example.c and makefile to see how things work. Questions and Answers --------------------- Q. What is a table? (also refered to a type table or type tree) A. A table is simply a data structure that holds a description of the types from an ASN.1 module. This table can then be used by a number of "generic" routines to do ASN.1 related (BER encoding/decoding) or other useful things such as printing values, freeing values and whatever else you can dream up. Q. How do I create a table from my ASN.1 source files? A. Run snacc with the -T option, e.g.: snacc -T mytbls.tt myMod1.asn1 myMod2.asn1 the above command will create the "mytbls.tt" file that holds the descriptions of the ASN.1 types in the "myMod1.asn1" and "myMod2.asn1" files. (look in the makefile in this directory) Q. Why is there only a C interface to tables? A. Time. Tables drivers create/read/free these types without having seen a typedef for them. The C implementation uses some assumptions about how structures etc. are allocated and accessed. With C++ this is much more difficult. It can be done but required more time than I had. Q. Ok, tables sound great, what's the catch? A. Well, 1. table driven encoding and decoding is something like 4 times slower than the C or C++ version. (but tables are *way* smaller than the .o's for the compiled approach) 2. the ANY DEFINED BY stuff is not supported at all. 3. subtype information is not included in the tables (time crunch again) (PER encoders/decoders will need the subtype info) 4. Values from the ASN.1 source are not included in the table. If you have the time and skills, you can fix 2, 3 and 4. 1 is harder. Q. Tell me more. A. Look at the manual. (in .../doc/) #------------------------------------------------------------------------------- # $Header: /baseline/SNACC/tbl-example/readme,v 1.2 2003/12/17 19:05:04 gronej Exp $ # $Log: readme,v $ # Revision 1.2 2003/12/17 19:05:04 gronej # SNACC baseline merged with PER v1_7 tag # # Revision 1.1.2.1 2003/11/05 14:58:57 gronej # working PER code merged with esnacc_1_6 # # Revision 1.1.1.1 2000/08/21 20:35:48 leonberp # First CVS Version of SNACC. # # Revision 1.1 1997/02/15 19:33:24 rj # first check-in # esnacc-ng-1.8.1/tbl-tools/000077500000000000000000000000001302010526100152645ustar00rootroot00000000000000esnacc-ng-1.8.1/tbl-tools/berdecode/000077500000000000000000000000001302010526100172005ustar00rootroot00000000000000esnacc-ng-1.8.1/tbl-tools/berdecode/berdecode.c000066400000000000000000000103731302010526100212640ustar00rootroot00000000000000#include "tbl-gen.h" #include "sbuf.h" #include "tbl-dbg.h" #if TIME_WITH_SYS_TIME # include # include #else # if HAVE_SYS_TIME_H # include # else # include # endif #endif #if STDC_HEADERS || HAVE_STRING_H #include #else #include #endif #include #include #if defined(_AIX) #include #else #include #endif int debug = 0; int strip = 0; TBL* tbl; char* progname; char* tblfilename = "/home/oms2/oms2_u_02/wan/madecode/ICD.HCI53.tt"; int process (char* buffer, int bytes) { SBuf sb; /* use simple buffers for reading in (know sizes) */ GenBuf gb; void* val; unsigned long bytesDecoded; SBufInstallData(&sb, buffer+strip, bytes-strip); PutSBufInGenBuf(&sb, &gb); DBGMinCode = debug? TDEINFO: TDEWARNING; if (!TdeDecode(tbl, &gb, &bytesDecoded, DBGType, DBGSimple, DBGExc)) fprintf(stdout,"%s: !!! Decoding error occured after %d bytes.\n", progname,(int)bytesDecoded); fflush(stdout); return (int) bytesDecoded+strip; } int readable(int fd) { int result; fd_set fds; struct timeval tim; FD_ZERO(&fds); FD_SET(fd,&fds); tim.tv_sec = tim.tv_usec = 0; result = select(fd+1,&fds,NULL,NULL,&tim); return result; } int decode(int fd) { char buffer[40960], *pointer; int bytes = 0; int nr; int result; if (tblfilename) { tbl = LoadTblFile(tblfilename); if (tbl == NULL) { fprintf(stderr,"%s: !!! Can't load ASN.1 grammar table '%s'.\n", progname,tblfilename); exit(2); } tblfilename = NULL; } while(1) { if (bytes==0 || readable(fd)) { nr = read(fd,buffer+bytes,sizeof(buffer)-bytes); if (nr<0) { perror("!!! read failed"); return(2); } bytes += nr; if (bytes==0) break; } result = process(buffer,bytes); if (result<=strip) { while (readable(fd)) { nr = read(fd,buffer,sizeof(buffer)); if (nr<0) { perror("!!! read failed"); return(2); } if (nr==0) return 0; } bytes = 0; continue; } bytes -= result; if (bytes<0) { fprintf(stdout,"%s: !!! Decoded past end of buffer.\n",progname); fflush(stdout); bytes = 0; } if (bytes) memcpy(buffer,buffer+result,bytes); } return(0); } int decodefn (char* filename) { if (!strcmp(filename,"-")) decode(0); else { int fd = open(filename,O_RDONLY); if (fd<0) { perror(filename); return 2; } decode(fd); close(fd); } } int main (int argc, char* argv[]) { int status = 0; int files = 0; progname = argv[0]; InitNibbleMem(1024,1024); while (--argc) { ++argv; if (!strcmp(*argv,"-s") || !strcmp(*argv,"-strip")) { strip = strtol(*++argv,NULL,0); argc--; } else if (!strcmp(*argv,"-d") || !strcmp(*argv,"-debug")) { debug = 1; } else if (!strcmp(*argv,"-T") || !strcmp(*argv,"-table")) { if (!tblfilename) { fprintf(stderr,"%s: Give before all filenames.\n", progname); return 1; } else { tblfilename = *++argv; argc--; } } else { files++; status += decodefn(*argv); } } if (!files) { char* revision = "$Revision: 1.2 $"; char* date = "$Date: 2003/12/17 19:05:04 $"; char* p; p = strchr(revision,' '); if (p) revision = p+1; p = strchr(revision,' '); if (p) *p = '\0'; p = strchr(date,' '); if (p) date = p+1; p = strchr(date,' '); if (p) *p = '\0'; fprintf(stderr,"Usage: %s [-s|-strip ] [-d|-debug]\n", progname); fprintf(stderr," [-T|-table |-}\n"); fprintf(stderr,"\n"); fprintf(stderr,"This is berdecode, revision %s as of %s.\n", revision,date); fprintf(stderr,"This program reads a binary ASN.1 grammar file generated by snacc -T\n"); fprintf(stderr,"and uses it to decode ASN.1 BER encoded data from files or stdin.\n"); fprintf(stderr,"\n"); fprintf(stderr,"From every message the first bytes (default 0)\n"); fprintf(stderr,"are skipped.\n"); fprintf(stderr,"\n"); fprintf(stderr,"Flag -d gives additional information during decoding.\n"); status = 1; } return status; } esnacc-ng-1.8.1/tbl-tools/berdecode/readme000066400000000000000000000006501302010526100203610ustar00rootroot00000000000000Usage: berdecode [-s|-strip ] [-d|-debug] [-T|-table |-} This is berdecode, revision 1.10 as of 1997/06/24. This program reads a binary ASN.1 grammar file generated by snacc -T and uses it to decode ASN.1 BER encoded data from files or stdin. From every message the first bytes (default 2) are skipped. Flag -d gives additional information during decoding. esnacc-ng-1.8.1/tbl-tools/mkchdr/000077500000000000000000000000001302010526100165345ustar00rootroot00000000000000esnacc-ng-1.8.1/tbl-tools/mkchdr/mkchdr.c000066400000000000000000000040761302010526100201570ustar00rootroot00000000000000/* * file: .../tbl-tools/mkchdr/mkchdr.c - given a type table generated * by snacc (-T option) mkchdr generates a .h file that contains the C * type defs for the types in the given table. * * NOTE: these C typedefs are as the table decoder/encoder will * return/expect. They are DIFFERENT from the ones usually * generated by snacc's C backend * * * Mike Sample * * Copyright (C) 1993 Michael Sample * and the University of British Columbia * * $Header: /baseline/SNACC/tbl-tools/mkchdr/mkchdr.c,v 1.2 2003/12/17 19:05:04 gronej Exp $ * $Log: mkchdr.c,v $ * Revision 1.2 2003/12/17 19:05:04 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.1.2.1 2003/11/05 14:59:00 gronej * working PER code merged with esnacc_1_6 * * Revision 1.1.1.1 2000/08/21 20:35:48 leonberp * First CVS Version of SNACC. * * Revision 1.1 1997/02/15 19:05:30 rj * first check-in * */ #include "tbl-incl.h" #include "tbl-gen-c-hdr.h" void Usage PARAMS ((prg), char *prg) { fprintf (stderr,"Usage: %s [output-file]\n\n",prg); fprintf (stderr,"Reads the type table from tbl-file and writes\n"); fprintf (stderr,"the equivalent C typedefs to output-file.\n"); fprintf (stderr,"If no output-file is given, stdout is used.\n\n"); fprintf (stderr,"The table files are generated with the snacc -T option.\n"); } int main PARAMS ((argc, argv), int argc _AND_ char **argv) { char *tblFileName; FILE *outputFile; TBL *tbl; if (argc < 2) { Usage (argv[0]); return 1; } tblFileName = argv[1]; if (argc == 3) { /* open output file */ outputFile = fopen (argv[2], "w"); if (outputFile == NULL) { perror ("fopen: "); return 1; } } else /* use stdout */ outputFile = stdout; InitNibbleMem (1024,1024); tbl = LoadTblFile (tblFileName); if (tbl == NULL) return 1; /* Load routine will have printed errs */ TblPrintCHdr (tbl, outputFile); return 0; } /* main */ esnacc-ng-1.8.1/tbl-tools/mkchdr/readme000066400000000000000000000022351302010526100177160ustar00rootroot00000000000000(RCS control information is at the end of this file.) mkchdr - Making C header files from a Type Table ------------------------------------------------ synopsis: mkchdr [output-file] mkchdr reads the type table from tbl-file and writes the equivalent C typedefs to output-file. If no output-file is given, stdout is used. The table files are generated with the snacc -T option. Look in .../tbl-example/ to see how these header files are used. The table decoder/encoder does not use them---they are simply a mechanism to allow your program to deal with the values returned from the table driven decoder (or given to the encoder) in a nice fashion. #------------------------------------------------------------------------------- # $Header: /baseline/SNACC/tbl-tools/mkchdr/readme,v 1.2 2003/12/17 19:05:04 gronej Exp $ # $Log: readme,v $ # Revision 1.2 2003/12/17 19:05:04 gronej # SNACC baseline merged with PER v1_7 tag # # Revision 1.1.2.1 2003/11/05 14:59:00 gronej # working PER code merged with esnacc_1_6 # # Revision 1.1.1.1 2000/08/21 20:35:48 leonberp # First CVS Version of SNACC. # # Revision 1.1 1997/02/15 19:08:49 rj # first check-in # esnacc-ng-1.8.1/tbl-tools/mkchdr/tbl-gen-c-hdr.c000066400000000000000000000170131302010526100212250ustar00rootroot00000000000000/* * file: .../tbl-tools/mkchdr/tbl_gen_c_hdr.c - prints C type defs for * vals tbl decoder will return for the given type table. * * * Mike Sample * * Copyright (C) 1993 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program and the associated libraries are distributed in the hope * that they will be useful, but WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License and GNU Library General * Public License for more details. * * $Header: /baseline/SNACC/tbl-tools/mkchdr/tbl-gen-c-hdr.c,v 1.2 2003/12/17 19:05:04 gronej Exp $ * $Log: tbl-gen-c-hdr.c,v $ * Revision 1.2 2003/12/17 19:05:04 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.1.2.1 2003/11/05 14:59:00 gronej * working PER code merged with esnacc_1_6 * * Revision 1.1.1.1 2000/08/21 20:35:48 leonberp * First CVS Version of SNACC. * * Revision 1.1 1997/02/15 19:05:31 rj * first check-in * */ #include "tbl-incl.h" static int indentIncrG = 4; void TblPrintCType PROTO ((TBLTypeDef *tblTd, TBLType *tblT, FILE *f, unsigned short int indent)); static char *genericFieldNameG = "field"; /* * Print C type info for the values that the tbl decode will return (and * tbl encoder will expect) for the given tbl */ void TblPrintCHdr PARAMS ((tbl, f), TBL *tbl _AND_ FILE *f) { TBLTypeDef *tblTd; TBLModule *tblMod; /* print file comment */ fprintf (f,"/*\n"); fprintf (f," * type definitions for the values that the snacc table\n"); fprintf (f," * decoder will return and snacc table encoder expects\n"); fprintf (f," * for the type table that contains the following modules:\n"); fprintf (f," * \n"); FOR_EACH_LIST_ELMT (tblMod, tbl->modules) { if (!tblMod->isUseful) { if (tblMod->name.octs != NULL) fprintf (f," * %s\n",tblMod->name.octs); else { fprintf (f," id = "); PrintAsnOid (f, &tblMod->id, 0); fprintf (f,"\n"); } } } fprintf (f," *\n"); fprintf (f," * UBC snacc written by Mike Sample\n"); fprintf (f," * NOTE: This is a machine generated file \n"); fprintf (f," * NOTE2: Table routines don't use this so feel free to make changes\n"); fprintf (f," * that do not affect the structure. Changing field \n"); fprintf (f," * and type names is fine.\n"); fprintf (f," */\n\n\n"); /* print C type defs */ FOR_EACH_LIST_ELMT (tblMod, tbl->modules) { if (!tblMod->isUseful) /* don't print useful types */ { fprintf (f,"/* start of module %s's definitions */\n\n", tblMod->name.octs); FOR_EACH_LIST_ELMT (tblTd, tblMod->typeDefs) { fprintf (f,"typedef "); TblPrintCType (tblTd, tblTd->type, f, 0); fprintf (f," %s;\n\n", tblTd->typeName.octs); } } } } /* TblPrintCHdr */ /* * simple routine to print the C version of the type * This routine only indents directly after printing a newline * (ie no indent is done for the first text written) */ void TblPrintCType PARAMS ((tblTd, tblT, f, indent), TBLTypeDef *tblTd _AND_ TBLType *tblT _AND_ FILE *f _AND_ unsigned short int indent) { TBLType *structElmtType; TBLType *choiceElmtType; void *tmp; int currElmt; int currFieldNo; switch (tblT->typeId) { case TBL_TYPEREF: fprintf (f, "%s",tblT->content->a.typeRef->typeDefPtr->typeName.octs); break; case TBL_SEQUENCE: case TBL_SET: fprintf (f,"struct %s\n", tblTd->typeName.octs); Indent (f, indent); fprintf (f,"{\n"); currFieldNo = 0; tmp = CURR_LIST_NODE (tblT->content->a.elmts); FOR_EACH_LIST_ELMT (structElmtType, tblT->content->a.elmts) { Indent (f, indent+indentIncrG); TblPrintCType (tblTd, structElmtType, f, indent+indentIncrG); if (structElmtType->fieldName.octs != NULL) fprintf (f," %s;", structElmtType->fieldName.octs); else fprintf (f," %s%d;", genericFieldNameG, currFieldNo++); fprintf (f,"\n"); } SET_CURR_LIST_NODE (tblT->content->a.elmts, tmp); fprintf (f,"}"); break; case TBL_SEQUENCEOF: case TBL_SETOF: fprintf (f,"AsnList"); break; case TBL_CHOICE: fprintf (f,"struct %s\n", tblTd->typeName.octs); Indent (f, indent); fprintf (f,"{\n"); /* print enum */ Indent (f, indent+indentIncrG); fprintf (f,"enum\n"); Indent (f, indent+indentIncrG); fprintf (f,"{\n"); currElmt = 0; currFieldNo = 0; tmp = CURR_LIST_NODE (tblT->content->a.elmts); FOR_EACH_LIST_ELMT (choiceElmtType, tblT->content->a.elmts) { Indent (f, indent+indentIncrG+indentIncrG); if (choiceElmtType->fieldName.octs != NULL) fprintf (f,"%s", choiceElmtType->fieldName.octs); else fprintf (f," %s%d", genericFieldNameG, currFieldNo++); fprintf (f,"_ID = %d", currElmt++); if (choiceElmtType != LAST_LIST_ELMT (tblT->content->a.elmts)) fprintf (f,","); fprintf (f,"\n"); } Indent (f, indent); fprintf (f," } choiceId;\n"); /* print elmt union */ Indent (f, indent+indentIncrG); fprintf (f,"union\n"); Indent (f, indent+indentIncrG); fprintf (f,"{\n"); currFieldNo = 0; FOR_EACH_LIST_ELMT (choiceElmtType, tblT->content->a.elmts) { Indent (f, indent+indentIncrG+indentIncrG); TblPrintCType (tblTd, choiceElmtType, f, indent+indentIncrG+indentIncrG); if (choiceElmtType->fieldName.octs != NULL) fprintf (f," %s;\n", choiceElmtType->fieldName.octs); else fprintf (f," %s%d;", genericFieldNameG, currFieldNo++); } SET_CURR_LIST_NODE (tblT->content->a.elmts, tmp); Indent (f, indent+indentIncrG); fprintf (f,"} a;\n"); Indent (f, indent); fprintf (f,"}"); break; case TBL_BOOLEAN: fprintf (f,"AsnBool"); break; case TBL_INTEGER: case TBL_ENUMERATED: fprintf (f,"AsnInt"); break; case TBL_BITSTRING: fprintf (f,"AsnBits"); break; case TBL_OCTETSTRING: fprintf (f,"AsnOcts"); break; case TBL_NULL: fprintf (f,"AsnNull"); break; case TBL_OID: fprintf (f,"AsnOid"); break; case TBL_REAL: fprintf (f,"AsnReal"); break; default: fprintf (f, ""); } /* * types defined directly from another typedef are * the same type as the other typedef (so not a pointer). * All other type refs are done by pointer */ if (tblT != tblTd->type) fprintf (f,"*"); } /* TblPrintCType */ esnacc-ng-1.8.1/tbl-tools/ptbl/000077500000000000000000000000001302010526100162255ustar00rootroot00000000000000esnacc-ng-1.8.1/tbl-tools/ptbl/pasn1.c000066400000000000000000000236331302010526100174220ustar00rootroot00000000000000/* * file: .../tbl-tools/ptbl/pasn1.c - this takes a table and prints a version of * is contents in a rough ASN.1 format. Its * rough - ie IMPORT/EXPORT info is not re-computed and printed. * Its much easier to understand than the * printout of the table's actual values * * MS 93 * Copyright (C) 1993 Michael Sample * and the University of British Columbia * * $Header: /baseline/SNACC/tbl-tools/ptbl/pasn1.c,v 1.2 2003/12/17 19:05:04 gronej Exp $ * $Log: pasn1.c,v $ * Revision 1.2 2003/12/17 19:05:04 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.1.2.1 2003/11/05 14:59:00 gronej * working PER code merged with esnacc_1_6 * * Revision 1.1.1.1 2000/08/21 20:35:48 leonberp * First CVS Version of SNACC. * * Revision 1.3 1997/06/19 09:17:18 wan * Added isPdu flag to tables. Added value range checks during parsing. * * Revision 1.2 1997/05/07 15:18:36 wan * Added (limited) size constraints, bitstring and enumeration names to tables * * Revision 1.1 1997/02/15 19:26:21 rj * first check-in * */ #include "tbl-incl.h" #include "pasn1.h" static void PrintElmts PROTO ((FILE *f, TBL *tbl, TBLTypeDef *td, AsnList *elmts)); static void PrintTag PROTO ((FILE *f, TBLTag *tag)); int UnivTagCodeMatch PROTO ((TBLTypeId tid, TBLTagClass tclass)); void PrintTblInAsn1 PARAMS ((f, tbl), FILE *f _AND_ TBL *tbl) { TBLModule *m; TBLTypeDef *td; /* print internal info */ fprintf (f,"--\n"); fprintf (f,"-- This printout contains the following modules:\n"); FOR_EACH_LIST_ELMT (m, tbl->modules) { fprintf (f,"-- %s \n", m->name.octs); } fprintf (f,"--\n\n"); /* print each module */ FOR_EACH_LIST_ELMT (m, tbl->modules) { fprintf (f,"-- Definitions for %s \n", m->name.octs); fprintf (f,"%s ", m->name.octs); if (m->id.octs != NULL) PrintAsnOid (f, &m->id, 0); fprintf (f," DEFINITIONS ::=\n"); fprintf (f,"BEGIN\n"); /* print this module's type defs */ FOR_EACH_LIST_ELMT (td, m->typeDefs) { PrintTblTypeDefInAsn1 (f, tbl, td); } fprintf (f,"END\n"); } } /* PrintTblInAsn1 */ void PrintTblTypeDefInAsn1 PARAMS ((f, tbl, td), FILE *f _AND_ TBL *tbl _AND_ TBLTypeDef *td) { /* * I don't think there is a case where no * typename is defined for the typedef. * (I marked it optional at one point, so ...) */ if (td->typeName.octs != NULL) fprintf (f,"%s ::= ", td->typeName.octs); else fprintf (f,"??? ::= "); if (td->isPdu) fprintf (f,"--snacc isPdu:\"TRUE\" -- "); PrintTblTypeInAsn1 (f, tbl, td, td->type); fprintf (f,"\n"); } /* PrintTblTypeDefInAsn1 */ void PrintTblRange PARAMS ((f, r, s1, s2), FILE* f _AND_ TBLRange* r _AND_ char* s1 _AND_ char* s2) { if (r) { fprintf(f," %s",s1); fprintf(f,r->from==r->to?"(%d)":"(%d..%d)",r->from,r->to); fprintf(f,"%s",s2); } } TBLTypeId RealTypeId PARAMS ((t), TBLType* t) { switch (t->typeId) { case TBL_TYPEREF: return RealTypeId (t->content->a.typeRef->typeDefPtr->type); default: return t->typeId; } } /* * prints "{ field list}" for the given elmts * good for SET, SEQ and CHOICE types */ static void PrintTblValues PARAMS ((f, tnnl), FILE *f _AND_ TBLNamedNumberList *tnnl) { TBLNamedNumber *tnn; if (!tnnl || LIST_EMPTY(tnnl)) return; fprintf (f,"\n{\n"); FOR_EACH_LIST_ELMT (tnn, tnnl) { if (tnn->name.octs != NULL) fprintf (f," %s ", tnn->name.octs); else fprintf (f, " "); fprintf(f,"(%d)",tnn->value); if (tnn != LAST_LIST_ELMT (tnnl)) fprintf (f,",\n"); else fprintf (f,"\n"); } fprintf (f,"}"); } /* PrintTblValues */ void PrintTblTypeInAsn1 PARAMS ((f, tbl, td, t), FILE *f _AND_ TBL *tbl _AND_ TBLTypeDef *td _AND_ TBLType *t) { TBLTag *tag; TBLTag *lastTag; TBLType *elmt; /* print tags */ FOR_EACH_LIST_ELMT (tag, t->tagList) { /* don't print the tag if it the last one and it has UNIVERSAL class */ if (!((tag == LAST_LIST_ELMT (t->tagList)) && (tag->tclass == UNIV))) PrintTag (f, tag); } /* figure out if IMPLICIT tagging has been done */ if (t->tagList != NULL) lastTag = LAST_LIST_ELMT (t->tagList); else lastTag = NULL; if (lastTag != NULL) { if (t->typeId == TBL_TYPEREF) { if (lastTag->tclass == UNIV) /* weird case - user using univ tags*/ PrintTag (f, lastTag); if (t->content->a.typeRef->implicit) fprintf (f,"IMPLICIT "); } /* * non univ tag on builtin/non ref type means orig univ tag * has been removed due to implicit tagging */ else if (lastTag->tclass != UNIV) fprintf (f,"IMPLICIT "); /* * last tag is universal - it should match the type then * if not, then implicit tagging with universal tags * has been done - like useful types * ie NumericString ::= [UNIVERSAL 18] IMPLICT OCTET STRING */ else if (!UnivTagCodeMatch (t->typeId, lastTag->code)) { /* * last tag was universal but did not match * so must print univsal tag (not printed * in above tag printing code) as well * as the implicit */ PrintTag (f, lastTag); fprintf (f,"IMPLICIT "); } } /* print type info */ switch (t->typeId) { case TBL_BOOLEAN: fprintf (f,"BOOLEAN"); break; case TBL_INTEGER: fprintf (f,"INTEGER"); PrintTblRange(f,t->constraint,"",""); break; case TBL_BITSTRING: fprintf (f,"BIT STRING"); PrintTblValues(f,t->values); break; case TBL_OCTETSTRING: fprintf (f,"OCTET STRING"); PrintTblRange(f,t->constraint,"(SIZE",")"); break; case TBL_NULL: fprintf (f,"NULL"); break; case TBL_OID: fprintf (f,"OBJECT IDENTIFIER"); break; case TBL_REAL: fprintf (f,"REAL"); break; case TBL_ENUMERATED: fprintf (f,"ENUMERATED"); PrintTblValues(f,t->values); break; case TBL_SEQUENCE: fprintf (f,"SEQUENCE\n"); PrintElmts (f, tbl, td, t->content->a.elmts); break; case TBL_SET: fprintf (f,"SET\n"); PrintElmts (f, tbl, td, t->content->a.elmts); break; case TBL_SEQUENCEOF: fprintf (f,"SEQUENCE"); PrintTblRange(f,t->constraint,"SIZE",""); fprintf (f," OF "); PrintTblTypeInAsn1 (f, tbl, td, FIRST_LIST_ELMT (t->content->a.elmts)); break; case TBL_SETOF: fprintf (f,"SET OF "); PrintTblTypeInAsn1 (f, tbl, td, FIRST_LIST_ELMT (t->content->a.elmts)); break; case TBL_CHOICE: fprintf (f,"CHOICE\n"); PrintElmts (f, tbl, td, t->content->a.elmts); break; case TBL_TYPEREF: fprintf (f,"%s", t->content->a.typeRef->typeDefPtr->typeName.octs); if (RealTypeId(t)==TBL_INTEGER) PrintTblRange(f,t->constraint,"",""); else PrintTblRange(f,t->constraint,"(SIZE",")"); break; } } /* PrintTblTypeInAsn1 */ /* * prints "{ field list}" for the given elmts * good for SET, SEQ and CHOICE types */ static void PrintElmts PARAMS ((f, tbl, td, elmts), FILE *f _AND_ TBL *tbl _AND_ TBLTypeDef *td _AND_ AsnList *elmts) { TBLType *elmt; fprintf (f,"{\n"); FOR_EACH_LIST_ELMT (elmt, elmts) { if (elmt->fieldName.octs != NULL) fprintf (f," %s ", elmt->fieldName.octs); else fprintf (f, " "); PrintTblTypeInAsn1 (f, tbl, td, elmt); if (elmt != LAST_LIST_ELMT (elmts)) fprintf (f,",\n"); else fprintf (f,"\n"); } fprintf (f,"}"); } /* PrintElmts */ /* * returns true if the given tag class, tclass, * is the correct UNIVERSAL code for the type * with the given tid. */ int UnivTagCodeMatch PARAMS ((tid, tclass), TBLTypeId tid _AND_ TBLTagClass tclass) { int expectedClass; switch (tid) { case TBL_BOOLEAN: expectedClass = 1; break; case TBL_INTEGER: expectedClass = 2; break; case TBL_BITSTRING: expectedClass = 3; break; case TBL_OCTETSTRING: expectedClass = 4; break; case TBL_NULL: expectedClass = 5; break; case TBL_OID: expectedClass = 6; break; case TBL_REAL: expectedClass = 9; break; case TBL_ENUMERATED: expectedClass = 10; break; case TBL_SEQUENCE: case TBL_SEQUENCEOF: expectedClass = 16; break; case TBL_SET: case TBL_SETOF: expectedClass = 17; break; case TBL_CHOICE: case TBL_TYPEREF: expectedClass = -1; break; } return tclass == expectedClass; } /* UnivTagCodeMatch */ static void PrintTag PARAMS ((f, tag), FILE *f _AND_ TBLTag *tag) { fprintf (f,"["); switch (tag->tclass) { case UNIVERSAL: fprintf (f,"UNIVERSAL "); break; case APPLICATION: fprintf (f,"APPLICATION "); break; case CONTEXT: break; case PRIVATE: fprintf (f,"PRIVATE "); break; } fprintf (f,"%d",tag->code); fprintf (f,"] "); } /* PrintTag */ esnacc-ng-1.8.1/tbl-tools/ptbl/pasn1.h000066400000000000000000000012701302010526100174200ustar00rootroot00000000000000/* * file: .../tbl-tools/ptbl/pasn1.h * * $Header: /baseline/SNACC/tbl-tools/ptbl/pasn1.h,v 1.2 2003/12/17 19:05:04 gronej Exp $ * $Log: pasn1.h,v $ * Revision 1.2 2003/12/17 19:05:04 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.1.2.1 2003/11/05 14:59:00 gronej * working PER code merged with esnacc_1_6 * * Revision 1.1.1.1 2000/08/21 20:35:48 leonberp * First CVS Version of SNACC. * * Revision 1.1 1997/02/15 19:26:22 rj * first check-in * */ void PrintTblTypeDefInAsn1 PROTO ((FILE *f, TBL *tbl, TBLTypeDef *td)); void PrintTblTypeInAsn1 PROTO ((FILE *f, TBL *tbl, TBLTypeDef *td, TBLType *t)); void PrintTblInAsn1 PROTO ((FILE *f, TBL *tbl)); esnacc-ng-1.8.1/tbl-tools/ptbl/ptbl.c000066400000000000000000000036211302010526100173340ustar00rootroot00000000000000/* * file: .../tbl-tools/ptbl/ptbl.c - given a type table generated by snacc (-T option) * ptbl prints the contents of the table to stdout. * * This may be useful for debugging. * * Copyright (C) 1993 Michael Sample * and the University of British Columbia * * $Header: /baseline/SNACC/tbl-tools/ptbl/ptbl.c,v 1.2 2003/12/17 19:05:04 gronej Exp $ * $Log: ptbl.c,v $ * Revision 1.2 2003/12/17 19:05:04 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.1.2.1 2003/11/05 14:59:00 gronej * working PER code merged with esnacc_1_6 * * Revision 1.1.1.1 2000/08/21 20:35:48 leonberp * First CVS Version of SNACC. * * Revision 1.1 1997/02/15 19:26:23 rj * first check-in * */ #include "tbl-incl.h" #include "tbl-gen-c-hdr.h" void Usage PARAMS ((prg), char *prg) { fprintf (stderr,"Usage: %s [-a] \n",prg); fprintf (stderr," -a means print in ASN.1 format instead of the table data structure\n\n"); fprintf (stderr," ptbl reads the type table from tbl-file and prints"); fprintf (stderr," its contents\n to stdout."); fprintf (stderr," The table files are generated with the snacc -T option.\n"); } int main PARAMS ((argc, argv), int argc _AND_ char **argv) { char *tblFileName; FILE *outputFile; int asn1Mode = FALSE; TBL *tbl; if ((argc != 2) && (argc != 3)) { Usage (argv[0]); return 1; } /* danger - no error checking here */ if (argc == 2) tblFileName = argv[1]; else { asn1Mode = TRUE; tblFileName = argv[2]; } outputFile = stdout; InitNibbleMem (1024,1024); tbl = LoadTblFile (tblFileName); if (tbl == NULL) return 1; /* Load routine will have printed errs */ if (asn1Mode) PrintTblInAsn1 (outputFile, tbl); else PrintTBL (outputFile, tbl, 0); return 0; } /* main */ esnacc-ng-1.8.1/tbl-tools/ptbl/readme000066400000000000000000000027231302010526100174110ustar00rootroot00000000000000(RCS control information is at the end of this file.) Table printing README - MS 93 ----------------------------- This program is good for snooping through table file to see what they contain. You will almost always want to use the "-a" option. The ptbl program will print a type table in 2 forms: 1. By default tables are printed in ASN.1 value notation for the TBL ASN.1 data structure (See the tbl.asn1 file in snacc/asn1specs). 2. Using the "-a" option makes ptbl print the type in the type table in ASN.1 form. Some parts are not printed - IMPORT/EXPORT info (although you could figure it out). The ASN.1 printing code (in pasn1.c) is very simple and is a good way to become familiar with the TBL data structure (type tables). Type "make" to build ptbl. Type ./ptbl to see the arguments it expects. try: ./ptbl -a ../demo-tbls/p-rec.tt also try: ./ptbl ../demo-tbls/p-rec.tt ptbl without the -a option is only really useful for debugging. #------------------------------------------------------------------------------- # $Header: /baseline/SNACC/tbl-tools/ptbl/readme,v 1.2 2003/12/17 19:05:04 gronej Exp $ # $Log: readme,v $ # Revision 1.2 2003/12/17 19:05:04 gronej # SNACC baseline merged with PER v1_7 tag # # Revision 1.1.2.1 2003/11/05 14:59:00 gronej # working PER code merged with esnacc_1_6 # # Revision 1.1.1.1 2000/08/21 20:35:48 leonberp # First CVS Version of SNACC. # # Revision 1.1 1997/02/15 19:26:19 rj # first check-in # esnacc-ng-1.8.1/tbl-tools/pval/000077500000000000000000000000001302010526100162265ustar00rootroot00000000000000esnacc-ng-1.8.1/tbl-tools/pval/pval.c000066400000000000000000000111701302010526100173340ustar00rootroot00000000000000/* * file: .../tbl-tools/pval/pval.c - decodes and prints a BER values * given a type table and the type name of the value (module name * optional). * * Mike Sample * * Copyright (C) 1993 Michael Sample * and the University of British Columbia * * $Header: /baseline/SNACC/tbl-tools/pval/pval.c,v 1.2 2003/12/17 19:05:04 gronej Exp $ * $Log: pval.c,v $ * Revision 1.2 2003/12/17 19:05:04 gronej * SNACC baseline merged with PER v1_7 tag * * Revision 1.1.2.1 2003/11/05 14:59:00 gronej * working PER code merged with esnacc_1_6 * * Revision 1.1.1.1 2000/08/21 20:35:47 leonberp * First CVS Version of SNACC. * * Revision 1.1 1997/02/15 19:15:09 rj * first check-in * */ #include "tbl-incl.h" #include "sbuf.h" void Usage PARAMS ((prg), char *prg) { fprintf (stderr,"Usage: %s -T [-m ] -n \n \n\n",prg); fprintf (stderr,"E.G. %s -T x400.tt -m P1 -n MPDU p1msg1.ber p1msg2.ber\n\n",prg); fprintf (stderr,"The BER values in the file list will be decoded and printed to stdout.\n"); fprintf (stderr,"The module name is optional - if left out, the first occurence\nof the named type will be used.\n"); } char* NextParamStr PARAMS ((argv, currArg), char **argv _AND_ int *currArg) { char *retVal; if (argv[*currArg][2] != '\0') { /* no space between opt (ie -T) and parameter */ retVal = &argv[*currArg][2]; *currArg += 1; } else { retVal = argv[*currArg+1]; *currArg += 2; } return retVal; } int main PARAMS ((argc, argv), int argc _AND_ char **argv) { char *tblFileName; char *typeName; char *modName; int gotTbl; int gotType; TBL *tbl; int i; char *fileData; unsigned long int fsize; AVal *val; unsigned long int bytesDecoded; int currArg; char **fileArr; int numValFiles; SBuf sb; GenBuf gb; if (argc <= 1) { Usage (argv[0]); return 1; } fileArr = (char **) malloc ((argc -1) * sizeof (char *)); /* * parse cmd line args */ numValFiles = 0; gotType = gotTbl = FALSE; modName = NULL; /* optional param - present if non-null after cmd parse */ for (currArg = 1; (currArg < argc); ) { if ((argv[currArg][0] == '-') && (argv[currArg][1] != '\0')) switch (argv[currArg][1]) { case 'T': gotTbl = TRUE; tblFileName = NextParamStr (argv, &currArg); break; case 'm': modName = NextParamStr (argv, &currArg); break; case 'n': gotType = TRUE; typeName = NextParamStr (argv, &currArg); break; default: fprintf (stderr,"%s: ERROR - unknown cmd line option \"%s\"\n\n", argv[0], argv[currArg]); Usage (argv[0]); return 1; } else /* assume it's the name of a BER file */ fileArr[numValFiles++] = argv[currArg++]; } /* check sanity of cmd line args */ if (numValFiles == 0) { fprintf (stderr,"ERROR - no BER files were given.\n"); Usage (argv[0]); return 1; } if (!gotType) { fprintf (stderr,"ERROR - you must specify a type name.\n"); Usage (argv[0]); return 1; } if (!gotTbl) { fprintf (stderr,"ERROR - you must specify a type table file.\n"); Usage (argv[0]); return 1; } /* start decoding and printing the given files */ InitNibbleMem (1024,1024); tbl = LoadTblFile (tblFileName); if (tbl == NULL) return 1; for (i = 0; i < numValFiles; i++) { fileData = LoadFile (fileArr[i], &fsize); if (fileData == NULL) return 1; SBufInstallData (&sb, fileData, fsize); PutSBufInGenBuf (&sb, &gb); fprintf (stdout, "\n\n-- Contents of file \"%s\"--\n", fileArr[i]); fprintf (stdout, "-- module = %s, type = %s --\n\n", ((modName)? (modName):("???")), typeName); val = TblDecode (tbl, modName, typeName, &gb, &bytesDecoded); if (val == NULL) fprintf (stdout,"-- Decoding error occured somewhere -- \n"); else TblPrintValue (tbl, modName, typeName, stdout, val); fprintf (stdout, "\n\n -- decoded %d bytes for the above value --\n\n", bytesDecoded, fileArr[i]); free (fileData); /* was malloc'd in LoadFile (holds BER data) */ } return 0; } /* main */ esnacc-ng-1.8.1/tbl-tools/pval/readme000066400000000000000000000021721302010526100174100ustar00rootroot00000000000000(RCS control information is at the end of this file.) Value printing README - MS 93 ----------------------------- pval is a program that prints BER values in their value notation. Its arguments are a type table file, a module and type name and a list of BER files of that type. Look at the code in pval.c - quite simple & very generic. This is the advantage of type tables. Type "make" to build pval. Type ./pval to see the arguments it expects. try: ./pval -T ../demo-tbls/p-rec.tt -n PersonnelRecord ../demo-tbls/p-rec.ber cool, eh? #------------------------------------------------------------------------------- # $Header: /baseline/SNACC/tbl-tools/pval/readme,v 1.2 2003/12/17 19:05:04 gronej Exp $ # $Log: readme,v $ # Revision 1.2 2003/12/17 19:05:04 gronej # SNACC baseline merged with PER v1_7 tag # # Revision 1.1.2.1 2003/11/05 14:59:00 gronej # working PER code merged with esnacc_1_6 # # Revision 1.1.1.1 2000/08/21 20:35:47 leonberp # First CVS Version of SNACC. # # Revision 1.2 1997/02/15 19:21:15 rj # make without args just builds, doesn't install # # Revision 1.1 1997/02/15 19:15:07 rj # first check-in # esnacc-ng-1.8.1/tcl-asn/000077500000000000000000000000001302010526100147065ustar00rootroot00000000000000esnacc-ng-1.8.1/tcl-asn/asnwish.c000066400000000000000000000004351302010526100165300ustar00rootroot00000000000000#include "tk.h" extern int Tbl_AppInit (); int main(argc, argv) int argc; /* Number of command-line arguments. */ char **argv; /* Values of command-line arguments. */ { Tk_Main(argc, argv, Tbl_AppInit); return 0; /* Needed only to prevent compiler warning. */ } esnacc-ng-1.8.1/tcl-asn/beredit000066400000000000000000000234361302010526100162570ustar00rootroot00000000000000#!/bin/sh # the next line restarts using wish \ exec asnwish "$0" "$@" proc err {msg} { tk_dialog .err Error $msg {} 0 Damn } proc ref {desc} { set res [lindex $desc 0] if {$res==""} { set res [lindex $desc 1] if {$res=="TYPEREF"} { set res [lindex [lindex $desc 4] 1] } } return $res } proc complete {ntp} { global pdu upvar $ntp tp set tp [string trimright "$pdu $tp"] } proc newenc {tp r toggle} { global asnenc set idx $tp if {$toggle} { set cur [lindex [array get asnenc $idx] 1] set pr [lsearch -exact $cur $r] if {$pr==-1} { lappend cur $r } else { set cur [lreplace $cur $pr $pr] } set asnenc($idx) $cur } else { set asnenc($idx) $r } fillcomposer } proc selpress {y} { global tag set i [.selector.l nearest $y] if {$i==0} return set tpval [.selector.l get $i] if {$tag(selector)=="CHOICE"} { newenc [lindex $tpval 0] [lindex $tpval 1] 0 } else { newenc [lindex $tpval 0] [lindex $tpval 1] 1 } } proc comppress {y} { global table tag set i [.composer.l nearest $y] set tpval [.composer.l get $i] set tp [lindex $tpval 0] set val [lindex $tpval 1] set typetoask $tp set td [$table type -followref $typetoask] set t [lindex $td 1] switch $t { CHOICE { set tag(selector) $t .selector.l delete 0 end .selector.l insert end "$tp is a CHOICE of:" foreach {subtypedesc req} [lindex $td 4] { set r [ref $subtypedesc] .selector.l insert end [list $tp $r] } wm withdraw .insertor wm deiconify .selector raise .selector } SEQUENCE { set tag(selector) $t .selector.l delete 0 end .selector.l insert end "In SEQUENCE $tp, the following are OPTIONAL:" foreach {subtypedesc req} [lindex $td 4] { if {!$req} { set r [ref $subtypedesc] .selector.l insert end [list $tp $r] } } wm withdraw .insertor wm deiconify .selector raise .selector } default { if {$t=="SEQUENCE OF"} { set text "Size of SEQUENCE OF $tp:" } else { set text "New value of $tp:" } set tag(insertor) $tp .insertor.l configure -text $text .insertor.e delete 0 end .insertor.e insert 0 $val wm withdraw .selector wm deiconify .insertor raise .insertor } } } proc inspress {} { global tag newenc $tag(insertor) [.insertor.e get] 0 } proc fillcomposer {} { global table pdu set fraction 0.0 if [winfo exists .composer.l] { set fraction [lindex [.composer.l yview] 0] .composer.l delete 0 end } else { frame .composer pack .composer -fill both -expand 1 listbox .composer.l -yscrollcommand ".composer.v set" scrollbar .composer.v -orient vertical -command ".composer.l yview" pack .composer.v -fill y -side right pack .composer.l -expand yes -fill both bind .composer.l {comppress %y} toplevel .selector listbox .selector.l -yscrollcommand ".selector.v set" scrollbar .selector.v -orient vertical -command ".selector.l yview" pack .selector.v -fill y -side right pack .selector.l -expand yes -fill both bind .selector.l {selpress %y} wm protocol .selector WM_DELETE_WINDOW {wm withdraw .selector} wm title .selector "Snacc ASN.1 data item selection" toplevel .insertor label .insertor.l entry .insertor.e pack .insertor.l -fill x -expand yes -side top pack .insertor.e -fill x -expand yes -side bottom bind .insertor.e {inspress} wm protocol .insertor WM_DELETE_WINDOW {wm withdraw .insertor} wm title .insertor "Snacc ASN.1 data item modification" } wm withdraw .selector wm withdraw .insertor set null [open "/dev/null" w] $table encode $null $pdu "encodevalcompose $null" close $null .composer.l yview moveto $fraction wm deiconify . raise . } proc decodetype {tp val} { complete tp if {$val==-1} { set l [expr [llength $tp]-1] set final [lindex $tp $l] set addto [lrange $tp 0 [expr $l-1]] global table asnenc set td [$table type -followref $addto] if {[lindex $td 1]=="SEQUENCE"} { if [catch {set asnenc($addto)}] { set asnenc($addto) "" } foreach {elem req} [lindex $td 4] { if {[lindex $elem 0]==$final} { if {!$req} { lappend asnenc($addto) $final } break } } } else { set asnenc($addto) $final } } } proc decodeval {chan tp val} { decodetype $tp -1 global asnenc table complete tp set typ [$table type -followref $tp] if {[lindex $typ 1]=="BIT STRING"} { set namespecs [lindex $typ 3] set bitno 0 foreach bit [split $val ""] { set idx [lsearch $namespecs "$bitno *"] if {$idx>=0 && $bit} { lappend val "[lindex {! {}} $bit][lindex [lindex $namespecs $idx] 1]($bitno)" } incr bitno } } elseif {[lindex $typ 1]=="ENUMERATED"} { set namespecs [lindex $typ 3] set idx [lsearch $namespecs "$val *"] if {$idx>=0} { lappend val "[lindex [lindex $namespecs $idx] 1]" } } set asnenc($tp) $val } proc encodevalcompose {chan tp} { global asnenc complete tp if [catch {set val $asnenc($tp)}] { set val {} } .composer.l insert end [list $tp $val] return $val } proc encodeval {chan tp val} { global table set prefix - set val [subst -nobackslashes $val] set typ [$table type -followref $tp] if {[lindex $typ 1]=="OCTET STRING"} { set fromto [lindex $typ 2] set from [lindex $fromto 0] set to [lindex $fromto 1] if {$to==""} { set to $from } regsub -all {[^\\]} $val {} slashes set len [expr [string length $val] - [string length $slashes] * 3] if {$from!={} && $from>$len} { set val [format "%$prefix[expr $from]s" $val] } elseif {$to!={} && $to<$len} { err [list encodeval: value $val for $tp >$to] while {$to<$len} { set last [string last \\ $val] if {$last==-1 || $last<[string length $val]-4} { set val [string range $val 0 [expr [string length $val] - 2]] } else { set val [string range $val 0 [expr $last - 1]] } regsub -all {[^\\]} $val {} slashes set len [expr [string length $val] - [string length $slashes] * 3] } } } elseif {[lindex $typ 1]=="BIT STRING"} { set namespecs [lindex $typ 3] if {[regexp {^[01]+$} [lindex $val 0]]} { set val [split [lindex $val 0] ""] } else { set names $val set val {} foreach name $names { if {[regsub {([a-zA-Z_][a-zA-Z0-9_]*)?\(([0-9]+)\)} $name {\2} bitno]!=1} { set idx [lsearch -regexp $namespecs "^\[0-9\]+ $name$"] if {$idx<0} { err "Bit $name of $tp not in $namespecs" continue } set bitno [lindex [lindex $namespecs $idx] 0] } while {[llength $val]<=$bitno} { lappend val 0 } set val [lreplace $val $bitno $bitno 1] } } proc namespeccmp {a b} {return [expr [lindex $a 0] - [lindex $b 0]]} set sorted [lsort -command namespeccmp -decreasing $namespecs] set bitno [lindex [lindex $sorted 0] 0] while {[llength $val]<=$bitno} { lappend val 0 } set val [join $val ""] } elseif {[lindex $typ 1]=="ENUMERATED"} { set namespecs [lindex $typ 3] if {![regexp {^[0-9]*$} [lindex $val 0]]} { set idx [lsearch -regexp $namespecs "^\[0-9\]+ $val$"] if {$idx<0} { err "Named value $val of $tp not in $namespecs" } else { set val [lindex [lindex $namespecs $idx] 0] } } } return $val } proc encodeasnenc {chan tp} { global asnenc pdu complete tp if [catch {set val $asnenc($tp)}] { set val {} } return [encodeval $chan $tp $val] } wm title . "Snacc ASN.1 message editor" wm geometry . 400x300 frame .mbar -relief raised pack .mbar -side top -fill x menubutton .mbar.file -text Message -menu .mbar.file.menu pack .mbar.file -side left menu .mbar.file.menu .mbar.file.menu add command -label "Open ..." -command {openfile} .mbar.file.menu add command -label "Save As ..." -command {savefile} .mbar.file.menu add command -label "Quit" -command {quit} wm protocol . WM_DELETE_WINDOW {quit} proc readfile {fn} { if {$fn==""} return global table pdu asnenc catch {unset asnenc} set chan [open $fn r] fconfigure $chan -translation binary set bytes [$table decode $chan $pdu "decodeval $chan" decodetype] close $chan fillcomposer } proc openfile {} { readfile [tk_getOpenFile -defaultextension .ber -filetypes {{{ASN.1 data} {.ber .bin .out .tt}} {{All files} {.*}}}] } proc savefile {} { set fn [tk_getSaveFile -defaultextension .ber -filetypes {{{ASN.1 data} {.ber .bin .out .tt}} {{All files} {.*}}}] if {$fn==""} return global table pdu set chan [open $fn w] $table encode $chan $pdu "encodeasnenc $chan" close $chan } proc quit {} { global done set done 1 } set asnfile [lindex $argv 0] if {$asnfile==""} { puts stderr "Usage: $argv0 ??" puts stderr "" puts stderr "This program is a simple editor for ASN.1 messages" puts stderr "encoded using the Basic Encoding Rules (BER). It requires" puts stderr "the grammar specification, in binary format as generated" puts stderr "by \"snacc -T\", as the initial argument on the command line." puts stderr "" puts stderr "The purpose of this program is to demonstrate the usage of" puts stderr "the new Tcl/Tk command \"asn\". Have a look at the Tcl/Tk" puts stderr "script \"$argv0\"!" exit 0 } set table [asn $asnfile] foreach type [$table types] { if {[lindex [$table type $type] 0]=="$type pdu"} { set pdu $type break } } readfile [lindex $argv 1] fillcomposer update idletasks vwait done $table close exit esnacc-ng-1.8.1/tcl-asn/readme000066400000000000000000000061201302010526100160650ustar00rootroot00000000000000asnwish - An ASN.1 Tcl/Tk interpreter based on snacc table files The only extension to standard Tcl/Tk is a command called "asn", which reads a binary ASN.1 grammar file (as generated by "snacc -T") into an internal data structure and returns a new command "asn". "asn" offers the following possibilities: "asn modules" Returns a list of all modules of the grammar. "asn types ?module?" Returns a list of all type definitions of the grammar respectively of the module given. Each type definition is returned as a list consisting of the module name and the type name. "asn type ?-followref? {?module? typedef ?subtype? ...} Returns a description of the given type. The description format is " ??". In case of a type definition, "" is a three- element list "{ "pdu"|"sub"}". In case of a subtype, is the fieldname, if any, or an empty list "{}". "" is one out of "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", "NULL", "OBJECT IDENTIFIER", "REAL", "ENUMERATED", "SEQUENCE", "SET", "SEQUENCE OF", "SET OF", "CHOICE" or "TYPEREF". "" is either empty, or a single numeric value, or a list of two numeric vaules. It can be available for types "SEQUENCE OF" (giving the lower and, optionally, the upper bounds of the index), "INTEGER" (giving the lowest and the highest possible value) and "OCTET STRING" (giving the minimum and, optionally, the maximum length). "" is either empty, or a list of two-element lists, each consisting of an integer value and a name. It can be available for types "BIT STRING" and "ENUMERATED". "??" is available for types "TYPEREF" (where it is a two-element list "{ }" and "SEQUENCE", "SET", "SEQUENCE OF", "SET OF", "CHOICE" (where it is a list of subtype descriptions, each of the format given here). "asn decode channel {?module? typedef ?subtype? ...} valcmd ?typecmd?" Reads from the channel the given type, BER encoded, and decodes it. During decoding, whenever a compound type is entered or left, the Tcl/Tk "typecmd" (if any) is executed, with the type path as first parameter, and a "1" resp. "-1" as second, and whenever a value is decoded, the Tcl/Tk "valcmd" is executed, with the type path as the first and the value as the second parameter. BOOLEAN values are represented as "TRUE" resp. "FALSE". INTEGER and ENUMERATED values are represented by their decimal representation. BIT STRINGs are represented by a string of "0" and "1" characters. OCTET STRINGs and OIDs are represented as following: printable characters (except the character "\") are copied unchanged; non-printable characters and the character "\" are represented by \OOO (e.g., their ASCII value encoded by three octal digits with leading 0). The NULL type is encoded as "NULL". REAL numbers representation follows sprintf %G. Returns the number of bytes decoded. "asn encode channel {?module? typedef ?subtype? ...} valcmd ?typecmd?" "asn close" Closes the grammar and deletes the internal data structure. esnacc-ng-1.8.1/tcl-asn/tclasn.c000066400000000000000000000744551302010526100163550ustar00rootroot00000000000000/* * Wishes: * Allow spec of PDU to decode in asn decode * (Prefixing tp during decoding with PDU is not necessary) * * */ #include "tk.h" #include "tbl-gen.h" #include "tbl-dbg.h" #include "sbuf.h" #include "exp-buf.h" #include typedef struct ChannelBuf { Tcl_Channel chan; int readError; } ChannelBuf; static void PutChannelBufInGenBuf _ANSI_ARGS_((Tcl_Channel chan, GenBuf* gb)); static unsigned char ChanGetByte (cb) ChannelBuf* cb; { unsigned char result = 0; if (!cb->readError) if (Tcl_Read(cb->chan,&result,1)!=1) cb->readError = TRUE; return result; } static char* ChanGetSeg (cb, len) ChannelBuf* cb; unsigned long* len; { static char result[100]; if (cb->readError) { *len = 0; return NULL; } if (*len>sizeof(result)) *len = sizeof(result); *len = Tcl_Read(cb->chan,result,*len); if (*len<0) { cb->readError = TRUE; *len = 0; return NULL; } return result; } static unsigned long ChanCopy (dst, cb, len) char* dst; ChannelBuf* cb; unsigned long len; { unsigned long result; if (cb->readError) { return 0; } result = Tcl_Read(cb->chan,dst,len); if (result!=len) { cb->readError = TRUE; if (result<0) result = 0; } return result; } static unsigned long ChanPeekCopy (dst, cb, len) char* dst; ChannelBuf* cb; unsigned long len; { unsigned long result, result2; if (cb->readError) { return 0; } result = ChanCopy(dst,cb,len); result2 = Tcl_Ungets(cb->chan,dst,result,0); if (result2!=result) { cb->readError = TRUE; } return result; } static unsigned char ChanPeekByte (cb) ChannelBuf* cb; { unsigned char result = 0; ChanPeekCopy(&result,cb,1); return result; } static int ChanReadError (cb) ChannelBuf* cb; { return cb->readError; } static void PutChannelBufInGenBuf (cb, gb) ChannelBuf* cb; GenBuf* gb; { gb->bufInfo = cb; cb->readError = FALSE; gb->getByte = (BufGetByteFcn) ChanGetByte; gb->getSeg = (BufGetSegFcn) ChanGetSeg; gb->copy = (BufCopyFcn) ChanCopy; gb->peekByte = (BufPeekByteFcn) ChanPeekByte; gb->peekCopy = (BufPeekCopyFcn) ChanPeekCopy; gb->readError = (BufReadErrorFcn) ChanReadError; } #if TCL_MAJORVERSION<8 #define Tcl_GetStringResult(interp) (interp->result) #endif #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b)) extern int matherr(); int *tclDummyMathPtr = (int *) matherr; Tcl_Interp* interpG; int interpResultG; char* tblvalcmdG; char* tbltypecmdG; void myAsn1ErrorHandler (str, severity) char* str; int severity; { Tcl_AppendResult(interpG,"ASN.1 error: ",str,NULL); interpResultG = TCL_ERROR; } int equal (char* s1, char* s2) { return s1==s2 || (s1 && s2 && !strcmp(s1,s2)); } int contained (char* in, char* el) { int argc; char** argv; if (Tcl_SplitList(interpG,in,&argc,&argv)!=TCL_OK) return FALSE; while (argc--) if (equal(*argv++,el)) return TRUE; return FALSE; } static struct TypePath { char* typename; char* fieldname; int index; } tp[20]; static int ntp; int TblDbgCallProc (cmdstart, value) char* cmdstart; char* value; { int i; Tcl_DString cmd, type; if (ntp<=1 || !cmdstart) return TCL_OK; Tcl_DStringInit(&cmd); Tcl_DStringAppend(&cmd,cmdstart,-1); Tcl_DStringInit(&type); for (i=1; ibitLen = strlen(iresult); ((AsnBits*)v)->bits = Asn1Alloc(((AsnBits*)v)->bitLen?(((AsnBits*)v)->bitLen-1)/8+1:0); for (i=0; iresult[i]; i++) if (iresult[i]!='0') SetAsnBit((AsnBits*)v,i); break; case TBL_OCTETSTRING: case TBL_OID: ((AsnOcts*)v)->octs = Asn1Alloc(strlen(iresult)); /* Might be too much, but don't care */ for (i=((AsnOcts*)v)->octetLen=0; iresult[i]; i++,((AsnOcts*)v)->octetLen++) if (iresult[i]=='\\') { char* skipto; strncpy(fmt,iresult+i+1,3); fmt[3] = '\0'; ((AsnOcts*)v)->octs[((AsnOcts*)v)->octetLen] = strtol(fmt,&skipto,8); i += skipto-fmt; } else ((AsnOcts*)v)->octs[((AsnOcts*)v)->octetLen] = iresult[i]; break; case SPECIALID_STR: *(char**)v = Asn1Alloc(strlen(iresult)+1); strcpy(*(char**)v,iresult); break; default: break; } Tcl_ResetResult(interpG); return TCL_OK; } int TblEncType PARAMS ((type, b, implicit, bytesEncoded), TBLType *type _AND_ BUF_TYPE b _AND_ int implicit _AND_ unsigned long int *bytesEncoded) { int result = TCL_OK; unsigned long int tmpBytesEncoded = 0; unsigned int currElmt; TBLType *elmt; TBLType* choice; int implicitRef; void *tmp; AsnBits optavail; char* elmtname; union { AsnBool bo; AsnInt in; AsnBits bi; AsnOcts oc; AsnReal re; } unival; if (type->typeId==TBL_TYPEREF && !tp[ntp-1].typename) tp[ntp-1].typename = type->content->a.typeRef->typeDefPtr->typeName.octs; if (type->typeId!=TBL_TYPEREF && !tp[ntp-1].typename) tp[ntp-1].typename = TIN[type->typeId]; if (!tp[ntp-1].fieldname) tp[ntp-1].fieldname = type->fieldName.octs; switch (type->typeId) { case TBL_TYPEREF: /* * carry over implicit ref if goes * through typeref with no tags */ implicitRef = type->content->a.typeRef->implicit || (implicit && ((type->tagList == NULL) || LIST_EMPTY (type->tagList))); result = TblEncType (type->content->a.typeRef->typeDefPtr->type, b, implicitRef, &tmpBytesEncoded); if (result!=TCL_OK) return result; break; case TBL_SEQUENCE: case TBL_SET: /* rvs though list value and list type def */ currElmt = LIST_COUNT (type->content->a.elmts); tmp = CURR_LIST_NODE (type->content->a.elmts); result = TblEncAsk(SPECIALID_STR,&elmtname,tbltypecmdG); if (result!=TCL_OK) return result; FOR_EACH_LIST_ELMT_RVS (elmt, type->content->a.elmts) { if (!elmt->optional || contained(elmtname,elmt->fieldName.octs) || !elmt->fieldName.octetLen && (elmt->typeId==TBL_TYPEREF && contained(elmtname, elmt->content->a.typeRef->typeDefPtr->typeName.octs) || elmt->typeId!=TBL_TYPEREF && contained(elmtname, TIN[elmt->typeId]))) { tp[ntp].typename = tp[ntp].fieldname = NULL; tp[ntp].index = 0; ntp++; result = TblEncType (elmt, b, FALSE, &tmpBytesEncoded); if (result!=TCL_OK) { Asn1Free(optavail.bits); return result; } ntp--; } } Asn1Free(elmtname); /* restore list curr in case recursive type */ SET_CURR_LIST_NODE (type->content->a.elmts, tmp); break; case TBL_SEQUENCEOF: case TBL_SETOF: result = TblEncAsk(TBL_INTEGER,&tp[ntp-1].index,tbltypecmdG); if (result!=TCL_OK) return result; elmt = FIRST_LIST_ELMT (type->content->a.elmts); for (;tp[ntp-1].index>=1;tp[ntp-1].index--) { tp[ntp].typename = tp[ntp].fieldname = NULL; tp[ntp].index = 0; ntp++; result = TblEncType (elmt, b, FALSE, &tmpBytesEncoded); if (result!=TCL_OK) return result; ntp--; } break; case TBL_CHOICE: result = TblEncAsk(SPECIALID_STR,&elmtname,tbltypecmdG); if (result!=TCL_OK) return result; tmp = CURR_LIST_NODE (type->content->a.elmts); choice = NULL; FOR_EACH_LIST_ELMT(elmt, type->content->a.elmts) if (equal(elmtname,elmt->fieldName.octs)) { choice = elmt; break; } if (!choice) FOR_EACH_LIST_ELMT(elmt, type->content->a.elmts) if (!elmt->fieldName.octetLen) { if (elmt->typeId==TBL_TYPEREF) { if (equal(elmtname,elmt->content->a.typeRef->typeDefPtr->typeName.octs)) { choice = elmt; break; } } else if (equal(elmtname,TIN[elmt->typeId])) { choice = elmt; break; } } Asn1Free(elmtname); SET_CURR_LIST_NODE (type->content->a.elmts, tmp); if (choice) { tp[ntp].typename = tp[ntp].fieldname = NULL; tp[ntp].index = 0; ntp++; result = TblEncType(choice,b,FALSE,&tmpBytesEncoded); if (result!=TCL_OK) return result; ntp--; } break; case TBL_BOOLEAN: result = TblEncAsk(type->typeId,&unival,tblvalcmdG); if (result!=TCL_OK) return result; tmpBytesEncoded += BEncAsnBoolContent (b, &unival.bo); if (interpResultG!=TCL_OK) return interpResultG; break; case TBL_INTEGER: case TBL_ENUMERATED: result = TblEncAsk(type->typeId,&unival,tblvalcmdG); if (result!=TCL_OK) return result; tmpBytesEncoded += BEncAsnIntContent (b, &unival.in); if (interpResultG!=TCL_OK) return interpResultG; break; case TBL_BITSTRING: result = TblEncAsk(type->typeId,&unival,tblvalcmdG); if (result!=TCL_OK) return result; tmpBytesEncoded += BEncAsnBitsContent (b, &unival.bi); Asn1Free(unival.bi.bits); if (interpResultG!=TCL_OK) return interpResultG; break; case TBL_OCTETSTRING: result = TblEncAsk(type->typeId,&unival,tblvalcmdG); if (result!=TCL_OK) return result; tmpBytesEncoded += BEncAsnOctsContent (b, &unival.oc); Asn1Free(unival.oc.octs); if (interpResultG!=TCL_OK) return interpResultG; break; case TBL_NULL: tmpBytesEncoded += BEncAsnNullContent (b, NULL); if (interpResultG!=TCL_OK) return interpResultG; break; case TBL_OID: result = TblEncAsk(type->typeId,&unival,tblvalcmdG); if (result!=TCL_OK) return result; tmpBytesEncoded += BEncAsnOidContent (b, &unival.oc); Asn1Free(unival.oc.octs); if (interpResultG!=TCL_OK) return interpResultG; break; case TBL_REAL: result = TblEncAsk(type->typeId,&unival,tblvalcmdG); if (result!=TCL_OK) return result; tmpBytesEncoded += BEncAsnRealContent (b, &unival.re); if (interpResultG!=TCL_OK) return interpResultG; break; default: Tcl_AppendResult(interpG,"strange type",NULL); return TCL_ERROR; } TblEncodeTagsAndLens (type, b, implicit, &tmpBytesEncoded); (*bytesEncoded) += tmpBytesEncoded; return TCL_OK; } int TblEnc PARAMS (( type, b), TBLType *type _AND_ BUF_TYPE b) { unsigned long int bytesEncoded = 0; int result; ntp = 1; result = TblEncType (type, b, FALSE, &bytesEncoded); if (result==TCL_OK && BufWriteError (b)) { Tcl_AppendResult(interpG,"error writing buffer",NULL); result = TCL_ERROR; } interpResultG = result; if (result==TCL_OK) return bytesEncoded; else return -1; } void TblDbgValue (type, val, pvalue) TBLType* type; AVal* val; Tcl_DString* pvalue; { char fmt[20]; switch (type->typeId) { case TBL_BOOLEAN: Tcl_DStringAppend(pvalue,*(AsnBool*)val? "TRUE" :"FALSE", -1); break; case TBL_INTEGER: case TBL_ENUMERATED: sprintf(fmt,"%d",*(AsnInt*)val); Tcl_DStringAppend(pvalue,fmt, -1); break; case TBL_BITSTRING: { AsnBits* v = (AsnBits*)val; unsigned long i; for (i=0; ibitLen; i++) Tcl_DStringAppend(pvalue,GetAsnBit(v,i)?"1":"0", -1); } break; case TBL_OCTETSTRING: case TBL_OID: { AsnOcts* v = (AsnOcts*)val; unsigned long i; for (i=0; ioctetLen; i++) if (v->octs[i]=='\\' || !isprint(v->octs[i])) { sprintf(fmt,"\\%03o",v->octs[i]); Tcl_DStringAppend(pvalue,fmt,-1); } else Tcl_DStringAppend(pvalue,v->octs+i,1); } break; case TBL_NULL: Tcl_DStringAppend(pvalue,"NULL", -1); break; case TBL_REAL: sprintf(fmt,"%G",*(AsnReal*)val); Tcl_DStringAppend(pvalue,fmt, -1); break; default: break; } } int TblDbgType PARAMS ((type, val, begin), TBLType* type _AND_ AVal* val _AND_ int begin) { int result = TCL_OK; if (begin) { if (type->typeId==TBL_TYPEREF && !tp[ntp-1].typename) tp[ntp-1].typename = type->content->a.typeRef->typeDefPtr->typeName.octs; if (type->typeId!=TBL_TYPEREF && !tp[ntp-1].typename) tp[ntp-1].typename = TIN[type->typeId]; if (!tp[ntp-1].fieldname) tp[ntp-1].fieldname = type->fieldName.octs; if (type->typeId >= TBL_SEQUENCE && type->typeId <= TBL_CHOICE) { result = TblDbgCallProc(tbltypecmdG,"1"); if (type->typeId == TBL_SEQUENCEOF || type->typeId == TBL_SETOF) tp[ntp-1].index = 1; tp[ntp].typename = tp[ntp].fieldname = NULL; tp[ntp].index = 0; ntp++; } } else if (type->typeId!=TBL_TYPEREF) { if (type->typeId < TBL_SEQUENCE) { Tcl_DString value; Tcl_DStringInit(&value); TblDbgValue(type,val,&value); result = TblDbgCallProc(tblvalcmdG,Tcl_DStringValue(&value)); Tcl_DStringFree(&value); } else { ntp--; if (type->typeId == TBL_SEQUENCEOF || type->typeId == TBL_SETOF) tp[ntp-1].index = 0; result = TblDbgCallProc(tbltypecmdG,"-1"); } tp[ntp-1].typename = tp[ntp-1].fieldname = NULL; if (ntp>=2) if (tp[ntp-2].index) tp[ntp-2].index++; } return result; } TBLType* TblFindType (type, argv, followref, ptr, ptnnl) TBLType* type; char** argv; int followref; TBLRange** ptr; TBLNamedNumberList** ptnnl; { TBLType* elmt; TBLType* result; void *tmp; if (!*argv) { if (ptr && !*ptr && type->constraint) *ptr = type->constraint; if (ptnnl && !*ptnnl && type->values) *ptnnl = type->values; if (!followref || type->typeId!=TBL_TYPEREF) return type; } switch (type->typeId) { case TBL_TYPEREF: return TblFindType(type->content->a.typeRef->typeDefPtr->type,argv,followref,ptr,ptnnl); case TBL_CHOICE: case TBL_SET: case TBL_SEQUENCE: tmp = CURR_LIST_NODE (type->content->a.elmts); result = NULL; FOR_EACH_LIST_ELMT(elmt,type->content->a.elmts) if (equal(*argv,elmt->fieldName.octs)) { result = TblFindType(elmt,argv+1,followref,ptr,ptnnl); break; } if (!result) { FOR_EACH_LIST_ELMT(elmt,type->content->a.elmts) if (!elmt->fieldName.octetLen) { if (elmt->typeId==TBL_TYPEREF) { if (equal(*argv,elmt->content->a.typeRef->typeDefPtr->typeName.octs)) { result = TblFindType(elmt->content->a.typeRef->typeDefPtr->type,argv+1,followref,ptr,ptnnl); break; } } else if (equal(*argv,TIN[elmt->typeId])) { result = TblFindType(elmt,argv+1,followref,ptr,ptnnl); break; } } } SET_CURR_LIST_NODE (type->content->a.elmts, tmp); return result; case TBL_SETOF: case TBL_SEQUENCEOF: if (**argv>='0'&&**argv<='9') argv++; return TblFindType(FIRST_LIST_ELMT(type->content->a.elmts),argv,followref,ptr,ptnnl); default: return NULL; } } TBLType* TblTypeOfPath (interp, tbl, path, followref, ptd, ptr, ptnnl) TBL* tbl; char* path; int followref; TBLTypeDef** ptd; TBLRange** ptr; TBLNamedNumberList** ptnnl; { TBLModule* tm = NULL; TBLTypeDef* td; TBLType* type = NULL; int argc; char** argv; if (Tcl_SplitList(interp,path,&argc,&argv)!=TCL_OK) return NULL; if (argc>=2 && (tm = TblFindModule(tbl,argv[0]))) { argv++; argc--; } if (argc<1 || !(td=TblFindTypeDef(tbl,tm?tm->name.octs:NULL,argv[0],&tm)) || !(type=TblFindType(td->type,argv+1,followref,ptr,ptnnl))) Tcl_AppendResult(interp,"wrong typepath \"",path, "\", should be ?module? typedef ?subtype? ...", NULL); else if (ptd) *ptd = td; Tcl_Free((char*)argv); return type; } int dowrite (Tcl_Channel chan, char* buffer, int n) { int written = 0; int onewrite; while (written EOF */ break; haveread += oneread; } return haveread; } int TblCmdDecode (interp, tbl, chan, path, valcmd, typecmd) Tcl_Interp* interp; TBL* tbl; Tcl_Channel chan; char* path; char* valcmd; char* typecmd; { int result; ChannelBuf cb; GenBuf gb; unsigned long bytesDecoded; char test; TBLType* type = TblTypeOfPath (interp, tbl, path, FALSE, NULL, NULL, NULL); if (!type) { Tcl_AppendResult(interp,"wrong typepath \"",path,"\"",NULL); return TCL_ERROR; } result = Tcl_Read(chan,&test,1); if (result<0) { Tcl_AppendResult(interp,"read failed",NULL); return TCL_ERROR; } if (result==0) { Tcl_AppendResult(interp,"0",NULL); return TCL_OK; } result = Tcl_Ungets(chan,&test,1,0); if (result!=1) { Tcl_AppendResult(interp,"ungets failed",NULL); return TCL_ERROR; } cb.chan = chan; PutChannelBufInGenBuf(&cb,&gb); interpG = interp; interpResultG = TCL_OK; tblvalcmdG = valcmd; tbltypecmdG = typecmd; ntp = 1; result = TdeDecodeSpecific(tbl,&gb,type,&bytesDecoded,TblDbgType,NULL,NULL); if (interpResultG==TCL_OK) { if (!result) Asn1Error("TdeDecodeSpecific failed"); } if (interpResultG==TCL_OK) { char buffer[11]; sprintf(buffer,"%u",(int)bytesDecoded); Tcl_SetResult(interp,buffer,TCL_VOLATILE); } return interpResultG; } int TblRealType (type) TBLType* type; { if (type->typeId==TBL_TYPEREF) return TblRealType(type->content->a.typeRef->typeDefPtr->type); else return type->typeId; } TBLModule* TblModuleOfTypeDef (tbl, td) TBL* tbl; TBLTypeDef* td; { TBLModule* tm; TBLTypeDef* td2; void *tmp1; void *tmp2; /* look in all modules and return typedef with given id */ tmp1 = CURR_LIST_NODE (tbl->modules); FOR_EACH_LIST_ELMT (tm, tbl->modules) { tmp2 = CURR_LIST_NODE (tm->typeDefs); FOR_EACH_LIST_ELMT (td2, tm->typeDefs) if (td2==td) { SET_CURR_LIST_NODE (tm->typeDefs, tmp2); SET_CURR_LIST_NODE (tbl->modules, tmp1); return tm; } SET_CURR_LIST_NODE (tm->typeDefs, tmp2); } SET_CURR_LIST_NODE (tbl->modules, tmp1); return NULL; } void TblDescType (ps, tbl, tm, td, type, tr, tnnl) Tcl_DString* ps; TBL* tbl; TBLModule* tm; TBLTypeDef* td; TBLType* type; TBLRange* tr; TBLNamedNumberList* tnnl; { if (td) { Tcl_DStringStartSublist(ps); Tcl_DStringAppendElement(ps,tm->name.octs); Tcl_DStringAppendElement(ps,td->typeName.octs); Tcl_DStringAppendElement(ps,td->isPdu?"pdu":"sub"); Tcl_DStringEndSublist(ps); } else { Tcl_DStringAppendElement(ps,type->fieldName.octs); } Tcl_DStringAppendElement(ps,TIN[type->typeId]); Tcl_DStringStartSublist(ps); if (!tr) tr = type->constraint; if (tr) { char fmt[20]; sprintf(fmt,"%d",tr->from); Tcl_DStringAppendElement(ps,fmt); if (tr->to!=tr->from) { sprintf(fmt,"%d",tr->to); Tcl_DStringAppendElement(ps,fmt); } } Tcl_DStringEndSublist(ps); Tcl_DStringStartSublist(ps); if (!tnnl) tnnl = type->values; if (tnnl) { TBLNamedNumber* tnn; FOR_EACH_LIST_ELMT(tnn,tnnl) { char fmt[20]; Tcl_DStringStartSublist(ps); sprintf(fmt,"%d",tnn->value); Tcl_DStringAppendElement(ps,fmt); if (tnn->name.octetLen) Tcl_DStringAppendElement(ps,tnn->name.octs); Tcl_DStringEndSublist(ps); } } Tcl_DStringEndSublist(ps); if (type->content) switch (type->content->choiceId) { case TBLTYPECONTENT_ELMTS: { TBLType* elmt; void* tmp = CURR_LIST_NODE (type->content->a.elmts); Tcl_DStringStartSublist(ps); FOR_EACH_LIST_ELMT(elmt,type->content->a.elmts) { Tcl_DStringStartSublist(ps); TblDescType(ps,tbl,tm,NULL,elmt,NULL,NULL); Tcl_DStringEndSublist(ps); Tcl_DStringAppendElement(ps,elmt->optional?"0":"1"); } Tcl_DStringEndSublist(ps); SET_CURR_LIST_NODE (type->content->a.elmts, tmp); } break; case TBLTYPECONTENT_TYPEREF: { TBLTypeDef* td = type->content->a.typeRef->typeDefPtr; Tcl_DStringStartSublist(ps); Tcl_DStringAppendElement(ps,TblModuleOfTypeDef(tbl,td)->name.octs); Tcl_DStringAppendElement(ps,td->typeName.octs); Tcl_DStringEndSublist(ps); } break; default: break; } } typedef struct TblCmdData { char name[20]; TBL* tbl; } TblCmdData; int TblCmd (tcd, interp, argc, argv) TblCmdData* tcd; Tcl_Interp* interp; int argc; char* argv[]; { int c; size_t l; if (argc>=2) { c = *argv[1]; l = strlen(argv[1]); if (argc==2 && !strncmp(argv[1],"close",l)) { Tcl_DeleteCommand(interp,tcd->name); return TCL_OK; } else if (!strncmp(argv[1],"decode",l) && (argc>=5 && argc<=6)) { int mode; Tcl_Channel chan = Tcl_GetChannel(interp,argv[2],&mode); if (!chan) return TCL_ERROR; if (!(mode & TCL_READABLE)) { Tcl_AppendResult(interp, "channel \"", argv[2], "\" wasn't opened for reading", NULL); return TCL_ERROR; } return TblCmdDecode(interp,tcd->tbl,chan,argv[3],argv[4],argv[5]); } else if (!strncmp(argv[1],"encode",l) && (argc>=5 && argc<=6)) { int mode; Tcl_Channel chan = Tcl_GetChannel(interp,argv[2],&mode); if (!chan) return TCL_ERROR; if (!(mode & TCL_WRITABLE)) { Tcl_AppendResult(interp, "channel \"", argv[2], "\" wasn't opened for writing", NULL); return TCL_ERROR; } return TblCmdEncode(interp,tcd->tbl,chan,argv[3],argv[4],argv[5]); } else if (argc==2 && !strncmp(argv[1],"modules",l)) { TBLModule *tm; FOR_EACH_LIST_ELMT (tm, tcd->tbl->modules) Tcl_AppendElement(interp,tm->name.octs); return TCL_OK; } else if (!strncmp(argv[1],"type",l) && (argc==3 || argc==4 && !strncmp(argv[2],"-followref",max(strlen(argv[2]),2)))) { TBLTypeDef* td; TBLRange* tr = NULL; TBLNamedNumberList* tnnl = NULL; TBLType* type = TblTypeOfPath(interp,tcd->tbl,argv[argc-1],argc==4, &td,&tr,&tnnl); if (!type) return TCL_ERROR; else { Tcl_DString ds; Tcl_DStringInit(&ds); TblDescType(&ds,tcd->tbl,TblModuleOfTypeDef(tcd->tbl,td), type==td->type?td:NULL,type,tr,tnnl); Tcl_DStringResult(interp,&ds); Tcl_DStringFree(&ds); return TCL_OK; } } else if (argc>=2 && argc<=3 && !strncmp(argv[1],"types",l)) { TBLModule *tm; TBLTypeDef* td; int moduleFound = 0; Tcl_DString ds; Tcl_DStringInit(&ds); FOR_EACH_LIST_ELMT (tm, tcd->tbl->modules) if (argc==2 || equal(tm->name.octs,argv[2])) { moduleFound = 1; FOR_EACH_LIST_ELMT (td, tm->typeDefs) { Tcl_DStringStartSublist(&ds); Tcl_DStringAppendElement(&ds,tm->name.octs); Tcl_DStringAppendElement(&ds,td->typeName.octs); Tcl_DStringEndSublist(&ds); } } Tcl_DStringResult(interp,&ds); Tcl_DStringFree(&ds); if (argc==3 && !moduleFound) { Tcl_AppendResult(interp,argv[0]," ",argv[1],": module \"",argv[2], "\" unknown",NULL); return TCL_ERROR; } return TCL_OK; } } Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " modules", " | types ?module?", " | type ?-followref? {?module? typedef ?subtype? ...}", " | decode channel {?module? typedef ?subtype? ...} valcmd ?typecmd?", " | encode channel {?module? typedef ?subtype? ...} valcmd ?typecmd?", " | close\"", NULL); return TCL_ERROR; } void TblCmdFree (tcd) TblCmdData* tcd; { FreeTBL(tcd->tbl); ckfree(tcd); } int TableCmd (clientData, interp, argc, argv) ClientData clientData; Tcl_Interp* interp; int argc; char* argv[]; { static int ntbl = 0; TBL* tbl; TblCmdData* tcd; if (argc != 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " path\"", NULL); return TCL_ERROR; } interpG = interp; interpResultG = TCL_OK; tbl = LoadTblFile(argv[1]); if (!tbl && interpResultG==TCL_OK) { Asn1Error("Can't load grammar table"); } if (interpResultG!=TCL_OK) return interpResultG; tcd = (TblCmdData*) ckalloc(sizeof(*tcd)); sprintf(tcd->name,"asn%d",++ntbl); tcd->tbl = tbl; Tcl_CreateCommand(interp,tcd->name,TblCmd,tcd,TblCmdFree); Tcl_AppendResult(interp,tcd->name,NULL); return TCL_OK; } /* *---------------------------------------------------------------------- * * Tcl_AppInit -- * * This procedure performs application-specific initialization. * Most applications, especially those that incorporate additional * packages, will have their own version of this procedure. * * Results: * Returns a standard Tcl completion code, and leaves an error * message in interp->result if an error occurs. * * Side effects: * Depends on the startup script. * *---------------------------------------------------------------------- */ int Tbl_AppInit(interp) Tcl_Interp *interp; /* Interpreter for application. */ { if (Tcl_Init(interp) == TCL_ERROR) { return TCL_ERROR; } if (Tk_Init(interp) == TCL_ERROR) { return TCL_ERROR; } /* * Call Tcl_CreateCommand for application-specific commands, if * they weren't already created by the init procedures called above. */ Asn1InstallErrorHandler(myAsn1ErrorHandler); InitNibbleMem(1024,1024); Tcl_CreateCommand(interp, "asn", TableCmd, NULL, NULL); return TCL_OK; } esnacc-ng-1.8.1/tcl-example/000077500000000000000000000000001302010526100155605ustar00rootroot00000000000000esnacc-ng-1.8.1/tcl-example/edex0.asn1000066400000000000000000000016641302010526100173600ustar00rootroot00000000000000-- file: edex0.asn1 -- -- snacced example, simple types module -- -- $Header: /baseline/SNACC/tcl-example/edex0.asn1,v 1.2 2003/12/17 19:05:04 gronej Exp $ -- $Log: edex0.asn1,v $ -- Revision 1.2 2003/12/17 19:05:04 gronej -- SNACC baseline merged with PER v1_7 tag -- -- Revision 1.1.2.1 2003/11/05 14:58:57 gronej -- working PER code merged with esnacc_1_6 -- -- Revision 1.1.1.1 2000/08/21 20:35:47 leonberp -- First CVS Version of SNACC. -- -- Revision 1.1 1997/01/01 22:57:11 rj -- first check-in -- EdEx-Simple DEFINITIONS ::= BEGIN RainbowColor ::= INTEGER { red(0), orange(1), yellow(2), green(3), blue(4), indigo(5), violet(6) } DayOfTheWeek ::= ENUMERATED { sunday(0), monday(1), tuesday(2), wednesday(3), thursday(4), friday(5), saturday(6) } Hand ::= BIT STRING { thumb(0), forefinger(1), middle-finger(2), ring-finger(3), little-finger(4) } victory Hand ::= { forefinger, middle-finger } File ::= OCTET STRING END esnacc-ng-1.8.1/tcl-example/edex1.asn1000066400000000000000000000030611302010526100173520ustar00rootroot00000000000000-- file: edex1.asn1 -- -- snacced example, structured types module -- -- $Header: /baseline/SNACC/tcl-example/edex1.asn1,v 1.2 2003/12/17 19:05:04 gronej Exp $ -- $Log: edex1.asn1,v $ -- Revision 1.2 2003/12/17 19:05:04 gronej -- SNACC baseline merged with PER v1_7 tag -- -- Revision 1.1.2.1 2003/11/05 14:58:57 gronej -- working PER code merged with esnacc_1_6 -- -- Revision 1.1.1.1 2000/08/21 20:35:47 leonberp -- First CVS Version of SNACC. -- -- Revision 1.2 1997/02/28 13:39:56 wan -- Modifications collected for new version 1.3: Bug fixes, tk4.2. -- -- Revision 1.1 1997/01/01 22:57:13 rj -- first check-in -- EdEx-Structured DEFINITIONS ::= BEGIN IMPORTS RainbowColor, DayOfTheWeek, Hand FROM EdEx-Simple; RGBColor ::= SEQUENCE { red INTEGER, green INTEGER, blue INTEGER } Coordinate ::= CHOICE { cartesian [0] SEQUENCE { x REAL, y REAL }, polar [1] SEQUENCE { angle REAL, distance REAL } } File ::= SET { name [0] PrintableString, contents [1] OCTET STRING, checksum [2] INTEGER OPTIONAL, read-only [3] BOOLEAN DEFAULT FALSE } Directory ::= SET { name PrintableString, files SET OF File } Simple ::= SET { null [0] NULL, boolv [1] BOOLEAN, day [2] DayOfTheWeek, intv [3] INTEGER, color [4] RainbowColor, real [5] REAL, bits [6] Hand, str [7] OCTET STRING, optstr [8] OCTET STRING OPTIONAL } Structured ::= SET { coord [0] Coordinate, color [1] CHOICE { rainbow RainbowColor, rgb RGBColor } } Various ::= SET { simple [0] Simple, struct [1] Structured, recursion [2] Various OPTIONAL } END esnacc-ng-1.8.1/tcl-lib/000077500000000000000000000000001302010526100146735ustar00rootroot00000000000000esnacc-ng-1.8.1/tcl-lib/bindings.tcl000066400000000000000000000022371302010526100172000ustar00rootroot00000000000000# file: bindings.tcl #\[sep]----------------------------------------------------------------------------------------------------------------------------- proc bit_string_entry_bindings {entry} \ { bind $entry { } # bind $entry {puts return} bind $entry {%W insert insert %A} bind $entry {%W insert insert %A} bind $entry [bind Entry ] bind $entry [bind Entry ] bind $entry [bind Entry ] bind $entry [bind Entry ] bind $entry [bind Entry ] bind $entry {%W icursor [expr [%W index insert] -1]} bind $entry {%W icursor [expr [%W index insert] +1]} } #\[sep]----------------------------------------------------------------------------------------------------------------------------- proc int_entry_bindings {entry} \ { bit_string_entry_bindings $entry for {set i 2} {$i < 10} {incr i} \ { bind $entry {%W insert insert %A} bind $entry {%W insert insert %A} } bind $entry {%W insert insert %A} bind $entry {%W insert insert %A} } esnacc-ng-1.8.1/tcl-lib/help.tcl000066400000000000000000000025671302010526100163410ustar00rootroot00000000000000# file: help.tcl # toplevel widget to display a help text (modal) # # $Header: /baseline/SNACC/tcl-lib/help.tcl,v 1.2 2003/12/17 19:05:04 gronej Exp $ # $Log: help.tcl,v $ # Revision 1.2 2003/12/17 19:05:04 gronej # SNACC baseline merged with PER v1_7 tag # # Revision 1.1.2.1 2003/11/05 14:58:56 gronej # working PER code merged with esnacc_1_6 # # Revision 1.1.1.1 2000/08/21 20:35:46 leonberp # First CVS Version of SNACC. # # Revision 1.1 1997/01/01 23:11:54 rj # first check-in # #\[sep]----------------------------------------------------------------------------------------------------------------------------- proc help {w helptext} \ { set help .help set text $help.text set sb $help.sb set dismiss $help.dismiss getpos $w x y incr x -100 toplevel $help -class Dialog wm title $help {Help} wm transient $help . wm geometry $help +$x+$y wm minsize $help 0 0 text $text -borderwidth 2 -relief sunken -yscrollcommand [list $sb set] -width 32 -height 8 scrollbar $sb -relief sunken -command [list $text yview] -width 10 -cursor arrow button $dismiss -text Dismiss -command [list destroy $help] pack $dismiss -side bottom -pady 2 pack $sb -side right -fill y pack $text -expand true -fill both bind $text [list destroy $help] $text insert end $helptext set oldfocus [focus] focus $text tkwait window $help focus $oldfocus } esnacc-ng-1.8.1/tcl-lib/make-snacced000066400000000000000000000003141302010526100171270ustar00rootroot00000000000000#!/bin/sh if [ $# -ne 3 ]; then echo "usage: $0 script wish tcldir" 1>&2 exit 1 fi set -e exec 1> "$1" echo "#!$2 -f" echo "set auto_path [linsert \$auto_path 0 $3]" echo "snacced" chmod +x "$1" esnacc-ng-1.8.1/tcl-lib/selbox.tcl000066400000000000000000000215311302010526100166750ustar00rootroot00000000000000# file: selbox.tcl # file and content type selection box (ASN.1) # # $Header: /baseline/SNACC/tcl-lib/selbox.tcl,v 1.2 2003/12/17 19:05:04 gronej Exp $ # $Log: selbox.tcl,v $ # Revision 1.2 2003/12/17 19:05:04 gronej # SNACC baseline merged with PER v1_7 tag # # Revision 1.1.2.1 2003/11/05 14:58:56 gronej # working PER code merged with esnacc_1_6 # # Revision 1.1.1.1 2000/08/21 20:35:46 leonberp # First CVS Version of SNACC. # # Revision 1.2 1997/02/28 13:39:56 wan # Modifications collected for new version 1.3: Bug fixes, tk4.2. # # Revision 1.1 1997/01/01 23:11:59 rj # first check-in # proc selbox_newfn {sbref} \ { upvar #0 $sbref sb set fn $sb(toplevel).f.fn.name set name [$fn get] debug $name } proc selbox_newbase {sbref} \ { global $sbref upvar #0 $sbref sb set fb_list $sb(toplevel).f.lists.basename set bs [$fb_list curselection] if {[llength $bs] == 1} \ { set base [$fb_list get $bs] debug base=$base set path [split $sb(fn) /] set len [llength $path] set last [expr $len-1] debug len=$len if {$base == {..}} \ { if {$len == 0} \ { set $sbref\(fn) .. } \ else \ { # set sb [join [lrange $path 0 $last] /] if {[lindex $path $last] == {..}} \ { append $sbref\(fn) /.. } \ else \ { set $sbref\(fn) [join [lrange $path 0 $last] /] } } } \ else \ { if {$len == 0} \ { set $sbref\(fn) $base } \ else \ { incr last -1 # set sb [join [concat [lrange $path 0 $last] $base] /] debug [list set $sbref\(fn) [join [concat [lrange $path 0 $last] $base] /]] set $sbref\(fn) [join [concat [lrange $path 0 $last] $base] /] } } debug "sb(fn)=$sb(fn)" } } #\[sep]----------------------------------------------------------------------------------------------------------------------------- proc selbox_update {name elem op} \ { debug ">selbox_update $name $elem $op" upvar #0 $name sb #debug "$name=$sb" set fb_list $sb(toplevel).f.lists.basename $fb_list delete 0 end $fb_list insert 0 .. set dir [file dirname $sb(fn)] set base [file tail $sb(fn)] set names [lsort [glob $dir/{.*,*}]] foreach name $names \ { set name [file tail $name] # debug $name if {$name != {.} && $name != {..}} \ { $fb_list insert end $name if {$name == $base} \ { $fb_list select from end $fb_list yview end } } } } #\[sep]----------------------------------------------------------------------------------------------------------------------------- proc selbox_tm_click {sbref} \ { upvar #0 $sbref sb global pdus set t $sb(toplevel).t.lists set tm $t.modules set tt $t.types set ms [$tm curselection] if {[llength $ms] == 1} \ { $tt delete 0 end eval $tt insert 0 $pdus([$tm get $ms]) } } #\[sep]----------------------------------------------------------------------------------------------------------------------------- proc selbox_ok {sbref} \ { upvar #0 $sbref sb set fn $sb(toplevel).f.fn.name set t $sb(toplevel).t.lists set m $t.modules set t $t.types if {$sb(want_fn) && $sb(fn) == {} && $sb(force_fn)} \ { tk_dialog .d {select filename} "You need to enter a file name" warning 0 Ok return } if {$sb(want_ct)} \ { set ms [$m curselection] set ts [$t curselection] if {[llength $ms] == 1 && [llength $ts] == 1} \ { set sb(ct) "[$m get $ms] [$t get $ts]" } \ else \ { tk_dialog .d {select content type} "You need to select a content type" warning 0 Ok return } } set sb(rc) 1 destroy $sb(toplevel) } #\[sep]----------------------------------------------------------------------------------------------------------------------------- proc selbox_cancel {sbref} \ { upvar #0 $sbref sb set sb(rc) 0 destroy $sb(toplevel) } #\[sep]----------------------------------------------------------------------------------------------------------------------------- # the selbox (short for `file and content type selection box') # selbox has to be called with two arguments, which may be either empty or be the name of a global variable. # the selbox can display two sections: one for selecting a file name, a second for selecting a content type. # the selbox arguments denote the variable names for the the two sections. # if a variable name is empty, its corresponding section will not be displayed. # if filename_ref is non-empty, a filename will forced to be entered unless `nullfn' is given in args. # the 1x1 geometry for the listboxes below allows them to shrink when the selbox is resized. # (otherwise, the buttons and the second listbox will disappear!) set #sb 0 proc selbox {filename_ref conttype_ref args} \ { # change this if you get widget or variable name collisions: set prefix selbox # choose a unique variable and widget name: global #sb while {[winfo exists [set toplevel .[set sbref $prefix${#sb}]]]} \ { incr #sb } global $sbref upvar #0 $sbref sb if {$filename_ref != {}} \ { set sb(want_fn) 1 set sb(force_fn) 1 upvar $filename_ref filename } \ else \ { set sb(want_fn) 0 } if {$conttype_ref != {}} \ { set sb(want_ct) 1 upvar $conttype_ref conttype } \ else \ { set sb(want_ct) 0 } foreach arg $args \ { switch $arg \ { nullfn \ { set sb(force_fn) 0 } default \ { error "selbox: illegal argument $arg" } } } set sb(toplevel) [toplevel $toplevel] wm minsize $toplevel 1 1 wm geometry $toplevel 300x300 #--- up to three frames, for the file name, for the content type, and for a row of buttons: set borderwidth 5 set relief ridge if {$sb(want_fn)} \ { set f [frame $toplevel.f -relief $relief -bd $borderwidth] } if {$sb(want_ct)} \ { set t [frame $toplevel.t -relief $relief -bd $borderwidth] } set btns [frame $toplevel.btns -relief $relief -bd $borderwidth] #--- fill the upper file frame: if {$sb(want_fn)} \ { # set c [canvas $f.c -bg blue] set flabel [label $f.label -text {File name:}] set flists [frame $f.lists] set fnf [frame $f.fn] #$c create window 0 0 -window $flists -anchor nw #set hsb [scrollbar $f.sb -orient horizontal -command "$c xview"] # set fd_list [listbox $flists.dirname -relief sunken] set fb_list [listbox $flists.basename -relief sunken -width 1 -height 1 -selectmode single] # set fd_sb [scrollbar $flists.dir_sb] set fb_sb [scrollbar $flists.base_sb] $fb_list configure -yscrollcommand "$fb_sb set" $fb_sb configure -command "$fb_list yview" # tk_listboxSingleSelect $fd_list $fb_list # tk_listboxSingleSelect $fb_list # bind $fd_list "sb_newdir $sb" bind $fb_list "selbox_newbase $sbref" set fn [entry $fnf.name -relief sunken -textvariable $sbref\(fn)] #bind $fn "sb_newfn $sb" # pack $fd_list $fd_sb $fb_list $fb_sb -side left -expand 1 -fill y pack $fb_list -side left -expand 1 -fill both pack $fb_sb -side left -fill y pack $fn pack $flabel -fill x pack $fnf -fill x pack $flists -expand 1 -fill both # pack $c $hsb -expand 1 -fill both trace variable $sbref\(fn) w selbox_update # ``set sb(fn) {}'' doesn't work! (selbox_update will be called with the alias, not the global name!) if {[info exists filename]} \ { set $sbref\(fn) $filename } \ else \ { set $sbref\(fn) {} } pack $f -expand 1 -fill both } #--- fill the middle type frame: if {$sb(want_ct)} \ { set tlabel [label $t.label -text {Content type:}] set tlists [frame $t.lists] set tm [listbox $tlists.modules -exportselection 0 -relief sunken -width 1 -height 1 -selectmode single] set tt [listbox $tlists.types -exportselection 0 -relief sunken -width 1 -height 1 -selectmode single] set tm_sb [scrollbar $tlists.mod_sb] set tt_sb [scrollbar $tlists.type_sb] # tk_listboxSingleSelect $tm $tt $tm configure -yscrollcommand "$tm_sb set" $tm_sb configure -command "$tm yview" global pdus eval $tm insert 0 [array names pdus] bind $tm <1> "[bind Listbox <1>]; selbox_tm_click $sbref" pack $tm $tm_sb $tt $tt_sb -side left pack configure $tm $tt -expand 1 -fill both pack configure $tm_sb $tt_sb -fill y pack $tlabel -fill x pack $tlists -expand 1 -fill both pack $t -expand 1 -fill both } #--- fill the lower button frame: button $btns.ok -text Ok -command "selbox_ok $sbref" button $btns.cancel -text Cancel -command "selbox_cancel $sbref" pack $btns.ok $btns.cancel -side left -padx 3m pack $btns -fill x #--- now we're set up, let's go to work: set of [focus] focus $fn tkwait window $toplevel # if we got an affirmative response, export the selection: if $sb(rc) \ { if {$sb(want_fn)} { set filename $sb(fn) } if {$sb(want_ct)} { set conttype $sb(ct) } } focus $of return $sb(rc) } esnacc-ng-1.8.1/tcl-lib/snacced.tcl000066400000000000000000001203721302010526100170040ustar00rootroot00000000000000# file: .../tcl-lib/snacced.tcl # # $Header: /baseline/SNACC/tcl-lib/snacced.tcl,v 1.2 2003/12/17 19:05:04 gronej Exp $ # $Log: snacced.tcl,v $ # Revision 1.2 2003/12/17 19:05:04 gronej # SNACC baseline merged with PER v1_7 tag # # Revision 1.1.2.1 2003/11/05 14:58:56 gronej # working PER code merged with esnacc_1_6 # # Revision 1.1.1.1 2000/08/21 20:35:46 leonberp # First CVS Version of SNACC. # # Revision 1.2 1997/02/28 13:39:57 wan # Modifications collected for new version 1.3: Bug fixes, tk4.2. # # Revision 1.1 1997/01/01 23:12:00 rj # first check-in # # todo: # int, enum and bit string editors with scrollbar #\[banner "initialization"]--------------------------------------------------------------------------------------------------------- set version 1.0 #tk colormodel . monochrome # check all types whether they were marked as PDU. # collect them in an associative array (indexed by module name) foreach t [snacc types] \ { if {[lindex [snacc type $t] 1] == {pdu}} \ { set module [lindex $t 0] set type [lindex $t 1] lappend pdus($module) $type } } #foreach n [array names pdus] \ #{ # debug "module $n: $pdus($n)" #} #\[banner "debugging aid"]---------------------------------------------------------------------------------------------------------- set debug 0 proc debug {text} \ { global debug if $debug {puts $text} } #\[banner "help texts"]------------------------------------------------------------------------------------------------------------- set helptext(about) "SnaccEd $version" set helptext(manoeuv) \ "Button 1 on label show/hide subnodes (except for lists) on list perform action (selected with button 3's popup) Button 2 on label open/close value editor on canvas, list or text drag view Button 3 on label show/hide parent on list select action mode (for button 1) on text pops up menu for text import/export " #\[banner "File loading and saving"]------------------------------------------------------------------------------------------------ # called from file_reload and file_load_from # clears the display so that only the file's root gets shown proc file_prune {fileref} \ { upvar #0 $fileref file set tree $file(tree) set handle $file(handle) list_cleanup /$handle $handle $tree prune {} ed_addnode $tree {} {} {} $handle $handle valid $tree draw } # this function is called from the "File" menu. # it reloads the file contents from its old origin: proc file_reload {fileref} \ { set rc 1 upvar #0 $fileref file # file_prune must be called before the snacc object is modified: file_prune $fileref $file(toplevel) config -cursor watch update idletasks if {[catch {snacc read $file(handle)} msg]} \ { tk_dialog .d load "Couldn't reload: $msg" warning 0 Dismiss } \ else \ { set file(modified) 0 set rc 0 } $file(toplevel) config -cursor arrow return $rc } # this function is called from the "File" menu. # it lets the user select a file and loads its contents proc file_load_from {fileref} \ { set rc 1 upvar #0 $fileref file if {[selbox fn ct]} \ { # file_prune must be called before the snacc object is modified: file_prune $fileref $file(toplevel) config -cursor watch update idletasks if {[catch {snacc read $file(handle) $ct $fn} msg]} \ { tk_dialog .d load "Couldn't load $fn: $msg" warning 0 Dismiss } \ else \ { set file(modified) 0 set rc 0 } $file(toplevel) config -cursor arrow } return $rc } # this function is called from the "File" menu. # it saves the file contents to its old origin: proc file_save {fileref} \ { set rc 1 upvar #0 $fileref file $file(toplevel) config -cursor watch update idletasks if {[catch {snacc write $file(handle)} msg]} \ { tk_dialog .d save "Couldn't save: $msg" warning 0 Dismiss } \ else \ { set file(modified) 0 set rc 0 } $file(toplevel) config -cursor arrow return $rc } # this function is called from the "File" menu. # it lets the user select a file and saves the file's contents proc file_save_as {fileref} \ { set rc 1 upvar #0 $fileref file if {[selbox fn {}]} \ { $file(toplevel) config -cursor watch update idletasks if {[catch {snacc write $file(handle) $fn} msg]} \ { tk_dialog .d save "Couldn't save $fn: $msg" warning 0 Dismiss } \ else \ { set file(modified) 0 set rc 0 } $file(toplevel) config -cursor arrow } return $rc } #\[sep]----------------------------------------------------------------------------------------------------------------------------- # this function is called from prune_or_add_children, list_click, new_choice, toggle_se* and set_or_add_root # it adds the node's children to the display # some of the children may already be displayed (this is usually the case when the function gets called from list_click or set_or_add_root). # ed_addnode will be called for every child. proc ed_expand {tree treepath snaccpath} \ { set canvas [$tree canvas] set info [snacc info $snaccpath] set type [lindex $info 2] switch $type \ { SEQUENCE - SET \ { debug "$type:" foreach elem [lindex $info 3] \ { set name [lindex $elem 0] set validity [lindex $elem 1] debug " $validity $name" ed_addnode $tree $treepath $treepath $snaccpath $name $name $validity } } SEQUENCE\ OF - SET\ OF \ { set len [lindex $info 3] set varname var:$treepath upvar #0 $varname var debug [list treepath=$treepath] debug [list varname=$varname] debug [list idlist=$var(idlist)] debug [list expand list ($type) len=$len] for {set i 0} {$i < $len} {incr i} \ { set id [lindex $var(idlist) $i] debug [list index $i id $id] if {$id} \ { ed_addnode $tree $treepath $treepath $snaccpath $id $i valid } } } CHOICE \ { set name [lindex $info 3] set validity [lindex $info 4] debug " $validity $name" ed_addnode $tree $treepath $treepath $snaccpath $name $name $validity } } } #\[sep]----------------------------------------------------------------------------------------------------------------------------- # ed_addnode is called from set_or_add_root, new_file, file_prune and ed_expand. # the node may already be displayed (this is usually the case when the function ed_expand gets called from list_click or set_or_add_root). in this case the node gets moved to the right position. # otherwise the node is created at the right place. # the arguments are: # tree name of the tree widget # treeparent tag of the displayed parent node. this is usually the same as the treeparentpath, except when the display gets extended into the parent direction where the root tag is {} # treeparentpath tag of the logical parent node. # snaccparentpath names of the # treenode node's name, gets appended to the treeparentpath # snaccnode node's name, gets appended to the snaccparentpath # validity proc ed_addnode {tree treeparent treeparentpath snaccparentpath treenode snaccnode validity} \ { set canvas [$tree canvas] set treepath "$treeparentpath/$treenode" set snaccpath "$snaccparentpath $snaccnode" if [llength [$canvas find withtag $treepath]] \ { debug [list movelink $treepath $treeparent] $tree movelink $treepath $treeparent } \ else \ { #debug [list addnode $snaccpath] if {[llength $snaccparentpath] > 0} \ { set nodelabeltext $snaccnode } \ else \ { set finfo [snacc finfo [string range $snaccpath 1 end]] if {[lindex $finfo 0] == {}} \ { set nodelabeltext {(unnamed)} } \ else \ { set nodelabeltext [lindex $finfo 0] } } $canvas create text 0 0 -text $nodelabeltext -tags [list $validity-label $treepath $treepath:label] set line [$canvas create line 0 0 0 0] # fix for canvas bug: for reverse video, the canvas displays black items on a black background if {[tk colormodel .] == {monochrome} && [lindex [$canvas config -background] 4] == {black}} \ { $canvas itemconfigure $treepath -fill white $canvas itemconfigure $line -fill white } if {$validity == {void}} \ { if {[tk colormodel .] == {color}} \ { # #b0b0b0 is the light grey of disabled checkbuttons: $canvas itemconfigure $treepath -fill #b0b0b0 $canvas itemconfigure $line -fill #b0b0b0 } \ else \ { $canvas itemconfigure $treepath -stipple gray50 $canvas itemconfigure $line -stipple gray50 } } debug [list addlink $treeparent $treepath $line] $tree addlink $treeparent $treepath $line } } #\[sep]----------------------------------------------------------------------------------------------------------------------------- # open/drop subtree proc prune_or_add_children {canvas} \ { set tree $canvas.t # debug $canvas set id [$canvas find withtag current] if {$id == {}} \ { debug "no item" } \ else \ { set treepath [lindex [$canvas gettags $id] 1] set snaccpath [tree2snacc $treepath] set type [lindex [snacc info $snaccpath] 2] switch $type \ { SEQUENCE\ OF - SET\ OF {} default { # debug $treepath if {[$tree isleaf $treepath]} \ { debug [list expanding $treepath $snaccpath] ed_expand $tree $treepath $snaccpath } \ else \ { debug [list cutting $treepath] # !!! list_cleanup usually has to be called with the node that gets removed! # in this case calling it with the node that stays around doesn't hurt because it is guaranteed not to be a SEQUENCE OF or SET OF type (they are handled a few lines above) list_cleanup $treepath $snaccpath $tree prune $treepath } } } } $tree draw } #\[sep]----------------------------------------------------------------------------------------------------------------------------- # this function has to be called whenever a subtree that may contain SET OF or SEQUENCE of types gets removed from the display # it must be called *before* the snacc object gets destroyed, the function examines it! proc list_cleanup {treepath snaccpath} \ { set info [snacc info $snaccpath] set type [lindex $info 2] switch $type \ { SET - SEQUENCE - CHOICE { foreach elem [lindex $info 3] \ { set name [lindex $elem 0] set validity [lindex $elem 1] if {$validity == {valid}} \ { set subtreepath "$treepath/$name" set subsnaccpath "$snaccpath $name" list_cleanup $subtreepath $subsnaccpath } } } SET\ OF - SEQUENCE\ OF { set varname var:$treepath global $varname debug [list varname=$varname] if {[info exists $varname]} \ { set idlist [set $varname\(idlist)] debug [list idlist=$idlist] set i 0 foreach id $idlist \ { if {$id != 0} \ { set subtreepath "$treepath/$id" set subsnaccpath "$snaccpath $i" list_cleanup $subtreepath $subsnaccpath } incr i } unset $varname } } } } # this function must be called when calling "$tree root $treepath". # it calls list_cleanup for all nodes that are neither parent nor in the subtree pointed to by $treepath. proc list_cleanup_not_me {treepath snaccpath} \ { if {[set i [llength $snaccpath]] > 1} \ { incr i -1 set parenttreepath [join [lrange [split $treepath /] 0 $i] /] incr i -1 set parentsnaccpath [lrange $snaccpath 0 $i] set info [snacc info $parentsnaccpath] set type [lindex $info 2] switch $type \ { SET - SEQUENCE - CHOICE { foreach elem [lindex $info 3] \ { set name [lindex $elem 0] set validity [lindex $elem 1] if {$validity == {valid}} \ { set subparenttreepath "$parenttreepath/$name" set subparentsnaccpath "$parentsnaccpath $name" if {$subparenttreepath != $treepath} \ { list_cleanup $subparenttreepath $subparentsnaccpath } } } } SET\ OF - SEQUENCE\ OF { set varname var:$parenttreepath global $varname debug [list varname=$varname] set idlist [set $varname\(idlist)] debug [list idlist=$idlist] set i 0 foreach id $idlist \ { if {$id != 0} \ { set subparenttreepath "$parenttreepath/$id" set subparentsnaccpath "$parentsnaccpath $i" if {$subparenttreepath != $treepath} \ { list_cleanup $subparenttreepath $subparentsnaccpath set $varname\(idlist) [lreplace [set $varname\(idlist)] $i $i 0] } } incr i } } } # recursion: list_cleanup_not_me $parenttreepath $parentsnaccpath } } #\[sep]----------------------------------------------------------------------------------------------------------------------------- # /file0/files/1/name \(-> { file0 files 0 name} proc tree2snacc {treepath} \ { set subtreepath {} foreach elem [lrange [split $treepath /] 1 end] \ { set treeelem $elem if {[regexp {^[0-9]} $elem]} \ { set varname var:$subtreepath global $varname set idlist [set $varname\(idlist)] set id $elem set index 0 foreach lid $idlist \ { if {$lid == $id} break incr index } if {$index == [llength $idlist]} \ { error "tree2snacc: id $id not found in idlist [list $idlist]" } set snaccelem $index } \ else \ { set snaccelem $elem } append subtreepath /$treeelem append subsnaccpath " $snaccelem" debug [list >>$subtreepath--$subsnaccpath<<] } debug [list >>$subtreepath--$subsnaccpath<<] return $subsnaccpath } #\[sep]----------------------------------------------------------------------------------------------------------------------------- proc import_text {text_w treepath} \ { if {[selbox fn {}]} \ { if {[catch {set text [snacc import $fn]} msg]} \ { tk_dialog .d import "Couldn't import $fn: $msg" warning 0 Dismiss } \ else \ { $text_w delete 0.0 end $text_w insert end $text snacc set [tree2snacc $treepath] $text } } } #\[sep]----------------------------------------------------------------------------------------------------------------------------- proc export_text {text_w} \ { if {[selbox fn {}]} \ { if {[catch {snacc export [$text_w get 0.0 end] $fn} msg]} \ { tk_dialog .d import "Couldn't export $fn: $msg" warning 0 Dismiss } } } proc frame_resize_bindings {fileref treepath} \ { upvar #0 $fileref file set frame $file(canvas).edit$treepath bind $frame [list frame_resize_start $fileref %x %y] bind $frame [list frame_resize_cont $fileref $treepath %x %y] bind $frame [list frame_resize_end $fileref $treepath] $frame config -cursor bottom_right_corner } proc frame_resize_start {fileref x y} \ { #debug [list frame_resize_start $fileref $x $y] upvar #0 $fileref file set file(resize_x) $x set file(resize_y) $y } proc frame_resize_cont {fileref treepath x y} \ { #debug [list frame_resize_cont $fileref $treepath $x $y] upvar #0 $fileref file set frame $file(canvas).edit$treepath set frametag $treepath:edit set oldw [lindex [$file(canvas) itemconfig $frametag -width] 4] set oldh [lindex [$file(canvas) itemconfig $frametag -height] 4] debug "old: $oldw x $oldh" set neww [max 1 [expr $oldw+$x-$file(resize_x)]] set newh [max 1 [expr $oldh+$y-$file(resize_y)]] debug "new: $neww x $newh" $file(canvas) itemconfig $frametag -width $neww -height $newh set file(resize_x) $x set file(resize_y) $y } proc frame_resize_end {fileref treepath} \ { #debug [list frame_resize_end $fileref $treepath] upvar #0 $fileref file $file(tree) nodeconfig $treepath $file(tree) draw } #\[sep]----------------------------------------------------------------------------------------------------------------------------- # toggle content editor proc toggle_editor {canvas} \ { set tree $canvas.t set id [$canvas find withtag current] if {$id == {}} \ { debug "no item" } \ else \ { set treepath [lindex [$canvas gettags $id] 1] set snaccpath [tree2snacc $treepath] set frame $canvas.edit$treepath if [llength [$canvas find withtag $treepath:edit]] \ { debug "removing editor for [list $treepath]" $canvas delete $treepath:edit destroy $frame $tree nodeconfig $treepath -remove {} } \ else \ { debug "opening editor for [list $treepath]" set fileref [lindex [split $treepath /] 1] frame $frame -borderwidth 3 -bg #cdb79e set cleanup [list [list destroy $frame]] set info [snacc info $snaccpath] set type [lindex $info 2] switch $type \ { NULL \ { set label $frame.label label $label -text NULL pack $label } BOOLEAN \ { set value [snacc get $snaccpath] set var var:$treepath global $var set $var $value set button $frame.button #checkbutton $button -variable $var checkbutton $button -onvalue TRUE -offvalue FALSE -variable $var -textvariable $var -command [list debug [list $canvas $treepath]] pack $button trace variable $var w change_simple } INTEGER \ { set value [snacc get $snaccpath] set var var:$treepath global $var set $var $value if {[lindex $info 0] != {{} {}}} \ { set typeinfo [snacc type [lindex $info 0]] foreach elem [lindex $typeinfo 3] \ { set en [lindex $elem 0] set ev [lindex $elem 1] set button $frame.button$en radiobutton $button -text $en -variable $var -value $ev -anchor w pack $button -fill x } } set entry $frame.entry entry $entry -textvariable $var -width 9 -relief sunken int_entry_bindings $entry pack $entry -anchor w -fill x focus $entry trace variable $var w change_simple } ENUMERATED \ { set typeinfo [snacc type [lindex $info 0]] if {[catch {set value [snacc get $snaccpath]} msg] == 1} \ { global errorInfo errorCode if {$errorCode == {SNACC ILLENUM}} \ { set value [lindex [lindex $typeinfo 3] 0] snacc set $snaccpath $value append msg "--setting to first legal symbolic value \"$value\"" tk_dialog .d illenum "$msg" warning 0 Dismiss } \ else \ { error $msg $errorInfo $errorCode } } set var var:$treepath global $var set $var $value foreach ev [lindex $typeinfo 3] \ { set button $frame.button$ev radiobutton $button -text $ev -variable $var -value $ev -anchor w pack $button -fill x } trace variable $var w change_simple } REAL \ { set value [snacc get $snaccpath] set var var:$treepath global $var set $var $value set entry $frame.entry entry $entry -textvariable $var -relief sunken pack $entry frame_resize_bindings $fileref $treepath focus $entry trace variable $var w change_simple } BIT\ STRING \ { set value [snacc get $snaccpath] set var var:$treepath global $var set $var $value set max_ev 0 if {[lindex $info 0] != {{} {}}} \ { set typeinfo [snacc type [lindex $info 0]] foreach elem [lindex $typeinfo 3] \ { set en [lindex $elem 0] set ev [lindex $elem 1] set max_ev [max $ev $max_ev] set button $frame.button$en checkbutton $button -text $en -variable $var:$ev -command [list toggle_bit $var $ev] -anchor w pack $button -fill x } } set entry $frame.entry entry $entry -textvariable $var -relief sunken set len [max 8 [string length $value] [expr $max_ev + 1]] if {$len > 0} \ { debug [list length of entry is $len] $entry config -width $len } pack $entry -anchor w -fill x bit_string_entry_bindings $entry focus $entry trace variable $var w change_bits set $var $value; # trigger the trace } OBJECT\ IDENTIFIER \ { set value [snacc get $snaccpath] set var var:$treepath global $var set $var $value set entry $frame.entry entry $entry -textvariable $var -relief sunken pack $entry -fill both frame_resize_bindings $fileref $treepath focus $entry trace variable $var w change_simple } OCTET\ STRING \ { set value [snacc get $snaccpath] set text $frame.text set sb $frame.sb text $text -borderwidth 2 -relief sunken -yscrollcommand [list $sb set] -width 32 -height 8 scrollbar $sb -relief sunken -command [list $text yview] -width 10 -cursor arrow pack $sb -side right -fill y pack $text -side left -expand true -fill both bind $text [list $text scan mark %y] bind $text [list $text scan dragto %y] bind $text "snacc set \[tree2snacc $treepath\] \[$text get 0.0 end\]" bind $text "snacc set \[tree2snacc $treepath\] \[$text get 0.0 end\]" set m $frame.menu menu $m $m add command -label Load... -command "[list import_text $text $treepath]; [list $m unpost]" $m add command -label Save... -command "[list export_text $text]; [list $m unpost]" bind $text "[list $m] post \[expr %X -16\] \[expr %Y -8\]" bind $m [list $m unpost] bind $m [list $m unpost] $text insert end $value focus $text frame_resize_bindings $fileref $treepath } SEQUENCE - SET \ { set typeinfo [snacc type [lindex $info 0]] debug "$type:" set varelems [lindex $info 3] set typeelems [lindex $typeinfo 3] for {set i 0; set len [llength $varelems]} {$i < $len} {incr i} \ { set varelem [lindex $varelems $i] set typeelem [lindex $typeelems $i] set name [lindex $varelem 0] set validity [lindex $varelem 1] debug " $validity $name" set var var:$treepath:$name global $var set $var $validity set button $frame.$name checkbutton $button -text $name -onvalue valid -offvalue void -variable $var -command [list toggle_se* $canvas $treepath $name] -anchor w if {[lindex $typeelem 4] == {mandatory}} \ { #$button configure -disabledforeground [lindex [$button configure -fg] 4] -state disabled $button configure -state disabled } pack $button -fill x } } SEQUENCE\ OF - SET\ OF \ { set len [lindex $info 3] set varname var:$treepath upvar #0 $varname var if {![info exists var(idlist)]} \ { set var(idlist) {} set var(lastid) 0 } # no! needs a longer lifetime! #lappend cleanup [list global $varname] [list unset $varname] # set mbar $frame.mbar set list $frame.list set sb $frame.sb scrollbar $sb -command [list $list yview] -width 10 -relief sunken -cursor arrow # listbox $list -yscroll [list $sb set] -relief sunken -width 4 -height 5 text $list -borderwidth 2 -relief sunken -yscrollcommand [list $sb set] -width 4 -height 8 -exportselection 0 pack $sb -side right -fill y pack $list -side left -expand true -fill both # frame $mbar -relief raised -bd 2 # pack $mbar -side top -fill x # set mode $mbar.mode # set mode $frame.mode # set m $mode.m # menubutton $mode -text Mode -menu $m set m $frame.mode menu $m set lm "[list list_mode $canvas $treepath]; [list $m unpost]" $m add radiobutton -label Display -variable ${varname}(mode) -value display -command $lm $m invoke last $m add radiobutton -label Insert -variable ${varname}(mode) -value insert -command $lm $m add radiobutton -label Append -variable ${varname}(mode) -value append -command $lm $m add radiobutton -label Delete -variable ${varname}(mode) -value delete -command $lm # pack $mode -side left # pack $mode -side top -fill x $list tag config display -background #b2dfee -relief raised bind $list [list list_click $canvas $treepath] bind $list { } bind $list { } bind $list { } bind $list "[list $m] post \[expr %X-16\] \[expr %Y-8\]" bind $m [list $m unpost] bind $m [list $m unpost] debug $m for {set i 0} {$i < $len} {incr i} \ { $list insert end [format "%4d\n" $i] if {[llength $var(idlist)] > $i} \ { if {[set id [lindex $var(idlist) $i]]} \ { set line [expr $i + 1] $list tag add display $line.0 $line.end } } \ else \ { set var(idlist) [linsert $var(idlist) $i 0] } } frame_resize_bindings $fileref $treepath } CHOICE \ { set name [lindex $info 3] set validity [lindex $info 4] set typeinfo [snacc type [lindex $info 0]] set var var:$treepath set oldvar oldvar:$treepath global $var $oldvar set $var $name set $oldvar $name foreach elem [lindex $typeinfo 3] \ { set en [lindex $elem 0] set button $frame.button$en radiobutton $button -text $en -variable $var -value $en -command [list new_choice $canvas $treepath] -anchor w pack $button -fill x } debug " $validity $name" } default \ { error "unexpected type $type" } } scan [$canvas bbox $treepath:label] "%d%d%d%d" lx uy rx ly $canvas create window $lx $ly -anchor nw -tags [list edit $treepath $treepath:edit] -window $frame update idletasks; # calculate frame's size (needed by tree widget) # explicitly set the frame's width&height to avoid nasty effects when resizing: scan [$canvas bbox $treepath:edit] "%d%d%d%d" lx uy rx ly $canvas itemconfig $treepath:edit -width [expr $rx - $lx] -height [expr $ly - $uy] #debug [list cleanup = [join $cleanup \;]] $tree nodeconfig $treepath -remove [join $cleanup \;] } } $tree draw } #\[sep]----------------------------------------------------------------------------------------------------------------------------- proc list_click {canvas treepath} \ { set tree $canvas.t set snaccpath [tree2snacc $treepath] debug [list treepath=$treepath] debug [list snaccpath=$snaccpath] debug [list tree2snacc: [tree2snacc $treepath]] set varname var:$treepath upvar #0 $varname var set frame $canvas.edit$treepath set list $frame.list debug [list list_click: $list] debug [list varname=$varname] debug [list idlist=$var(idlist)] # debug [$list tag ranges display] set text_index [$list index current] #debug [list index: $index] if {$text_index != ""} \ { # strip the column number: set line [lindex [split $text_index .] 0] # lines numbers start at 1, indices at 0: set index [expr $line - 1] set len [llength $var(idlist)] set tags [$list tag names $text_index] switch $var(mode) \ { display \ { debug [list tags: $tags] debug [list line: $line] if {$index < $len} \ { set id [lindex $var(idlist) $index] debug [list index $index id $id] if {$id} \ { $list tag remove display $line.0 $line.end list_cleanup $treepath/$id "$snaccpath $index" debug [list $tree rmlink $treepath/$id] $tree rmlink $treepath/$id set var(idlist) [lreplace $var(idlist) $index $index 0] } \ else \ { $list tag add display $line.0 $line.end set var(idlist) [lreplace $var(idlist) $index $index [incr var(lastid)]] ed_expand $tree $treepath $snaccpath } } } insert - append \ { if {$var(mode) == {append}} {incr index} debug [list insert $index 0] set var(idlist) [linsert $var(idlist) $index 0] debug [list $var(idlist)] debug [list catch [list snacc set "$snaccpath {insert $index}" {}]] catch [list snacc set "$snaccpath {insert $index}" {}] set file(modified) 1 debug [list [snacc get $snaccpath]] $list insert end [format "%4d\n" [expr [lindex [split [$list index end] .] 0] - 1]] for {set i $len} {$i > $index} {incr i -1} \ { set line [expr $i + 1] if {[set id [lindex $var(idlist) $i]]} \ { debug [list $canvas itemconfigure $treepath/$id:label -text $i] $canvas itemconfigure $treepath/$id:label -text $i if {![lindex $var(idlist) [expr $i - 1]]} \ { debug [list $list tag add display $line.0 $line.end] $list tag add display $line.0 $line.end } } \ else \ { if {![lindex $var(idlist) [expr $i - 1]]} \ { debug [list $list tag remove display $line.0 $line.end] $list tag remove display $line.0 $line.end } } } set line [expr $index + 1] debug [list $list tag remove display $line.0 $line.end] $list tag remove display $line.0 $line.end } delete \ { if {$index < $len} \ { debug [list delete $index] if {[set id [lindex $var(idlist) $index]]} \ { # list_cleanup must be called before the snacc object is modified: list_cleanup $treepath/$id "$snaccpath $index" $tree rmlink $treepath/$id } incr len -1 for {set i $index} {$i < $len} {incr i} \ { set line [expr $i + 1] if {[set id [lindex $var(idlist) [expr $i + 1]]]} \ { debug [list $canvas itemconfigure $treepath/$id:label -text $i] $canvas itemconfigure $treepath/$id:label -text $i if {![lindex $var(idlist) $i]} \ { debug [list $list tag add display $line.0 $line.end] $list tag add display $line.0 $line.end } } \ else \ { if {[lindex $var(idlist) $i]} \ { debug [list $list tag remove display $line.0 $line.end] $list tag remove display $line.0 $line.end } } } set var(idlist) [lreplace $var(idlist) $index $index] debug [list $var(idlist)] debug [list snacc unset "$snaccpath $index"] snacc unset "$snaccpath $index" set file(modified) 1 debug [list [snacc get $snaccpath]] $list delete [$list index {end - 1 line}] [$list index end] } } } $tree draw } } #\[sep]----------------------------------------------------------------------------------------------------------------------------- proc list_mode {canvas treepath} \ { set var var:$treepath global $var set mode [set ${var}(mode)] set frame $canvas.edit$treepath set list $frame.list switch $mode \ { display {set cursor arrow} insert {set cursor based_arrow_up} append {set cursor based_arrow_down} delete {set cursor pirate} } $list config -cursor $cursor debug [list list_mode: ${var}(mode) set to $mode] } #\[sep]----------------------------------------------------------------------------------------------------------------------------- proc toggle_bit {var i} \ { global $var:$i $var set bit [set $var:$i] set val [set $var] debug [list toggle_bit $val $i to $bit] set pre [string range $val 0 [expr $i - 1]] set fill {} for {set l [string length $val]} {$l < $i} {incr l} \ { append fill 0 debug [list appending: $val] } set post [string range $val [expr $i + 1] end] debug [list toggle_bit combining $pre $fill $bit $post] set $var $pre$fill$bit$post } #\[sep]----------------------------------------------------------------------------------------------------------------------------- proc change_bits {var element op} \ { global $var set val [set $var] debug [list change_bits $var set to $val] debug [list set l [string length $val]] set l [string length $val] for {set i 0} {$i < $l} {incr i} \ { global $var:$i if {[info exists $var:$i]} \ { debug [list set $var:$i [string index $val $i]] set $var:$i [string index $val $i] } \ else \ { debug [list non-exist: $var:$i] } } foreach bitvar [info globals $var:*] \ { set i [lindex [split $bitvar :] 2] if {$i >= $l} \ { global $bitvar set $bitvar 0 } } change_simple $var $element $op } #\[sep]----------------------------------------------------------------------------------------------------------------------------- proc change_simple {var element op} \ { global $var set val [set $var] debug [list change_simple $var set to $val] set treepath [lindex [split $var :] 1] debug [list treepath= $treepath] set fileref [lindex [split $treepath /] 1] upvar #0 $fileref file set canvas $file(canvas) debug [list canvas= $canvas] set snaccpath [tree2snacc $treepath] debug [list snaccpath= $snaccpath] snacc set $snaccpath $val set file(modified) 1 } #\[sep]----------------------------------------------------------------------------------------------------------------------------- proc new_choice {canvas treepath} \ { set tree $canvas.t set snaccpath [tree2snacc $treepath] set var var:$treepath set oldvar oldvar:$treepath global $var $oldvar set val [set $var] set oldval [set $oldvar] set fileref [lindex [split $treepath /] 1] upvar #0 $fileref file debug "$file(modified)" debug [list new choice: $snaccpath = $val] # list_cleanup must be called before the snacc object is modified: list_cleanup $treepath/$oldval "$snaccpath $oldval" catch {snacc set $snaccpath [list $val {}]} set file(modified) 1 debug "$file(modified)" if {[llength [$canvas find withtag "$treepath/$oldval"]]} \ { $tree rmlink "$treepath/$oldval" ed_expand $tree $treepath $snaccpath $tree draw } set $oldvar $val } #\[sep]----------------------------------------------------------------------------------------------------------------------------- proc toggle_se* {canvas treepath name} \ { set tree $canvas.t set snaccpath [tree2snacc $treepath] set var var:$treepath:$name global $var set val [set $var] set fileref [lindex [split $treepath /] 1] upvar #0 $fileref file debug "$snaccpath $name = $val" # this procedure is called after the button value has changed, so adjust the display to the current (new) setting: if {$val == {void}} \ { # (change valid \(-> void) # list_cleanup must be called before the snacc object is modified: list_cleanup $treepath/$name "$snaccpath $name" snacc unset "$snaccpath $name" } \ else \ { # (change void \(-> valid) catch {snacc set "$snaccpath $name" {}} } set file(modified) 1 if {[llength [$canvas find withtag "$treepath/$name"]]} \ { debug [list rmlink "$treepath/$name"] $tree rmlink "$treepath/$name" # a bug in the tree widget requires us to redraw here: $tree draw ed_expand $tree $treepath $snaccpath $tree draw } } #\[sep]----------------------------------------------------------------------------------------------------------------------------- # add/drop parent and siblings proc set_or_add_root {canvas} \ { set tree $canvas.t set id [$canvas find withtag current] if {$id == {}} \ { debug "no item" } \ else \ { set treepath [lindex [$canvas gettags $id] 1] set snaccpath [tree2snacc $treepath] # debug $path if {[llength $snaccpath] == 1} \ { debug "at root already" } \ else \ { if {[$tree isroot $treepath]} \ { # show the parent: debug [list expanding [list $treepath $snaccpath]] set i [llength $snaccpath] incr i -1 set treeparentpath [join [lrange [split $treepath /] 0 $i] /] set treeparentnode [lindex [split $treepath /] $i] incr i -1 set snaccparentpath [lrange $snaccpath 0 $i] set snaccparentnode [lindex $snaccpath $i] set treeparentparentpath [join [lrange [split $treepath /] 0 $i] /] incr i -1 set snaccparentparentpath [lrange $snaccpath 0 $i] #debug [list ed_addnode $tree {} $parentparentpath $parentnode valid] ed_addnode $tree {} $treeparentparentpath $snaccparentparentpath $treeparentnode $snaccparentnode valid #debug [list ed_expand $tree $parentpath] ed_expand $tree $treeparentpath $snaccparentpath } \ else \ { # hide everything above this subtree: # debug "cutting $path" list_cleanup_not_me $treepath $snaccpath $tree root $treepath } # debug [snacc info $path] } } $tree draw } #\[sep]----------------------------------------------------------------------------------------------------------------------------- proc file_open {} \ { if {[selbox fn ct nullfn]} \ { debug "fn=$fn ct=$ct" if {$fn != {}} \ { if {[catch {set f [snacc open $ct $fn create]} msg]} \ { tk_dialog .d load "Couldn't open $fn {$ct}: $msg" warning 0 Dismiss return -1 } } \ else \ { if {[catch {set f [snacc create $ct]} msg]} \ { tk_dialog .d create "Couldn't create {$ct}: $msg" warning 0 Dismiss return -1 } } new_file $f return 0 } return -1 } #\[sep]----------------------------------------------------------------------------------------------------------------------------- set #file 0 set #files 0 # returns 1 on `cancel', otherwise exits or returns 0 proc close_file {fileref} \ { upvar #0 $fileref file if {$file(modified)} \ { set fi [snacc finfo $file(handle)] set fn [lindex $fi 0] set hasfn [expr {$fn != {}}] set isrw [expr {[lindex $fi 1] == {rw}}] set msg {There are unsaved changes} if {$hasfn} \ { append msg " in `$fn'" } append msg {. Save them?} switch [lindex {save discard cancel} [tk_dialog .d modified $msg questhead 0 Yes No Cancel]] \ { cancel \ { return 1 } save \ { if {$hasfn && $isrw} \ { if {[file_save $fileref]} \ { return 1 } } \ else \ { if {[file_save_as $fileref]} \ { return 1 } } } } } destroy $file(toplevel) global #files if {![incr #files -1]} \ { exit } return 0 } proc file_quit {} \ { global #files for {set i 0} {${#files}} {incr i} \ { if {[winfo exists .[set fileref file$i]]} \ { if {[close_file $fileref]} \ { return } } } } proc new_file {handle} \ { global #file while {[winfo exists [set toplevel .[set fileref file${#file}]]]} \ { incr #file } #global $fileref upvar #0 $fileref file set file(handle) $handle set file(toplevel) [toplevel $toplevel] wm title $toplevel snaccEd wm minsize $toplevel 150 100 wm geometry $toplevel 500x500 global #files incr #files set file(modified) 0 $toplevel config -cursor arrow set menubar $toplevel.menu frame $menubar -relief raised -bd 2 pack $menubar -side top -fill x set filem $menubar.file set m $filem.m menubutton $filem -text File -menu $m menu $m $m add command -label Reload -command [list file_reload $fileref] $m add command -label Load... -command [list file_load_from $fileref] $m add command -label Save -command [list file_save $fileref] $m add command -label {Save As...} -command [list file_save_as $fileref] $m add command -label Close -command [list close_file $fileref] $m add separator $m add command -label Open... -command file_open $m add separator $m add command -label Quit -command file_quit set fi [snacc finfo $handle] set hasnofn [expr {[lindex $fi 0] == {}}] set isro [expr {[lindex $fi 1] == {ro}}] if {$hasnofn} \ { $m entryconfigure Reload -state disabled } if {$hasnofn || $isro} \ { $m entryconfigure Save -state disabled } pack $filem -side left set help $menubar.help set m $help.m menubutton $help -text Help -menu $help.m menu $m $m add command -label About -command "help [list $m] \$helptext(about)" $m add command -label Manoeuvering -command "help [list $m] \$helptext(manoeuv)" pack $help -side right tk_menuBar $menubar $filem $help frame $toplevel.f0 frame $toplevel.f1 pack $toplevel.f0 -expand true -fill both pack $toplevel.f1 -fill x set file(canvas) [set canvas [canvas $toplevel.c -width 0 -height 0]] set hsb [scrollbar $toplevel.hsb -orient horiz -relief sunken -command [list $canvas xview]] set vsb [scrollbar $toplevel.vsb -relief sunken -command [list $canvas yview]] $canvas config -xscroll [list $hsb set] -yscroll [list $vsb set] set blind [frame $toplevel.blind -width [lindex [$vsb config -width] 4]] pack $vsb -in $toplevel.f0 -side right -fill y pack $canvas -in $toplevel.f0 -side left -expand true -fill both pack $blind -in $toplevel.f1 -side right pack $hsb -in $toplevel.f1 -side left -expand true -fill x bind $canvas [list $canvas scan mark %x %y] bind $canvas [list $canvas scan dragto %x %y] $canvas bind valid-label {prune_or_add_children %W} $canvas bind valid-label {toggle_editor %W} $canvas bind valid-label {set_or_add_root %W} set file(tree) [set tree [tree $canvas.t]] ed_addnode $tree {} {} {} $handle $handle valid $tree draw tkwait visibility $toplevel } proc snacced {} \ { wm withdraw . global argc argv if {$argc == 0} \ { if {[file_open]} \ { exit 1 } } \ else \ { if {$argc == 3} \ { set ct [lrange $argv 0 1] set fn [lindex $argv 2] if {[catch {set f [snacc open $ct $fn create]} msg]} \ { tk_dialog .d load "Couldn't open $fn {$ct}: $msg" warning 0 Dismiss exit 1 } } \ elseif {$argc == 2} \ { set ct [lrange $argv 0 1] if {[catch {set f [snacc create $ct]} msg]} \ { tk_dialog .d create "Couldn't create {$ct}: $msg" warning 0 Dismiss exit 1 } } \ else \ { exit 1 } new_file $f } } esnacc-ng-1.8.1/tcl-lib/tkuti.tcl000066400000000000000000000011151302010526100165350ustar00rootroot00000000000000# file: tkuti.tcl # miscellaneous Tk utilities. # # $Header: /baseline/SNACC/tcl-lib/tkuti.tcl,v 1.2 2003/12/17 19:05:04 gronej Exp $ # $Log: tkuti.tcl,v $ # Revision 1.2 2003/12/17 19:05:04 gronej # SNACC baseline merged with PER v1_7 tag # # Revision 1.1.2.1 2003/11/05 14:58:56 gronej # working PER code merged with esnacc_1_6 # # Revision 1.1.1.1 2000/08/21 20:35:46 leonberp # First CVS Version of SNACC. # # Revision 1.1 1997/01/01 23:12:03 rj # first check-in # proc getpos {w xn yn} \ { upvar $xn x $yn y set geom [wm geometry $w] scan $geom {%dx%d+%d+%d} w h x y } esnacc-ng-1.8.1/tcl-lib/uti.tcl000066400000000000000000000004311302010526100161760ustar00rootroot00000000000000# file: uti.tcl #\[sep]----------------------------------------------------------------------------------------------------------------------------- proc max {a0 args} \ { set max $a0 foreach a $args \ { if {$a > $max} \ { set max $a } } return $max } esnacc-ng-1.8.1/version.h000066400000000000000000000001051302010526100151770ustar00rootroot00000000000000#define RELDATE "2016-12-01" #define BUGREPADDR "http://esnacc.org"