1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 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 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
|
// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
// SPDX-License-Identifier: BSD-3-Clause
#include "vtkFileResourceStream.h"
#include "vtkMemoryResourceStream.h"
#include "vtkNew.h"
#include "vtkTestUtilities.h"
#include <vtksys/FStream.hxx>
#include <array>
#include <cstring>
#include <iostream>
#define Check(expr, message) \
do \
{ \
if (!(expr)) \
{ \
vtkErrorWithObjectMacro(nullptr, "Test failed: \n" << message); \
return false; \
} \
} while (false)
namespace
{
bool TestStream(vtkResourceStream* stream)
{
Check(!stream->EndOfStream(), "Invalid stream");
std::array<char, 5> buffer;
Check(stream->Read(buffer.data(), buffer.size()) == 5, "Read wrong size");
Check(!stream->EndOfStream(), "Reach end of file too early");
Check(std::strncmp(buffer.data(), "Hello", 5) == 0, "Read wrong data");
if (stream->SupportSeek())
{
Check(stream->Tell() == 5, "Tell wrong position");
Check(stream->Seek(2, vtkResourceStream::SeekDirection::Current) == 7, "Seek wrong position");
Check(!stream->EndOfStream(), "Seek must not modify EndOfStream value");
Check(stream->Tell() == 7, "Tell wrong position");
Check(stream->Seek(10, vtkResourceStream::SeekDirection::Current) == 17, "Seek wrong position");
Check(!stream->EndOfStream(), "Seek must not modify EndOfStream value");
Check(stream->Read(nullptr, 0) == 0, "Read wrong size");
Check(!stream->EndOfStream(), "Last zero byte read must not set EOS");
Check(stream->Seek(10, vtkResourceStream::SeekDirection::Current) == 27, "Seek wrong position");
Check(!stream->EndOfStream(), "EndOfStream must be false after Seek");
Check(stream->Read(buffer.data(), 0) == 0, "Read wrong size");
Check(!stream->EndOfStream(), "Last zero byte read must not set EOS");
Check(stream->Seek(10, vtkResourceStream::SeekDirection::Current) == 37, "Seek wrong position");
Check(!stream->EndOfStream(), "EndOfStream must be false after Seek");
Check(stream->Read(buffer.data(), buffer.size()) == 0, "Read wrong size");
Check(stream->EndOfStream(), "Last read must lead the stream to EOS");
Check(stream->Seek(2, vtkResourceStream::SeekDirection::Begin) == 2, "Seek wrong position");
Check(!stream->EndOfStream(), "EndOfStream must be false after Seek");
Check(stream->Seek(-6, vtkResourceStream::SeekDirection::End) == 6, "Seek wrong position");
Check(!stream->EndOfStream(), "EndOfStream must be false after Seek");
}
else
{
Check(!stream->EndOfStream(), "Reach end of file too early");
}
Check(stream->Read(buffer.data(), buffer.size()) == 5, "Read wrong size");
Check(!stream->EndOfStream(), "Reach end of file too early");
Check(std::strncmp(buffer.data(), "world", 5) == 0, "Read wrong data");
Check(stream->Read(buffer.data(), buffer.size()) == 1, "Read wrong size");
Check(std::strncmp(buffer.data(), "!", 1) == 0, "Read wrong data");
Check(stream->EndOfStream(), "Last read must lead the stream to EOS");
return true;
}
bool TestFileResource(const std::string& temp_dir)
{
const auto file_path = temp_dir + "/restmp.txt";
vtksys::ofstream{ file_path.c_str(), std::ios_base::binary } << "Hello world!";
vtkNew<vtkFileResourceStream> file;
if (!file->Open(file_path.c_str()))
{
return false;
}
if (file->Open(nullptr))
{
return false;
}
if (!file->Open(file_path.c_str()))
{
return false;
}
return TestStream(file);
}
bool TestMemoryResource()
{
const std::string str{ "Hello world!" };
vtkNew<vtkMemoryResourceStream> memory;
memory->SetBuffer(str.data(), str.size());
return TestStream(memory);
}
bool TestOwnedMemoryResource()
{
const std::string str{ "Hello world!" };
vtkNew<vtkMemoryResourceStream> memory;
memory->SetBuffer(str.data(), str.size(), true); // copied
Check(TestStream(memory), "Basic checks failed");
Check(memory->OwnsBuffer(), "OwnsBuffer must return true");
memory->SetBuffer(nullptr, 0);
Check(!memory->OwnsBuffer(), "OwnsBuffer must return false");
Check(memory->EndOfStream(), "EndOfStream must return true");
memory->SetBuffer(str.data(), str.size(), true); // copied
Check(memory->OwnsBuffer(), "OwnsBuffer must return true");
memory->SetBuffer(nullptr, 0, true); // must have same effect
Check(!memory->OwnsBuffer(), "OwnsBuffer must return false");
Check(memory->EndOfStream(), "EndOfStream must return true");
std::vector<char> vec{ 'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!' };
memory->SetBuffer(vec);
Check(TestStream(memory), "Basic checks failed");
Check(memory->OwnsBuffer(), "OwnsBuffer must return true");
memory->SetBuffer(std::move(vec));
Check(TestStream(memory), "Basic checks failed");
Check(memory->OwnsBuffer(), "OwnsBuffer must return true");
std::string tmpstr{ "Hello world!" };
memory->SetBuffer(tmpstr);
Check(TestStream(memory), "Basic checks failed");
Check(memory->OwnsBuffer(), "OwnsBuffer must return true");
memory->SetBuffer(std::move(tmpstr));
Check(TestStream(memory), "Basic checks failed");
Check(memory->OwnsBuffer(), "OwnsBuffer must return true");
return true;
}
}
int TestResourceStreams(int argc, char* argv[])
{
char* tempDir =
vtkTestUtilities::GetArgOrEnvOrDefault("-T", argc, argv, "VTK_TEMP_DIR", "Testing/Temporary");
if (!TestFileResource(tempDir))
{
return 1;
}
delete[] tempDir;
if (!TestMemoryResource())
{
return 1;
}
if (!TestOwnedMemoryResource())
{
return 1;
}
return 0;
}
|