<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>