"Fossies" - the Fresh Open Source Software Archive

Member "erltools/com/asnquick/quickasn.ch" (28 May 2004, 29220 Bytes) of package /linux/misc/old/erltools-4.0.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1  language asn;
    2 
    3 #include "quickasn.h"
    4 #include "tabsort.h"
    5 
    6 #if defined(UNIX_DLL)
    7 #ifndef SOLARIS
    8 #include <getopt.h>
    9 #endif
   10 #include <dlfcn.h>
   11 #include <ctype.h>
   12 #endif
   13 
   14 bool GenGramm::CompareTag ( char *tag, EString &string, const CoordString &coord )
   15 {
   16     
   17     unsigned int    index ;        // index in string
   18     bool            first = true ; // first char 
   19     
   20     for ( index = 0 ; index < coord.length ; index++ ) {
   21         char    cRef ;   // ref char
   22         char    cFound ; // found char
   23         cRef = *(tag + index);
   24         cFound = string [coord.pos + index];
   25         
   26         // if first suppress constructed bit
   27         if ( first ) {
   28             cRef &= ~0x20 ;
   29             cFound &= ~0x20 ;
   30             first = false ;
   31         }
   32         
   33         // if not good char return
   34         if ( cRef != cFound ) 
   35             return false ;
   36     }
   37     
   38     // succeeded
   39     return true ;
   40 }
   41 
   42 int GenGramm::DecodeLength ( EString &string, CoordString &coord )
   43 {
   44     
   45     int     lengthLength = 0 ; // length of length
   46     int     result = -1 ;
   47     char    currChar ;         // current char
   48     
   49     currChar = string [coord.pos];
   50     
   51     // compute length, there are two cases
   52     // 2 : length on one octet
   53     // 3 : length on multiple octets
   54     if ( coord.length >= 1 ) {
   55         if ( currChar & 0x80 ) {
   56             lengthLength = ((int)currChar) & 0x7F ;
   57             
   58             // if value is incorrect return a length of 0
   59             if ( lengthLength < 0 || lengthLength > coord.length ) {
   60                 result = -1 ;
   61             } else {
   62                 int lengthToBeAdded = lengthLength ;
   63                 coord.pos++ ;
   64                 result = 0 ;
   65                 while ( lengthToBeAdded-- ) {
   66                     int add = string [coord.pos++];
   67                     result <<= 8 ;
   68                     result += add & 0xFF ;
   69                 }
   70             }
   71         } else {
   72             result = ((int)string [coord.pos++]) & 0x7F ;
   73         }
   74     } else 
   75         result = -1 ;
   76     
   77     // add length of first byte
   78     lengthLength += 1 ;
   79     
   80     // if invalid length treatment
   81     if ( result >= 0 ) {
   82         if ( lengthLength > coord.length ) {
   83             coord.pos += coord.length ;
   84             coord.length = 0 ;
   85             result = -1 ;
   86         }
   87     }
   88     
   89     // adjust length
   90     coord.length -= lengthLength ;
   91     
   92     // return result 
   93     return result ;
   94 }
   95 
   96 // DecodeOctetString : get string out of octet string value
   97 EString GenGramm::DecodeOctetString ( EString &octetString )
   98 {
   99     char    digit [2];
  100     EString resString ;
  101     char    *theValue = (char *)(octetString.c_str());
  102     int     length = octetString.length();
  103     
  104     // read value
  105     *(digit + 1) = '\0';
  106     while ( length-- ) {
  107         char    c = *theValue++ ;
  108         {
  109             int val = c >> 4 & 0xF ;
  110             if ( val < 10 ) 
  111                 *digit = '0' + val ;
  112             else 
  113                 *digit = 'A' + val - 10 ;
  114             resString += digit ;
  115             val = c & 0xF ;
  116             if ( val < 10 ) 
  117                 *digit = '0' + val ;
  118             else 
  119                 *digit = 'A' + val - 10 ;
  120             resString += digit ;
  121         }
  122     }
  123     
  124     // return res
  125     return resString ;
  126 }
  127 
  128 EString GenGramm::ConvertStringToBin ( EString &string )
  129 {
  130     char    *pt ;
  131     EString result ;
  132     int     length = string.length();
  133     
  134     for ( pt = (char *)(string.c_str()) ; length > 1 ; length -= 2 ) {
  135         int nb = 0 ;
  136         if ( *pt >= 'a' ) 
  137             nb = 16 * (*pt - 'a' + 10);
  138         else if ( *pt >= 'A' ) 
  139             nb = 16 * (*pt - 'A' + 10);
  140         else 
  141             nb = 16 * (*pt - '0');
  142         pt++ ;
  143         if ( *pt >= 'a' ) 
  144             nb += *pt - 'a' + 10 ;
  145         else if ( *pt >= 'A' ) 
  146             nb += *pt - 'A' + 10 ;
  147         else 
  148             nb += *pt - '0';
  149         pt++ ;
  150         result += (char)nb ;
  151     }
  152     return result ;
  153 }
  154 
  155 PTREE GenGramm::GetInteger ( EString &string, CoordString &coord, bool checkTag )
  156 {
  157     int codedLength = coord.length ;
  158     
  159     if ( checkTag ) {
  160         CoordString coordString(coord.pos, 1);
  161         if ( !CompareTag("\002", string, coordString) ) 
  162             return PTREE(0);
  163         coord.length -= 1 ;
  164         coord.pos += 1 ;
  165         if ( (codedLength = DecodeLength(string, coord)) < 0 ) 
  166             return PTREE(0);
  167         else 
  168             coord.length -= codedLength ;
  169         checkTag = false ;
  170     }
  171     
  172     ENCODE_INT  valInteger ; // value of integer
  173     char        currChar ;   // current char
  174     
  175     // initialize with -1 or 0 depending if number is positive or negative
  176     currChar = string [coord.pos];
  177     if ( currChar & 0x80 ) 
  178         valInteger = ~0 ;
  179     else 
  180         valInteger = 0 ;
  181     
  182     // put value inside number
  183     while ( codedLength-- ) {
  184         valInteger = valInteger << 8 & ~0xff | ((int)(string [coord.pos++])) & 0xff ;
  185     }
  186     
  187     // construct return value
  188     
  189     bool        negative = false ;   // tells if negative number
  190     ENCODE_INT  rest ;               // rest of divide by 10
  191     char        digit ;              // a digit
  192     bool        sthingDone = false ; // tells if sthing was done
  193     EString     resultString ;       // the result string
  194     
  195     // convert number to a positive one
  196     if ( valInteger < 0 ) {
  197         negative = true ;
  198         valInteger = -1 * valInteger ;
  199     }
  200     
  201     // convert number to string
  202     while ( valInteger ) {
  203         rest = valInteger % 10 ;
  204         valInteger = valInteger / 10 ;
  205         digit = '0' + rest ;
  206         resultString.prepend(digit);
  207         sthingDone = true ;
  208     }
  209     if ( sthingDone ) {
  210         if ( negative ) 
  211             resultString.prepend("-");
  212     } else {
  213         resultString = "0";
  214     }
  215     
  216     // consruct result and return it
  217     PTREE   result ;
  218     
  219     result = PTREE(asn::NUMB, 1);
  220     result.ReplaceTree(1, PTREE(resultString));
  221     if ( negative ) {
  222         PTREE   negative(asn::UN_MINUS, 1);
  223         negative.ReplaceTree(1, result);
  224         result = negative ;
  225     }
  226     
  227     // return result
  228     return result ;
  229 }
  230 
  231 PTREE GenGramm::GetObjectIdentifier ( EString &string, CoordString &coord, bool checkTag )
  232 {
  233     int codedLength = coord.length ;
  234     
  235     if ( checkTag ) {
  236         CoordString coordString(coord.pos, 1);
  237         if ( !CompareTag("\006", string, coordString) ) 
  238             return PTREE(0);
  239         coord.length -= 1 ;
  240         coord.pos += 1 ;
  241         if ( (codedLength = DecodeLength(string, coord)) < 0 ) 
  242             return PTREE(0);
  243         else 
  244             coord.length -= codedLength ;
  245         checkTag = false ;
  246     }
  247     
  248     int     valInteger ; // value of integer
  249     char    currChar ;   // current char
  250     PTREE   listValue ;  // list of values
  251     
  252     // initialize with -1 or 0 depending if number is positive or negative
  253     currChar = string [coord.pos];
  254     
  255     bool    first = true ;
  256     
  257     while ( codedLength ) {
  258         
  259         // lire le prochain nombre
  260         char    octet = 0x80 ;
  261         int     nbObject = 0 ;
  262         while ( octet & 0x80 && codedLength >= 0 ) {
  263             octet = string [coord.pos];
  264             coord.pos += 1 ;
  265             codedLength-- ;
  266             
  267             // add octet to the value
  268             nbObject = nbObject << 7 | octet & 0x7F ;
  269         }
  270         if ( first ) {
  271             listValue *= <NUMB,PTREE(CompactItoa(nbObject / 40))>;
  272             
  273             // if more data it is a x.0.y
  274             if ( nbObject % 40 || codedLength ) {
  275                 listValue *= <NUMB,PTREE(CompactItoa(nbObject % 40))>;
  276             }
  277             first = false ;
  278         } else {
  279             listValue *= <NUMB,PTREE(CompactItoa(nbObject))>;
  280         }
  281     }
  282     
  283     // return result
  284     return listValue ;
  285 }
  286 
  287 PTREE GenGramm::GetBoolean ( EString &string, CoordString &coord, bool checkTag )
  288 {
  289     int codedLength = coord.length ;
  290     
  291     if ( checkTag ) {
  292         CoordString coordString(coord.pos, 1);
  293         if ( !CompareTag("\001", string, coordString) ) 
  294             return PTREE(0);
  295         coord.length -= 1 ;
  296         coord.pos += 1 ;
  297         if ( (codedLength = DecodeLength(string, coord)) < 0 ) 
  298             return PTREE(0);
  299         else 
  300             coord.length -= codedLength ;
  301         checkTag = false ;
  302     }
  303     
  304     char    currChar ; // current char
  305     
  306     // get value of boolean
  307     currChar = string [coord.pos++];
  308     
  309     // return result
  310     {
  311         PTREE   result ; // result 
  312         if ( currChar ) {
  313             result = <TRUE>;
  314         } else {
  315             result = <FALSE>;
  316         }
  317         return result ;
  318     }
  319 }
  320 
  321 PTREE GenGramm::GetIA5String ( EString &string, CoordString &coord, bool checkTag )
  322 {
  323     int codedLength = coord.length ;
  324     
  325     if ( checkTag ) {
  326         CoordString coordString(coord.pos, 1);
  327         if ( !CompareTag("\026", string, coordString) ) 
  328             return PTREE(0);
  329         coord.length -= 1 ;
  330         coord.pos += 1 ;
  331         if ( (codedLength = DecodeLength(string, coord)) < 0 ) 
  332             return PTREE(0);
  333         else 
  334             coord.length -= codedLength ;
  335         checkTag = false ;
  336     }
  337     
  338     char    currChar ;  // current char
  339     EString resString ; // resulting string
  340     
  341     // get string and return it
  342     {
  343         
  344         // get the string
  345         while ( codedLength-- ) {
  346             resString += string [coord.pos++];
  347         }
  348         
  349         // return it
  350         PTREE   result ; // the result 
  351         result = <STRING,PTREE(resString)>;
  352         return result ;
  353     }
  354 }
  355 
  356 PTREE GenGramm::GetRealString ( EString &string, CoordString &coord, bool checkTag )
  357 {
  358     int codedLength = coord.length ;
  359     
  360     if ( checkTag ) {
  361         CoordString coordString(coord.pos, 1);
  362         if ( !CompareTag("\011", string, coordString) ) 
  363             return PTREE(0);
  364         coord.length -= 1 ;
  365         coord.pos += 1 ;
  366         if ( (codedLength = DecodeLength(string, coord)) < 0 ) 
  367             return PTREE(0);
  368         else 
  369             coord.length -= codedLength ;
  370         checkTag = false ;
  371     }
  372     
  373     // get NR3 indicator
  374     coord.pos++ ;
  375     coord.length-- ;
  376     codedLength-- ;
  377     
  378     char    currChar ;  // current char
  379     EString resString ; // resulting string
  380     
  381     // get string and return it
  382     {
  383         
  384         // get the string
  385         while ( codedLength-- ) {
  386             resString += string [coord.pos++];
  387         }
  388         
  389         // return it
  390         PTREE   result ; // the result 
  391         result = <REAL,PTREE(resString)>;
  392         return result ;
  393     }
  394 }
  395 
  396 PTREE GenGramm::GetOctetString ( EString &string, CoordString &coord, bool checkTag )
  397 {
  398     int codedLength = coord.length ;
  399     
  400     if ( checkTag ) {
  401         CoordString coordString(coord.pos, 1);
  402         if ( !CompareTag("\004", string, coordString) ) 
  403             return PTREE(0);
  404         coord.length -= 1 ;
  405         coord.pos += 1 ;
  406         if ( (codedLength = DecodeLength(string, coord)) < 0 ) 
  407             return PTREE(0);
  408         else 
  409             coord.length -= codedLength ;
  410         checkTag = false ;
  411     }
  412     
  413     char    currChar ;  // current char
  414     EString resString ; // resulting string
  415     
  416     // get string and return it
  417     {
  418         
  419         // get the string
  420         while ( codedLength-- ) {
  421             resString += string [coord.pos++];
  422         }
  423         
  424         // return it
  425         PTREE   result ; // the result 
  426         result = <HSTRING,PTREE(DecodeOctetString(resString))>;
  427         return result ;
  428     }
  429 }
  430 
  431 PTREE GenGramm::GetNullType ( EString &string, CoordString &coord, bool checkTag )
  432 {
  433     int codedLength = coord.length ;
  434     
  435     if ( checkTag ) {
  436         CoordString coordString(coord.pos, 1);
  437         if ( !CompareTag("\005", string, coordString) ) 
  438             return PTREE(0);
  439         coord.length -= 1 ;
  440         coord.pos += 1 ;
  441         if ( (codedLength = DecodeLength(string, coord)) < 0 ) 
  442             return PTREE(0);
  443         else 
  444             coord.length -= codedLength ;
  445         checkTag = false ;
  446     }
  447     
  448     // return value
  449     return <NULL_VALUE>;
  450 }
  451 
  452 PTREE GenGramm::GetEnumerated ( PTREE val, Enumerated enumerated [] )
  453 {
  454     int enumeratedIndex ; // index for enumerated
  455     
  456     // get index
  457     enumeratedIndex = atoi(Value(val));
  458     
  459     // search it in array
  460     Enumerated  *ptEnumerated = enumerated ; // pointer on enumerated array
  461     
  462     while ( (*ptEnumerated)[1] ) {
  463         
  464         // if found valid index
  465         if ( (int)((*ptEnumerated)[0]) == enumeratedIndex ) {
  466             
  467             // construct return value
  468             PTREE   retValue ; // return value
  469             retValue = <IDENT,PTREE((*ptEnumerated)[1])>;
  470             
  471             // return it
  472             return retValue ;
  473         }
  474         
  475         // next value
  476         ptEnumerated++ ;
  477     }
  478     
  479     // fail
  480     return PTREE(0);
  481 }
  482 
  483 PTREE GenGramm::GetBitString ( EString &string, CoordString &coord, Enumerated enumerated [], bool checkTag )
  484 {
  485     
  486     // compute the bit string
  487     
  488     int     bitStringLength ;     // bit string length
  489     EString bitString ;           // the bit string
  490     char    currChar ;            // current character
  491     int     initPos = coord.pos ; // initPos 
  492     int     codedLength = coord.length ;
  493     
  494     if ( checkTag ) {
  495         CoordString coordString(coord.pos, 1);
  496         if ( !CompareTag("\003", string, coordString) ) 
  497             return PTREE(0);
  498         coord.length -= 1 ;
  499         coord.pos += 1 ;
  500         if ( (codedLength = DecodeLength(string, coord)) < 0 ) 
  501             return PTREE(0);
  502         else 
  503             coord.length -= codedLength ;
  504         checkTag = false ;
  505     }
  506     coord.length = codedLength ;
  507     
  508     // skip unused bits indication
  509     coord.pos += 1 ;
  510     coord.length -= 1 ;
  511     
  512     // extract bit string
  513     bitStringLength = coord.length ;
  514     while ( bitStringLength-- ) {
  515         currChar = string [coord.pos++];
  516         int nbBit = 8 ; // number of bits
  517         while ( nbBit-- ) {
  518             if ( currChar & 0x80 ) 
  519                 bitString += '1';
  520             else 
  521                 bitString += '0';
  522             currChar = currChar << 1 ;
  523         }
  524     }
  525     
  526     // construct response
  527     
  528     PTREE           retList ;         // returned list
  529     unsigned int    indexString = 0 ; // index in string
  530     
  531     if ( enumerated [0][1] ) {
  532         for ( indexString = 0 ; indexString < bitString.length() ; indexString++ ) {
  533             currChar = bitString [indexString];
  534             if ( currChar == '1' ) {
  535                 Enumerated  *ptEnumerated ; // pointer on enumerated
  536                 ptEnumerated = enumerated ;
  537                 while ( (*ptEnumerated)[1] ) {
  538                     
  539                     // if found valid index
  540                     if ( (int)((*ptEnumerated)[0]) == indexString ) {
  541                         
  542                         // construct return value
  543                         PTREE   retValue ; // return value
  544                         retValue = <IDENT,PTREE((*ptEnumerated)[1])>;
  545                         
  546                         // add it to list
  547                         retList *= retValue ;
  548                         
  549                         // it is ok
  550                         break ;
  551                     }
  552                     ptEnumerated++ ;
  553                 }
  554             }
  555         }
  556     } else 
  557         retList = <BSTRING,PTREE(bitString)>;
  558     
  559     // return result
  560     PTREE   retValue ; // return value
  561     
  562     retValue = <SEQUENCE_VALUE,retList>;
  563     return retValue ;
  564 }
  565 
  566 //
  567 // Encode an integer in hexa
  568 //
  569 EString GenGramm::EncodeInt ( ENCODE_INT numb )
  570 {
  571     
  572     int         nbOct = 0 ;        // number of byte necesary for coding integer
  573     ENCODE_INT  shiftNumb ;        // shifted number
  574     bool        negative = false ; // found zero
  575     bool        first = true ;
  576     
  577     // compute the number of bytes necessary to code number
  578     for ( nbOct = sizeof(ENCODE_INT) - 1 ; nbOct >= 0 ; nbOct-- ) {
  579         shiftNumb = ((ENCODE_INT)numb & (ENCODE_INT)(0xff << nbOct * 8)) >> nbOct * 8 ;
  580         char    compChar = (char)shiftNumb ;
  581         
  582         // on first loop look if number is negative with first ff
  583         if ( first ) {
  584             negative = compChar == (char)0xff ;
  585             first = false ;
  586         }
  587         
  588         // look if end
  589         if ( negative && compChar != (char)0xff || !negative && compChar != (char)0 ) 
  590             break ;
  591     }
  592     if ( nbOct < 0 ) 
  593         nbOct = 0 ;
  594     
  595     // if positive first bit must not be 1, if negative must be 1 
  596     if ( numb >= 0 && (shiftNumb & 0x80) != 0 || numb < 0 && !(shiftNumb & 0x80) ) {
  597         nbOct++ ;
  598     }
  599     nbOct++ ;
  600     
  601     // compute result 
  602     EString result ; // resulting string
  603     
  604     // create resulting string
  605     while ( nbOct-- ) {
  606         result += (char)(((ENCODE_INT)(numb >> ((ENCODE_INT)(nbOct * 8)))) & 0xff);
  607     }
  608     
  609     // return it
  610     return result ;
  611 }
  612 
  613 //
  614 // Encode a number in hexa
  615 //
  616 EString GenGramm::EncodeHexa ( int numb )
  617 {
  618     EString string((char)numb); // res string
  619     
  620     return string ;
  621 }
  622 
  623 void GenGramm::EncodeLength ( EString &string, int length )
  624 {
  625     
  626     // si la longueur est inferieure a 127 code en un seul
  627     // octet sinon plusieurs
  628     if ( length <= 127 ) {
  629         string += EncodeHexa(length);
  630     } else {
  631         
  632         // compute length
  633         EString lengthString = EncodeInt(length);
  634         
  635         // put header
  636         int     compteur = lengthString.length();
  637         compteur |= 0x80 ;
  638         string += EncodeHexa(compteur);
  639         string += lengthString ;
  640     }
  641 }
  642 
  643 void GenGramm::EncodeInteger ( EString &string, ENCODE_INT integer )
  644 {
  645     
  646     // if necessary put tag
  647     string += '\002';
  648     
  649     // compute content
  650     EString content = EncodeInt(integer);
  651     
  652     // add length to string
  653     EncodeLength(string, content.length());
  654     
  655     // add content to string
  656     string += content ;
  657 }
  658 
  659 //
  660 // Encoding in base 128
  661 //
  662 EString GenGramm::Encode128 ( long val )
  663 {
  664     long    divid, rem ;
  665     EString res("");
  666     char    string [20];
  667     int     first = 1 ;
  668     
  669     if ( !val ) {
  670         res += '\0';
  671         return res ;
  672     }
  673     divid = rem = val ;
  674     while ( divid ) {
  675         
  676         // compute reminder and dividend
  677         rem = divid ;
  678         divid = rem >> 7 ;
  679         rem = rem & 0x7F ;
  680         
  681         // if other bytes put a 1 at beginning
  682         if ( !first ) 
  683             rem |= 0x80 ;
  684         
  685         // add string to the those allready computed
  686         res.prepend((char)rem);
  687         
  688         // after that put 1
  689         first = 0 ;
  690     }
  691     
  692     // return result
  693     return res ;
  694 }
  695 
  696 void GenGramm::EncodeObjectIdentifier ( EString &string, PTREE listValue, int *objectDef )
  697 {
  698     
  699     // if necessary put tag
  700     string += '\006';
  701     
  702     bool    first = true ;
  703     PTREE   elem ;
  704     EString content ;
  705     long    tot ;
  706     PTREE   list = listValue ;
  707     
  708     while ( list != <LIST> && list.TreeArity() >= 1 ) 
  709         list = list [1];
  710     while ( elem = nextl(list) ) {
  711         if ( first ) {
  712             if ( elem == <IDENT> && objectDef != (int *)0 ) {
  713                 PTREE   newList ;
  714                 while ( *objectDef != -1 ) {
  715                     newList *= <IDENT,PTREE(CompactItoa(*objectDef))>;
  716                     objectDef++ ;
  717                 }
  718                 while ( elem = nextl(list) ) 
  719                     newList *= copytree(elem);
  720                 list = newList ;
  721                 elem = nextl(list);
  722             }
  723             tot = atoi(Value(elem));
  724             elem = nextl(list);
  725             tot = tot * 40 + atoi(Value(elem));
  726             content = Encode128(tot);
  727             first = false ;
  728         } else 
  729             content += Encode128(atoi(Value(elem)));
  730     }
  731     
  732     // add length to string
  733     EncodeLength(string, content.length());
  734     
  735     // add content to string
  736     string += content ;
  737 }
  738 
  739 void GenGramm::EncodeBoolean ( EString &string, bool boolean )
  740 {
  741     
  742     // put tag and length
  743     string += "\001\001";
  744     
  745     // put content
  746     if ( boolean ) 
  747         string += (char)0xff ;
  748     else 
  749         string += (char)0 ;
  750 }
  751 
  752 void GenGramm::EncodeIA5String ( EString &string, EString valString )
  753 {
  754     
  755     // if necessary put tag
  756     string += '\026';
  757     
  758     // add length to string
  759     EncodeLength(string, valString.length());
  760     
  761     // add content to string
  762     string += valString ;
  763 }
  764 
  765 void GenGramm::EncodeRealString ( EString &string, EString valString )
  766 {
  767     
  768     // if necessary put tag
  769     string += '\011';
  770     
  771     // add length to string
  772     EncodeLength(string, valString.length() + 1);
  773     
  774     // real is encoded NR3
  775     string += '\003';
  776     
  777     // add content to string
  778     string += valString ;
  779 }
  780 
  781 void GenGramm::EncodeRealString ( EString &string, PTREE &tree )
  782 {
  783     if ( tree == <STRING> ) {
  784         EString valString (Value(tree)) ;
  785         EncodeRealString(string, DecodeOctetString(valString));
  786     } else {
  787         EncodeRealString(string, Value(tree));
  788     }
  789 }
  790 
  791 void GenGramm::EncodeIA5String ( EString &string, PTREE &tree )
  792 {
  793     if ( tree == <HSTRING> ) {
  794         EString valString (Value(tree)) ;
  795         EncodeIA5String(string, ConvertStringToBin(valString));
  796     } else {
  797         EncodeIA5String(string, Value(tree));
  798     }
  799 }
  800 
  801 void GenGramm::EncodeOctetString ( EString &string, EString valString )
  802 {
  803     
  804     // if necessary put tag
  805     string += '\004';
  806     
  807     // add length to string
  808     EncodeLength(string, valString.length() / 2);
  809     
  810     // add content to string
  811     string += ConvertStringToBin(valString);
  812 }
  813 
  814 void GenGramm::EncodeOctetString ( EString &string, PTREE &tree )
  815 {
  816     if ( tree == <STRING> ) {
  817         EString valString (Value(tree)) ;
  818         EncodeOctetString(string, DecodeOctetString(valString));
  819     } else {
  820         EncodeOctetString(string, Value(tree));
  821     }
  822 }
  823 
  824 void GenGramm::EncodeNullType ( EString &string )
  825 {
  826     
  827     //  put tag  
  828     string += '\005';
  829     
  830     // put length
  831     string += '\0';
  832 }
  833 
  834 void GenGramm::EncodeEnumerated ( EString &string, Enumerated enumerated [], EString val )
  835 {
  836     
  837     int         enumeratedIndex ;            // index for enumerated
  838     
  839     // search it in array
  840     Enumerated  *ptEnumerated = enumerated ; // pointer on enumerated array
  841     
  842     while ( (*ptEnumerated)[1] ) {
  843         
  844         // if found valid index
  845         if ( val == (*ptEnumerated)[1] ) {
  846             EncodeInteger(string, (int)((*ptEnumerated)[0]));
  847             return ;
  848         }
  849         ptEnumerated++ ;
  850     }
  851 }
  852 
  853 void GenGramm::EncodeBitString ( EString &string, Enumerated enumeratedRef [], Enumerated enumeratedVal [] )
  854 {
  855     
  856     // put values in enumerated val
  857     
  858     Enumerated  *ptEnumeratedVal = enumeratedVal ; // pointer on enumerated array
  859     int         maxIndex = -1 ;                    // max index for bits
  860     EString     resultString ;                     // result string
  861     
  862     // if there is no enumerated ref transmit directly bit string
  863     if ( enumeratedRef [0][1] ) {
  864         while ( (*ptEnumeratedVal)[1] ) {
  865             char    *valString ; // the val string
  866             valString = (*ptEnumeratedVal)[1];
  867             
  868             // search the string in ref array
  869             Enumerated  *ptEnumeratedRef = enumeratedRef ; // pointer on enumerated array
  870             while ( (*ptEnumeratedRef)[1] ) {
  871                 
  872                 // if found valid index store it
  873                 if ( !strcmp(valString, (*ptEnumeratedRef)[1]) ) {
  874                     int valIndex ; // value of current index
  875                     (*ptEnumeratedVal)[0] = (*ptEnumeratedRef)[0];
  876                     valIndex = (int)((*ptEnumeratedVal)[0]);
  877                     if ( valIndex > maxIndex ) 
  878                         maxIndex = valIndex ;
  879                     break ;
  880                 }
  881                 ptEnumeratedRef++ ;
  882             }
  883             ptEnumeratedVal++ ;
  884         }
  885         
  886         // construct resulting string
  887         int indexBit ; // index on bits
  888         
  889         // while there are some bits to encode, encode them
  890         for ( indexBit = 0 ; indexBit <= maxIndex ; indexBit++ ) {
  891             
  892             // search if value is set
  893             // search it in array
  894             Enumerated  *ptEnumerated = enumeratedVal ; // pointer on enumerated array
  895             bool        foundBit = false ;
  896             while ( (*ptEnumerated)[1] ) {
  897                 
  898                 // if found valid index
  899                 if ( indexBit == (int)((*ptEnumerated)[0]) ) {
  900                     resultString += '1';
  901                     foundBit = 1 ;
  902                     break ;
  903                 }
  904                 ptEnumerated++ ;
  905             }
  906             if ( !foundBit ) 
  907                 resultString += '0';
  908         }
  909     } else 
  910         resultString = enumeratedVal [0][1];
  911     
  912     // round number of bits to byte limit
  913     unsigned int    missingBits = 8 - resultString.length() % 8 ;
  914     
  915     if ( missingBits == 8 ) 
  916         missingBits = 0 ;
  917     
  918     unsigned int    padding = missingBits ;
  919     
  920     while ( missingBits-- ) 
  921         resultString += '0';
  922     
  923     // construct result
  924     string += '\003';
  925     
  926     // put length
  927     EncodeLength(string, 1 + resultString.length() / 8);
  928     
  929     // put missing bits number
  930     string += EncodeHexa(padding);
  931     
  932     // encode the string
  933     
  934     unsigned int    index ;           // index in string
  935     int             byteCounter = 0 ; // counter for bytes
  936     char            currChar = '\0';  // current character
  937     
  938     for ( index = 0 ; index < resultString.length() ; index++ ) {
  939         
  940         // insert new bit
  941         currChar <<= 1 ;
  942         if ( resultString [index] == '1' ) {
  943             currChar |= 0x1 ;
  944         }
  945         byteCounter++ ;
  946         
  947         // if a byte is done insert it in result
  948         if ( byteCounter == 8 ) {
  949             string += currChar ;
  950             currChar = '\0';
  951             byteCounter = 0 ;
  952         }
  953     }
  954 }
  955 
  956 void GenGramm::PutConstructed ( EString &string, bool state )
  957 {
  958     char    *ptString = (char *)(string.c_str());
  959     
  960     // put constructed flag or suppress it
  961     if ( state ) {
  962         *ptString |= 0x20 ;
  963     } else {
  964         *ptString &= ~0x20 ;
  965     }
  966 }
  967 
  968 unsigned int GenGramm::LengthTag ( EString &string )
  969 {
  970     char            *pt = (char *)(string.c_str());
  971     unsigned int    length = 1 ;
  972     
  973     // compute length 
  974     char            comp = *pt++ & 0x3F ;
  975     
  976     if ( comp == 0x3F ) {
  977         length++ ;
  978         while ( *pt++ & 0x80 ) 
  979             length++ ;
  980     }
  981     
  982     // return it
  983     return length ;
  984 }
  985 
  986 #define EXTERN_FUNC_VOID extern "C" _declspec(dllimport) void 
  987 #define EXTERN_FUNC_PTREE extern "C" _declspec(dllimport) PPTREE 
  988 
  989 extern void                 (*FctMetaExit)(int, const char *) ;
  990 extern TabSortString        (*ptStackString)[];
  991 extern TabSortEqual<TREE>   (*ptStackPtree)[];
  992 extern bool                 *ptStackInitialized ;
  993 extern int                  *ptTabPtPos ;
  994 extern PPTREE               *ptTabPt ;
  995 
  996 typedef void    (*INITIALIZER_FUNCT)(char *metaName, TabSortString *(*pptStackString), TabSortEqual<TREE> *(*pptStackPtree), bool *pptStackInitialized
  997                 , void(*ptMetaExit)(int, const char *), int *, PPTREE *) ;
  998 
  999 // LoadGramm : try to load library for a grammar
 1000 // parameters :
 1001 //              name : name of grammar
 1002 // return : tells if success
 1003 bool GenGramm::LoadGramm ( EString &name, EString metaName )
 1004 {
 1005 #if defined(UNIX_DLL)
 1006 #define HINSTANCE void *
 1007 #define GetProcAddress dlsym
 1008 #endif
 1009     
 1010     EString fileDll ; // file name for the dll
 1011     
 1012     // construct dll name and try to load it
 1013     fileDll = name ;
 1014     //if ( access(fileDll.c_str(), 0) ) 
 1015     //    return false ;
 1016     HINSTANCE   hInst ;
 1017     
 1018 #if defined(UNIX_DLL)
 1019     fileDll = EString("lib") + fileDll + ".so";
 1020     hInst = dlopen(fileDll.c_str(), RTLD_LAZY);
 1021 #else 
 1022     fileDll += ".dll";
 1023     hInst = LoadLibrary(fileDll.c_str());
 1024 #endif
 1025     if ( hInst != 0 ) {
 1026         EString initializerName(""); // name of initializer
 1027         initializerName = name + "SetParam";
 1028         
 1029         // in linux real shared libraries
 1030 #if defined(W_DLL)
 1031         {
 1032             
 1033             // set interpreter and thread control for library
 1034             INITIALIZER_FUNCT   ptDefFunc = (INITIALIZER_FUNCT)GetProcAddress(hInst, initializerName.c_str());
 1035             if ( ptDefFunc ) {
 1036                 char    *name = (char *)metaName.c_str();
 1037                 (*ptDefFunc)(name, (TabSortString *(*))ptStackString, (TabSortEqual<TREE> *(*))ptStackPtree, ptStackInitialized, &MetaExit, ptTabPtPos
 1038                     , ptTabPt);
 1039             }
 1040         }
 1041 #endif
 1042         
 1043         // retrieve functions
 1044         {
 1045             
 1046             // get name of functions
 1047             EString encoderName("");  // name of encoder
 1048             EString decoderName("");  // name of decoder
 1049             encoderName = name + "RootEncode";
 1050             decoderName = name + "RootDecode";
 1051             
 1052             // retrieve the functions
 1053             pvDecoderFunct = (DECODER_FUNCT)GetProcAddress(hInst, decoderName.c_str());
 1054             pvEncoderFunct = (ENCODER_FUNCT)GetProcAddress(hInst, encoderName.c_str());
 1055         }
 1056     } else {
 1057 #if defined(UNIX_DLL)
 1058         EString theError = dlerror();
 1059 #endif
 1060         return false ;
 1061     }
 1062     
 1063     // success
 1064     return true ;
 1065 }