#include "wrap-string.hpp" #include "eng-malloc.hpp" #include "streambuffer.hpp" #include "spookyv2.hpp" #include #include int lua_writer_into_streambuffer(lua_State *L, const void* bytes, size_t sz, void* sbv) { StreamBuffer *sb = (StreamBuffer *)sbv; memcpy(sb->make_space(sz), bytes, sz); sb->wrote_space(sz); return 0; } static bool streq(const char *str, const char *data) { int len = strlen(str); return memcmp(str, data, len) == 0; } LuaDefine(unittests_streambuffer, "", "some unit tests") { // An 11-byte fixed-size stream buffer. StreamBuffer sb11(11, true); // Check the initial state. LuaAssert(L, sb11.layout_is(0, 0, 11)); // Write a few bytes. sb11.write_bytes("abcdef"); LuaAssert(L, sb11.layout_is(0, 6, 5)); // Try reading some bytes. LuaAssert(L, streq("abcd", sb11.read_bytes(4))); LuaAssert(L, sb11.layout_is(4, 2, 5)); // Put back two bytes. sb11.unread_to(2); LuaAssert(L, sb11.layout_is(2, 4, 5)); // Read some more bytes. LuaAssert(L, streq("cdef", sb11.read_bytes(4))); LuaAssert(L, sb11.layout_is(6, 0, 5)); // Reading bytes now should raise an EOF and should not alter layout try { sb11.read_bytes(1); LuaAssert(L, false && "This should have thrown an exception"); } catch (const StreamEofOnRead &) {} LuaAssert(L, sb11.layout_is(6, 0, 5)); // Write some more bytes into the stream, forcing a shift-left sb11.write_bytes("ghijkl"); LuaAssert(L, sb11.layout_is(0, 6, 5)); // Test buffer wrapping a little more. LuaAssert(L, streq("ghi", sb11.read_bytes(3))); LuaAssert(L, sb11.layout_is(3, 3, 5)); sb11.write_bytes("mnopqr"); LuaAssert(L, sb11.layout_is(0, 9, 2)); LuaAssert(L, streq("jklmnopqr", sb11.read_bytes(9))); LuaAssert(L, sb11.layout_is(9, 0, 2)); // Test 1-byte integer ops. sb11.clear(); for (int i = 0; i < 10; i++) { sb11.write_int8(i); sb11.write_int8(i+100); LuaAssert(L, sb11.read_int8() == i); LuaAssert(L, sb11.read_int8() == i+100); } // Test 2-byte integer ops. for (int i = 0; i < 10; i++) { sb11.write_int16(i); sb11.write_int16(i+10000); LuaAssert(L, sb11.read_int16() == i); LuaAssert(L, sb11.read_int16() == i+10000); } // Test 4-byte integer ops. for (int i = 0; i < 10; i++) { sb11.write_int32(i); sb11.write_int32(i+1000000); LuaAssert(L, sb11.read_int32() == i); LuaAssert(L, sb11.read_int32() == i+1000000); } // Test 8-byte integer ops. for (int i = 0; i < 10; i++) { sb11.write_int64(i + 1000000); LuaAssert(L, sb11.read_int64() == i + 1000000); } // Check the write count and read count accumulator ability. sb11.clear(); LuaAssert(L, sb11.total_writes() == 0); LuaAssert(L, sb11.total_reads() == 0); for (int i = 0; i < 10; i++) { LuaAssert(L, sb11.total_writes() == i * 8); sb11.write_int32(i); sb11.write_int32(i+1000000); LuaAssert(L, sb11.total_reads() == i * 8); LuaAssert(L, sb11.read_int32() == i); LuaAssert(L, sb11.read_int32() == i+1000000); } // Try clearing the buffer. sb11.clear(); LuaAssert(L, sb11.layout_is(0, 0, 11)); // Write a number then overwrite. for (int i = 0; i < 2; i++) { sb11.write_int16(12); sb11.write_int16(34); int64_t wc = sb11.total_writes(); sb11.write_int16(56); sb11.write_int16(78); sb11.overwrite_int16(wc, 90); LuaAssert(L, sb11.read_int16() == 12); LuaAssert(L, sb11.read_int16() == 90); LuaAssert(L, sb11.read_int16() == 56); LuaAssert(L, sb11.read_int16() == 78); } // Try compact string encoding. sb11.clear(); sb11.write_string("abc"); sb11.write_string(""); sb11.write_string("de"); LuaAssert(L, sb11.layout_is(0, 8, 3)); LuaAssert(L, sb11.read_string() == "abc"); LuaAssert(L, sb11.read_string() == ""); LuaAssert(L, sb11.read_string() == "de"); // Make sure that contents_equal is not obviously broken. StreamBuffer eqsb1, eqsb2; eqsb1.write_int32(12); eqsb1.write_int32(34); eqsb2.write_int32(34); LuaAssert(L, !eqsb1.contents_equal(&eqsb2)); eqsb1.read_int32(); LuaAssert(L, eqsb1.contents_equal(&eqsb2)); eqsb1.write_int32(34); LuaAssert(L, !eqsb1.contents_equal(&eqsb2)); return 0; }