1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-04-18 21:44:02 +03:00
drrtuy 8ae5a3da40
Fix/mcol 5787 rgdata buffer max size dev (#3325)
* fix(rowgroup): RGData now uses uint64_t counter for the fixed sizes columns data buf.
	The buffer can utilize > 4GB RAM that is necessary for PM side join.
	RGData ctor uses uint32_t allocating data buffer.
 	This fact causes implicit heap overflow.

* feat(bytestream,serdes): BS buffer size type is uint64_t
	This necessary to handle 64bit RGData, that comes as
	a separate patch. The pair of patches would allow to
	have PM joins when SmallSide size > 4GB.

* feat(bytestream,serdes): Distribute BS buf size data type change to avoid implicit data type narrowing

* feat(rowgroup): this returns bits lost during cherry-pick. The bits lost caused the first RGData::serialize to crash a process
2024-11-09 19:44:02 +00:00

923 lines
19 KiB
C++

/* Copyright (C) 2024 MariaDB Corporation.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; version 2 of
the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
#include <string>
#include <stdexcept>
#include <iostream>
#include <fstream>
#include <memory>
using namespace std;
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <boost/thread.hpp>
#include <boost/scoped_ptr.hpp>
#include <cppunit/extensions/HelperMacros.h>
#include "bytestream.h"
using namespace messageqcpp;
#include "configcpp.h"
using namespace config;
#include "mcs_decimal.h"
class ByteStreamTestSuite : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE(ByteStreamTestSuite);
CPPUNIT_TEST(bs_1);
CPPUNIT_TEST(bs_1_1);
CPPUNIT_TEST(bs_1_2);
CPPUNIT_TEST(bs_2);
CPPUNIT_TEST(bs_3);
CPPUNIT_TEST(bs_4);
CPPUNIT_TEST_EXCEPTION(bs_5_1, std::underflow_error);
CPPUNIT_TEST_EXCEPTION(bs_5_2, std::underflow_error);
CPPUNIT_TEST_EXCEPTION(bs_5_3, std::underflow_error);
CPPUNIT_TEST_EXCEPTION(bs_5_4, std::underflow_error);
CPPUNIT_TEST_EXCEPTION(bs_5_5, std::underflow_error);
CPPUNIT_TEST_EXCEPTION(bs_5_6, std::underflow_error);
CPPUNIT_TEST(bs_6);
CPPUNIT_TEST(bs_7);
CPPUNIT_TEST(bs_8);
CPPUNIT_TEST_EXCEPTION(bs_9, std::underflow_error);
CPPUNIT_TEST(bs_10);
CPPUNIT_TEST(bs_12);
CPPUNIT_TEST(bs_13);
CPPUNIT_TEST(bs_14);
CPPUNIT_TEST(bs_15);
CPPUNIT_TEST(bs_16);
CPPUNIT_TEST_SUITE_END();
private:
ByteStream::byte b;
ByteStream::doublebyte d;
ByteStream::quadbyte q;
ByteStream::octbyte o;
uint8_t u8;
uint16_t u16;
uint32_t u32;
uint64_t u64;
uint128_t u128;
int8_t i8;
int16_t i16;
int32_t i32;
int64_t i64;
int128_t i128;
ByteStream bs;
ByteStream bs1;
ByteStream::byte* bap;
ByteStream::byte* bap1;
int len;
public:
void setUp()
{
bs.reset();
bs1.reset();
bap = 0;
bap1 = 0;
}
void tearDown()
{
bs.reset();
bs1.reset();
delete[] bap;
bap = 0;
delete[] bap1;
bap1 = 0;
}
void bs_1()
{
bs.reset();
o = 0xdeadbeefbadc0ffeLL;
bs << o;
CPPUNIT_ASSERT(bs.length() == 8);
o = 0;
bs >> o;
CPPUNIT_ASSERT(o == 0xdeadbeefbadc0ffeLL);
CPPUNIT_ASSERT(bs.length() == 0);
q = 0xdeadbeef;
bs << q;
CPPUNIT_ASSERT(bs.length() == 4);
q = 0;
bs >> q;
CPPUNIT_ASSERT(q == 0xdeadbeef);
CPPUNIT_ASSERT(bs.length() == 0);
d = 0xf00f;
bs << d;
CPPUNIT_ASSERT(bs.length() == 2);
d = 0;
bs >> d;
CPPUNIT_ASSERT(d == 0xf00f);
CPPUNIT_ASSERT(bs.length() == 0);
b = 0x0f;
bs << b;
CPPUNIT_ASSERT(bs.length() == 1);
b = 0;
bs >> b;
CPPUNIT_ASSERT(b == 0x0f);
CPPUNIT_ASSERT(bs.length() == 0);
o = 0xdeadbeefbadc0ffeLL;
bs << o;
CPPUNIT_ASSERT(bs.length() == 8);
o = 0;
q = 0xdeadbeef;
bs << q;
CPPUNIT_ASSERT(bs.length() == 12);
q = 0;
d = 0xf00f;
bs << d;
CPPUNIT_ASSERT(bs.length() == 14);
d = 0;
b = 0x0f;
bs << b;
CPPUNIT_ASSERT(bs.length() == 15);
b = 0;
bs >> o;
CPPUNIT_ASSERT(o == 0xdeadbeefbadc0ffeLL);
CPPUNIT_ASSERT(bs.length() == 7);
bs >> q;
CPPUNIT_ASSERT(q == 0xdeadbeef);
CPPUNIT_ASSERT(bs.length() == 3);
bs >> d;
CPPUNIT_ASSERT(d == 0xf00f);
CPPUNIT_ASSERT(bs.length() == 1);
bs >> b;
CPPUNIT_ASSERT(b == 0x0f);
CPPUNIT_ASSERT(bs.length() == 0);
}
void bs_1_1()
{
bs.reset();
o = 0xdeadbeefbadc0ffeLL;
bs << o;
CPPUNIT_ASSERT(bs.length() == 8);
o = 0;
q = 0xdeadbeef;
bs << q;
CPPUNIT_ASSERT(bs.length() == 12);
q = 0;
d = 0xf00f;
bs << d;
CPPUNIT_ASSERT(bs.length() == 14);
d = 0;
b = 0x0f;
bs << b;
CPPUNIT_ASSERT(bs.length() == 15);
b = 0;
ByteStream bbs1;
bbs1 << bs;
CPPUNIT_ASSERT(bbs1.length() == bs.length() + sizeof(messageqcpp::BSSizeType));
bs.reset();
bbs1 >> bs;
CPPUNIT_ASSERT(bbs1.length() == 0);
CPPUNIT_ASSERT(bs.length() == 15);
bs >> o;
CPPUNIT_ASSERT(o == 0xdeadbeefbadc0ffeLL);
CPPUNIT_ASSERT(bs.length() == 7);
bs >> q;
CPPUNIT_ASSERT(q == 0xdeadbeef);
CPPUNIT_ASSERT(bs.length() == 3);
bs >> d;
CPPUNIT_ASSERT(d == 0xf00f);
CPPUNIT_ASSERT(bs.length() == 1);
bs >> b;
CPPUNIT_ASSERT(b == 0x0f);
CPPUNIT_ASSERT(bs.length() == 0);
}
void bs_1_2()
{
bs.reset();
i64 = -2401053089477160962;
bs << i64;
CPPUNIT_ASSERT(bs.length() == 8);
i64 = 0;
i32 = -559038737;
bs << i32;
CPPUNIT_ASSERT(bs.length() == 12);
i32 = 0;
i16 = -4081;
bs << i16;
CPPUNIT_ASSERT(bs.length() == 14);
i16 = 0;
i8 = 15;
bs << i8;
CPPUNIT_ASSERT(bs.length() == 15);
i8 = 0;
bs >> i64;
CPPUNIT_ASSERT(i64 == -2401053089477160962);
CPPUNIT_ASSERT(bs.length() == 7);
bs >> i32;
CPPUNIT_ASSERT(i32 == -559038737);
CPPUNIT_ASSERT(bs.length() == 3);
bs >> i16;
CPPUNIT_ASSERT(i16 == -4081);
CPPUNIT_ASSERT(bs.length() == 1);
bs >> i8;
CPPUNIT_ASSERT(i8 == 15);
CPPUNIT_ASSERT(bs.length() == 0);
}
void bs_2()
{
int i;
bs.reset();
srand(time(0));
for (i = 0; i < 10240; i++)
{
bs << (uint32_t)rand();
}
bs1 = bs;
uint32_t q1;
for (i = 0; i < 10240; i++)
{
bs >> u32;
bs1 >> q1;
CPPUNIT_ASSERT(u32 == q1);
}
bs.reset();
bs1.reset();
}
void bs_3()
{
uint8_t ba[1024] = {
0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
};
bs.load(ba, 8);
CPPUNIT_ASSERT(bs.length() == 8);
bs >> u8;
CPPUNIT_ASSERT(u8 == 0x12);
bs >> u16;
CPPUNIT_ASSERT(u16 == 0x5634);
bs >> u32;
CPPUNIT_ASSERT(u32 == 0xdebc9a78);
CPPUNIT_ASSERT(bs.length() == 1);
bs.reset();
CPPUNIT_ASSERT(bs.length() == 0);
bs.load(ba, 8);
len = bs.length();
CPPUNIT_ASSERT(len == 8);
bap = new ByteStream::byte[len];
// bs >> bap;
memcpy(bap, bs.buf(), len);
CPPUNIT_ASSERT(memcmp(ba, bap, len) == 0);
delete[] bap;
bap = 0;
bs.reset();
for (u32 = 0; u32 < 20480; u32++)
{
bs << u32;
}
len = bs.length();
CPPUNIT_ASSERT(len == (20480 * sizeof(u32)));
bap = new ByteStream::byte[len];
// bs >> bap;
memcpy(bap, bs.buf(), len);
bs.reset();
for (u32 = 0; u32 < 20480; u32++)
{
bs << u32;
}
len = bs.length();
CPPUNIT_ASSERT(len == (20480 * sizeof(q)));
bap1 = new ByteStream::byte[len];
// bs >> bap1;
memcpy(bap1, bs.buf(), len);
CPPUNIT_ASSERT(memcmp(bap1, bap, len) == 0);
delete[] bap;
bap = 0;
delete[] bap1;
bap1 = 0;
bs.reset();
}
void bs_4()
{
for (i32 = 0; i32 < 20480; i32++)
{
bs << i32;
}
ByteStream bs2(bs);
len = bs2.length();
CPPUNIT_ASSERT(len == (20480 * sizeof(i32)));
bap = new ByteStream::byte[len];
// bs2 >> bap;
memcpy(bap, bs2.buf(), len);
bs1 = bs2;
len = bs1.length();
CPPUNIT_ASSERT(len == (20480 * sizeof(i32)));
bap1 = new ByteStream::byte[len];
// bs1 >> bap1;
memcpy(bap1, bs1.buf(), len);
CPPUNIT_ASSERT(memcmp(bap1, bap, len) == 0);
delete[] bap;
bap = 0;
delete[] bap1;
bap1 = 0;
bs.reset();
bs1.reset();
bs2.reset();
}
void bs_5_1()
{
bs.reset();
u8 = 0x0f;
bs << u8;
for (;;)
bs >> u32;
}
void bs_5_2()
{
bs.reset();
u8 = 0x0f;
bs << u8;
for (;;)
bs >> u16;
}
void bs_5_3()
{
bs.reset();
u8 = 0x0f;
bs << u8;
for (;;)
bs >> u8;
}
void bs_5_4()
{
bs.reset();
i8 = 0x0f;
bs << i8;
for (;;)
bs >> i32;
}
void bs_5_5()
{
bs.reset();
i8 = 0x0f;
bs << i8;
for (;;)
bs >> i16;
}
void bs_5_6()
{
bs.reset();
i8 = 0x0f;
bs << i8;
for (;;)
bs >> i8;
}
void bs_6()
{
u8 = 0x1a;
bs << u8;
u8 = 0x2b;
bs << u8;
u8 = 0x3c;
bs << u8;
bs >> u8;
CPPUNIT_ASSERT(u8 == 0x1a);
bs >> u8;
CPPUNIT_ASSERT(u8 == 0x2b);
bs >> u8;
CPPUNIT_ASSERT(u8 == 0x3c);
bs.reset();
u8 = 12;
bs << u8;
u8 = 3;
bs << u8;
u8 = 0;
bs << u8;
u8 = 2;
bs << u8;
ByteStream bs3(bs);
bs3 >> u8;
CPPUNIT_ASSERT(u8 == 12);
bs3 >> u8;
CPPUNIT_ASSERT(u8 == 3);
bs3 >> u8;
CPPUNIT_ASSERT(u8 == 0);
bs3 >> u8;
CPPUNIT_ASSERT(u8 == 2);
}
void bs_7()
{
size_t i;
bs.reset();
bap = new ByteStream::byte[ByteStream::BlockSize * 2];
ByteStream::byte* bapp;
for (bapp = &bap[0], i = 0; i < ByteStream::BlockSize; bapp++, i++)
*bapp = 0xa5;
bs.append(bap, ByteStream::BlockSize);
CPPUNIT_ASSERT(bs.length() == (ByteStream::BlockSize * 1));
for (bapp = &bap[0], i = 0; i < ByteStream::BlockSize; bapp++, i++)
*bapp = 0x5a;
bs.append(bap, ByteStream::BlockSize);
CPPUNIT_ASSERT(bs.length() == (ByteStream::BlockSize * 2));
for (bapp = &bap[0], i = 0; i < ByteStream::BlockSize * 2; bapp++, i++)
*bapp = 0x55;
bs.append(bap, ByteStream::BlockSize * 2);
CPPUNIT_ASSERT(bs.length() == (ByteStream::BlockSize * 4));
delete[] bap;
bap = new ByteStream::byte[bs.length()];
// bs >> bap;
memcpy(bap, bs.buf(), bs.length());
bap1 = new ByteStream::byte[bs.length()];
for (bapp = &bap1[0], i = 0; i < ByteStream::BlockSize; bapp++, i++)
*bapp = 0xa5;
for (i = 0; i < ByteStream::BlockSize; bapp++, i++)
*bapp = 0x5a;
for (i = 0; i < ByteStream::BlockSize * 2; bapp++, i++)
*bapp = 0x55;
CPPUNIT_ASSERT(memcmp(bap, bap1, bs.length()) == 0);
delete[] bap;
bap = 0;
delete[] bap1;
bap1 = 0;
}
std::string getString()
{
static const std::string s(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore "
"et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut "
"aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse "
"cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in "
"culpa qui officia deserunt mollit anim id est laborum.");
return s;
}
void bs_8()
{
bs.reset();
string s;
s = "This is a test";
bs << s;
string s1;
bs >> s1;
CPPUNIT_ASSERT(s == s1);
CPPUNIT_ASSERT(bs.length() == 0);
bs.reset();
s = getString();
bs << s;
bs >> s1;
CPPUNIT_ASSERT(s == s1);
CPPUNIT_ASSERT(bs.length() == 0);
u8 = 0xa5;
bs << u8;
u16 = 0x5aa5;
bs << u16;
u32 = 0xdeadbeef;
bs << u32;
bs << s;
s += s1;
bs << s;
s += s1;
bs << s;
bs << u32;
bs << u16;
bs << u8;
bs >> u8;
CPPUNIT_ASSERT(u8 == 0xa5);
bs >> u16;
CPPUNIT_ASSERT(u16 == 0x5aa5);
bs >> u32;
CPPUNIT_ASSERT(u32 == 0xdeadbeef);
bs >> s;
CPPUNIT_ASSERT(s == s1);
CPPUNIT_ASSERT(s.length() == (s1.length() * 1));
bs >> s;
CPPUNIT_ASSERT(s.length() == (s1.length() * 2));
bs >> s;
CPPUNIT_ASSERT(s.length() == (s1.length() * 3));
bs >> u32;
CPPUNIT_ASSERT(u32 == 0xdeadbeef);
bs >> u16;
CPPUNIT_ASSERT(u16 == 0x5aa5);
bs >> u8;
CPPUNIT_ASSERT(u8 == 0xa5);
CPPUNIT_ASSERT(bs.length() == 0);
}
void bs_9()
{
bs.reset();
// Load up a bogus string (too short)
u32 = 100;
bs << u32;
bs.append(reinterpret_cast<const ByteStream::byte*>("This is a test"), 14);
string s;
// Should throw underflow
bs >> s;
}
void bs_10()
{
bs.reset();
bs1.reset();
u32 = 0xdeadbeef;
bs << u32;
CPPUNIT_ASSERT(bs.length() == 4);
CPPUNIT_ASSERT(bs1.length() == 0);
bs.swap(bs1);
CPPUNIT_ASSERT(bs1.length() == 4);
CPPUNIT_ASSERT(bs.length() == 0);
bs1 >> u32;
CPPUNIT_ASSERT(u32 == 0xdeadbeef);
bs.reset();
bs1.reset();
u32 = 0xdeadbeef;
bs << u32;
bs1 << u32;
bs += bs1;
CPPUNIT_ASSERT(bs.length() == 8);
bs >> u32;
CPPUNIT_ASSERT(u32 == 0xdeadbeef);
bs >> u32;
CPPUNIT_ASSERT(u32 == 0xdeadbeef);
bs.reset();
bs1.reset();
ByteStream bs2;
u32 = 0xdeadbeef;
bs1 << u32;
bs2 << u32;
bs = bs1 + bs2;
CPPUNIT_ASSERT(bs.length() == 8);
bs >> u32;
CPPUNIT_ASSERT(u32 == 0xdeadbeef);
bs >> u32;
CPPUNIT_ASSERT(u32 == 0xdeadbeef);
}
void bs_12()
{
bs.reset();
i128 = 10 * 100000000000000000000000000000000000000_xxl;
bs << i128;
CPPUNIT_ASSERT(bs.length() == 16);
i128 = 0;
bs >> i128;
CPPUNIT_ASSERT(i128 == static_cast<int128_t>(10 * 100000000000000000000000000000000000000_xxl));
CPPUNIT_ASSERT(bs.length() == 0);
u128 = 10 * 100000000000000000000000000000000000000_xxl;
bs << u128;
CPPUNIT_ASSERT(bs.length() == 16);
u128 = 0;
bs >> u128;
CPPUNIT_ASSERT(u128 == 10 * 100000000000000000000000000000000000000_xxl);
CPPUNIT_ASSERT(bs.length() == 0);
u64 = 0xdeadbeefbadc0ffeLL;
bs << u64;
CPPUNIT_ASSERT(bs.length() == 8);
u64 = 0;
bs.peek(u64);
CPPUNIT_ASSERT(u64 == 0xdeadbeefbadc0ffeLL);
CPPUNIT_ASSERT(bs.length() == 8);
u64 = 0;
bs >> u64;
CPPUNIT_ASSERT(u64 == 0xdeadbeefbadc0ffeLL);
CPPUNIT_ASSERT(bs.length() == 0);
u16 = 0xf00f;
bs << u16;
CPPUNIT_ASSERT(bs.length() == 2);
u16 = 0;
bs.peek(u16);
CPPUNIT_ASSERT(u16 == 0xf00f);
CPPUNIT_ASSERT(bs.length() == 2);
u16 = 0;
bs >> u16;
CPPUNIT_ASSERT(u16 == 0xf00f);
CPPUNIT_ASSERT(bs.length() == 0);
u8 = 0x0f;
bs << u8;
CPPUNIT_ASSERT(bs.length() == 1);
u8 = 0;
bs.peek(u8);
CPPUNIT_ASSERT(u8 == 0x0f);
CPPUNIT_ASSERT(bs.length() == 1);
u8 = 0;
bs >> u8;
CPPUNIT_ASSERT(u8 == 0x0f);
CPPUNIT_ASSERT(bs.length() == 0);
u32 = 0xdeadbeef;
bs << u32;
CPPUNIT_ASSERT(bs.length() == 4);
u32 = 0;
u16 = 0xf00f;
bs << u16;
CPPUNIT_ASSERT(bs.length() == 6);
u16 = 0;
u8 = 0x0f;
bs << u8;
CPPUNIT_ASSERT(bs.length() == 7);
u8 = 0;
bs.peek(u32);
CPPUNIT_ASSERT(u32 == 0xdeadbeef);
CPPUNIT_ASSERT(bs.length() == 7);
u32 = 0;
bs >> u32;
CPPUNIT_ASSERT(u32 == 0xdeadbeef);
CPPUNIT_ASSERT(bs.length() == 3);
u16 = 0;
bs.peek(u16);
CPPUNIT_ASSERT(u16 == 0xf00f);
CPPUNIT_ASSERT(bs.length() == 3);
u16 = 0;
bs >> u16;
CPPUNIT_ASSERT(u16 == 0xf00f);
CPPUNIT_ASSERT(bs.length() == 1);
u8 = 0;
bs.peek(u8);
CPPUNIT_ASSERT(u8 == 0x0f);
CPPUNIT_ASSERT(bs.length() == 1);
u8 = 0;
bs >> u8;
CPPUNIT_ASSERT(u8 == 0x0f);
CPPUNIT_ASSERT(bs.length() == 0);
string s;
s = "This is a test";
bs << s;
string s1;
bs.peek(s1);
CPPUNIT_ASSERT(s == s1);
CPPUNIT_ASSERT(bs.length() == s1.size() + 4);
CPPUNIT_ASSERT(!s1.empty());
string s2;
bs >> s2;
CPPUNIT_ASSERT(s == s2);
CPPUNIT_ASSERT(bs.length() == 0);
}
void bs_13()
{
bs.reset();
std::string s = getString();
bs << s;
ofstream of("bs_13.dat");
of << bs;
of.close();
ifstream ifs;
ifs.open("./bs_13.dat");
ifs.seekg(0, ios::end);
size_t ifs_len1 = ifs.tellg();
// will be longer than orig file because string length is encoded into stream
CPPUNIT_ASSERT((s.size() + sizeof(ByteStream::quadbyte)) == ifs_len1);
ifs.seekg(0, ios::beg);
std::unique_ptr<char[]> buf1(new char[ifs_len1]);
bs1.reset();
ifs >> bs1;
ifs.close();
CPPUNIT_ASSERT(bs.length() == bs1.length());
string s1;
bs1 >> s1;
CPPUNIT_ASSERT(s == s1);
}
void bs_14()
{
ByteStream bs1(0);
ByteStream bs2(bs1);
CPPUNIT_ASSERT(bs2.fBuf == 0);
ByteStream bs3(0);
bs3 = bs1;
CPPUNIT_ASSERT(bs3.fBuf == 0);
}
void bs_15()
{
ByteStream b1, b2, empty;
uint8_t u8;
CPPUNIT_ASSERT(b1 == b2);
CPPUNIT_ASSERT(b2 == b1);
CPPUNIT_ASSERT(b2 == empty);
CPPUNIT_ASSERT(b1 == empty);
CPPUNIT_ASSERT(!(b1 != b2));
CPPUNIT_ASSERT(!(b2 != b1));
CPPUNIT_ASSERT(!(b2 != empty));
CPPUNIT_ASSERT(!(b1 != empty));
b1 << "Woo hoo";
CPPUNIT_ASSERT(b1 != b2);
CPPUNIT_ASSERT(b2 != b1);
CPPUNIT_ASSERT(b1 != empty);
CPPUNIT_ASSERT(!(b1 == b2));
CPPUNIT_ASSERT(!(b2 == b1));
CPPUNIT_ASSERT(!(b1 == empty));
b2 << "Woo hoo";
CPPUNIT_ASSERT(b1 == b2);
CPPUNIT_ASSERT(b2 == b1);
CPPUNIT_ASSERT(!(b1 != b2));
CPPUNIT_ASSERT(!(b2 != b1));
b1 >> u8;
CPPUNIT_ASSERT(b1 != b2);
CPPUNIT_ASSERT(b2 != b1);
CPPUNIT_ASSERT(!(b1 == b2));
CPPUNIT_ASSERT(!(b2 == b1));
b1 << u8;
CPPUNIT_ASSERT(b1 != b2);
CPPUNIT_ASSERT(b2 != b1);
CPPUNIT_ASSERT(!(b1 == b2));
CPPUNIT_ASSERT(!(b2 == b1));
b2 >> u8;
b2 << u8;
CPPUNIT_ASSERT(b1 == b2);
CPPUNIT_ASSERT(b2 == b1);
CPPUNIT_ASSERT(!(b1 != b2));
CPPUNIT_ASSERT(!(b2 != b1));
}
void bs_16()
{
int i;
uint32_t len;
bs.reset();
srand(time(0));
for (i = 0; i < 10240; i++)
{
bs << (ByteStream::quadbyte)rand();
}
std::unique_ptr<ByteStream::byte[]> bp(new ByteStream::byte[bs.length()]);
ByteStream::byte* bpp = bp.get();
std::unique_ptr<ByteStream::byte[]> bp1(new ByteStream::byte[bs.length()]);
ByteStream::byte* bpp1 = bp1.get();
len = bs.length();
CPPUNIT_ASSERT(len == 10240 * 4);
bs.peek(bpp);
CPPUNIT_ASSERT(bs.length() == len);
CPPUNIT_ASSERT(memcmp(bpp, bs.buf(), len) == 0);
bs >> bpp1;
CPPUNIT_ASSERT(bs.length() == 0);
CPPUNIT_ASSERT(memcmp(bpp, bpp1, len) == 0);
bs.reset();
}
};
#define TS_NS(x) (x)
#define TS_US(x) ((x) * 1000)
#define TS_MS(x) ((x) * 1000000)
CPPUNIT_TEST_SUITE_REGISTRATION(ByteStreamTestSuite);
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/ui/text/TestRunner.h>
#include <csignal>
void setupSignalHandlers()
{
struct sigaction ign;
memset(&ign, 0, sizeof(ign));
ign.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &ign, 0);
}
int main(int argc, char** argv)
{
setupSignalHandlers();
CppUnit::TextUi::TestRunner runner;
CppUnit::TestFactoryRegistry& registry = CppUnit::TestFactoryRegistry::getRegistry();
runner.addTest(registry.makeTest());
bool wasSuccessful = runner.run("", false);
return (wasSuccessful ? 0 : 1);
}