1 /*
2 * Copyright 2014 Google Inc. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 // independent from idl_parser, since this code is not needed for most clients
18
19 #include "idl_gen_binary.h"
20
21 #include <limits>
22 #include <memory>
23 #include <string>
24 #include <unordered_set>
25
26 #include "flatbuffers/base.h"
27 #include "flatbuffers/code_generators.h"
28 #include "flatbuffers/flatbuffers.h"
29 #include "flatbuffers/flatc.h"
30 #include "flatbuffers/idl.h"
31 #include "flatbuffers/util.h"
32
33 namespace flatbuffers {
34 namespace {
35
BinaryFileName(const Parser & parser,const std::string & path,const std::string & file_name)36 static std::string BinaryFileName(const Parser &parser, const std::string &path,
37 const std::string &file_name) {
38 auto ext = parser.file_extension_.length() ? parser.file_extension_ : "bin";
39 return path + file_name + "." + ext;
40 }
41
GenerateBinary(const Parser & parser,const std::string & path,const std::string & file_name)42 static bool GenerateBinary(const Parser &parser, const std::string &path,
43 const std::string &file_name) {
44 if (parser.opts.use_flexbuffers) {
45 auto data_vec = parser.flex_builder_.GetBuffer();
46 auto data_ptr = reinterpret_cast<char *>(data(data_vec));
47 return !parser.flex_builder_.GetSize() ||
48 flatbuffers::SaveFile(
49 BinaryFileName(parser, path, file_name).c_str(), data_ptr,
50 parser.flex_builder_.GetSize(), true);
51 }
52 return !parser.builder_.GetSize() ||
53 flatbuffers::SaveFile(
54 BinaryFileName(parser, path, file_name).c_str(),
55 reinterpret_cast<char *>(parser.builder_.GetBufferPointer()),
56 parser.builder_.GetSize(), true);
57 }
58
BinaryMakeRule(const Parser & parser,const std::string & path,const std::string & file_name)59 static std::string BinaryMakeRule(const Parser &parser, const std::string &path,
60 const std::string &file_name) {
61 if (!parser.builder_.GetSize()) return "";
62 std::string filebase =
63 flatbuffers::StripPath(flatbuffers::StripExtension(file_name));
64 std::string make_rule =
65 BinaryFileName(parser, path, filebase) + ": " + file_name;
66 auto included_files =
67 parser.GetIncludedFilesRecursive(parser.root_struct_def_->file);
68 for (auto it = included_files.begin(); it != included_files.end(); ++it) {
69 make_rule += " " + *it;
70 }
71 return make_rule;
72 }
73
74 class BinaryCodeGenerator : public CodeGenerator {
75 public:
GenerateCode(const Parser & parser,const std::string & path,const std::string & filename)76 Status GenerateCode(const Parser &parser, const std::string &path,
77 const std::string &filename) override {
78 if (!GenerateBinary(parser, path, filename)) { return Status::ERROR; }
79 return Status::OK;
80 }
81
82 // Generate code from the provided `buffer` of given `length`. The buffer is a
83 // serialized reflection.fbs.
GenerateCode(const uint8_t *,int64_t,const CodeGenOptions &)84 Status GenerateCode(const uint8_t *, int64_t,
85 const CodeGenOptions &) override {
86 return Status::NOT_IMPLEMENTED;
87 }
88
GenerateMakeRule(const Parser & parser,const std::string & path,const std::string & filename,std::string & output)89 Status GenerateMakeRule(const Parser &parser, const std::string &path,
90 const std::string &filename,
91 std::string &output) override {
92 output = BinaryMakeRule(parser, path, filename);
93 return Status::OK;
94 }
95
GenerateGrpcCode(const Parser & parser,const std::string & path,const std::string & filename)96 Status GenerateGrpcCode(const Parser &parser, const std::string &path,
97 const std::string &filename) override {
98 (void)parser;
99 (void)path;
100 (void)filename;
101 return Status::NOT_IMPLEMENTED;
102 }
103
GenerateRootFile(const Parser & parser,const std::string & path)104 Status GenerateRootFile(const Parser &parser,
105 const std::string &path) override {
106 (void)parser;
107 (void)path;
108 return Status::NOT_IMPLEMENTED;
109 }
110
IsSchemaOnly() const111 bool IsSchemaOnly() const override { return false; }
112
SupportsBfbsGeneration() const113 bool SupportsBfbsGeneration() const override { return false; }
114
SupportsRootFileGeneration() const115 bool SupportsRootFileGeneration() const override { return false; }
116
Language() const117 IDLOptions::Language Language() const override { return IDLOptions::kBinary; }
118
LanguageName() const119 std::string LanguageName() const override { return "binary"; }
120 };
121
122 } // namespace
123
NewBinaryCodeGenerator()124 std::unique_ptr<CodeGenerator> NewBinaryCodeGenerator() {
125 return std::unique_ptr<BinaryCodeGenerator>(new BinaryCodeGenerator());
126 }
127
128 } // namespace flatbuffers
129