From 186819080baea53410ae8d8100179a3874ac1e32 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Tue, 19 May 2020 21:07:05 +0200 Subject: [PATCH] Simplify stream availability handling Just have a simply number of bytes argument to avoid a lot of complexity. --- common/rdr/BufferedInStream.cxx | 17 ++++++--------- common/rdr/BufferedInStream.h | 2 +- common/rdr/BufferedOutStream.cxx | 17 +++++---------- common/rdr/BufferedOutStream.h | 2 +- common/rdr/HexInStream.cxx | 2 +- common/rdr/HexOutStream.cxx | 14 +++---------- common/rdr/HexOutStream.h | 2 +- common/rdr/InStream.h | 36 +++++++++++++------------------- common/rdr/MemInStream.h | 2 +- common/rdr/MemOutStream.h | 10 ++++----- common/rdr/OutStream.h | 34 +++++++++++++----------------- common/rdr/TLSInStream.cxx | 4 ++-- common/rdr/TLSOutStream.cxx | 13 +++--------- common/rdr/TLSOutStream.h | 2 +- common/rdr/ZlibInStream.cxx | 2 +- common/rdr/ZlibOutStream.cxx | 15 ++++--------- common/rdr/ZlibOutStream.h | 2 +- common/rfb/JpegCompressor.cxx | 2 +- common/rfb/JpegCompressor.h | 4 ++-- tests/perf/decperf.cxx | 7 ++----- tests/perf/encperf.cxx | 7 ++----- 21 files changed, 70 insertions(+), 126 deletions(-) diff --git a/common/rdr/BufferedInStream.cxx b/common/rdr/BufferedInStream.cxx index 5083eb2d..5db3953a 100644 --- a/common/rdr/BufferedInStream.cxx +++ b/common/rdr/BufferedInStream.cxx @@ -44,12 +44,12 @@ size_t BufferedInStream::pos() return offset + ptr - start; } -size_t BufferedInStream::overrun(size_t itemSize, size_t nItems, bool wait) +bool BufferedInStream::overrun(size_t needed, bool wait) { - if (itemSize > bufSize) + if (needed > bufSize) throw Exception("BufferedInStream overrun: " "requested size of %lu bytes exceeds maximum of %lu bytes", - (long unsigned)itemSize, (long unsigned)bufSize); + (long unsigned)needed, (long unsigned)bufSize); if (end - ptr != 0) memmove(start, ptr, end - ptr); @@ -58,15 +58,10 @@ size_t BufferedInStream::overrun(size_t itemSize, size_t nItems, bool wait) end -= ptr - start; ptr = start; - while (avail() < itemSize) { + while (avail() < needed) { if (!fillBuffer(start + bufSize - end, wait)) - return 0; + return false; } - size_t nAvail; - nAvail = avail() / itemSize; - if (nAvail < nItems) - return nAvail; - - return nItems; + return true; } diff --git a/common/rdr/BufferedInStream.h b/common/rdr/BufferedInStream.h index fc62133e..61e57d65 100644 --- a/common/rdr/BufferedInStream.h +++ b/common/rdr/BufferedInStream.h @@ -38,7 +38,7 @@ namespace rdr { private: virtual bool fillBuffer(size_t maxSize, bool wait) = 0; - virtual size_t overrun(size_t itemSize, size_t nItems, bool wait); + virtual bool overrun(size_t needed, bool wait); private: size_t bufSize; diff --git a/common/rdr/BufferedOutStream.cxx b/common/rdr/BufferedOutStream.cxx index 76b0163b..69e877ad 100644 --- a/common/rdr/BufferedOutStream.cxx +++ b/common/rdr/BufferedOutStream.cxx @@ -71,22 +71,22 @@ void BufferedOutStream::flush() ptr = sentUpTo = start; } -size_t BufferedOutStream::overrun(size_t itemSize, size_t nItems) +void BufferedOutStream::overrun(size_t needed) { - if (itemSize > bufSize) + if (needed > bufSize) throw Exception("BufferedOutStream overrun: " "requested size of %lu bytes exceeds maximum of %lu bytes", - (long unsigned)itemSize, (long unsigned)bufSize); + (long unsigned)needed, (long unsigned)bufSize); // First try to get rid of the data we have flush(); // Still not enough space? - while (itemSize > avail()) { + while (needed > avail()) { // Can we shuffle things around? // (don't do this if it gains us less than 25%) if (((size_t)(sentUpTo - start) > bufSize / 4) && - (itemSize < bufSize - (ptr - sentUpTo))) { + (needed < bufSize - (ptr - sentUpTo))) { memmove(start, sentUpTo, ptr - sentUpTo); ptr = start + (ptr - sentUpTo); sentUpTo = start; @@ -105,11 +105,4 @@ size_t BufferedOutStream::overrun(size_t itemSize, size_t nItems) ptr = sentUpTo = start; } } - - size_t nAvail; - nAvail = avail() / itemSize; - if (nAvail < nItems) - return nAvail; - - return nItems; } diff --git a/common/rdr/BufferedOutStream.h b/common/rdr/BufferedOutStream.h index 092ea1f0..c33621b6 100644 --- a/common/rdr/BufferedOutStream.h +++ b/common/rdr/BufferedOutStream.h @@ -46,7 +46,7 @@ namespace rdr { virtual bool flushBuffer(bool wait) = 0; - virtual size_t overrun(size_t itemSize, size_t nItems); + virtual void overrun(size_t needed); private: size_t bufSize; diff --git a/common/rdr/HexInStream.cxx b/common/rdr/HexInStream.cxx index 0901afee..ab98298f 100644 --- a/common/rdr/HexInStream.cxx +++ b/common/rdr/HexInStream.cxx @@ -73,7 +73,7 @@ decodeError: bool HexInStream::fillBuffer(size_t maxSize, bool wait) { - if (!in_stream.check(2, 1, wait)) + if (!in_stream.check(2, wait)) return false; const U8* iptr = in_stream.getptr(); diff --git a/common/rdr/HexOutStream.cxx b/common/rdr/HexOutStream.cxx index 6118c136..a44c3998 100644 --- a/common/rdr/HexOutStream.cxx +++ b/common/rdr/HexOutStream.cxx @@ -95,18 +95,10 @@ HexOutStream::flush() { out_stream.flush(); } -size_t -HexOutStream::overrun(size_t itemSize, size_t nItems) { - if (itemSize > bufSize) - throw Exception("HexOutStream overrun: max itemSize exceeded"); +void HexOutStream::overrun(size_t needed) { + if (needed > bufSize) + throw Exception("HexOutStream overrun: buffer size exceeded"); writeBuffer(); - - size_t nAvail; - nAvail = avail() / itemSize; - if (nAvail < nItems) - return nAvail; - - return nItems; } diff --git a/common/rdr/HexOutStream.h b/common/rdr/HexOutStream.h index 92442a72..29827689 100644 --- a/common/rdr/HexOutStream.h +++ b/common/rdr/HexOutStream.h @@ -37,7 +37,7 @@ namespace rdr { private: void writeBuffer(); - size_t overrun(size_t itemSize, size_t nItems); + virtual void overrun(size_t needed); OutStream& out_stream; diff --git a/common/rdr/InStream.h b/common/rdr/InStream.h index 665084f2..ce3a344d 100644 --- a/common/rdr/InStream.h +++ b/common/rdr/InStream.h @@ -43,31 +43,24 @@ namespace rdr { return end - ptr; } - // check() ensures there is buffer data for at least one item of size - // itemSize bytes. Returns the number of items in the buffer (up to a - // maximum of nItems). If wait is false, then instead of blocking to wait - // for the bytes, zero is returned if the bytes are not immediately - // available. + // check() ensures there is buffer data for at least needed bytes. Returns + // true once the data is available. If wait is false, then instead of + // blocking to wait for the bytes, false is returned if the bytes are not + // immediately available. - inline size_t check(size_t itemSize, size_t nItems=1, bool wait=true) + inline size_t check(size_t needed, bool wait=true) { - size_t nAvail; + if (needed > avail()) + return overrun(needed, wait); - if (itemSize > avail()) - return overrun(itemSize, nItems, wait); - - nAvail = avail() / itemSize; - if (nAvail < nItems) - return nAvail; - - return nItems; + return true; } // checkNoWait() tries to make sure that the given number of bytes can // be read without blocking. It returns true if this is the case, false // otherwise. The length must be "small" (less than the buffer size). - inline bool checkNoWait(size_t length) { return check(length, 1, false)!=0; } + inline bool checkNoWait(size_t length) { return check(length, false); } // readU/SN() methods read unsigned and signed N-bit integers. @@ -137,13 +130,12 @@ namespace rdr { private: // overrun() is implemented by a derived class to cope with buffer overrun. - // It ensures there are at least itemSize bytes of buffer data. Returns - // the number of items in the buffer (up to a maximum of nItems). itemSize - // is supposed to be "small" (a few bytes). If wait is false, then - // instead of blocking to wait for the bytes, zero is returned if the bytes - // are not immediately available. + // It ensures there are at least needed bytes of buffer data. Returns true + // once the data is available. If wait is false, then instead of blocking + // to wait for the bytes, false is returned if the bytes are not + // immediately available. - virtual size_t overrun(size_t itemSize, size_t nItems, bool wait=true) = 0; + virtual bool overrun(size_t needed, bool wait=true) = 0; protected: diff --git a/common/rdr/MemInStream.h b/common/rdr/MemInStream.h index 3e9e77bc..83740dd9 100644 --- a/common/rdr/MemInStream.h +++ b/common/rdr/MemInStream.h @@ -53,7 +53,7 @@ namespace rdr { private: - size_t overrun(size_t itemSize, size_t nItems, bool wait) { throw EndOfStream(); } + bool overrun(size_t needed, bool wait) { throw EndOfStream(); } const U8* start; bool deleteWhenDone; }; diff --git a/common/rdr/MemOutStream.h b/common/rdr/MemOutStream.h index a839473b..f8b4d93c 100644 --- a/common/rdr/MemOutStream.h +++ b/common/rdr/MemOutStream.h @@ -52,11 +52,11 @@ namespace rdr { protected: - // overrun() either doubles the buffer or adds enough space for nItems of - // size itemSize bytes. + // overrun() either doubles the buffer or adds enough space for + // needed bytes. - size_t overrun(size_t itemSize, size_t nItems) { - size_t len = ptr - start + itemSize * nItems; + virtual void overrun(size_t needed) { + size_t len = ptr - start + needed; if (len < (size_t)(end - start) * 2) len = (end - start) * 2; @@ -69,8 +69,6 @@ namespace rdr { delete [] start; start = newStart; end = newStart + len; - - return nItems; } U8* start; diff --git a/common/rdr/OutStream.h b/common/rdr/OutStream.h index 33381d9a..bb88f325 100644 --- a/common/rdr/OutStream.h +++ b/common/rdr/OutStream.h @@ -48,22 +48,12 @@ namespace rdr { return end - ptr; } - // check() ensures there is buffer space for at least one item of size - // itemSize bytes. Returns the number of items which fit (up to a maximum - // of nItems). + // check() ensures there is buffer space for at least needed bytes. - inline size_t check(size_t itemSize, size_t nItems=1) + inline void check(size_t needed) { - size_t nAvail; - - if (itemSize > avail()) - return overrun(itemSize, nItems); - - nAvail = avail() / itemSize; - if (nAvail < nItems) - return nAvail; - - return nItems; + if (needed > avail()) + overrun(needed); } // writeU/SN() methods write unsigned and signed N-bit integers. @@ -95,7 +85,10 @@ namespace rdr { void writeBytes(const void* data, size_t length) { while (length > 0) { - size_t n = check(1, length); + check(1); + size_t n = length; + if (length > avail()) + n = avail(); memcpy(ptr, data, n); ptr += n; data = (U8*)data + n; @@ -107,7 +100,10 @@ namespace rdr { void copyBytes(InStream* is, size_t length) { while (length > 0) { - size_t n = check(1, length); + check(1); + size_t n = length; + if (length > avail()) + n = avail(); is->readBytes(ptr, n); ptr += n; length -= n; @@ -143,11 +139,9 @@ namespace rdr { private: // overrun() is implemented by a derived class to cope with buffer overrun. - // It ensures there are at least itemSize bytes of buffer space. Returns - // the number of items which fit (up to a maximum of nItems). itemSize is - // supposed to be "small" (a few bytes). + // It ensures there are at least needed bytes of buffer space. - virtual size_t overrun(size_t itemSize, size_t nItems) = 0; + virtual void overrun(size_t needed) = 0; protected: diff --git a/common/rdr/TLSInStream.cxx b/common/rdr/TLSInStream.cxx index 92c2f0c6..70303db0 100644 --- a/common/rdr/TLSInStream.cxx +++ b/common/rdr/TLSInStream.cxx @@ -36,7 +36,7 @@ ssize_t TLSInStream::pull(gnutls_transport_ptr_t str, void* data, size_t size) InStream *in = self->in; try { - if (!in->check(1, 1, false)) { + if (!in->check(1, false)) { gnutls_transport_set_errno(self->session, EAGAIN); return -1; } @@ -84,7 +84,7 @@ size_t TLSInStream::readTLS(U8* buf, size_t len, bool wait) int n; if (gnutls_record_check_pending(session) == 0) { - n = in->check(1, 1, wait); + n = in->check(1, wait); if (n == 0) return 0; } diff --git a/common/rdr/TLSOutStream.cxx b/common/rdr/TLSOutStream.cxx index 089aa660..76f5dffe 100644 --- a/common/rdr/TLSOutStream.cxx +++ b/common/rdr/TLSOutStream.cxx @@ -93,19 +93,12 @@ void TLSOutStream::flush() out->flush(); } -size_t TLSOutStream::overrun(size_t itemSize, size_t nItems) +void TLSOutStream::overrun(size_t needed) { - if (itemSize > bufSize) - throw Exception("TLSOutStream overrun: max itemSize exceeded"); + if (needed > bufSize) + throw Exception("TLSOutStream overrun: buffer size exceeded"); flush(); - - size_t nAvail; - nAvail = avail() / itemSize; - if (nAvail < nItems) - return nAvail; - - return nItems; } size_t TLSOutStream::writeTLS(const U8* data, size_t length) diff --git a/common/rdr/TLSOutStream.h b/common/rdr/TLSOutStream.h index 71a7f3bf..9ce6eb6d 100644 --- a/common/rdr/TLSOutStream.h +++ b/common/rdr/TLSOutStream.h @@ -39,7 +39,7 @@ namespace rdr { size_t length(); protected: - size_t overrun(size_t itemSize, size_t nItems); + virtual void overrun(size_t needed); private: size_t writeTLS(const U8* data, size_t length); diff --git a/common/rdr/ZlibInStream.cxx b/common/rdr/ZlibInStream.cxx index 675600d5..2e4e080b 100644 --- a/common/rdr/ZlibInStream.cxx +++ b/common/rdr/ZlibInStream.cxx @@ -94,7 +94,7 @@ bool ZlibInStream::fillBuffer(size_t maxSize, bool wait) zs->next_out = (U8*)end; zs->avail_out = maxSize; - size_t n = underlying->check(1, 1, wait); + size_t n = underlying->check(1, wait); if (n == 0) return false; zs->next_in = (U8*)underlying->getptr(); zs->avail_in = underlying->avail(); diff --git a/common/rdr/ZlibOutStream.cxx b/common/rdr/ZlibOutStream.cxx index f102980a..78abfc49 100644 --- a/common/rdr/ZlibOutStream.cxx +++ b/common/rdr/ZlibOutStream.cxx @@ -98,18 +98,18 @@ void ZlibOutStream::flush() ptr = start; } -size_t ZlibOutStream::overrun(size_t itemSize, size_t nItems) +void ZlibOutStream::overrun(size_t needed) { #ifdef ZLIBOUT_DEBUG vlog.debug("overrun"); #endif - if (itemSize > bufSize) - throw Exception("ZlibOutStream overrun: max itemSize exceeded"); + if (needed > bufSize) + throw Exception("ZlibOutStream overrun: buffer size exceeded"); checkCompressionLevel(); - while (avail() < itemSize) { + while (avail() < needed) { zs->next_in = start; zs->avail_in = ptr - start; @@ -129,13 +129,6 @@ size_t ZlibOutStream::overrun(size_t itemSize, size_t nItems) ptr -= zs->next_in - start; } } - - size_t nAvail; - nAvail = avail() / itemSize; - if (nAvail < nItems) - return nAvail; - - return nItems; } void ZlibOutStream::deflate(int flush) diff --git a/common/rdr/ZlibOutStream.h b/common/rdr/ZlibOutStream.h index 11bb0468..aa1875c3 100644 --- a/common/rdr/ZlibOutStream.h +++ b/common/rdr/ZlibOutStream.h @@ -45,7 +45,7 @@ namespace rdr { private: - size_t overrun(size_t itemSize, size_t nItems); + virtual void overrun(size_t needed); void deflate(int flush); void checkCompressionLevel(); diff --git a/common/rfb/JpegCompressor.cxx b/common/rfb/JpegCompressor.cxx index a4af92fa..4cb35a47 100644 --- a/common/rfb/JpegCompressor.cxx +++ b/common/rfb/JpegCompressor.cxx @@ -95,7 +95,7 @@ JpegEmptyOutputBuffer(j_compress_ptr cinfo) JpegCompressor *jc = dest->instance; jc->setptr(jc->getend()); - jc->overrun(jc->getend() - jc->getstart(), 1); + jc->overrun(jc->getend() - jc->getstart()); dest->pub.next_output_byte = jc->getptr(); dest->pub.free_in_buffer = jc->avail(); diff --git a/common/rfb/JpegCompressor.h b/common/rfb/JpegCompressor.h index 8fbb7a9e..ab0f9f85 100644 --- a/common/rfb/JpegCompressor.h +++ b/common/rfb/JpegCompressor.h @@ -49,8 +49,8 @@ namespace rfb { inline rdr::U8* getstart() { return start; } - inline int overrun(int itemSize, int nItems) { - return MemOutStream::overrun(itemSize, nItems); + inline virtual void overrun(int needed) { + return MemOutStream::overrun(needed); } private: diff --git a/tests/perf/decperf.cxx b/tests/perf/decperf.cxx index 687ac7a9..e1307070 100644 --- a/tests/perf/decperf.cxx +++ b/tests/perf/decperf.cxx @@ -52,7 +52,7 @@ public: virtual void flush(); private: - virtual size_t overrun(size_t itemSize, size_t nItems); + virtual void overrun(size_t needed); int offset; rdr::U8 buf[131072]; @@ -99,12 +99,9 @@ void DummyOutStream::flush() ptr = buf; } -size_t DummyOutStream::overrun(size_t itemSize, size_t nItems) +void DummyOutStream::overrun(size_t needed) { flush(); - if (itemSize * nItems > avail()) - nItems = avail() / itemSize; - return nItems; } CConn::CConn(const char *filename) diff --git a/tests/perf/encperf.cxx b/tests/perf/encperf.cxx index 4665346f..6bcb6f74 100644 --- a/tests/perf/encperf.cxx +++ b/tests/perf/encperf.cxx @@ -76,7 +76,7 @@ public: virtual void flush(); private: - virtual size_t overrun(size_t itemSize, size_t nItems); + virtual void overrun(size_t needed); int offset; rdr::U8 buf[131072]; @@ -156,12 +156,9 @@ void DummyOutStream::flush() ptr = buf; } -size_t DummyOutStream::overrun(size_t itemSize, size_t nItems) +void DummyOutStream::overrun(size_t needed) { flush(); - if (itemSize * nItems > avail()) - nItems = avail() / itemSize; - return nItems; } CConn::CConn(const char *filename) -- 2.39.5