xref: /aosp_15_r20/prebuilts/android-emulator/linux-x86_64/include/flatbuffers/registry.h (revision d870e0501505f2fc9999364ffe386a6b6151adc1)
1 /*
2  * Copyright 2017 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 #ifndef FLATBUFFERS_REGISTRY_H_
18 #define FLATBUFFERS_REGISTRY_H_
19 
20 #include "flatbuffers/base.h"
21 #include "flatbuffers/idl.h"
22 
23 namespace flatbuffers {
24 
25 // Convenience class to easily parse or generate text for arbitrary FlatBuffers.
26 // Simply pre-populate it with all schema filenames that may be in use, and
27 // This class will look them up using the file_identifier declared in the
28 // schema.
29 class Registry {
30  public:
31   // Call this for all schemas that may be in use. The identifier has
32   // a function in the generated code, e.g. MonsterIdentifier().
Register(const char * file_identifier,const char * schema_path)33   void Register(const char *file_identifier, const char *schema_path) {
34     Schema schema;
35     schema.path_ = schema_path;
36     schemas_[file_identifier] = schema;
37   }
38 
39   // Generate text from an arbitrary FlatBuffer by looking up its
40   // file_identifier in the registry.
FlatBufferToText(const uint8_t * flatbuf,size_t len,std::string * dest)41   bool FlatBufferToText(const uint8_t *flatbuf, size_t len, std::string *dest) {
42     // Get the identifier out of the buffer.
43     // If the buffer is truncated, exit.
44     if (len < sizeof(uoffset_t) + kFileIdentifierLength) {
45       lasterror_ = "buffer truncated";
46       return false;
47     }
48     std::string ident(
49         reinterpret_cast<const char *>(flatbuf) + sizeof(uoffset_t),
50         kFileIdentifierLength);
51     // Load and parse the schema.
52     Parser parser;
53     if (!LoadSchema(ident, &parser)) return false;
54     // Now we're ready to generate text.
55     if (!GenerateText(parser, flatbuf, dest)) {
56       lasterror_ = "unable to generate text for FlatBuffer binary";
57       return false;
58     }
59     return true;
60   }
61 
62   // Converts a binary buffer to text using one of the schemas in the registry,
63   // use the file_identifier to indicate which.
64   // If DetachedBuffer::data() is null then parsing failed.
TextToFlatBuffer(const char * text,const char * file_identifier)65   DetachedBuffer TextToFlatBuffer(const char *text,
66                                   const char *file_identifier) {
67     // Load and parse the schema.
68     Parser parser;
69     if (!LoadSchema(file_identifier, &parser)) return DetachedBuffer();
70     // Parse the text.
71     if (!parser.Parse(text)) {
72       lasterror_ = parser.error_;
73       return DetachedBuffer();
74     }
75     // We have a valid FlatBuffer. Detach it from the builder and return.
76     return parser.builder_.Release();
77   }
78 
79   // Modify any parsing / output options used by the other functions.
SetOptions(const IDLOptions & opts)80   void SetOptions(const IDLOptions &opts) { opts_ = opts; }
81 
82   // If schemas used contain include statements, call this function for every
83   // directory the parser should search them for.
AddIncludeDirectory(const char * path)84   void AddIncludeDirectory(const char *path) { include_paths_.push_back(path); }
85 
86   // Returns a human readable error if any of the above functions fail.
GetLastError()87   const std::string &GetLastError() { return lasterror_; }
88 
89  private:
LoadSchema(const std::string & ident,Parser * parser)90   bool LoadSchema(const std::string &ident, Parser *parser) {
91     // Find the schema, if not, exit.
92     auto it = schemas_.find(ident);
93     if (it == schemas_.end()) {
94       // Don't attach the identifier, since it may not be human readable.
95       lasterror_ = "identifier for this buffer not in the registry";
96       return false;
97     }
98     auto &schema = it->second;
99     // Load the schema from disk. If not, exit.
100     std::string schematext;
101     if (!LoadFile(schema.path_.c_str(), false, &schematext)) {
102       lasterror_ = "could not load schema: " + schema.path_;
103       return false;
104     }
105     // Parse schema.
106     parser->opts = opts_;
107     if (!parser->Parse(schematext.c_str(), include_paths_.data(),
108                        schema.path_.c_str())) {
109       lasterror_ = parser->error_;
110       return false;
111     }
112     return true;
113   }
114 
115   struct Schema {
116     std::string path_;
117     // TODO(wvo) optionally cache schema file or parsed schema here.
118   };
119 
120   std::string lasterror_;
121   IDLOptions opts_;
122   std::vector<const char *> include_paths_;
123   std::map<std::string, Schema> schemas_;
124 };
125 
126 }  // namespace flatbuffers
127 
128 #endif  // FLATBUFFERS_REGISTRY_H_
129