summaryrefslogtreecommitdiff
path: root/zinflate.cpp
diff options
context:
space:
mode:
authorweidai <weidai11@users.noreply.github.com>2004-04-08 01:28:03 +0000
committerweidai <weidai11@users.noreply.github.com>2004-04-08 01:28:03 +0000
commit391a03279134a32e28523d60dd41c294cf810572 (patch)
treefb0ea8ae3af76e0dee03294315afce0f61594591 /zinflate.cpp
parentc2f6c37e6dda61645fe30e24e911c7340a0de82c (diff)
downloadcryptopp-git-391a03279134a32e28523d60dd41c294cf810572.tar.gz
speed up DEFLATE decompression
Diffstat (limited to 'zinflate.cpp')
-rw-r--r--zinflate.cpp33
1 files changed, 22 insertions, 11 deletions
diff --git a/zinflate.cpp b/zinflate.cpp
index 4f5412c8..34613370 100644
--- a/zinflate.cpp
+++ b/zinflate.cpp
@@ -223,7 +223,7 @@ void Inflator::IsolatedInitialize(const NameValuePairs &parameters)
m_reader.SkipBits(m_reader.BitsBuffered());
}
-inline void Inflator::OutputByte(byte b)
+void Inflator::OutputByte(byte b)
{
m_window[m_current++] = b;
if (m_current == m_window.size())
@@ -231,26 +231,38 @@ inline void Inflator::OutputByte(byte b)
ProcessDecompressedData(m_window + m_lastFlush, m_window.size() - m_lastFlush);
m_lastFlush = 0;
m_current = 0;
+ m_wrappedAround = true;
}
- if (m_maxDistance < m_window.size())
- m_maxDistance++;
}
void Inflator::OutputString(const byte *string, unsigned int length)
{
- while (length--)
- OutputByte(*string++);
+ while (length)
+ {
+ unsigned int len = STDMIN(length, m_window.size() - m_current);
+ memcpy(m_window + m_current, string, len);
+ m_current += len;
+ if (m_current == m_window.size())
+ {
+ ProcessDecompressedData(m_window + m_lastFlush, m_window.size() - m_lastFlush);
+ m_lastFlush = 0;
+ m_current = 0;
+ m_wrappedAround = true;
+ }
+ string += len;
+ length -= len;
+ }
}
void Inflator::OutputPast(unsigned int length, unsigned int distance)
{
- if (distance > m_maxDistance)
- throw BadBlockErr();
unsigned int start;
- if (m_current > distance)
+ if (distance <= m_current)
start = m_current - distance;
- else
+ else if (m_wrappedAround && distance <= m_window.size())
start = m_current + m_window.size() - distance;
+ else
+ throw BadBlockErr();
if (start + length > m_window.size())
{
@@ -268,7 +280,6 @@ void Inflator::OutputPast(unsigned int length, unsigned int distance)
{
memcpy(m_window + m_current, m_window + start, length);
m_current += length;
- m_maxDistance = STDMIN((unsigned int)m_window.size(), m_maxDistance + length);
}
}
@@ -311,7 +322,7 @@ void Inflator::ProcessInput(bool flush)
return;
ProcessPrestreamHeader();
m_state = WAIT_HEADER;
- m_maxDistance = 0;
+ m_wrappedAround = false;
m_current = 0;
m_lastFlush = 0;
m_window.New(1 << GetLog2WindowSize());