test_rewind.cxx 4.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*
 * Unit tests for class RewindInputStream.
 */

#include "config.h"
#include "input/plugins/RewindInputPlugin.hxx"
#include "input/InputStream.hxx"
#include "thread/Mutex.hxx"
#include "thread/Cond.hxx"

#include <cppunit/TestFixture.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/ui/text/TestRunner.h>
#include <cppunit/extensions/HelperMacros.h>

#include <string>

#include <string.h>
19
#include <stdlib.h>
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38

class StringInputStream final : public InputStream {
	const char *data;
	size_t remaining;

public:
	StringInputStream(const char *_uri,
			  Mutex &_mutex, Cond &_cond,
			  const char *_data)
		:InputStream(_uri, _mutex, _cond),
		 data(_data), remaining(strlen(data)) {
		SetReady();
	}

	/* virtual methods from InputStream */
	bool IsEOF() override {
		return remaining == 0;
	}

39
	size_t Read(void *ptr, size_t read_size) override {
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
		size_t nbytes = std::min(remaining, read_size);
		memcpy(ptr, data, nbytes);
		data += nbytes;
		remaining -= nbytes;
		offset += nbytes;
		return nbytes;
	}
};

class RewindTest : public CppUnit::TestFixture {
	CPPUNIT_TEST_SUITE(RewindTest);
	CPPUNIT_TEST(TestRewind);
	CPPUNIT_TEST_SUITE_END();

public:
	void TestRewind() {
		Mutex mutex;
		Cond cond;

		StringInputStream *sis =
			new StringInputStream("foo://", mutex, cond,
					      "foo bar");
		CPPUNIT_ASSERT(sis->IsReady());

		InputStream *ris = input_rewind_open(sis);
		CPPUNIT_ASSERT(ris != sis);
		CPPUNIT_ASSERT(ris != nullptr);

		const ScopeLock protect(mutex);

		ris->Update();
		CPPUNIT_ASSERT(ris->IsReady());
		CPPUNIT_ASSERT(!ris->KnownSize());
73
		CPPUNIT_ASSERT_EQUAL(offset_type(0), ris->GetOffset());
74 75

		char buffer[16];
76
		size_t nbytes = ris->Read(buffer, 2);
77 78 79
		CPPUNIT_ASSERT_EQUAL(size_t(2), nbytes);
		CPPUNIT_ASSERT_EQUAL('f', buffer[0]);
		CPPUNIT_ASSERT_EQUAL('o', buffer[1]);
80
		CPPUNIT_ASSERT_EQUAL(offset_type(2), ris->GetOffset());
81 82
		CPPUNIT_ASSERT(!ris->IsEOF());

83
		nbytes = ris->Read(buffer, 2);
84 85 86
		CPPUNIT_ASSERT_EQUAL(size_t(2), nbytes);
		CPPUNIT_ASSERT_EQUAL('o', buffer[0]);
		CPPUNIT_ASSERT_EQUAL(' ', buffer[1]);
87
		CPPUNIT_ASSERT_EQUAL(offset_type(4), ris->GetOffset());
88 89
		CPPUNIT_ASSERT(!ris->IsEOF());

90
		ris->Seek(1);
91
		CPPUNIT_ASSERT_EQUAL(offset_type(1), ris->GetOffset());
92 93
		CPPUNIT_ASSERT(!ris->IsEOF());

94
		nbytes = ris->Read(buffer, 2);
95 96 97
		CPPUNIT_ASSERT_EQUAL(size_t(2), nbytes);
		CPPUNIT_ASSERT_EQUAL('o', buffer[0]);
		CPPUNIT_ASSERT_EQUAL('o', buffer[1]);
98
		CPPUNIT_ASSERT_EQUAL(offset_type(3), ris->GetOffset());
99 100
		CPPUNIT_ASSERT(!ris->IsEOF());

101
		ris->Seek(0);
102
		CPPUNIT_ASSERT_EQUAL(offset_type(0), ris->GetOffset());
103 104
		CPPUNIT_ASSERT(!ris->IsEOF());

105
		nbytes = ris->Read(buffer, 2);
106 107 108
		CPPUNIT_ASSERT_EQUAL(size_t(2), nbytes);
		CPPUNIT_ASSERT_EQUAL('f', buffer[0]);
		CPPUNIT_ASSERT_EQUAL('o', buffer[1]);
109
		CPPUNIT_ASSERT_EQUAL(offset_type(2), ris->GetOffset());
110 111
		CPPUNIT_ASSERT(!ris->IsEOF());

112
		nbytes = ris->Read(buffer, sizeof(buffer));
113 114 115
		CPPUNIT_ASSERT_EQUAL(size_t(2), nbytes);
		CPPUNIT_ASSERT_EQUAL('o', buffer[0]);
		CPPUNIT_ASSERT_EQUAL(' ', buffer[1]);
116
		CPPUNIT_ASSERT_EQUAL(offset_type(4), ris->GetOffset());
117 118
		CPPUNIT_ASSERT(!ris->IsEOF());

119
		nbytes = ris->Read(buffer, sizeof(buffer));
120 121 122 123
		CPPUNIT_ASSERT_EQUAL(size_t(3), nbytes);
		CPPUNIT_ASSERT_EQUAL('b', buffer[0]);
		CPPUNIT_ASSERT_EQUAL('a', buffer[1]);
		CPPUNIT_ASSERT_EQUAL('r', buffer[2]);
124
		CPPUNIT_ASSERT_EQUAL(offset_type(7), ris->GetOffset());
125 126
		CPPUNIT_ASSERT(ris->IsEOF());

127
		ris->Seek(3);
128
		CPPUNIT_ASSERT_EQUAL(offset_type(3), ris->GetOffset());
129 130
		CPPUNIT_ASSERT(!ris->IsEOF());

131
		nbytes = ris->Read(buffer, sizeof(buffer));
132 133 134 135 136
		CPPUNIT_ASSERT_EQUAL(size_t(4), nbytes);
		CPPUNIT_ASSERT_EQUAL(' ', buffer[0]);
		CPPUNIT_ASSERT_EQUAL('b', buffer[1]);
		CPPUNIT_ASSERT_EQUAL('a', buffer[2]);
		CPPUNIT_ASSERT_EQUAL('r', buffer[3]);
137
		CPPUNIT_ASSERT_EQUAL(offset_type(7), ris->GetOffset());
138 139 140 141 142 143 144 145 146 147 148 149 150 151
		CPPUNIT_ASSERT(ris->IsEOF());
	}
};

CPPUNIT_TEST_SUITE_REGISTRATION(RewindTest);

int
main(gcc_unused int argc, gcc_unused char **argv)
{
	CppUnit::TextUi::TestRunner runner;
	auto &registry = CppUnit::TestFactoryRegistry::getRegistry();
	runner.addTest(registry.makeTest());
	return runner.run() ? EXIT_SUCCESS : EXIT_FAILURE;
}