Annotation of 43BSDReno/contrib/isode-beta/pepsy/doc/DESCRIPTION, revision 1.1

1.1     ! root        1: 
        !             2: 
        !             3: 
        !             4: 
        !             5: 
        !             6: 
        !             7: _1.  _O_v_e_r_v_i_e_w _o_f _p_e_p_s_y _s_y_s_t_e_m
        !             8: 
        !             9:      This  section  describes  how  the  various  parts  fit
        !            10: together  to  make  the  system  work.  The principle behind
        !            11: pepsy is fairly simple.  The ASN.1 is summarised  as  tables
        !            12: of integers.  These tables are read by driver routines which
        !            13: encode or decode data to or from the  internal  format  that
        !            14: ISODE  OSI implementation uses.  In ISODE specific functions
        !            15: are generated for each ASN.1 type defined  in  contrast  the
        !            16: pepsy  merely generates a new table of data which is far far
        !            17: smaller.
        !            18: 
        !            19:      As there is a great deal  of  effort  invested  in  the
        !            20: ISODE  interface  to  the  encoding/decoding  routines pepsy
        !            21: automatically provides macros which map the  original  func-
        !            22: tions  into the appropriate function call of a driver.  This
        !            23: allows existing posy using code to switch to the pepsy  sys-
        !            24: tem  with  no  changes  to  the  code  provided  no function
        !            25: pointers are used to the  original  ISODE  functions.   Even
        !            26: when  there  are function pointers used the changes are very
        !            27: simple and take only a few hours to implement.
        !            28: 
        !            29: _1._1.  _B_r_i_e_f _d_e_s_c_r_i_p_t_i_o_n _o_f _t_h_e _u_s_e _o_f _t_h_e _p_e_p_s_y _s_y_s_t_e_m.
        !            30: 
        !            31: _1._1._1.  _O_u_t_l_i_n_e _o_f _t_h_e _f_i_l_e_s _p_r_o_d_u_c_e_d _u_n_d_e_r _t_h_e  _p_e_p_s_y  _s_y_s_-
        !            32: _t_e_m.
        !            33: 
        !            34:      The pepsy system consists  of  a  program  called  _p_o_s_y
        !            35: which  translates ASN.1 modules into a set of tables, called
        !            36: _p_o_s_y at the moment, and library of driver  routines,  called
        !            37: _l_i_b_p_e_p_s_y._a.   Running  this  _p_o_s_y  program on the ASN.1 file
        !            38: will produce several files.  If the name of the ASN.1 module
        !            39: is MODULE the following files are generated:
        !            40: 
        !            41: MODULE-types.h
        !            42:      which contains C structure definitions.   The  user  of
        !            43:      the  library  provides data as a linked list of these C
        !            44:      data structures and expects to receive data back  as  a
        !            45:      similar linked list.  These data structures are exactly
        !            46:      the same as those produced by the original  ISODE  _p_o_s_y
        !            47:      so that existing software written for the old _p_o_s_y pro-
        !            48:      gram needs no change.  For details on the C data struc-
        !            49:      tures types generated see the documentation of the ori-
        !            50:      ginal _p_o_s_y program in volume 4 Chapter 5 of  the  ISODE
        !            51:      manuals.
        !            52: 
        !            53: MODULE_tables.c
        !            54:      This file contains the tables generated by the new _p_o_s_y
        !            55:      program.   These  tables  consist  of  three parts, the
        !            56:      first which contains the summary of ASN.1 types.   Each
        !            57:      type  is  summarised  as  an array of a primitive type,
        !            58:      struct pte, for encoding and decoding, and struct  ptpe
        !            59:      for  printing.   As implied there is one array for each
        !            60:      type for each of encoding,  decoding  and  printing  as
        !            61: 
        !            62: 
        !            63: 
        !            64:                       January 23, 1990
        !            65: 
        !            66: 
        !            67: 
        !            68: 
        !            69: 
        !            70:                            - 2 -
        !            71: 
        !            72: 
        !            73:      specified  when _p_o_s_y is run.  The next part contains up
        !            74:      to three tables of pointers to these arrays.   Each  of
        !            75:      the three different types of arrays, encoding, decoding
        !            76:      and printing, has its own table of  pointers.   Finally
        !            77:      there is the module type definition which contains con-
        !            78:      tains pointers to these tables and  some  other  useful
        !            79:      information  about  the  module such as its name.  This
        !            80:      module type structure, which is typedefed to modtyp, is
        !            81:      the only piece of data which is global, all the rest of
        !            82:      the data is static and is only addressable via the mod-
        !            83:      typ  data  structure.  This  provides  a kind of object
        !            84:      oriented approach to handling the tables.  Once you are
        !            85:      passed a pointer to an ASN.1's modtyp structure you can
        !            86:      encode, decode and print any of its  types  by  calling
        !            87:      the   appropriate  libpepsy.a  routine  with  its  type
        !            88:      number.
        !            89: 
        !            90: MODULE_pre_defs.h
        !            91:      This file contains #defines symbol of each of the ASN.1
        !            92:      types  to its type number, which is used when calling a
        !            93:      libpepsy.a routine.  Each symbol  is  _Ztype-nameMODULE
        !            94:      where _t_y_p_e-_n_a_m_e is the name of the type with dashes (-)
        !            95:      turned into underscores (_) and _M_O_D_U_L_E is the  name  of
        !            96:      the  module.   For  example of the ASN.1 universal type
        !            97:      _G_r_a_p_h_i_c_S_t_r_i_n_g would  have  the  #define  symbol  _ZGra-
        !            98:      phicStringUNIV.  The __Z is prepended to try to make the
        !            99:      symbols unique.  This file  also  contains  and  extern
        !           100:      declaration for the modtyp data for its module.
        !           101: 
        !           102: MODULE_defs.h
        !           103:      This file contains macros for  all the encoding, decod-
        !           104:      ing  and printing functions that the _p_e_p_y program would
        !           105:      have for these ASN.1 types.  This allows  much  of  the
        !           106:      code  that  uses  the routines generated by running the
        !           107:      old _p_o_s_y program and taking its output and running _p_e_p_y
        !           108:      on  augmented ASN.1 output can be recompiled unchanged.
        !           109:      If the code used pointers  to  these  functions  it  is
        !           110:      necessary  to change it to pass around the type numbers
        !           111:      instead and to call  appropriately  call  a  libpepsy.a
        !           112:      library  routine  with the type number.  As pointers to
        !           113:      the printing routines in ISODE are passed as  arguments
        !           114:      a  #define  is  provided  to turn the argument into the
        !           115:      pair of arguments, type number and  pointer  to  modtyp
        !           116:      structure,  which  are  needed  to allow the diagnostic
        !           117:      printing code to work with no change  for  the  current
        !           118:      ISODE stack.  This file also contains a #include of the
        !           119:      _M_O_D_U_L_E__p_r_e__d_e_f_s._h file.
        !           120: 
        !           121:      As the _M_O_D_U_L_E-_t_y_p_e_s._h file #include's the _M_O_D_U_L_E__d_e_f_s._h
        !           122: file  no  further  #includes  need  to be added to the files
        !           123: using the encoding/decoding/printing functions.  This  means
        !           124: that code written to use posy/pepy system may need no change
        !           125: at all and  the  only  effort  required  is  to  change  the
        !           126: Makefile  to use the pepsy system.  If there is code changes
        !           127: 
        !           128: 
        !           129: 
        !           130:                       January 23, 1990
        !           131: 
        !           132: 
        !           133: 
        !           134: 
        !           135: 
        !           136:                            - 3 -
        !           137: 
        !           138: 
        !           139: required it would most likely be because  function  pointers
        !           140: are  used  to reference the functions generated by posy.  If
        !           141: only the _p_e_p_y system was used, not posy then pepy, with code
        !           142: placed inside action statements then quite a large amount of
        !           143: work may be needed to change over to the new system, depend-
        !           144: ing on how large and complex the _p_e_p_y module is.
        !           145: 
        !           146: _1._1._2.  _O_u_t_l_i_n_e _o_f _t_h_e _p_e_p_s_y _l_i_b_r_a_r_y.
        !           147: 
        !           148: enc.cThis contains the routines that encode data from the  C
        !           149:      data  structures into ISODE's PElement linked list data
        !           150:      structure which it uses for all presentation data.  The
        !           151:      most  important  function to pepsy users is enc_f which
        !           152:      called to encode a particular type.  It is  passed  the
        !           153:      type  number and a pointer to modtyp structure for that
        !           154:      module and then the rest of  the  arguments  which  are
        !           155:      passed  to  an  encode  function generated by _p_o_s_y/_p_e_p_y
        !           156:      system.  See the documentation in Volume 4, "The Appli-
        !           157:      cations  Cookbook",  Section  6.4 called "Pepy Environ-
        !           158:      ment".  Most of these  latter  arguments  are  ignored,
        !           159:      only parm and pe, are used.
        !           160: 
        !           161:      Contrary to what the  ISODE  documentation  says  these
        !           162: ignored  parameters  are  hardly ever used by existing code.
        !           163: We have not found a single case where used  for  encoding  a
        !           164: named type, which is all that the user can reference anyway,
        !           165: so we don't see  any  problems  with  ignoring  these  other
        !           166: parameters.   Hopefully  one  day  they  can  be thrown away
        !           167: entirely, until then they are actually passed the the encod-
        !           168: ing function.
        !           169: 
        !           170:      The rest of the functions are mostly recursive routines
        !           171: which  encode a particular type of table entry.  For example
        !           172: SEQUENCE is encoded by en_seq which may call itself or  oth-
        !           173: ers  to  encode  the  types  from which it is built up.  The
        !           174: function en_type builds up a simple type and en_obj  encodes
        !           175: a  new  type (object) and so on with other functions.  There
        !           176: are a few utility routines in the file such  as  same  which
        !           177: determines  whether  the  value  is  the same as the default
        !           178: value also.
        !           179: 
        !           180: dec.cThis file contains the decoding routines that translate
        !           181:      presentation data into C data structures defined in the
        !           182:      MODULE-types.h is like _e_n_c._c.  It is very much like the
        !           183:      file _e_n_c._c except the routines do the reverse tasks The
        !           184:      routines are structured in a very similar way.  We have
        !           185:      dec_f  which is called by the user to decode a type and
        !           186:      like enc_f takes the same  arguments  as  the  decoding
        !           187:      functions  generated  by  _p_o_s_y  with two additions, the
        !           188:      type number and a pointer to the modtyp  structure  for
        !           189:      that  module.   Likewise  the  other functions are very
        !           190:      much like those of enc.c
        !           191: 
        !           192: prnt.cThis  file  contains  the  routines  that  print   the
        !           193: 
        !           194: 
        !           195: 
        !           196:                       January 23, 1990
        !           197: 
        !           198: 
        !           199: 
        !           200: 
        !           201: 
        !           202:                            - 4 -
        !           203: 
        !           204: 
        !           205:      presentation data in a format similar to that generated
        !           206:      by  _p_e_p_y's  printing  functions.   It's  main  function
        !           207:      prnt_f  is  takes  the  same  arguments as the printing
        !           208:      function generated by _p_e_p_y as well as the now  familiar
        !           209:      type  number  and  modtyp  pointer.   The functions are
        !           210:      modeled on the decoding routines as it has similar  job
        !           211:      to.  The only difference is that instead of storing the
        !           212:      decoded data into a  C  data  structure  it  is  nicely
        !           213:      printed out.
        !           214: 
        !           215: fr.c This file contains code to  free  the  data  structures
        !           216:      defined  in MODULE-types.h.  Likewise if the -f flag is
        !           217:      given when generating the types file it  also  includes
        !           218:      macros  in  the  types  file  which replace the freeing
        !           219:      functions generated by ISODE's _p_o_s_y.  The function that
        !           220:      the  user calls us fre_obj which takes a pointer to the
        !           221:      data structure, its decoding table entry and a  pointer
        !           222:      to  the modtyp structure for the module. The freeing is
        !           223:      based on the decoding routines except instead of decod-
        !           224:      ing  all  it  does is free each part of the data struc-
        !           225:      ture, which might  involve  recursive  calls,  then  it
        !           226:      frees the data structure at the end.
        !           227: 
        !           228: util.cThis contains the utility routines used by  more  than
        !           229:      one of the above files.  This is mostly diagnostic rou-
        !           230:      tines at the moment, more  general  routines  could  be
        !           231:      included  in  here.  If there is an error at the moment
        !           232:      which it can't recover from it just prints out  a  mes-
        !           233:      sage on standard error and calls exit.  Not perfect and
        !           234:      this is something that will need work.
        !           235: 
        !           236: main.cThis contains code to perform a series of tests on the
        !           237:      _p_e_p_s_y  library  which  is a useful check to see whether
        !           238:      any of the routines has  been  broken  by  any  changes
        !           239:      made.   It  basically  loops  through a whole series of
        !           240:      test cases.  Each test case is encoded from some  built
        !           241:      in test data and then decoded and checked to see if the
        !           242:      data has changed in the transfer.  If  it  is  compiled
        !           243:      with  -_D_P_R_N_T=_1  the encoded data is also printed out to
        !           244:      check the printing  routines  which  generates  a  vast
        !           245:      amount  of  output.  Finally the free routines are used
        !           246:      to  free  the  allocated  data,  although  it  can  not
        !           247:      directly  check  the free routines to see if they work,
        !           248:      it can be used with a malloc tracing package  to  check
        !           249:      that the routines work.
        !           250: 
        !           251: test_table.h
        !           252:      This contains the test cases that _m_a_i_n._c program  runs.
        !           253:      Each  entry in the table corresponds to a type.  One of
        !           254:      the fields is count of how many times that type  is  to
        !           255:      be tested to try out the different possibly data values
        !           256:      it might have.
        !           257: 
        !           258: pep.h and pepdefs.h
        !           259: 
        !           260: 
        !           261: 
        !           262:                       January 23, 1990
        !           263: 
        !           264: 
        !           265: 
        !           266: 
        !           267: 
        !           268:                            - 5 -
        !           269: 
        !           270: 
        !           271:      These files contain the definition of  types  used  for
        !           272:      the  tables  that  drive the encoding/decoding/printing
        !           273:      routines.  All the constants used  in  that  table  are
        !           274:      defined  here  via  #defines.   The modtyp structure is
        !           275:      defined in _p_e_p_d_e_f_s._h.
        !           276: 
        !           277: t1.py and t2.py
        !           278:      These are test ASN.1 modules that are  used  by  _m_a_i_n._c
        !           279:      routines  to  check  the _p_e_p_s_y library.  The file _t_1._p_y
        !           280:      contains the majority of different types with a few  of
        !           281:      a  different module provided in _t_2._p_y.  This allows the
        !           282:      testing of the code for handling ASN.1 external  refer-
        !           283:      ences,  i.e.  references  to  types  defined  in other,
        !           284:      external, modules.
        !           285: 
        !           286: _1._1._3.  _N_e_w _f_i_l_e_s _i_n _t_h_e _p_e_p_y _d_i_r_e_c_t_o_r_y
        !           287: 
        !           288: etabs.c, dtabs.c and ptabs.c
        !           289:      These  files  contain  the   code   to   generate   the
        !           290:      encoding/decoding/printing tables.  The main routine in
        !           291:      _e_t_a_b_s._c is tenc_typ which is called on each ASN.1  type
        !           292:      to  generate  an array of entries which describe how to
        !           293:      encode that type.  See the  details  section  for  more
        !           294:      information  about  how  the  table  entries  function.
        !           295:      Similarly _d_t_a_b_s._c contains the routine  tdec_typ  which
        !           296:      is  called  on each type to generate its decoding table
        !           297:      entries.   Likewise  tprnt_typ  routine  generates  the
        !           298:      arrays  of table entries for the printing tables.  This
        !           299:      function is in _p_t_a_b_s._c.
        !           300: 
        !           301: dfns.cThis file contains miscellaneous string handling  rou-
        !           302:      tines  and hash table routines that don't really belong
        !           303:      anywhere else.  Some of the routines could  be  cleaned
        !           304:      up in that they tend not to free memory they use.
        !           305: 
        !           306: mine.hThis  file  contains  the  definitions  for  the  hash
        !           307:      table(s)  that  are  used  to  keep  track of the ASN.1
        !           308:      types.  This could probably be done  with  out  a  hash
        !           309:      table,  should  anyone want to clean this up, feel wel-
        !           310:      come.  The lookup function is in _d_f_n_s._c.
        !           311: 
        !           312: pass2.h
        !           313:      This file has most of the #defines for the  table  gen-
        !           314:      erating  program.  Most of the prefixes and suffixes of
        !           315:      function names and files names  are  defined  here  so,
        !           316:      hopefully,  the names can be changed by merely changing
        !           317:      the definition.  This contains most  of  the  important
        !           318:      definitions  needed  by the changes to the _p_o_s_y program
        !           319:      needed to generate tables.
        !           320: 
        !           321: posy.hThis contains the definition of a symbol which is  now
        !           322:      needed  outside  of  the  the main routine and the yacc
        !           323:      file.  By putting it here we can include  it  any  file
        !           324:      that  needs  to  know  it  with out putting in any that
        !           325: 
        !           326: 
        !           327: 
        !           328:                       January 23, 1990
        !           329: 
        !           330: 
        !           331: 
        !           332: 
        !           333: 
        !           334:                            - 6 -
        !           335: 
        !           336: 
        !           337:      doesn't need it and with out including  all  the  other
        !           338:      definitions  that  occur  in _p_e_p_y._h.  The structure and
        !           339:      meaning of the tables generated from the ASN.1 grammar
        !           340: 
        !           341:      Each collection of ASN.1 grammar is  called  a  module.
        !           342: (See  ASN.1  )  Each ASN.1 module is completely specified in
        !           343: the program by a single C structure of type modtyp  and  the
        !           344: data  which  it  references.   See the _p_e_p_d_e_f_s._h file in the
        !           345: _p_e_p_s_y directory.  For each  ASN.1  module  there  are  three
        !           346: tables that are generated fromASN.1 grammar.  These initial-
        !           347: ised arrays which we call tables are  called  the  encoding,
        !           348: decoding  and  printing  tables.   Each  of  these tables is
        !           349: referenced through a different pointer of the modtyp  struc-
        !           350: ture.
        !           351: 
        !           352:      Each of these pointers references an array of pointers,
        !           353: one  pointer for each ASN.1 type defined in the module.  The
        !           354: position of one of these pointers is the unique type  number
        !           355: we  give  to its corresponding type.  The pointer references
        !           356: an array of type tpe or ptpe, depending  whether  it  is  an
        !           357: entry  in  the  decoding/encoding  tables or printing tables
        !           358: respectively.  See _p_e_p._h in the _p_e_p_s_y directory.  This array
        !           359: actually    contains    the    necessary    information   to
        !           360: encode/decode/print that ASN.1 type.  So  given  the  modtyp
        !           361: structure  of  an  ASN.1  module and its type number you can
        !           362: call a routine to encode, decode or print that type.
        !           363: 
        !           364:      The rest of this document assumes a good  knowledge  of
        !           365: ASN.1  notation  so  go  read a copy if you haven't already.
        !           366: From here on I shall mention only tpe and this means tpe  in
        !           367: the  case  of  encoding  or decoding and ptpe in the case of
        !           368: printing, unless otherwise stated.  Each type is represented
        !           369: by  an  array of tpe (or ptpe for printing).  The basic ele-
        !           370: ment consists of four integer fields, the printing table  is
        !           371: the  same with an addition char pointer field which contains
        !           372: the name corresponding to that entry in the  ASN.1  grammar.
        !           373: The first specifies the type of the entry and determines how
        !           374: the rest are interpreted.  The possible types are listed  in
        !           375: _p_e_p_s_y/_p_e_p._h.   Each  type  is  an array which starts with an
        !           376: entry of type PE_START and ends with  one  of  type  PE_END.
        !           377: Each  primitive type requires one entry to specify it, apart
        !           378: from possible PE_START and PE_END used to specify the  start
        !           379: and end of the type.  Constructed types are represented by a
        !           380: list of entries terminated by an entry of type  PE_END.   As
        !           381: ASN.1  types can be nested inside so will the representation
        !           382: in tpe entries be nested.  For example the ASN.1 type defin-
        !           383: ition:
        !           384:            Example1 ::=
        !           385:                    SEQUENCE {
        !           386:                        seq1 SEQUENCE {
        !           387:                                 an-i INTEGER,
        !           388:                                 an-ostring OCTET STRING
        !           389:                             },
        !           390:                        a-bool IMPLICIT [0] BOOLEAN
        !           391: 
        !           392: 
        !           393: 
        !           394:                       January 23, 1990
        !           395: 
        !           396: 
        !           397: 
        !           398: 
        !           399: 
        !           400:                            - 7 -
        !           401: 
        !           402: 
        !           403:                    }
        !           404:               Will generate an encoding array:
        !           405: static tpe et_Example1Test[] = {
        !           406:         { PE_START, 0, 0, 0 },
        !           407:         { SEQ_START, 0, 16, FL_UNIVERSAL },
        !           408:         { SEQ_START, OFFSET(struct type_Test_Example1, seq1), 16, FL_UNIVERSAL },
        !           409:         { INTEGER, OFFSET(struct element_Test_0, an__i), 2, FL_UNIVERSAL },
        !           410:         { OCTETSTRING, OFFSET(struct element_Test_0, an__ostring), 4, FL_UNIVERSAL },
        !           411:         { PE_END, 0, 0, 0 },
        !           412:         { BOOLEAN, OFFSET(struct type_Test_Example1, a__bool), 0, FL_CONTEXT },
        !           413:         { PE_END, 0, 0, 0 },
        !           414:         { PE_END, 0, 0, 0 }
        !           415:         };
        !           416: 
        !           417: 
        !           418:      Here the second last PE_END matches and closes off  the
        !           419: first  SEQ_START.  The entries which correspond to the other
        !           420: primative types are pretty obvious, with the  INTEGER  entry
        !           421: corresponding  to  the  primative  INTEGER.  For fields that
        !           422: generate data the general interpretation of the other  three
        !           423: fields is offset, tag and flags/class fields respectively.
        !           424: 
        !           425: offsetThe second field gives the offset in a C  data  struc-
        !           426:      ture  needed  to reference the data that corresponds to
        !           427:      this table entry.  Each  ASN.1  type  has  C  structure
        !           428:      types  generated  as  described  in  the ISODE manuals,
        !           429:      volume 4 "The applications Cookbook" Section 5.2, "POSY
        !           430:      Environment".  As this offset may have to be determined
        !           431:      in a compiler dependent manner a C  preprocessor  macro
        !           432:      is used hide the actual details.
        !           433: 
        !           434: tag  This is the tag associated with the ASN.1 type for that
        !           435:      entry.   Notice  that  in  the example the [0] IMPLICIT
        !           436:      which changes the tag associated with the BOOLEAN entry
        !           437:      actually  has the correct tag of 0 in the table.  Like-
        !           438:      wise  SEQUENCE  has  the  correct  tag  of  16  in  its
        !           439:      SEQ_START entry and so on for the others.
        !           440: 
        !           441: flags/class
        !           442:      This contains  the  ASN.1  class  associated  with  the
        !           443:      entry's  type.   That  is  UNIVERSAL for all except the
        !           444:      BOOLEAN type which is CONTEXT class.  This  fourth  can
        !           445:      also contain flags that specify if the type is OPTIONAL
        !           446:      or DEFAULT.  There is plenty of room here as  there  is
        !           447:      only four possibly classes.
        !           448: 
        !           449:      Now that you have some idea of  how  these  arrays  are
        !           450: arranged  for a type definition I will proceed to go through
        !           451: the possible type of entries and describe what they  do  and
        !           452: how  they  work.   These  values are defined in _p_e_p_s_y/_p_e_p._h.
        !           453: Those entries with a value below TYPE_DATA are entries  that
        !           454: don't  correspond  to data to be encoded/decoded and are for
        !           455: other book keeping type purposes.
        !           456: 
        !           457: 
        !           458: 
        !           459: 
        !           460:                       January 23, 1990
        !           461: 
        !           462: 
        !           463: 
        !           464: 
        !           465: 
        !           466:                            - 8 -
        !           467: 
        !           468: 
        !           469: PE_START and PE_END
        !           470:      As explained above PE_START starts the beginning  of  a
        !           471:      ASN.1  type's  array.   It probably isn't necessary but
        !           472:      the size of the tables is so small it isn't much of  an
        !           473:      over  head  to  keep  around for cosmetic reasons.  The
        !           474:      entry type PE_END is necessary to mark the end of  some
        !           475:      compound type as well as the end of ASN.1 data type.
        !           476: 
        !           477: XOBJECT and UCODE
        !           478:      These  are  obsolete  types  and  probably  should   be
        !           479:      removed.  They were to allow C code written directly by
        !           480:      the user to be incorporated into the  encoding/decoding
        !           481:      but  it was found unnecessary.  Prehaps some brave soul
        !           482:      would like to use them in an  attempt  to  implement  a
        !           483:      similar  system  based  on  _p_e_p_y which is what we first
        !           484:      attempted to do until we found this to be much easier.
        !           485: 
        !           486: MALLOCThis field only occurs in  the  decoding  tables.   It
        !           487:      specifies  how much space to malloc out for the current
        !           488:      C structure it is just inside of.  For instance in  the
        !           489:      example  above  the  decoding  table  has the following
        !           490:      entry:
        !           491: 
        !           492:       { MALLOC, 0, sizeof (struct type_Test_Example1), 0 },
        !           493: 
        !           494:      just after the first SEQ_START entry.  It tells  it  to
        !           495:      malloc  out  a  struct  type_Test_Example1 structure to
        !           496:      hold the data from the sequence when it is decoded.
        !           497: 
        !           498: SCTRLThis entry is used in handling the ASN.1  CHOICE  type.
        !           499:      The  C type generated for ASN.1 CHOICE type is a struc-
        !           500:      ture with an offset field in it and a union of all  the
        !           501:      C  types present in the CHOICE.  Each ASN.1 type in the
        !           502:      CHOICE of types has a C type definition  generated  for
        !           503:      it.   The union is of all these types, which is quite a
        !           504:      logical way to implement a  CHOICE  type.   The  offset
        !           505:      field  specifies  which possibility of interpreting the
        !           506:      union should be used (which  _m_e_m_b_e_r  should  selected).
        !           507:      As  such  it  needs to be read by the encoding routines
        !           508:      when encoding the data from the C data  structures  and
        !           509:      to  be set by the decoding routines when it is decoding
        !           510:      the data into the C data structures.  There is one such
        !           511:      entry  for each CHOICE type to specify where the offset
        !           512:      field is.
        !           513: 
        !           514: CH_ACTAnother redundant entry type.  I think this  was  also
        !           515:      used  in  code to handle C statements or actions speci-
        !           516:      fied by the user.  It probably should be removed.
        !           517: 
        !           518: OPTL This is used to handle the optionals field that is gen-
        !           519:      erated  by posy when optional types that are _n_o_t imple-
        !           520:      mented by pointers are present in the ASN.1 type.   For
        !           521:      example  if an ASN.1 type has an optional integer field
        !           522:      how does the encoding routine determine if the  integer
        !           523: 
        !           524: 
        !           525: 
        !           526:                       January 23, 1990
        !           527: 
        !           528: 
        !           529: 
        !           530: 
        !           531: 
        !           532:                            - 9 -
        !           533: 
        !           534: 
        !           535:      is  to  be  present or not?  If it was implemented as a
        !           536:      pointer it could use a NULL (zero) pointer to mean that
        !           537:      the  type was not present because NULL is guaranteed to
        !           538:      never occur as a legal pointer to a real  object.   But
        !           539:      all  the  possible  values for integer could be legally
        !           540:      passed  so  instead  for  these  types  which  are  not
        !           541:      pointers and are optional a bit map is allocated in the
        !           542:      structure.  Each non pointer optional type a  bit  from
        !           543:      the bit map is allocated.
        !           544: 
        !           545:      If that bit is set the corresponding  type  is  present
        !           546: and it is not present if the bit is not set.  Each bit has a
        !           547: #define generated for it.  The bit map is merely an  integer
        !           548: field  called  "optionals"  limiting  maximum number of such
        !           549: optionals to 32 on Sun machines, 16  on  some  others.   (An
        !           550: array  of char as BSD fd_sets would have avoid all such lim-
        !           551: its, not that this limit is expected  to  be  exceeded  very
        !           552: often  !)  Like  the SCTRL entry this entry merely serves to
        !           553: specify where this field is so it can be test and set by the
        !           554: encoding and decoding routines respectively.
        !           555: 
        !           556: ANY and CONS_ANY
        !           557:      The C type corresponding to the entry is a PE  pointer.
        !           558:      To  conform  with  _p_e_p_y the tag and class of this entry
        !           559:      are ignored, which may or may not be the most  sensible
        !           560:      thing.   The CONS_ANY is a redundant symbol which means
        !           561:      the same thing but is not used.  This should  be  clean
        !           562:      up and removed.
        !           563: 
        !           564: INTEGER, BOOLEAN, BITSTRING, OCTETSTRING and OBJID
        !           565:      These are just as described in the first article.   See
        !           566:      the ISODE manual to find out what they are allocated as
        !           567:      a C data type to implement  them.   The  offset  fields
        !           568:      says  where  to find this data type with in the current
        !           569:      structure.
        !           570: 
        !           571: SET_START, SETOF_START, SEQ_START and SEQOF_START
        !           572:      These compound entries differ from the  above  in  that
        !           573:      they group all the following entries together up to the
        !           574:      matching  PE_END.   The  entries  with   OF   in   them
        !           575:      correspond  to  the  ASN.1  types which have OF in them
        !           576:      e.g. SET OF.  Allowing the OF items to  have  an  arbi-
        !           577:      trary  number of entries is excessive flexibility, they
        !           578:      can only have one type by the ASN.1 grammar rules.  The
        !           579:      C data type corresponding to them is either a structure
        !           580:      if it is the first such type in the array or a  pointer
        !           581:      to a structure is isn't.  This complicates the process-
        !           582:      ing of these structures a little but not greatly.   The
        !           583:      OF types differ one other important way, they may occur
        !           584:      zero, one or more times, with no upper bound.  To  cope
        !           585:      with  this  the C data type is a linked list structure.
        !           586:      The pointer to the data structure determines whether or
        !           587:      not  there  is another occurrence of the type, if it is
        !           588:      NULL there isn't.  Thus each data  structure  has  this
        !           589: 
        !           590: 
        !           591: 
        !           592:                       January 23, 1990
        !           593: 
        !           594: 
        !           595: 
        !           596: 
        !           597: 
        !           598:                            - 10 -
        !           599: 
        !           600: 
        !           601:      pointer  to  the  next  occurrence,  the offset of this
        !           602:      pointer is placed in the PE_END field where it can con-
        !           603:      veniently  be  used to determine whether or not to make
        !           604:      another pass through the table entry.
        !           605: 
        !           606: OBJECTWhen one  type  references  another  it  generates  an
        !           607:      OBJECT  entry.   This  specifies the type number of the
        !           608:      type which is present in  the  3rd  field  of  the  tpe
        !           609:      structure,  pe_tag.   The  2nd  field  still  gives the
        !           610:      offset in the C data structure  which  specifies  where
        !           611:      the  user's data for that type is to be found.  Usually
        !           612:      this a pointer to the C data structure for that type.
        !           613: 
        !           614: T_NULLThis entry means the ASN.1 primative  type  NULL.   It
        !           615:      doesn't have any body and consequently has no offset as
        !           616:      it cannot carry data directly.   Only  its  absence  or
        !           617:      presence can mean anything so if it is optional it sets
        !           618:      or clears a bit in the bit map as described earlier for
        !           619:      OPTL entry.
        !           620: 
        !           621: T_OIDThis use to be used for Object Identifiers and  now  is
        !           622:      unused, it should be got rid.
        !           623: 
        !           624: OBJIDThis corresponds to the Object  Identifier  ASN.1  type
        !           625:      primitive.   It is implemented the same as other prima-
        !           626:      tive types like INTEGER and OCTET STRING.
        !           627: 
        !           628: ETAG This entry gives the  explicit  tag  of  the  following
        !           629:      entry.  The usual fields which define class and tag are
        !           630:      the only ones which have meaning  in  this  entry.   By
        !           631:      concatenating successive ETAG entries it is possibly to
        !           632:      build up an limited number explicit tags, although this
        !           633:      hasn't been tested yet.
        !           634: 
        !           635: IMP_OBJ
        !           636:      If a type has an implicit tag usually all we have to do
        !           637:      is  set  its  tag and class appropriately in its entry.
        !           638:      This works for all but one important case,  the  refer-
        !           639:      ence  of  another type.  This is messy because we can't
        !           640:      alter the definition of the type with out  wrecking  it
        !           641:      for  the  other  uses.   So  what we do for encoding is
        !           642:      build the type normally and then afterward it is  built
        !           643:      change  its  tag  and  class  to be the values we want.
        !           644:      Similarly for decoding we match the tag  and  class  up
        !           645:      and  then  decode the body of the type.  We can't use a
        !           646:      OBJECT entry for this because among other reasons there
        !           647:      3rd  field  is  already to store the type number.  (The
        !           648:      forth needs to be free to contain flags such as DEFAULT
        !           649:      and  OPTIONAL) So a new entry type is used, IMP_OBJ, to
        !           650:      hold the tag and class.  It  must  be  followed  by  an
        !           651:      OBJECT  entry  which is used to handle the type as nor-
        !           652:      mal, the IMP_OBJ entry gives the tag and  class  to  be
        !           653:      used.   Like  the  ETAG  entry  the IMP_OBJ affects the
        !           654:      entry that follows it.
        !           655: 
        !           656: 
        !           657: 
        !           658:                       January 23, 1990
        !           659: 
        !           660: 
        !           661: 
        !           662: 
        !           663: 
        !           664:                            - 11 -
        !           665: 
        !           666: 
        !           667: EXTOBJ and EXTMOD
        !           668:      These handle external type references.   This  is  just
        !           669:      like a normal (internal?) type reference except we must
        !           670:      now specify which module as well as  the  type.   Simi-
        !           671:      larly  because  there  are  no  more free fields in the
        !           672:      OBJECT type we need two entries to hold all the  infor-
        !           673:      mation  we need.  The EXTMOD occurs first and holds the
        !           674:      type number and the offset into the  C  data  structure
        !           675:      and  the  flags,  exactly  as for an OBJECT entry.  The
        !           676:      next entry, which must be an EXTMOD, contains a pointer
        !           677:      to  the modtyp structure for its module.  Like a normal
        !           678:      OBJECT entry to handle the case of an implicit  tag  an
        !           679:      IMP_OBJ  entry  would  occur  before  these two entries
        !           680:      which gives the class and tag.  Likewise it could  have
        !           681:      an  explicit tag in which the two entries would be pro-
        !           682:      ceeded by an ETAG entry.
        !           683: 
        !           684: DFLT_F and DFLT_B
        !           685:      When a type has a default value, to handle decoding and
        !           686:      encoding properly you need to know its value.  As there
        !           687:      is no space to store the value in most entries we allo-
        !           688:      cate a whole entry to specify the value.  When encoding
        !           689:      it is convenient to have the default occur  before  the
        !           690:      entry it refers to.  This allows a single check to han-
        !           691:      dle all the default encoding.  All  it  has  to  do  is
        !           692:      check  whether  it is the same as the default value and
        !           693:      if so not bother encoding the next type.  On the  other
        !           694:      hand  when  decoding  it is more convenient to have the
        !           695:      entry after the one it refers to.  In this case we need
        !           696:      to  determine  that  it  is  missing  before we use the
        !           697:      default value to determine the value  to  pass  to  the
        !           698:      user.   To  handle  this we have entries of both types.
        !           699:      _D_F_L_T__F contains the default  value  for  the  following
        !           700:      entry  (F  =  Front)  and  DFLT_B contains that for the
        !           701:      entry before it (B = Back).   Consequently  DFLT_F  are
        !           702:      only used in the decoding tables and DFLT_B entries are
        !           703:      only used in the decoding (and printing tables).
        !           704: 
        !           705: S-Types
        !           706:      These types are entries for the same ASN.1 type as  the
        !           707:      entry  type  formed  by removing the starting `S'.  The
        !           708:      above forms would do to handle ASN.1 but we  also  have
        !           709:      to  be  compatible with the C data structures generated
        !           710:      by _p_o_s_y.  The implementors decided to  optimise  the  C
        !           711:      data  structures  generated  a  little means we have to
        !           712:      have all these S type entries.  If a type was a  single
        !           713:      field in most cases they produced a #define which elim-
        !           714:      inates the need to have a whole structure just for that
        !           715:      type.   In  all  the places where this type is used the
        !           716:      field of the C structure is changed from a  pointer  to
        !           717:      field  which holds the value directly in the structure.
        !           718:      See the ISODE reference given above for more details.
        !           719: 
        !           720:      We handle this by generating the same tables that would
        !           721: 
        !           722: 
        !           723: 
        !           724:                       January 23, 1990
        !           725: 
        !           726: 
        !           727: 
        !           728: 
        !           729: 
        !           730:                            - 12 -
        !           731: 
        !           732: 
        !           733: be generated with out the optimisation, except the optimised
        !           734: types the S-type of entries instead of the normal ones.  For
        !           735: example  an optimised OCTET STRING would have the type field
        !           736: of its entry as SOCTETSTRING instead  of  OCTETSTRING.   The
        !           737: only  difference  in how S type and its corresponding normal
        !           738: are handle is how they find the C data  structure  for  that
        !           739: entry.   That  difference  is  that  there is no indirection
        !           740: through pointers.
        !           741: 
        !           742: Flags field
        !           743:      Besides the encoding the class the pe_flags field  also
        !           744:      contains  a  few  possible  flags.   Mainly FL_OPTIONAL
        !           745:      which means the ASN.1 type corresponding to  this  flag
        !           746:      is  OPTIONAL.   Consequently  when  encoding  it has to
        !           747:      determine if the type is present in the user data  pos-
        !           748:      sibly  using  the  bit  map as described under the OPTL
        !           749:      entry.  Likewise when decoding it may have to set a bit
        !           750:      in  the  bit  map appropriately.  The other flag at the
        !           751:      moment is FL_DEFAULT which means the entry  corresponds
        !           752:      to  an ASN.1 DEFAULT type.  This bit is still needed as
        !           753:      not all types have DFLT_* entries implmented  for  them
        !           754:      at  the  moment.   In  particular compound value things
        !           755:      like SEQUENCE and SET can't have  thier  default  value
        !           756:      specified.   This  is  consistent  with  ISODE, if fact
        !           757:      implementing that may even break existing  ISODE  code.
        !           758:      This last flag FL_IMPLICIT is obsolete and not not used
        !           759:      any where.
        !           760: 
        !           761: 
        !           762: _1._2.  _W_a_l_k _t_h_r_o_u_g_h _o_f _p_e_p_s_y _l_i_b_r_a_r_y _r_o_u_t_i_n_e_s.
        !           763: 
        !           764:      Here we walk through all the pepsy library routines  at
        !           765: least  briefly.   If any new routines are added or a routine
        !           766: changed this documentation is the most likely part that will
        !           767: need changing.  First we give some theory as to how the task
        !           768: have have been brocken  into  routines  then  describe  each
        !           769: function in detail.  We assume you are familiar with ISODE's
        !           770: PE data structure manipulation routines.  if  not  they  are
        !           771: documented  in  the  ISODE  manuals,  Volume one, chapter 5,
        !           772: "Encoding of Data-Structures" (It actually  covers  decoding
        !           773: as well).
        !           774: 
        !           775: _1._2._1.  _O_v_e_r_v_i_e_w _o_f _p_e_p_s_y _l_i_b_r_a_r_y
        !           776: 
        !           777:      Each seperate task is put into a  different  file.   So
        !           778: all  the  encoding stuff is in _e_n_c._c, all the decoding stuff
        !           779: is in _d_e_c._c, printing stuff in _p_r_n_t._c and freeing  stuff  in
        !           780: _f_r_e._c.   Actually  it breaks down a little in practice, some
        !           781: of the routines for moving around the  tables  are  used  in
        !           782: both  _e_n_c._c  and  _d_e_c._c  for  example.  Probably they should
        !           783: defined in _u_t_i_l._c so that linking one of the files from  the
        !           784: library doesn't force linking any other except _u_t_i_l._o.
        !           785: 
        !           786:      There is a common structure to each of the major  files
        !           787: 
        !           788: 
        !           789: 
        !           790:                       January 23, 1990
        !           791: 
        !           792: 
        !           793: 
        !           794: 
        !           795: 
        !           796:                            - 13 -
        !           797: 
        !           798: 
        !           799: as  well.   There  is a main routine which the user calls to
        !           800: obtain the services provided by that  file's  routines.   As
        !           801: all  the  files  revolve  about processing the table entries
        !           802: their structure  is  based  on  running  through  the  table
        !           803: entries.
        !           804: 
        !           805:      We shall call each array  of  entries  a  table  or  an
        !           806: object.   There  is a routine, usually with a name ending in
        !           807: _obj, which is designed to process an object.   For  example
        !           808: en_obj is the routine called to generated an encoded object.
        !           809: Then there are routines to call on each compound  type  such
        !           810: as en_seq for encode a SEQUENCE.  Finally all the primitives
        !           811: are handled by a one function that ends in _type.  This lets
        !           812: each routine concentrate on handling the features particular
        !           813: to its type and call the appropriate routine to handle  each
        !           814: type it finds with in its compound type.
        !           815: 
        !           816:      Most of these table processing routines have just three
        !           817: arguements: which are called parm, p, mod.  The parm is char
        !           818: * or char ** in the encoding and decoding  routines  respec-
        !           819: tively.   This points to the user's C structure that data to
        !           820: be encoded is taken from when encoding.  When decoding it is
        !           821: the address of a pointer which is made to point the C struc-
        !           822: ture filled with the decode data.   The  freeing,  which  is
        !           823: based  on  the  decoding  routines,  has a char ** while the
        !           824: printing routines don't look at the user's data and so don't
        !           825: have  such  a  pointer.   The  p points to the current table
        !           826: entry we are up to processing and the mod  arguement  points
        !           827: to  the  modtyp structure for the current module we are pro-
        !           828: cessing.
        !           829: 
        !           830:      All these processing routines return a PE  type,  which
        !           831: is  defined  in ISODE's file _h/_p_s_a_p._h, and to return zero if
        !           832: they have an error, but not always.  In fact the error  han-
        !           833: dling  is needs some work and has not been tested very well.
        !           834: Generally it tries to print out the table entry where  some-
        !           835: thing went wrong and the name of the function it was in.  It
        !           836: then sometimes does an exit which may not be  very  pleasent
        !           837: for the user.
        !           838: 
        !           839: _1._2._2.  _T_h_e _e_n_c_o_d_i_n_g _r_o_u_t_i_n_e_s - _e_n_c._c
        !           840: 
        !           841: enc_fThis is the the routine made available to the user  for
        !           842:      the  encoding  routines.   It  is  fairly  simple as it
        !           843:      leaves all the hard things up to other  routines.   All
        !           844:      it  does  is  use the type number and modtyp pointer to
        !           845:      get a pointer to the  table  for  encoding  that  type.
        !           846:      Then  it  calls  the  table or object encoding routine,
        !           847:      en_obj, on that object.  It first  does  a  consistency
        !           848:      check  of making sure the first entry in the table is a
        !           849:      PE_start.  Note that  it  returns  an  integer  (OK  or
        !           850:      NOTOK)  instead  of a PE pointer.  This is to be consi-
        !           851:      tent with ISODE functions.
        !           852: 
        !           853: 
        !           854: 
        !           855: 
        !           856:                       January 23, 1990
        !           857: 
        !           858: 
        !           859: 
        !           860: 
        !           861: 
        !           862:                            - 14 -
        !           863: 
        !           864: 
        !           865: en_objWe loop through the entries until we come to  the  end
        !           866:      of the table and then we return the PE we have built up
        !           867:      from the user's data which is pointed to by  parm.   In
        !           868:      looping through each entry we call the appropriate rou-
        !           869:      tine to encode its data.  The default case  is  handled
        !           870:      by  calling  en_type which takes care of all the primi-
        !           871:      tive types.
        !           872: 
        !           873:      The macro NEXT_TPE sets its arguement to point  to  the
        !           874: next type in the table, counting compound types as one type.
        !           875: Thus if NEXT_TPE is called on a SET_START it will  skip  all
        !           876: the  entries  up  to  and including the matching PE_END.  As
        !           877: many objects consist of one compound type and its components
        !           878: the  main loop will only be run through once.  Even when the
        !           879: object is not based on a compound type it will then  consist
        !           880: of  one  simple  type  which  is processed by en_type, again
        !           881: probably going through the loop only once.  In fact the only
        !           882: way  it can go through the loop more than once is to process
        !           883: entries that subsidary to the main type, e.g.  ETAG  entries
        !           884: and  things  like  that.   To  double check this is the case
        !           885: there is some code that looks for  the  processing  of  more
        !           886: than one data generating entry.
        !           887: 
        !           888:      Much of that testing could probably be eliminated  with
        !           889: no  loss.   Similarly  prehaps the IMP_OBJ and ETAG could be
        !           890: handled by the default action of calling en_type.  As  these
        !           891: routines  have  evolved  after many changes there are things
        !           892: like that which really need to be looked at  closely  before
        !           893: trying.   The comment /*SUPRESS 288*/ means suppress warning
        !           894: 288 to saber C debugging tool that we use.
        !           895: 
        !           896: en_type
        !           897:      This is one of the longest functions as it has so  many
        !           898:      cases  to handle.  It again is structure as a loop over
        !           899:      the types until PE_END but it actually returns as  soon
        !           900:      as  it  has  encoded the next type.  We can now look at
        !           901:      the encoding of the primative ASN.1 types in detail.
        !           902: 
        !           903: DFLT_FBecause we have arranged  that  for  encoding  tables,
        !           904:      that  we  precede  the entry with a DFLT_F entry we can
        !           905:      neatly handle all the default  cases.   All  we  do  is
        !           906:      check  if  the  parameter  passed  in the user data, in
        !           907:      parm, is the same as the default value specified in the
        !           908:      DFLT_F  entry.   The function same performs this check.
        !           909:      If it is the same don't encode  anything  just  return,
        !           910:      otherwise continue on and encode it.
        !           911: 
        !           912: ETAG To handle explicit tags we merely allocate  a  PE  with
        !           913:      the right tag and call en_etype to encode its contents,
        !           914:      which are in the following entries.  The switch on  the
        !           915:      pe_ucode  field  use to make a difference but now it is
        !           916:      meaningless and should be cleaned up.
        !           917: 
        !           918: SEQ_START, SEQOF_START, SET_START, SETOF_START
        !           919: 
        !           920: 
        !           921: 
        !           922:                       January 23, 1990
        !           923: 
        !           924: 
        !           925: 
        !           926: 
        !           927: 
        !           928:                            - 15 -
        !           929: 
        !           930: 
        !           931:      We merely call the appropriate  function  handle  them.
        !           932:      Note  one  _i_m_p_o_r_t_a_n_t  difference  in  the  way they are
        !           933:      called here from that in enc_obj, the parm arguement is
        !           934:      used  as a base to index off and fetch a new pointer to
        !           935:      pass the next function.  This seemly bizarre action  is
        !           936:      quite  straight forward when seen written as it is nor-
        !           937:      mally in C, "parm->offset".  Where the field offset  is
        !           938:      a  pointer  which  has  an offset from the start of the
        !           939:      structure of p->pe_ucode bytes.
        !           940: 
        !           941:      This is the magic of how we access  all  the  different
        !           942: fields  of the C data structures with the one piece of code.
        !           943: It is also prehaps the most critical dependency of the whole
        !           944: system on the implementation of the C language.  As the BGNU
        !           945: C compiler supports this feature then it is compilerable  on
        !           946: most machines.  But any porters should pay attention to this
        !           947: to ensure that thier  compiler  is  happy  generating  these
        !           948: offsets and compiling these casts properly.
        !           949: 
        !           950:      The reason why this is  different  from  the  calls  in
        !           951: en_obj  is  that  this is not the first compound type in the
        !           952: table.  The first and only the first does not have an offset
        !           953: and  does  not  need  to be indirected through any pointers.
        !           954: All the compound types inside this type will have  as  their
        !           955: field  a  pointer which points to a structure.  From here on
        !           956: we shall say _i_n_d_i_r_e_c_t_i_o_n  to mean this adding  the  pe_ucode
        !           957: field to the pointer to the structure and using it to refer-
        !           958: ence a pointer.  Whether to use _i_n_d_i_r_e_c_t_i_o_n or not  is  very
        !           959: important  matter  that  really  needs  to  be understood to
        !           960: understand how the routines are structured.
        !           961: 
        !           962: IMP_OBJ
        !           963:      Here we have to handle the case where we can encode the
        !           964:      object  then  have  to  change  its tag and class after
        !           965:      encoding.  At the end of this entry this is  done  very
        !           966:      simply by assigning the right values to the appropriate
        !           967:      fields after the object has  been  built.   This  means
        !           968:      that if the intermeadiate form is altered this piece of
        !           969:      code may have to be altered as well.  There seems to be
        !           970:      no better way of handling this.
        !           971: 
        !           972:      The complication in handling this field is the handling
        !           973: of  all  the possible types of object.  If it is an external
        !           974: object we have to perform a call to enc_f with all the right
        !           975: arguements  where  a  normal  OBJECT,  the last else branch,
        !           976: requires a normal call to en_obj.  Note the case of  SOBJECT
        !           977: is the same as OBJECT _e_x_c_e_p_t _t_h_e_r_e _i_s _n_o _i_n_d_i_r_e_c_t_i_o_n.
        !           978: 
        !           979: SOBJECT and OBJECT
        !           980:      Here is the code that handles the two cases  sperately.
        !           981:      It  is  exactly as in the IMP_OBJ case except seperated
        !           982:      out.  Note the only difference between the two cases is
        !           983:      lack of indirection in the SOBJECT case.
        !           984: 
        !           985: 
        !           986: 
        !           987: 
        !           988:                       January 23, 1990
        !           989: 
        !           990: 
        !           991: 
        !           992: 
        !           993: 
        !           994:                            - 16 -
        !           995: 
        !           996: 
        !           997: CHOICE_START
        !           998:      This is exactly  as  all  other  compound  types,  like
        !           999:      SEQ_START  and  OBJECT, we call the appropriate routine
        !          1000:      with indirection.  From reading the ISODE manuals  that
        !          1001:      the  ASN.1 CHOICE type is handled by a structure of its
        !          1002:      own like the other compund types.
        !          1003: 
        !          1004: EXTOBJ and SEXTOBJ
        !          1005: 
        !          1006: 
        !          1007: 
        !          1008: 
        !          1009: 
        !          1010: 
        !          1011: 
        !          1012: 
        !          1013: 
        !          1014: 
        !          1015: 
        !          1016: 
        !          1017: 
        !          1018: 
        !          1019: 
        !          1020: 
        !          1021: 
        !          1022: 
        !          1023: 
        !          1024: 
        !          1025: 
        !          1026: 
        !          1027: 
        !          1028: 
        !          1029: 
        !          1030: 
        !          1031: 
        !          1032: 
        !          1033: 
        !          1034: 
        !          1035: 
        !          1036: 
        !          1037: 
        !          1038: 
        !          1039: 
        !          1040: 
        !          1041: 
        !          1042: 
        !          1043: 
        !          1044: 
        !          1045: 
        !          1046: 
        !          1047: 
        !          1048: 
        !          1049: 
        !          1050: 
        !          1051: 
        !          1052: 
        !          1053: 
        !          1054:                       January 23, 1990
        !          1055: 
        !          1056: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.