forked from substrait-io/substrait-cpp
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSaveBinary.cpp
More file actions
120 lines (103 loc) · 3.5 KB
/
SaveBinary.cpp
File metadata and controls
120 lines (103 loc) · 3.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/* SPDX-License-Identifier: Apache-2.0 */
#include "substrait/textplan/converter/SaveBinary.h"
#include <absl/strings/str_join.h>
#include <fmt/format.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/text_format.h>
#include <google/protobuf/util/json_util.h>
#ifdef _WIN32
#include <io.h>
#else
#include <sys/fcntl.h>
#include <sys/stat.h>
#endif
#include <fstream>
#include "substrait/proto/plan.pb.h"
#include "substrait/textplan/StringManipulation.h"
#include "substrait/textplan/SymbolTablePrinter.h"
#include "substrait/textplan/converter/ParseBinary.h"
namespace io::substrait::textplan {
absl::Status savePlanToBinary(
const ::substrait::proto::Plan& plan,
std::string_view output_filename) {
// Open file in binary mode and get its file descriptor
std::ofstream of(std::string{output_filename}, std::ios::binary);
if (!of) {
return absl::InternalError(
fmt::format("Failed to open file {} for writing", output_filename));
}
if (!plan.SerializeToOstream(&of)) {
return ::absl::UnknownError("Failed to write plan to stream.");
}
of.close();
return absl::OkStatus();
}
absl::Status savePlanToJson(
const ::substrait::proto::Plan& plan,
std::string_view output_filename) {
std::ofstream stream(std::string{output_filename});
if ((stream.fail())) {
return absl::UnavailableError(
fmt::format("Failed to open file {} for writing", output_filename));
}
std::string output;
auto status = ::google::protobuf::util::MessageToJsonString(plan, &output);
if (!status.ok()) {
return absl::UnknownError("Failed to save plan as a JSON protobuf.");
}
stream << output;
stream.close();
if (stream.fail()) {
return absl::UnknownError("Failed to write the plan as a JSON protobuf.");
}
return absl::OkStatus();
}
absl::Status savePlanToText(
const ::substrait::proto::Plan& plan,
std::string_view output_filename) {
std::ofstream stream(std::string{output_filename});
if ((stream.fail())) {
return absl::UnavailableError(
fmt::format("Failed to open file {} for writing", output_filename));
}
auto result = parseBinaryPlan(plan);
auto errors = result.getAllErrors();
if (!errors.empty()) {
return absl::UnknownError(absl::StrJoin(errors, ""));
}
SubstraitErrorListener errorListener;
stream << SymbolTablePrinter::outputToText(
result.getSymbolTable(), &errorListener);
stream.close();
if (stream.fail()) {
return absl::UnknownError("Failed to write the plan as text.");
}
if (!errorListener.getErrorMessages().empty()) {
return absl::UnknownError(fmt::format(
"Errors while writing to text: {}",
absl::StrJoin(errorListener.getErrorMessages(), "\n")));
}
return absl::OkStatus();
}
absl::Status savePlanToProtoText(
const ::substrait::proto::Plan& plan,
std::string_view output_filename) {
int outputFileDescriptor =
creat(std::string{output_filename}.c_str(), S_IREAD | S_IWRITE);
if (outputFileDescriptor == -1) {
return absl::ErrnoToStatus(
errno,
fmt::format("Failed to open file {} for writing", output_filename));
}
auto stream =
new google::protobuf::io::FileOutputStream(outputFileDescriptor);
if (!::google::protobuf::TextFormat::Print(plan, stream)) {
return absl::UnknownError("Failed to save plan as a text protobuf.");
}
if (!stream->Close()) {
return absl::AbortedError("Failed to close file descriptor.");
}
delete stream;
return absl::OkStatus();
}
} // namespace io::substrait::textplan