File tree Expand file tree Collapse file tree 6 files changed +40
-22
lines changed
Expand file tree Collapse file tree 6 files changed +40
-22
lines changed Original file line number Diff line number Diff line change @@ -30,12 +30,15 @@ enum class PlanFileFormat {
3030 * amount of memory that it consumed on disk.
3131 *
3232 * \param input_filename The filename containing the plan to convert.
33+ * \param force_binary If true, the plan will be opened as a binary file.
34+ * Required on Windows to avoid text mode line-ending translation.
3335 * \return If loading was successful, returns a plan. If loading was not
3436 * successful this is a status containing a list of parse errors in the status's
3537 * message.
3638 */
3739absl::StatusOr<::substrait::proto::Plan> loadPlan (
38- std::string_view input_filename);
40+ std::string_view input_filename,
41+ bool force_binary = false );
3942
4043/*
4144 * \brief Writes the provided plan to disk.
Original file line number Diff line number Diff line change @@ -37,8 +37,10 @@ PlanFileFormat detectFormat(std::string_view content) {
3737} // namespace
3838
3939absl::StatusOr<::substrait::proto::Plan> loadPlan (
40- std::string_view input_filename) {
41- auto contentOrError = textplan::readFromFile (input_filename.data ());
40+ std::string_view input_filename,
41+ bool forceBinary) {
42+ auto contentOrError =
43+ textplan::readFromFile (input_filename.data (), forceBinary);
4244 if (!contentOrError.ok ()) {
4345 return contentOrError.status ();
4446 }
Original file line number Diff line number Diff line change @@ -52,7 +52,8 @@ class SaveAndLoadTestFixture : public ::testing::TestWithParam<PlanFileFormat> {
5252 std::filesystem::path (" my_temp_dir" ))
5353 .string ();
5454
55- if (!std::filesystem::create_directory (testFileDirectory_)) {
55+ std::filesystem::create_directory (testFileDirectory_);
56+ if (!std::filesystem::exists (testFileDirectory_)) {
5657 ASSERT_TRUE (false ) << " Failed to create temporary directory." ;
5758 testFileDirectory_.clear ();
5859 }
@@ -87,7 +88,15 @@ TEST_P(SaveAndLoadTestFixture, SaveAndLoad) {
8788 auto status = ::io::substrait::savePlan (plan, tempFilename, encoding);
8889 ASSERT_TRUE (status.ok ()) << " Save failed.\n " << status;
8990
91+ #ifdef _WIN32
92+ // Windows cannot rely on io::substrait::loadPlan to detect the file format,
93+ // since it needs to a-priori specify how the file should be loaded.
94+ bool forceBinary = encoding == PlanFileFormat::kBinary ;
95+ auto result = ::io::substrait::loadPlan (tempFilename, forceBinary);
96+ #else
9097 auto result = ::io::substrait::loadPlan (tempFilename);
98+ #endif
99+
91100 ASSERT_TRUE (result.ok ()) << " Load failed.\n " << result.status ();
92101 ASSERT_THAT (
93102 *result,
Original file line number Diff line number Diff line change @@ -42,17 +42,24 @@ class StringErrorCollector : public google::protobuf::io::ErrorCollector {
4242
4343} // namespace
4444
45- absl::StatusOr<std::string> readFromFile (std::string_view msgPath) {
46- std::ifstream textFile (std::string{msgPath});
47- if (textFile.fail ()) {
45+ absl::StatusOr<std::string> readFromFile (
46+ std::string_view msgPath,
47+ bool forceBinary) {
48+ std::ifstream file;
49+ if (forceBinary)
50+ file.open (std::string{msgPath}, std::ios::binary);
51+ else
52+ file.open (std::string{msgPath}, std::ios::in);
53+
54+ if (file.fail ()) {
4855 auto currDir = std::filesystem::current_path ().string ();
4956 return absl::ErrnoToStatus (
5057 errno,
5158 fmt::format (
5259 " Failed to open file {} when running in {}" , msgPath, currDir));
5360 }
5461 std::stringstream buffer;
55- buffer << textFile .rdbuf ();
62+ buffer << file .rdbuf ();
5663 return buffer.str ();
5764}
5865
Original file line number Diff line number Diff line change @@ -12,8 +12,11 @@ class Plan;
1212
1313namespace io ::substrait::textplan {
1414
15- // Read the contents of a file from disk.
16- absl::StatusOr<std::string> readFromFile (std::string_view msgPath);
15+ // Read the contents of a file from disk. 'forceBinary' enables file reading in
16+ // binary mode.
17+ absl::StatusOr<std::string> readFromFile (
18+ std::string_view msgPath,
19+ bool forceBinary = false );
1720
1821// Reads a plan from a json-encoded text proto.
1922// Returns a list of errors if the file cannot be parsed.
Original file line number Diff line number Diff line change @@ -27,24 +27,18 @@ namespace io::substrait::textplan {
2727absl::Status savePlanToBinary (
2828 const ::substrait::proto::Plan& plan,
2929 std::string_view output_filename) {
30- int outputFileDescriptor =
31- creat (std::string{output_filename}.c_str (), S_IREAD | S_IWRITE);
32- if (outputFileDescriptor == -1 ) {
33- return absl::ErrnoToStatus (
34- errno,
30+ // Open file in binary mode and get its file descriptor
31+ std::ofstream of (std::string{output_filename}, std::ios::binary);
32+ if (!of) {
33+ return absl::InternalError (
3534 fmt::format (" Failed to open file {} for writing" , output_filename));
3635 }
37- auto stream =
38- new google::protobuf::io::FileOutputStream (outputFileDescriptor);
3936
40- if (!plan.SerializeToZeroCopyStream (stream )) {
37+ if (!plan.SerializeToOstream (&of )) {
4138 return ::absl::UnknownError (" Failed to write plan to stream." );
4239 }
4340
44- if (!stream->Close ()) {
45- return absl::AbortedError (" Failed to close file descriptor." );
46- }
47- delete stream;
41+ of.close ();
4842 return absl::OkStatus ();
4943}
5044
You can’t perform that action at this time.
0 commit comments