Skip to content

Commit

Permalink
ARROW-8083: [GLib] Add support for Peek() to GIOInputStream
Browse files Browse the repository at this point in the history
Closes #6589 from kou/glib-gio-input-stream-peek

Authored-by: Sutou Kouhei <kou@clear-code.com>
Signed-off-by: Yosuke Shiro <yosuke.shiro615@gmail.com>
  • Loading branch information
kou authored and shiro615 committed Mar 12, 2020
1 parent 52fb3c6 commit f60c0b1
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 0 deletions.
31 changes: 31 additions & 0 deletions c_glib/arrow-glib/input-stream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,37 @@ namespace garrow {
}
}

arrow::Result<arrow::util::string_view> Peek(int64_t nbytes) override {
if (!G_IS_BUFFERED_INPUT_STREAM(input_stream_)) {
std::string message("[gio-input-stream][peek] "
"not peekable input stream: <");
message += G_OBJECT_CLASS_NAME(G_OBJECT_GET_CLASS(input_stream_));
message += ">";
return arrow::Status::NotImplemented(message);
}

auto stream = G_BUFFERED_INPUT_STREAM(input_stream_);
auto available_n_bytes = g_buffered_input_stream_get_available(stream);
if (available_n_bytes < static_cast<gsize>(nbytes)) {
GError *error = NULL;
auto filled_size =
g_buffered_input_stream_fill(stream, nbytes, NULL, &error);
if (filled_size == -1) {
return garrow_error_to_status(error,
arrow::StatusCode::IOError,
"[gio-input-stream][peek] "
"failed to fill");
}
}
gsize data_size;
auto data = g_buffered_input_stream_peek_buffer(stream, &data_size);
if (data_size > static_cast<gsize>(nbytes)) {
data_size = nbytes;
}
return arrow::util::string_view(static_cast<const char *>(data),
data_size);
}

arrow::Status Seek(int64_t position) override {
if (!G_IS_SEEKABLE(input_stream_)) {
std::string message("[gio-input-stream][seek] "
Expand Down
9 changes: 9 additions & 0 deletions c_glib/test/test-gio-input-stream.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,13 @@ def test_getter
input = Arrow::GIOInputStream.new(input_stream)
assert_equal(input_stream, input.raw)
end

def test_peek
input_stream = Gio::MemoryInputStream.new("Hello World")
buffered_input_stream = Gio::BufferedInputStream.new(input_stream)
input = Arrow::GIOInputStream.new(buffered_input_stream)
assert_equal("He", input.peek(2).to_s)
assert_equal("Hel", input.read_bytes(3).to_s)
assert_equal("lo ", input.peek(3).to_s)
end
end

0 comments on commit f60c0b1

Please sign in to comment.