Add a FileWriter interface (#7821)

* Add a FileWriter interface

* Change interface

* Provide 2 impl for File interface: FileManager & FileNameManager

* Update

* update

* Update

* Add file_writer file

* Update

* Format files

* Update based on review

* Update

* Format bzl file

* Add LoadFile function

* Format

---------

Co-authored-by: Derek Bailey <derekbailey@google.com>
This commit is contained in:
Khanh Nguyen
2023-04-05 18:49:29 -07:00
committed by GitHub
parent 0888e7cb4d
commit 0916f1c87e
13 changed files with 217 additions and 10 deletions

View File

@@ -47,6 +47,7 @@ filegroup(
"include/flatbuffers/code_generators.h",
"include/flatbuffers/default_allocator.h",
"include/flatbuffers/detached_buffer.h",
"include/flatbuffers/file_manager.h",
"include/flatbuffers/flatbuffer_builder.h",
"include/flatbuffers/flatbuffers.h",
"include/flatbuffers/flex_flat_util.h",

View File

@@ -127,6 +127,7 @@ set(FlatBuffers_Library_SRCS
include/flatbuffers/default_allocator.h
include/flatbuffers/detached_buffer.h
include/flatbuffers/code_generator.h
include/flatbuffers/file_manager.h
include/flatbuffers/flatbuffer_builder.h
include/flatbuffers/flatbuffers.h
include/flatbuffers/flexbuffers.h
@@ -171,6 +172,9 @@ set(FlatBuffers_Compiler_SRCS
src/idl_gen_grpc.cpp
src/idl_gen_json_schema.cpp
src/idl_gen_swift.cpp
src/file_name_saving_file_manager.cpp
src/file_binary_writer.cpp
src/file_writer.cpp
src/idl_namer.h
src/namer.h
src/flatc.cpp

View File

@@ -0,0 +1,48 @@
/*
* Copyright 2023 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FLATBUFFERS_FILE_MANAGER_H_
#define FLATBUFFERS_FILE_MANAGER_H_
#include <set>
#include <string>
#include "flatbuffers/util.h"
namespace flatbuffers {
// A File interface to write data to file by default or
// save only file names
class FileManager {
public:
FileManager() = default;
virtual ~FileManager() = default;
virtual bool SaveFile(const std::string &absolute_file_name,
const std::string &content) = 0;
virtual bool LoadFile(const std::string &absolute_file_name,
std::string *buf) = 0;
private:
// Copying is not supported.
FileManager(const FileManager &) = delete;
FileManager &operator=(const FileManager &) = delete;
};
} // namespace flatbuffers
#endif // FLATBUFFERS_FILE_MANAGER_H_

View File

@@ -1184,7 +1184,8 @@ class FlatBufferBuilder {
// Allocates space for a vector of structures.
// Must be completed with EndVectorOfStructs().
template<typename T> T *StartVectorOfStructs(size_t vector_size) {
StartVector(vector_size * sizeof(T) / AlignOf<T>(), sizeof(T), AlignOf<T>());
StartVector(vector_size * sizeof(T) / AlignOf<T>(), sizeof(T),
AlignOf<T>());
return reinterpret_cast<T *>(buf_.make_space(vector_size * sizeof(T)));
}

View File

@@ -56,6 +56,7 @@ struct FlatCOptions {
bool schema_binary = false;
bool grpc_enabled = false;
bool requires_bfbs = false;
bool file_names_only = false;
std::vector<std::shared_ptr<CodeGenerator>> generators;
};

View File

@@ -1424,12 +1424,10 @@ class Builder FLATBUFFERS_FINAL_CLASS {
template<typename T> static Type GetScalarType() {
static_assert(flatbuffers::is_scalar<T>::value, "Unrelated types");
return flatbuffers::is_floating_point<T>::value
? FBT_FLOAT
: flatbuffers::is_same<T, bool>::value
? FBT_BOOL
: (flatbuffers::is_unsigned<T>::value ? FBT_UINT
: FBT_INT);
return flatbuffers::is_floating_point<T>::value ? FBT_FLOAT
: flatbuffers::is_same<T, bool>::value
? FBT_BOOL
: (flatbuffers::is_unsigned<T>::value ? FBT_UINT : FBT_INT);
}
public:

View File

@@ -408,7 +408,7 @@ inline std::string FlatBufferToString(const uint8_t *buffer,
const TypeTable *type_table,
bool multi_line = false,
bool vector_delimited = true,
const std::string& indent = "") {
const std::string &indent = "") {
ToStringVisitor tostring_visitor(multi_line ? "\n" : " ", false, indent,
vector_delimited);
IterateFlatBuffer(buffer, type_table, &tostring_visitor);

View File

@@ -722,9 +722,10 @@ enum class Case {
kSnake2 = 9,
};
// Convert the `input` string of case `input_case` to the specified `output_case`.
// Convert the `input` string of case `input_case` to the specified
// `output_case`.
std::string ConvertCase(const std::string &input, Case output_case,
Case input_case = Case::kSnake);
Case input_case = Case::kSnake);
} // namespace flatbuffers

View File

@@ -69,6 +69,9 @@ cc_library(
"bfbs_gen_nim.cpp",
"bfbs_gen_nim.h",
"bfbs_namer.h",
"file_binary_writer.cpp",
"file_name_saving_file_manager.cpp",
"file_writer.cpp",
"flatc_main.cpp",
"idl_gen_binary.cpp",
"idl_gen_binary.h",

View File

@@ -0,0 +1,49 @@
/*
* Copyright 2023 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <fstream>
#include <set>
#include <string>
#include "flatbuffers/file_manager.h"
namespace flatbuffers {
class FileBinaryWriter : public FileManager {
public:
bool SaveFile(const std::string &absolute_file_name,
const std::string &content) override {
std::ofstream ofs(absolute_file_name, std::ofstream::binary);
if (!ofs.is_open()) return false;
ofs.write(content.c_str(), content.size());
return !ofs.bad();
}
bool Loadfile(const std::string &absolute_file_name, std::string *output) {
if (DirExists(absolute_file_name.c_str())) return false;
std::ifstream ifs(absolute_file_name, std::ifstream::binary);
if (!ifs.is_open()) return false;
// The fastest way to read a file into a string.
ifs.seekg(0, std::ios::end);
auto size = ifs.tellg();
(*output).resize(static_cast<size_t>(size));
ifs.seekg(0, std::ios::beg);
ifs.read(&(*output)[0], (*output).size());
return !ifs.bad();
}
};
} // namespace flatbuffers

View File

@@ -0,0 +1,49 @@
/*
* Copyright 2023 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <fstream>
#include <set>
#include <string>
#include "flatbuffers/file_manager.h"
namespace flatbuffers {
class FileNameSavingFileManager : public FileManager {
public:
FileNameSavingFileManager(std::set<std::string> file_names)
: file_names_(file_names) {}
bool SaveFile(const std::string &absolute_file_name,
const std::string &content) override {
(void)content;
auto pair = file_names_.insert(absolute_file_name);
// pair.second indicates whether the insertion is
// successful or not.
return pair.second;
}
bool Loadfile(const std::string &absolute_file_name, std::string *content) {
(void) absolute_file_name;
(void) content;
return false;
}
private:
std::set<std::string> file_names_;
};
} // namespace flatbuffers

47
src/file_writer.cpp Normal file
View File

@@ -0,0 +1,47 @@
/*
* Copyright 2023 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <fstream>
#include <set>
#include <string>
#include "flatbuffers/file_manager.h"
namespace flatbuffers {
class FileWriter : public FileManager {
public:
bool SaveFile(const std::string &absolute_file_name,
const std::string &content) override {
std::ofstream ofs(absolute_file_name, std::ofstream::out);
if (!ofs.is_open()) return false;
ofs.write(content.c_str(), content.size());
return !ofs.bad();
}
bool Loadfile(const std::string &absolute_file_name, std::string *output) {
if (DirExists(absolute_file_name.c_str())) return false;
std::ifstream ifs(absolute_file_name, std::ifstream::in);
if (!ifs.is_open()) return false;
// This is slower, but works correctly on all platforms for text files.
std::ostringstream oss;
oss << ifs.rdbuf();
*output = oss.str();
return !ifs.bad();
}
};
} // namespace flatbuffers

View File

@@ -250,6 +250,8 @@ const static FlatCOption flatc_options[] = {
{ "", "no-leak-private-annotation", "",
"Prevents multiple type of annotations within a Fbs SCHEMA file. "
"Currently this is required to generate private types in Rust" },
{ "", "file-names-only", "",
"Print out generated file names without writing to the files"},
};
auto cmp = [](FlatCOption a, FlatCOption b) { return a.long_opt < b.long_opt; };
@@ -653,6 +655,9 @@ FlatCOptions FlatCompiler::ParseFromCommandLineArguments(int argc,
} else if (arg == "--annotate") {
if (++argi >= argc) Error("missing path following: " + arg, true);
options.annotate_schema = flatbuffers::PosixPath(argv[argi]);
} else if(arg == "--file-names-only") {
// TODO (khhn): Provide 2 implementation
options.file_names_only = true;
} else {
if (arg == "--proto") { opts.proto_mode = true; }