summaryrefslogtreecommitdiffstats
path: root/Source/cmFileAPI.h
blob: 589b8370717563ce8796e36b6a7f7274d92fb483 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#ifndef cmFileAPI_h
#define cmFileAPI_h

#include "cmConfigure.h" // IWYU pragma: keep

#include "cm_jsoncpp_value.h"
#include "cm_jsoncpp_writer.h"

#include <map>
#include <memory> // IWYU pragma: keep
#include <string>
#include <unordered_set>
#include <vector>

class cmake;

class cmFileAPI
{
public:
  cmFileAPI(cmake* cm);

  /** Read fileapi queries from disk.  */
  void ReadQueries();

  /** Write fileapi replies to disk.  */
  void WriteReplies();

  /** Get the "cmake" instance with which this was constructed.  */
  cmake* GetCMakeInstance() const { return this->CMakeInstance; }

private:
  cmake* CMakeInstance;

  /** The api/v1 directory location.  */
  std::string APIv1;

  /** The set of files we have just written to the reply directory.  */
  std::unordered_set<std::string> ReplyFiles;

  static std::vector<std::string> LoadDir(std::string const& dir);
  void RemoveOldReplyFiles();

  // Keep in sync with ObjectKindName.
  enum class ObjectKind
  {
    InternalTest
  };

  /** Identify one object kind and major version.  */
  struct Object
  {
    ObjectKind Kind;
    unsigned long Version = 0;
    friend bool operator<(Object const& l, Object const& r)
    {
      if (l.Kind != r.Kind) {
        return l.Kind < r.Kind;
      }
      return l.Version < r.Version;
    }
  };

  /** Represent content of a query directory.  */
  struct Query
  {
    /** Known object kind-version pairs.  */
    std::vector<Object> Known;
    /** Unknown object kind names.  */
    std::vector<std::string> Unknown;
  };

  /** Whether the top-level query directory exists at all.  */
  bool QueryExists = false;

  /** The content of the top-level query directory.  */
  Query TopQuery;

  /** The content of each "client-$client" query directory.  */
  std::map<std::string, Query> ClientQueries;

  /** Reply index object generated for object kind/version.
      This populates the "objects" field of the reply index.  */
  std::map<Object, Json::Value> ReplyIndexObjects;

  std::unique_ptr<Json::StreamWriter> JsonWriter;

  std::string WriteJsonFile(
    Json::Value const& value, std::string const& prefix,
    std::string (*computeSuffix)(std::string const&) = ComputeSuffixHash);
  static std::string ComputeSuffixHash(std::string const&);
  static std::string ComputeSuffixTime(std::string const&);

  static bool ReadQuery(std::string const& query,
                        std::vector<Object>& objects);
  void ReadClient(std::string const& client);

  Json::Value BuildReplyIndex();
  Json::Value BuildCMake();
  Json::Value BuildReply(Query const& q);
  static Json::Value BuildReplyError(std::string const& error);
  Json::Value const& AddReplyIndexObject(Object const& o);

  static const char* ObjectKindName(ObjectKind kind);
  static std::string ObjectName(Object const& o);

  Json::Value BuildObject(Object const& object);

  Json::Value BuildInternalTest(Object const& object);
};

#endif