Annotation of 43BSDReno/contrib/isode-beta/pepsy/doc/DESCRIPTION, revision 1.1.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.