Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-08-27 09:30:28

0001 /*
0002  * Copyright 2017 Google Inc. All rights reserved.
0003  *
0004  * Licensed under the Apache License, Version 2.0 (the "License");
0005  * you may not use this file except in compliance with the License.
0006  * You may obtain a copy of the License at
0007  *
0008  *     http://www.apache.org/licenses/LICENSE-2.0
0009  *
0010  * Unless required by applicable law or agreed to in writing, software
0011  * distributed under the License is distributed on an "AS IS" BASIS,
0012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013  * See the License for the specific language governing permissions and
0014  * limitations under the License.
0015  */
0016 
0017 #ifndef FLATBUFFERS_REGISTRY_H_
0018 #define FLATBUFFERS_REGISTRY_H_
0019 
0020 #include "flatbuffers/base.h"
0021 #include "flatbuffers/idl.h"
0022 
0023 namespace flatbuffers {
0024 
0025 // Convenience class to easily parse or generate text for arbitrary FlatBuffers.
0026 // Simply pre-populate it with all schema filenames that may be in use, and
0027 // This class will look them up using the file_identifier declared in the
0028 // schema.
0029 class Registry {
0030  public:
0031   // Call this for all schemas that may be in use. The identifier has
0032   // a function in the generated code, e.g. MonsterIdentifier().
0033   void Register(const char *file_identifier, const char *schema_path) {
0034     Schema schema;
0035     schema.path_ = schema_path;
0036     schemas_[file_identifier] = schema;
0037   }
0038 
0039   // Generate text from an arbitrary FlatBuffer by looking up its
0040   // file_identifier in the registry.
0041   bool FlatBufferToText(const uint8_t *flatbuf, size_t len, std::string *dest) {
0042     // Get the identifier out of the buffer.
0043     // If the buffer is truncated, exit.
0044     if (len < sizeof(uoffset_t) + kFileIdentifierLength) {
0045       lasterror_ = "buffer truncated";
0046       return false;
0047     }
0048     std::string ident(
0049         reinterpret_cast<const char *>(flatbuf) + sizeof(uoffset_t),
0050         kFileIdentifierLength);
0051     // Load and parse the schema.
0052     Parser parser;
0053     if (!LoadSchema(ident, &parser)) return false;
0054     // Now we're ready to generate text.
0055     auto err = GenText(parser, flatbuf, dest);
0056     if (err) {
0057       lasterror_ =
0058           "unable to generate text for FlatBuffer binary: " + std::string(err);
0059       return false;
0060     }
0061     return true;
0062   }
0063 
0064   // Converts a binary buffer to text using one of the schemas in the registry,
0065   // use the file_identifier to indicate which.
0066   // If DetachedBuffer::data() is null then parsing failed.
0067   DetachedBuffer TextToFlatBuffer(const char *text,
0068                                   const char *file_identifier) {
0069     // Load and parse the schema.
0070     Parser parser;
0071     if (!LoadSchema(file_identifier, &parser)) return DetachedBuffer();
0072     // Parse the text.
0073     if (!parser.Parse(text)) {
0074       lasterror_ = parser.error_;
0075       return DetachedBuffer();
0076     }
0077     // We have a valid FlatBuffer. Detach it from the builder and return.
0078     return parser.builder_.Release();
0079   }
0080 
0081   // Modify any parsing / output options used by the other functions.
0082   void SetOptions(const IDLOptions &opts) { opts_ = opts; }
0083 
0084   // If schemas used contain include statements, call this function for every
0085   // directory the parser should search them for.
0086   void AddIncludeDirectory(const char *path) { include_paths_.push_back(path); }
0087 
0088   // Returns a human readable error if any of the above functions fail.
0089   const std::string &GetLastError() { return lasterror_; }
0090 
0091  private:
0092   bool LoadSchema(const std::string &ident, Parser *parser) {
0093     // Find the schema, if not, exit.
0094     auto it = schemas_.find(ident);
0095     if (it == schemas_.end()) {
0096       // Don't attach the identifier, since it may not be human readable.
0097       lasterror_ = "identifier for this buffer not in the registry";
0098       return false;
0099     }
0100     auto &schema = it->second;
0101     // Load the schema from disk. If not, exit.
0102     std::string schematext;
0103     if (!LoadFile(schema.path_.c_str(), false, &schematext)) {
0104       lasterror_ = "could not load schema: " + schema.path_;
0105       return false;
0106     }
0107     // Parse schema.
0108     parser->opts = opts_;
0109     if (!parser->Parse(schematext.c_str(), include_paths_.data(),
0110                        schema.path_.c_str())) {
0111       lasterror_ = parser->error_;
0112       return false;
0113     }
0114     return true;
0115   }
0116 
0117   struct Schema {
0118     std::string path_;
0119     // TODO(wvo) optionally cache schema file or parsed schema here.
0120   };
0121 
0122   std::string lasterror_;
0123   IDLOptions opts_;
0124   std::vector<const char *> include_paths_;
0125   std::map<std::string, Schema> schemas_;
0126 };
0127 
0128 }  // namespace flatbuffers
0129 
0130 #endif  // FLATBUFFERS_REGISTRY_H_