[singlejar] Use Win32 API directly in OutputJar::AppendFile
`pread` is only used by `OutputJar::AppendFile`. Implementing `OutputJar::AppendFile` directly with Win32 API means better performance and no worry about whether `pread` polyfill follows POSIX spec correctly.
Also remove unused `pread` polyfill.
See #2241
Closes #6021.
PiperOrigin-RevId: 210714886
diff --git a/src/tools/singlejar/output_jar.cc b/src/tools/singlejar/output_jar.cc
index 9238946..52a80de 100644
--- a/src/tools/singlejar/output_jar.cc
+++ b/src/tools/singlejar/output_jar.cc
@@ -26,7 +26,14 @@
#ifndef _WIN32
#include <unistd.h>
-#endif
+#else
+
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif // WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#endif // _WIN32
#include "src/tools/singlejar/combiners.h"
#include "src/tools/singlejar/diag.h"
@@ -911,6 +918,23 @@
}
ssize_t total_written = 0;
+#ifdef _WIN32
+ HANDLE hFile = reinterpret_cast<HANDLE>(_get_osfhandle(in_fd));
+ while (static_cast<size_t>(total_written) < count) {
+ ssize_t len = std::min(kBufferSize, count - total_written);
+ DWORD n_read;
+ if (!::ReadFile(hFile, buffer.get(), len, &n_read, NULL)) {
+ return -1;
+ }
+ if (n_read == 0) {
+ break;
+ }
+ if (!WriteBytes(buffer.get(), n_read)) {
+ return -1;
+ }
+ total_written += n_read;
+ }
+#else
while (static_cast<size_t>(total_written) < count) {
size_t len = std::min(kBufferSize, count - total_written);
ssize_t n_read = pread(in_fd, buffer.get(), len, offset + total_written);
@@ -925,6 +949,7 @@
return -1;
}
}
+#endif // _WIN32
return total_written;
}
diff --git a/src/tools/singlejar/port.cc b/src/tools/singlejar/port.cc
index 3b09678..3d09134 100644
--- a/src/tools/singlejar/port.cc
+++ b/src/tools/singlejar/port.cc
@@ -12,29 +12,5 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#ifdef _WIN32
-
-#include "src/tools/singlejar/port.h"
-
-#ifndef WIN32_LEAN_AND_MEAN
-#define WIN32_LEAN_AND_MEAN
-#endif // WIN32_LEAN_AND_MEAN
-#include <windows.h>
-
-ssize_t pread(int fd, void *buf, size_t count, off64_t offset) {
- DWORD ret = -1;
- HANDLE hFile = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
- if (hFile) {
- OVERLAPPED overlap;
- memset(&overlap, 0, sizeof(OVERLAPPED));
- overlap.Offset = offset;
- if (!::ReadFile(hFile, buf, count, &ret, &overlap)) {
- // For this simple implementation, we don't update errno.
- // Just return -1 as error.
- return -1;
- }
- }
- return ret;
-}
-
-#endif // _WIN32
+// TODO(rongjiecomputer) Remove this file if it is still unused when the
+// porting work completes.
diff --git a/src/tools/singlejar/port.h b/src/tools/singlejar/port.h
index 5e01739..a8ba46c 100644
--- a/src/tools/singlejar/port.h
+++ b/src/tools/singlejar/port.h
@@ -59,10 +59,6 @@
return nullptr;
}
-// Make sure that the file HANDLE associated with |fd| is created by CreateFile
-// with FILE_FLAG_OVERLAPPED flag for this function to work.
-ssize_t pread(int fd, void* buf, size_t count, off64_t offset);
-
#endif // _WIN32
#endif // BAZEL_SRC_TOOLS_SINGLEJAR_PORT_H_