Skip to content

Commit

Permalink
apacheGH-35007: [C++] Fix reading stdin
Browse files Browse the repository at this point in the history
  • Loading branch information
resetius committed Apr 24, 2023
1 parent 5de5692 commit 00015e0
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 6 deletions.
60 changes: 60 additions & 0 deletions cpp/src/arrow/io/file_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

#include "arrow/buffer.h"
#include "arrow/io/file.h"
#include "arrow/io/stdio.h"
#include "arrow/io/interfaces.h"
#include "arrow/io/test_common.h"
#include "arrow/memory_pool.h"
Expand Down Expand Up @@ -1075,5 +1076,64 @@ TEST_F(TestMemoryMappedFile, ThreadSafety) {
ASSERT_EQ(niter * 2, correct_count);
}

// ----------------------------------------------------------------------
// Stdio tests

class TestStdio : public FileTestFixture {
public:
void CreateStdinWithData(const char* data, size_t size) {
EnsureFileDeleted();

ASSERT_OK_AND_ASSIGN(auto file, FileOutputStream::Open(path_, false));
ASSERT_OK(file->Write(data, size));
ASSERT_OK(file->Close());
cin_.reset(new std::ifstream(path_));
std::cin.rdbuf(cin_->rdbuf());
}

protected:
std::shared_ptr<std::ifstream> cin_;
};

TEST_F(TestStdio, ReadStdinReadAtOnce) {
const char data[] = "testdata";
CreateStdinWithData(data, sizeof(data));

StdinStream input;
char buffer[sizeof(data)];
ASSERT_OK_AND_ASSIGN(auto res, input.Read(sizeof(buffer), buffer));
ASSERT_EQ(sizeof(data), res);
ASSERT_EQ(0, std::memcmp(buffer, data, sizeof(data)));
ASSERT_EQ(sizeof(data), input.Tell());
}

TEST_F(TestStdio, ReadStdinReadUnalignedBuffer) {
const char data[] = "testdata";
CreateStdinWithData(data, sizeof(data));

StdinStream input;
char buffer[sizeof(data)+16];
ASSERT_OK_AND_ASSIGN(auto res, input.Read(sizeof(buffer), buffer));
ASSERT_EQ(sizeof(data), res);
ASSERT_EQ(0, std::memcmp(buffer, data, sizeof(data)));
ASSERT_EQ(sizeof(data), input.Tell());
}

TEST_F(TestStdio, ReadStdinReadAfterClose) {
const char data[] = "testdata";
CreateStdinWithData(data, sizeof(data));

StdinStream input;
char buffer[4];
ASSERT_OK_AND_ASSIGN(auto res, input.Read(sizeof(buffer), buffer));
ASSERT_EQ(sizeof(buffer), res);
ASSERT_EQ(0, std::memcmp(buffer, data, sizeof(buffer)));
ASSERT_EQ(sizeof(buffer), input.Tell());
cin_->close();
ASSERT_OK_AND_ASSIGN(res, input.Read(sizeof(buffer), buffer));
ASSERT_EQ(0, res);
ASSERT_EQ(sizeof(buffer), input.Tell());
}

} // namespace io
} // namespace arrow
9 changes: 3 additions & 6 deletions cpp/src/arrow/io/stdio.cc
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,9 @@ Result<int64_t> StdinStream::Tell() const { return pos_; }

Result<int64_t> StdinStream::Read(int64_t nbytes, void* out) {
std::cin.read(reinterpret_cast<char*>(out), nbytes);
if (std::cin) {
pos_ += nbytes;
return nbytes;
} else {
return 0;
}
nbytes = std::cin.gcount();
pos_ += nbytes;
return nbytes;
}

Result<std::shared_ptr<Buffer>> StdinStream::Read(int64_t nbytes) {
Expand Down

0 comments on commit 00015e0

Please sign in to comment.