<html>
  <head>

    <meta http-equiv="content-type" content="text/html; charset=utf-8">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <tt><font size="+1">In asn-buf.cpp the operator<() and the
        operator==() methods <br>
        suffer from a performance issue, they are running in a loop
        until <br>
        an exception is not thrown. This is a very bad idea, and very <br>
        inefficient way of error handling. I have done some performance<br>
        tests with gproof. The performance has improved about 4 times
        better,<br>
        the code runs faster after my fix. I removed the exception
        handling from <br>
        operator<() and the operator==() and replaced them to a<br>
        boolean function, that can signal if an exception would be
        thrown.<br>
        <br>
        Signed-off-by: László Kovács <a class="moz-txt-link-rfc2396E" href="mailto:laszlo.kovacs@neti.com"><laszlo.kovacs@neti.com></a>
        <a class="moz-txt-link-rfc2396E" href="mailto:sabbath24@gmail.com"><sabbath24@gmail.com></a><br>
        Acked-by:      László Kovács <a class="moz-txt-link-rfc2396E" href="mailto:laszlo.kovacs@neti.com"><laszlo.kovacs@neti.com></a>
        <a class="moz-txt-link-rfc2396E" href="mailto:sabbath24@gmail.com"><sabbath24@gmail.com></a><br>
        Tested-by:     László Kovács <a class="moz-txt-link-rfc2396E" href="mailto:laszlo.kovacs@neti.com"><laszlo.kovacs@neti.com></a>
        <a class="moz-txt-link-rfc2396E" href="mailto:sabbath24@gmail.com"><sabbath24@gmail.com></a><br>
        Reported-by:   László Kovács <a class="moz-txt-link-rfc2396E" href="mailto:laszlo.kovacs@neti.com"><laszlo.kovacs@neti.com></a>
        <a class="moz-txt-link-rfc2396E" href="mailto:sabbath24@gmail.com"><sabbath24@gmail.com></a><br>
      </font></tt><tt><font size="+1"><br>
        ---<br>
      </font></tt><tt><font size="+1"><br>
        diff --git a/esnacc-ng-master/cxx-lib/inc/asn-buf.h
        b/esnacc-ng-master/cxx-lib/inc/asn-buf.h<br>
        index 4d06590..4235fb9 100644<br>
        --- a/esnacc-ng-master/cxx-lib/inc/asn-buf.h<br>
        +++ b/esnacc-ng-master/cxx-lib/inc/asn-buf.h<br>
        @@ -32,13 +32,13 @@<br>
         #define SNACCDLL_API __declspec(dllexport)<br>
         #else<br>
         #ifdef SNACCDLL_NONE<br>
        -#define SNACCDLL_API <br>
        +#define SNACCDLL_API<br>
         #else<br>
         #define SNACCDLL_API __declspec(dllimport)<br>
         #endif<br>
         #endif<br>
         #else<br>
        -#define SNACCDLL_API <br>
        +#define SNACCDLL_API<br>
         #endif<br>
         #endif<br>
         <br>
        @@ -115,7 +115,9 @@ public:<br>
             void skip(size_t skipBytes);<br>
             char PeekByte() const;<br>
             char GetByte() const;<br>
        +    bool GetByteNoEx(char& ret) const;<br>
             unsigned char GetUByte() const        { return (unsigned
        char)GetByte();}<br>
        +    bool GetUByteNoEx(unsigned char &ret) const        {
        char val; bool tmp=GetByteNoEx(val); ret=(unsigned char)val;
        return tmp; }<br>
         //    unsigned long GetSeg(char* seg, long segLen) const;<br>
             void GetSeg(char* seg, long segLen) const;<br>
             void GetUSeg(unsigned char* seg, long segLen) const {<br>
        @@ -135,7 +137,7 @@ public:<br>
             void insert(const AsnBuf& that);<br>
             long splice(AsnBuf& b);<br>
             void hexDump(std::ostream& os) const;<br>
        -   <br>
        +<br>
         #ifdef _DEBUG<br>
             void status(std::ostream& os);<br>
         #endif<br>
        @@ -152,7 +154,7 @@ protected:<br>
             mutable SNACC::Deck m_deck;<br>
         };<br>
         <br>
        -class SNACCDLL_API AsnBufBits <br>
        +class SNACCDLL_API AsnBufBits<br>
         {<br>
         private:<br>
             std::streambuf* m_pbuf;                // Stream buffer
        containing the bits<br>
        @@ -190,13 +192,13 @@ public:<br>
                 m_ulNumBits         = 0;<br>
                 m_ulBitsLeft        = 0;<br>
             }<br>
        -    <br>
        +<br>
             ~AsnBufBits(){ if (m_isInternalBuf && m_pbuf)
        delete m_pbuf; }<br>
         <br>
        -    <br>
        +<br>
             bool IsAligned()            { return bAlign; }<br>
         <br>
        -    <br>
        +<br>
         /*<br>
             AsnBufBits & operator=(const AsnBufBits &buf)<br>
             {<br>
        @@ -222,7 +224,7 @@ public:<br>
             unsigned long GetBits(AsnBits& bits, unsigned long
        numBits);<br>
             bool GetBit();<br>
             unsigned char GetByte();<br>
        -    <br>
        +<br>
             unsigned long  length(){ return m_ulBitsLeft; }<br>
             int            OctetAlignWrite();<br>
             int            OctetAlignRead();<br>
        @@ -230,12 +232,12 @@ public:<br>
             void          hexDump(std::ostream &os);<br>
             void          AppendTo(AsnBufBits &bufBitsOut);<br>
         <br>
        -    AsnBufBits(const AsnBufBits& buf);    <br>
        +    AsnBufBits(const AsnBufBits& buf);<br>
             AsnBufBits& operator=(const AsnBufBits& buf);<br>
         <br>
         private:<br>
             unsigned char ReadByte();    // Reads next byte from the
        stream<br>
        -        <br>
        +<br>
         };<br>
         <br>
         <br>
        @@ -254,14 +256,14 @@ public:<br>
         <br>
            const char *str()  { return m_pStart; }<br>
            int         pcount() { return ( (m_buf + m_segSize) -
        m_pStart ); }<br>
        - <br>
        +<br>
            long max_size() const {return m_segSize;}<br>
         <br>
            friend class AsnBuf;<br>
         <br>
         protected:<br>
            virtual int_type        underflow();<br>
        -   virtual int_type        overflow(int c = EOF);   <br>
        +   virtual int_type        overflow(int c = EOF);<br>
            virtual std::streamsize xsputn(const char *s,
        std::streamsize n);<br>
             virtual std::streambuf::pos_type       
        seekoff(std::streambuf::off_type off, std::ios_base::seekdir
        way,<br>
                                            std::ios_base::openmode
        which = std::ios_base::in | std::ios_base::out);<br>
        @@ -316,7 +318,7 @@ private:<br>
         //<br>
         <br>
         // Deck contains a streambuf * and a bool flag that indicates<br>
        -// whether or not the streambuf can be deleted. <br>
        +// whether or not the streambuf can be deleted.<br>
         //<br>
         enum AsnBufType { FILE_TYPE=0, RVS_BUF_TYPE, IN_MEM_TYPE,
        EXT_MEM_TYPE } ;<br>
         <br>
        @@ -329,7 +331,7 @@ public:<br>
               m_cDataW = 0x00;<br>
               m_iBitPosW = 0;<br>
               m_iBitPosR = 0;<br>
        -      first = NULL; <br>
        +      first = NULL;<br>
               second = EXT_MEM_TYPE;<br>
            }<br>
         #endif<br>
        @@ -339,8 +341,8 @@ public:<br>
               m_cDataW = 0x00;<br>
               m_iBitPosW = 0;<br>
               m_iBitPosR = 0;<br>
        -      first = sb; <br>
        -      second = EXT_MEM_TYPE; <br>
        +      first = sb;<br>
        +      second = EXT_MEM_TYPE;<br>
            }<br>
         <br>
            Card(const std::stringstream &ss)<br>
        @@ -348,7 +350,7 @@ public:<br>
               m_cDataW = 0x00;<br>
               m_iBitPosW = 0;<br>
               m_iBitPosR = 0;<br>
        -      first = ss.rdbuf(); <br>
        +      first = ss.rdbuf();<br>
               second = EXT_MEM_TYPE;<br>
            }<br>
         <br>
        @@ -357,16 +359,16 @@ public:<br>
               m_cDataW = 0x00;<br>
               m_iBitPosW = 0;<br>
               m_iBitPosR = 0;<br>
        -      first = pRvsBuf; <br>
        +      first = pRvsBuf;<br>
               second = RVS_BUF_TYPE;<br>
            }<br>
        -  <br>
        +<br>
            Card(AsnFileSeg *pFs)<br>
            {  m_cDataR = 0x00;<br>
               m_cDataW = 0x00;<br>
               m_iBitPosW = 0;<br>
               m_iBitPosR = 0;<br>
        -      first = pFs; <br>
        +      first = pFs;<br>
               second = FILE_TYPE;<br>
            }<br>
         <br>
        @@ -378,7 +380,7 @@ public:<br>
               first = o.first;<br>
               second = o.second;<br>
            }<br>
        -   <br>
        +<br>
            virtual ~Card()<br>
            {<br>
               if (second != EXT_MEM_TYPE)<br>
        @@ -386,14 +388,14 @@ public:<br>
            }<br>
         <br>
            int        BitPosW(){return m_iBitPosW;}<br>
        -   int      SetBitPosW(int newBitPos){m_iBitPosW = newBitPos;
        return m_iBitPosW;}   <br>
        -   <br>
        +   int      SetBitPosW(int newBitPos){m_iBitPosW = newBitPos;
        return m_iBitPosW;}<br>
        +<br>
            int        BitPosR(){return m_iBitPosR;}<br>
            int        SetBitPosR(int newBitPos){m_iBitPosR = newBitPos;
        return m_iBitPosR;}<br>
         <br>
            char     cDataW(){return m_cDataW;}<br>
            char     cDataW(char chr){m_cDataW=chr; return m_cDataW;}<br>
        -   <br>
        +<br>
            char     cDataR(){return m_cDataR;}<br>
            char     cDataR(char chr){m_cDataR=chr; return m_cDataR;}<br>
         <br>
        diff --git a/esnacc-ng-master/cxx-lib/src/asn-buf.cpp
        b/esnacc-ng-master/cxx-lib/src/asn-buf.cpp<br>
        index 62d61df..defa019 100644<br>
        --- a/esnacc-ng-master/cxx-lib/src/asn-buf.cpp<br>
        +++ b/esnacc-ng-master/cxx-lib/src/asn-buf.cpp<br>
        @@ -38,8 +38,8 @@ AsnBuf::AsnBuf()<br>
         }<br>
         <br>
         AsnBuf::AsnBuf(const char *seg, size_t segLen)<br>
        -{ <br>
        -   m_card = m_deck.insert(m_deck.begin(), new Card(new
        AsnRvsBuf(seg, segLen))); <br>
        +{<br>
        +   m_card = m_deck.insert(m_deck.begin(), new Card(new
        AsnRvsBuf(seg, segLen)));<br>
         }<br>
         <br>
         AsnBuf::AsnBuf(const std::stringstream &ss)<br>
        @@ -126,7 +126,7 @@ void AsnBuf::PutSegRvs(const char *seg,
        size_t segLen)<br>
               if (segLen > 0)<br>
               {<br>
                  // reuse any existing card(s)<br>
        -         if (m_card == m_deck.begin()) <br>
        +         if (m_card == m_deck.begin())<br>
                     m_card = m_deck.insert(m_deck.begin(), new Card(new
        AsnRvsBuf));<br>
                  else<br>
                     --m_card;<br>
        @@ -163,7 +163,7 @@ void
        AsnBuf::ResetMode(std::ios_base::openmode mode) const<br>
         <br>
            if (mode == std::ios_base::in)<br>
               m_card = m_deck.begin();<br>
        -   else <br>
        +   else<br>
            {<br>
               m_card = m_deck.end();<br>
               if ( ! m_deck.empty())<br>
        @@ -222,11 +222,11 @@ void AsnBuf::GetSeg(char *seg, long
        segLen) const<br>
             FUNC("AsnBuf::GetSeg()");<br>
            long bytesRead = 0;<br>
            long lTmp;<br>
        -   <br>
        +<br>
            while (segLen > 0 && m_card != m_deck.end() )<br>
            {<br>
               lTmp =
        (*m_card)->rdbuf()->sgetn(&seg[bytesRead], segLen);<br>
        -   <br>
        +<br>
               bytesRead += lTmp;<br>
               if (lTmp != segLen)<br>
                  m_card++;<br>
        @@ -263,6 +263,27 @@ void AsnBuf::GetSeg(std::string &seg,
        long segLen) const<br>
            }<br>
         }<br>
         <br>
        +bool AsnBuf::GetByteNoEx(char& ret) const<br>
        +{<br>
        +    std::streambuf::int_type ch;<br>
        +<br>
        +    if(m_card==m_deck.end()) return false;<br>
        +<br>
        +    do<br>
        +    {<br>
        +        ch=(*m_card)->rdbuf()->sbumpc();<br>
        +        if(ch==EOF)<br>
        +        {<br>
        +            ++m_card;<br>
        +            if(m_card==m_deck.end()) return false;<br>
        +        }<br>
        +    }<br>
        +    while(ch==EOF);<br>
        +<br>
        +    ret=(char)ch;<br>
        +    return true;<br>
        +}<br>
        +<br>
         bool AsnBuf::operator<(const AsnBuf &rhs) const<br>
         {<br>
            bool lessThan = true;<br>
        @@ -271,32 +292,23 @@ bool AsnBuf::operator<(const AsnBuf
        &rhs) const<br>
            rhs.ResetMode();<br>
            std::streambuf::int_type ch1;<br>
            std::streambuf::int_type ch2;<br>
        +   unsigned char Ch1;<br>
        +   unsigned char Ch2;<br>
        +<br>
            while ( lessThan )<br>
            {<br>
        -      try<br>
        -      {<br>
        -         ch1 = GetUByte();<br>
        -      }<br>
        -      catch (BufferException &)<br>
        -      {<br>
        -         ch1 = EOF;<br>
        -      }<br>
        +      if(GetUByteNoEx(Ch1)) ch1=Ch1;<br>
        +      else ch1=EOF;<br>
         <br>
        -      try<br>
        -      {<br>
        -         ch2 = rhs.GetUByte();<br>
        -      }<br>
        -      catch (BufferException &)<br>
        -      {<br>
        -         ch2 = EOF;<br>
        -      }<br>
        +      if(rhs.GetUByteNoEx(Ch2)) ch2=Ch2;<br>
        +      else ch2=EOF;<br>
         <br>
               if ((ch1 == EOF) && (ch2 == EOF))<br>
               {<br>
                  if (firstTime)<br>
                     lessThan = false;<br>
                  break;<br>
        -      } <br>
        +      }<br>
               else if (ch2 == EOF)<br>
               {<br>
                  lessThan = false;<br>
        @@ -313,7 +325,9 @@ bool AsnBuf::operator<(const AsnBuf
        &rhs) const<br>
                  break;<br>
         <br>
               firstTime = false;<br>
        +<br>
            }<br>
        +<br>
            ResetMode();<br>
            rhs.ResetMode();<br>
            return lessThan;<br>
        @@ -344,10 +358,10 @@ unsigned long AsnBuf::length() const<br>
                  endPos = (*tmpCard)->rdbuf()->pubseekoff(0,
        std::ios_base::end, std::ios_base::in);<br>
                  (*tmpCard)->rdbuf()->pubseekpos(currPos,
        std::ios_base::in);<br>
                  bytesRemaining += endPos - currPos;<br>
        -            <br>
        +<br>
                  tmpCard++;<br>
               }<br>
        -   <br>
        +<br>
               //SetReadLoc(readLoc);<br>
            }<br>
         <br>
        @@ -366,8 +380,8 @@ void AsnBuf::UnGetBytes(long
        lBytesToPutBack) const<br>
                 if( ((*m_card)->rdbuf()->sungetc()) == EOF )<br>
                 {<br>
                     if( m_card != m_deck.begin() )<br>
        -            {    <br>
        -                m_card--;                <br>
        +            {<br>
        +                m_card--;<br>
                     }<br>
                     else<br>
                     {<br>
        @@ -376,7 +390,7 @@ void AsnBuf::UnGetBytes(long
        lBytesToPutBack) const<br>
                 }<br>
                 else<br>
                 {<br>
        -            lBytesToPutBack--;    <br>
        +            lBytesToPutBack--;<br>
                 }<br>
             }<br>
         }<br>
        @@ -420,14 +434,14 @@ void AsnBuf::GrabAny(AsnBuf &anyBuf,
        AsnLen &bytesDecoded) const<br>
            AsnLen tmpLen = bytesDecoded;<br>
            AsnBufLoc readLoc = GetReadLoc();<br>
            AsnLen lTmpbytesDecoded=0;<br>
        -   <br>
        +<br>
            // Decode tag of the ANY.  This will be encoded into AnyBuf
        after the length<br>
            //<br>
            // @todo: decode the tag using an ASN.1 TagId structure, and
        check<br>
            // validity<br>
            //<br>
            (void)BDecTag(*this, bytesDecoded);<br>
        -   <br>
        +<br>
            // Decode length of the ANY.  This will be encoded into
        anyBuf after the data.<br>
            len = BDecLen(*this, bytesDecoded);<br>
         <br>
        @@ -447,10 +461,10 @@ void AsnBuf::GrabAny(AsnBuf &anyBuf,
        AsnLen &bytesDecoded) const<br>
            {<br>
               throw BufferException("len error from BDecLen call",
        STACK_ENTRY);<br>
            }<br>
        -   <br>
        +<br>
            SetReadLoc(readLoc);<br>
        -   <br>
        -   // length is greater than the magic size and <br>
        +<br>
        +   // length is greater than the magic size and<br>
            // the m_card contains a file then store a<br>
            // AsnFileSeg object in output buf.<br>
            //<br>
        @@ -514,7 +528,7 @@ AsnBufLoc AsnBuf::GetReadLoc() const<br>
         #ifdef _DEBUG<br>
            Card *pCard=*m_card;<br>
         #endif<br>
        -   if (bl.m_offset == -1) <br>
        +   if (bl.m_offset == -1)<br>
                bl.m_offset = 0;<br>
            return bl;<br>
         }<br>
        @@ -524,11 +538,11 @@ void AsnBuf::SetReadLoc(const AsnBufLoc
        &bl) const<br>
            FUNC("AsnBuf::setReadLoc()");<br>
         <br>
            Deck::iterator i = m_deck.begin();<br>
        -   <br>
        +<br>
            // first make sure interator bl.m_card is between current
        card<br>
            // start of the deck.<br>
            //<br>
        -   <br>
        +<br>
            while (i != bl.m_card && i != m_deck.end())<br>
            {<br>
               i++;<br>
        @@ -607,7 +621,7 @@ void BDEC_2ND_EOC_OCTET(const SNACC::AsnBuf
        &b, SNACC::AsnLen &bytesDecoded)<br>
         <br>
            if ((b.GetByte() != 0))<br>
               throw EXCEPT("second octet of EOC not zero",
        DECODE_ERROR);<br>
        -   <br>
        +<br>
            bytesDecoded++;<br>
         }<br>
         <br>
        @@ -647,16 +661,16 @@ bool AsnBuf::operator == (const AsnBuf
        &b) const<br>
            b.ResetMode();<br>
            std::streambuf::int_type ch1;<br>
            std::streambuf::int_type ch2;<br>
        +   unsigned char Ch1;<br>
        +   unsigned char Ch2;<br>
        +<br>
            while ( equal )<br>
            {<br>
        -      try<br>
        -      {<br>
        -         ch1 = GetUByte();<br>
        -      }<br>
        -      catch (BufferException &)<br>
        -      {<br>
        -         ch1 = EOF;<br>
        -      }<br>
        +      if(GetUByteNoEx(Ch1)) ch1=Ch1;<br>
        +      else ch1=EOF;<br>
        +<br>
        +      if(b.GetUByteNoEx(Ch2)) ch2=Ch2;<br>
        +      else ch2=EOF;<br>
         <br>
               try<br>
               {<br>
        @@ -682,14 +696,14 @@ void AsnBuf::hexDump(std::ostream &os)
        const<br>
         {<br>
            bool done = false;<br>
            int ch;<br>
        -   <br>
        +<br>
            ResetMode();<br>
         <br>
            std::hex(os);<br>
         <br>
            while (! done)<br>
            {<br>
        -     <br>
        +<br>
              try<br>
               {<br>
                  ch = GetUByte();<br>
        @@ -704,16 +718,16 @@ void AsnBuf::hexDump(std::ostream &os)
        const<br>
                  os.unsetf(std::ios_base::hex);<br>
                  done = true;<br>
               }<br>
        - <br>
        +<br>
            }<br>
         <br>
        -  <br>
        +<br>
         }<br>
         <br>
         <br>
         <br>
         std::ostream & operator<<(std::ostream &os, const
        SNACC::AsnBuf &b)<br>
        -{ <br>
        +{<br>
             SNACC::Deck::const_iterator card = b.deck().begin();<br>
             while (card != b.deck().end())<br>
             {<br>
        @@ -722,7 +736,7 @@ std::ostream &
        operator<<(std::ostream &os, const SNACC::AsnBuf
        &b)<br>
                card++;<br>
             }<br>
             os.flush();<br>
        -    return os; <br>
        +    return os;<br>
         }<br>
         <br>
         long Card::size()<br>
        @@ -730,15 +744,15 @@ long Card::size()<br>
           long currPos, endPos;<br>
         <br>
           currPos = first->pubseekoff(0, std::ios_base::cur,
        std::ios_base::in);<br>
        -  <br>
        +<br>
           endPos = first->pubseekoff(0, std::ios_base::end,
        std::ios_base::in);<br>
        - <br>
        +<br>
           if (currPos != -1)<br>
               first->pubseekpos(currPos, std::ios_base::in);<br>
        - <br>
        +<br>
           if (endPos == -1)<br>
              endPos = 0;<br>
        -     <br>
        +<br>
           return endPos;<br>
         }<br>
         <br>
        @@ -747,14 +761,14 @@ long Card::length()<br>
           long currPos, endPos;<br>
         <br>
           currPos = first->pubseekoff(0, std::ios_base::cur,
        std::ios_base::in);<br>
        -  <br>
        +<br>
           if (currPos == -1)<br>
              currPos = 0;<br>
        -  <br>
        +<br>
           endPos = first->pubseekoff(0, std::ios_base::end,
        std::ios_base::in);<br>
        - <br>
        +<br>
           first->pubseekpos(currPos, std::ios_base::in);<br>
        - <br>
        +<br>
           if (endPos == -1)<br>
              endPos = 0;<br>
         <br>
        <br>
      </font></tt>
  </body>
</html>