1 // Copyright 2020 The Amber Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef SRC_VIRTUAL_FILE_STORE_H_
16 #define SRC_VIRTUAL_FILE_STORE_H_
17 
18 #include <cassert>
19 #include <string>
20 #include <unordered_map>
21 
22 #include "amber/result.h"
23 
24 namespace amber {
25 
26 /// Stores a number of virtual files by path.
27 class VirtualFileStore {
28  public:
29   /// Return the path sanitized into a canonical form.
30   static std::string GetCanonical(const std::string& path);
31 
32   /// Adds the virtual file with content |content| to the virtual file path
33   /// |path|. If there's already a virtual file with the given path, an error is
34   /// returned.
Add(const std::string & path,const std::string & content)35   Result Add(const std::string& path, const std::string& content) {
36     if (path.length() == 0) {
37       return Result("Virtual file path was empty");
38     }
39 
40     auto canonical = GetCanonical(path);
41 
42     auto it = files_by_path_.find(canonical);
43     if (it != files_by_path_.end()) {
44       return Result("Virtual file '" + path + "' already declared");
45     }
46     files_by_path_.emplace(canonical, content);
47     return {};
48   }
49 
50   /// Look up the virtual file by path. If the file was found, the content is
51   /// assigned to content.
Get(const std::string & path,std::string * content)52   Result Get(const std::string& path, std::string* content) const {
53     assert(content);
54 
55     if (path.length() == 0) {
56       return Result("Virtual file path was empty");
57     }
58 
59     auto canonical = GetCanonical(path);
60 
61     auto it = files_by_path_.find(canonical);
62     if (it == files_by_path_.end()) {
63       return Result("Virtual file '" + path + "' not found");
64     }
65     *content = it->second;
66     return {};
67   }
68 
69  private:
70   std::unordered_map<std::string, std::string> files_by_path_;
71 };
72 
73 }  // namespace amber
74 
75 #endif  // SRC_VIRTUAL_FILE_STORE_H_
76