• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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