summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2012-01-12 12:19:27 -0500
committerNat Goodspeed <nat@lindenlab.com>2012-01-12 12:19:27 -0500
commit39a86eda8d6d810bd7f4dd6b96f022548a496ba1 (patch)
treea2ec5e25a034443a9b5828392a1ce6e99a2ab9ef /indra/llcommon
parent61b5f3143e4ea53c9f64e5a1a5ad19f2edf3e776 (diff)
Add LLStreamQueue::size() and tests to exercise it.
Diffstat (limited to 'indra/llcommon')
-rw-r--r--indra/llcommon/llstreamqueue.h11
-rw-r--r--indra/llcommon/tests/llstreamqueue_test.cpp30
2 files changed, 36 insertions, 5 deletions
diff --git a/indra/llcommon/llstreamqueue.h b/indra/llcommon/llstreamqueue.h
index 2fbc2067d2..0726bad175 100644
--- a/indra/llcommon/llstreamqueue.h
+++ b/indra/llcommon/llstreamqueue.h
@@ -53,6 +53,7 @@ class LLGenericStreamQueue
{
public:
LLGenericStreamQueue():
+ mSize(0),
mClosed(false)
{}
@@ -134,6 +135,7 @@ public:
// we want this to scale to large data volumes, better to allocate
// individual pieces.
mBuffer.push_back(string(s, n));
+ mSize += n;
return n;
}
@@ -167,10 +169,17 @@ public:
/// at EOF we simply skip 0 characters.
std::streamsize skip(std::streamsize n);
+ /// How many characters do we currently have buffered?
+ std::streamsize size() const
+ {
+ return mSize;
+ }
+
private:
typedef std::basic_string<Ch> string;
typedef std::list<string> BufferList;
BufferList mBuffer;
+ std::streamsize mSize;
bool mClosed;
};
@@ -212,12 +221,14 @@ std::streamsize LLGenericStreamQueue<Ch>::skip(std::streamsize n)
std::streamsize chunk(bli->length());
typename BufferList::iterator zap(bli++);
mBuffer.erase(zap);
+ mSize -= chunk;
toskip -= chunk;
skipped += chunk;
}
if (bli != blend && toskip)
{
bli->erase(bli->begin(), bli->begin() + toskip);
+ mSize -= toskip;
skipped += toskip;
}
return skipped;
diff --git a/indra/llcommon/tests/llstreamqueue_test.cpp b/indra/llcommon/tests/llstreamqueue_test.cpp
index e88c37d5be..050ad5c5bf 100644
--- a/indra/llcommon/tests/llstreamqueue_test.cpp
+++ b/indra/llcommon/tests/llstreamqueue_test.cpp
@@ -50,6 +50,8 @@ namespace tut
{
set_test_name("empty LLStreamQueue");
ensure_equals("brand-new LLStreamQueue isn't empty",
+ strq.size(), 0);
+ ensure_equals("brand-new LLStreamQueue returns data",
strq.asSource().read(&buffer[0], buffer.size()), 0);
strq.asSink().close();
ensure_equals("closed empty LLStreamQueue not at EOF",
@@ -62,18 +64,22 @@ namespace tut
set_test_name("one internal block, one buffer");
LLStreamQueue::Sink sink(strq.asSink());
ensure_equals("write(\"\")", sink.write("", 0), 0);
- ensure_equals("0 write should leave LLStreamQueue empty",
+ ensure_equals("0 write should leave LLStreamQueue empty (size())",
+ strq.size(), 0);
+ ensure_equals("0 write should leave LLStreamQueue empty (peek())",
strq.peek(&buffer[0], buffer.size()), 0);
// The meaning of "atomic" is that it must be smaller than our buffer.
std::string atomic("atomic");
ensure("test data exceeds buffer", atomic.length() < buffer.size());
ensure_equals(STRINGIZE("write(\"" << atomic << "\")"),
sink.write(&atomic[0], atomic.length()), atomic.length());
+ ensure_equals("size() after write()", strq.size(), atomic.length());
size_t peeklen(strq.peek(&buffer[0], buffer.size()));
ensure_equals(STRINGIZE("peek(\"" << atomic << "\")"),
peeklen, atomic.length());
ensure_equals(STRINGIZE("peek(\"" << atomic << "\") result"),
std::string(buffer.begin(), buffer.begin() + peeklen), atomic);
+ ensure_equals("size() after peek()", strq.size(), atomic.length());
// peek() should not consume. Use a different buffer to prove it isn't
// just leftover data from the first peek().
std::vector<char> again(buffer.size());
@@ -90,6 +96,7 @@ namespace tut
ensure_equals(STRINGIZE("read(\"" << atomic << "\") result"),
std::string(third.begin(), third.begin() + readlen), atomic);
ensure_equals("peek() after read()", strq.peek(&buffer[0], buffer.size()), 0);
+ ensure_equals("size() after read()", strq.size(), 0);
}
template<> template<>
@@ -107,6 +114,7 @@ namespace tut
std::string(buffer.begin(), buffer.begin() + peeklen), lovecraft);
std::streamsize skip1(4);
ensure_equals(STRINGIZE("skip(" << skip1 << ")"), strq.skip(skip1), skip1);
+ ensure_equals("size() after skip()", strq.size(), lovecraft.length() - skip1);
size_t readlen(strq.read(&buffer[0], buffer.size()));
ensure_equals(STRINGIZE("read(\"" << lovecraft.substr(skip1) << "\")"),
readlen, lovecraft.length() - skip1);
@@ -121,15 +129,20 @@ namespace tut
{
set_test_name("skip() multiple blocks");
std::string blocks[] = { "books of ", "H.P. ", "Lovecraft" };
- std::streamsize skip(blocks[0].length() + blocks[1].length() + 4);
+ std::streamsize total(blocks[0].length() + blocks[1].length() + blocks[2].length());
+ std::streamsize leave(5); // len("craft") above
+ std::streamsize skip(total - leave);
+ std::streamsize written(0);
BOOST_FOREACH(const std::string& block, blocks)
{
- strq.write(&block[0], block.length());
+ written += strq.write(&block[0], block.length());
+ ensure_equals("size() after write()", strq.size(), written);
}
std::streamsize skiplen(strq.skip(skip));
ensure_equals(STRINGIZE("skip(" << skip << ")"), skiplen, skip);
+ ensure_equals("size() after skip()", strq.size(), leave);
size_t readlen(strq.read(&buffer[0], buffer.size()));
- ensure_equals("read(\"craft\")", readlen, 5);
+ ensure_equals("read(\"craft\")", readlen, leave);
ensure_equals("read(\"craft\") result",
std::string(buffer.begin(), buffer.begin() + readlen), "craft");
}
@@ -162,14 +175,21 @@ namespace tut
strq.write(&block[0], block.length());
}
strq.close();
+ // We've already verified what strq.size() should be at this point;
+ // see above test named "skip() multiple blocks"
+ std::streamsize chksize(strq.size());
std::streamsize readlen(strq.read(&buffer[0], buffer.size()));
ensure_equals("read() 0", readlen, buffer.size());
ensure_equals("read() 0 result", std::string(buffer.begin(), buffer.end()), "abcdefghij");
+ chksize -= readlen;
+ ensure_equals("size() after read() 0", strq.size(), chksize);
readlen = strq.read(&buffer[0], buffer.size());
ensure_equals("read() 1", readlen, buffer.size());
ensure_equals("read() 1 result", std::string(buffer.begin(), buffer.end()), "klmnopqrst");
+ chksize -= readlen;
+ ensure_equals("size() after read() 1", strq.size(), chksize);
readlen = strq.read(&buffer[0], buffer.size());
- ensure_equals("read() 2", readlen, 6);
+ ensure_equals("read() 2", readlen, chksize);
ensure_equals("read() 2 result",
std::string(buffer.begin(), buffer.begin() + readlen), "uvwxyz");
ensure_equals("read() 3", strq.read(&buffer[0], buffer.size()), -1);