| 1887 | } |
| 1888 | |
| 1889 | Status DoWrite(const void* data, int64_t nbytes, |
| 1890 | std::shared_ptr<Buffer> owned_buffer = nullptr) { |
| 1891 | if (closed_) { |
| 1892 | return Status::Invalid("Operation on closed stream"); |
| 1893 | } |
| 1894 | |
| 1895 | const int8_t* data_ptr = reinterpret_cast<const int8_t*>(data); |
| 1896 | auto advance_ptr = [&data_ptr, &nbytes](const int64_t offset) { |
| 1897 | data_ptr += offset; |
| 1898 | nbytes -= offset; |
| 1899 | }; |
| 1900 | |
| 1901 | // Handle case where we have some bytes buffered from prior calls. |
| 1902 | if (current_part_size_ > 0) { |
| 1903 | // Try to fill current buffer |
| 1904 | const int64_t to_copy = std::min(nbytes, kPartUploadSize - current_part_size_); |
| 1905 | RETURN_NOT_OK(current_part_->Write(data_ptr, to_copy)); |
| 1906 | current_part_size_ += to_copy; |
| 1907 | advance_ptr(to_copy); |
| 1908 | pos_ += to_copy; |
| 1909 | |
| 1910 | // If buffer isn't full, break |
| 1911 | if (current_part_size_ < kPartUploadSize) { |
| 1912 | return Status::OK(); |
| 1913 | } |
| 1914 | |
| 1915 | // Upload current buffer. We're only reaching this point if we have accumulated |
| 1916 | // enough data to upload. |
| 1917 | RETURN_NOT_OK(CommitCurrentPart()); |
| 1918 | } |
| 1919 | |
| 1920 | // We can upload chunks without copying them into a buffer |
| 1921 | while (nbytes >= kPartUploadSize) { |
| 1922 | RETURN_NOT_OK(UploadPart(data_ptr, kPartUploadSize)); |
| 1923 | advance_ptr(kPartUploadSize); |
| 1924 | pos_ += kPartUploadSize; |
| 1925 | } |
| 1926 | |
| 1927 | // Buffer remaining bytes |
| 1928 | if (nbytes > 0) { |
| 1929 | current_part_size_ = nbytes; |
| 1930 | ARROW_ASSIGN_OR_RAISE(current_part_, io::BufferOutputStream::Create( |
| 1931 | kPartUploadSize, io_context_.pool())); |
| 1932 | RETURN_NOT_OK(current_part_->Write(data_ptr, current_part_size_)); |
| 1933 | pos_ += current_part_size_; |
| 1934 | } |
| 1935 | |
| 1936 | return Status::OK(); |
| 1937 | } |
| 1938 | |
| 1939 | Status Flush() override { |
| 1940 | auto fut = FlushAsync(); |
nothing calls this directly
no test coverage detected