Imported Upstream version 1.25.0
[platform/core/ml/nnfw.git] / onert-micro / externals / flatbuffers / registry.h
1 /*
2  * Copyright (c) 2023 Samsung Electronics Co., Ltd. All Rights Reserved
3  * Copyright 2017 Google Inc. All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #ifndef FLATBUFFERS_REGISTRY_H_
19 #define FLATBUFFERS_REGISTRY_H_
20
21 #include "flatbuffers/idl.h"
22
23 namespace flatbuffers
24 {
25
26 // Convenience class to easily parse or generate text for arbitrary FlatBuffers.
27 // Simply pre-populate it with all schema filenames that may be in use, and
28 // This class will look them up using the file_identifier declared in the
29 // schema.
30 class Registry
31 {
32 public:
33   // Call this for all schemas that may be in use. The identifier has
34   // a function in the generated code, e.g. MonsterIdentifier().
35   void Register(const char *file_identifier, const char *schema_path)
36   {
37     Schema schema;
38     schema.path_ = schema_path;
39     schemas_[file_identifier] = schema;
40   }
41
42   // Generate text from an arbitrary FlatBuffer by looking up its
43   // file_identifier in the registry.
44   bool FlatBufferToText(const uint8_t *flatbuf, size_t len, std::string *dest)
45   {
46     // Get the identifier out of the buffer.
47     // If the buffer is truncated, exit.
48     if (len < sizeof(uoffset_t) + FlatBufferBuilder::kFileIdentifierLength)
49     {
50       lasterror_ = "buffer truncated";
51       return false;
52     }
53     std::string ident(reinterpret_cast<const char *>(flatbuf) + sizeof(uoffset_t),
54                       FlatBufferBuilder::kFileIdentifierLength);
55     // Load and parse the schema.
56     Parser parser;
57     if (!LoadSchema(ident, &parser))
58       return false;
59     // Now we're ready to generate text.
60     if (!GenerateText(parser, flatbuf, dest))
61     {
62       lasterror_ = "unable to generate text for FlatBuffer binary";
63       return false;
64     }
65     return true;
66   }
67
68   // Converts a binary buffer to text using one of the schemas in the registry,
69   // use the file_identifier to indicate which.
70   // If DetachedBuffer::data() is null then parsing failed.
71   DetachedBuffer TextToFlatBuffer(const char *text, const char *file_identifier)
72   {
73     // Load and parse the schema.
74     Parser parser;
75     if (!LoadSchema(file_identifier, &parser))
76       return DetachedBuffer();
77     // Parse the text.
78     if (!parser.Parse(text))
79     {
80       lasterror_ = parser.error_;
81       return DetachedBuffer();
82     }
83     // We have a valid FlatBuffer. Detach it from the builder and return.
84     return parser.builder_.Release();
85   }
86
87   // Modify any parsing / output options used by the other functions.
88   void SetOptions(const IDLOptions &opts) { opts_ = opts; }
89
90   // If schemas used contain include statements, call this function for every
91   // directory the parser should search them for.
92   void AddIncludeDirectory(const char *path) { include_paths_.push_back(path); }
93
94   // Returns a human readable error if any of the above functions fail.
95   const std::string &GetLastError() { return lasterror_; }
96
97 private:
98   bool LoadSchema(const std::string &ident, Parser *parser)
99   {
100     // Find the schema, if not, exit.
101     auto it = schemas_.find(ident);
102     if (it == schemas_.end())
103     {
104       // Don't attach the identifier, since it may not be human readable.
105       lasterror_ = "identifier for this buffer not in the registry";
106       return false;
107     }
108     auto &schema = it->second;
109     // Load the schema from disk. If not, exit.
110     std::string schematext;
111     if (!LoadFile(schema.path_.c_str(), false, &schematext))
112     {
113       lasterror_ = "could not load schema: " + schema.path_;
114       return false;
115     }
116     // Parse schema.
117     parser->opts = opts_;
118     if (!parser->Parse(schematext.c_str(), vector_data(include_paths_), schema.path_.c_str()))
119     {
120       lasterror_ = parser->error_;
121       return false;
122     }
123     return true;
124   }
125
126   struct Schema
127   {
128     std::string path_;
129     // TODO(wvo) optionally cache schema file or parsed schema here.
130   };
131
132   std::string lasterror_;
133   IDLOptions opts_;
134   std::vector<const char *> include_paths_;
135   std::map<std::string, Schema> schemas_;
136 };
137
138 } // namespace flatbuffers
139
140 #endif // FLATBUFFERS_REGISTRY_H_