resolve cyclic dependency with zstd
[platform/upstream/cmake.git] / Source / cmArchiveWrite.h
1 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2    file Copyright.txt or https://cmake.org/licensing for details.  */
3 #pragma once
4
5 #include "cmConfigure.h" // IWYU pragma: keep
6
7 #include <cstddef>
8 #include <iosfwd>
9 #include <string>
10
11 #if defined(CMAKE_BOOTSTRAP)
12 #  error "cmArchiveWrite not allowed during bootstrap build!"
13 #endif
14
15 template <typename T>
16 class cmArchiveWriteOptional
17 {
18 public:
19   cmArchiveWriteOptional() { this->Clear(); }
20   explicit cmArchiveWriteOptional(T val) { this->Set(val); }
21
22   void Set(T val)
23   {
24     this->IsValueSet = true;
25     this->Value = val;
26   }
27   void Clear() { this->IsValueSet = false; }
28   bool IsSet() const { return this->IsValueSet; }
29   T Get() const { return this->Value; }
30
31 private:
32   T Value;
33   bool IsValueSet;
34 };
35
36 /** \class cmArchiveWrite
37  * \brief Wrapper around libarchive for writing.
38  *
39  */
40 class cmArchiveWrite
41 {
42 public:
43   /** Compression type.  */
44   enum Compress
45   {
46     CompressNone,
47     CompressCompress,
48     CompressGZip,
49     CompressBZip2,
50     CompressLZMA,
51     CompressXZ,
52     CompressZstd
53   };
54
55   /** Construct with output stream to which to write archive.  */
56   cmArchiveWrite(std::ostream& os, Compress c = CompressNone,
57                  std::string const& format = "paxr", int compressionLevel = 0,
58                  int numThreads = 1);
59
60   ~cmArchiveWrite();
61
62   cmArchiveWrite(const cmArchiveWrite&) = delete;
63   cmArchiveWrite& operator=(const cmArchiveWrite&) = delete;
64
65   bool Open();
66
67   /**
68    * Add a path (file or directory) to the archive.  Directories are
69    * added recursively.  The "path" must be readable on disk, either
70    * full path or relative to current working directory.  The "skip"
71    * value indicates how many leading bytes from the input path to
72    * skip.  The remaining part of the input path is appended to the
73    * "prefix" value to construct the final name in the archive.
74    */
75   bool Add(std::string path, size_t skip = 0, const char* prefix = nullptr,
76            bool recursive = true);
77
78   /** Returns true if there has been no error.  */
79   explicit operator bool() const { return this->Okay(); }
80
81   /** Returns true if there has been an error.  */
82   bool operator!() const { return !this->Okay(); }
83
84   /** Return the error string; empty if none.  */
85   std::string GetError() const { return this->Error; }
86
87   // TODO: More general callback instead of hard-coding calls to
88   // std::cout.
89   void SetVerbose(bool v) { this->Verbose = v; }
90
91   void SetMTime(std::string const& t) { this->MTime = t; }
92
93   //! Sets the permissions of the added files/folders
94   void SetPermissions(int permissions_)
95   {
96     this->Permissions.Set(permissions_);
97   }
98
99   //! Clears permissions - default is used instead
100   void ClearPermissions() { this->Permissions.Clear(); }
101
102   //! Sets the permissions mask of files/folders
103   //!
104   //! The permissions will be copied from the existing file
105   //! or folder. The mask will then be applied to unset
106   //! some of them
107   void SetPermissionsMask(int permissionsMask_)
108   {
109     this->PermissionsMask.Set(permissionsMask_);
110   }
111
112   //! Clears permissions mask - default is used instead
113   void ClearPermissionsMask() { this->PermissionsMask.Clear(); }
114
115   //! Sets UID and GID to be used in the tar file
116   void SetUIDAndGID(int uid_, int gid_)
117   {
118     this->Uid.Set(uid_);
119     this->Gid.Set(gid_);
120   }
121
122   //! Clears UID and GID to be used in the tar file - default is used instead
123   void ClearUIDAndGID()
124   {
125     this->Uid.Clear();
126     this->Gid.Clear();
127   }
128
129   //! Sets UNAME and GNAME to be used in the tar file
130   void SetUNAMEAndGNAME(const std::string& uname_, const std::string& gname_)
131   {
132     this->Uname = uname_;
133     this->Gname = gname_;
134   }
135
136   //! Clears UNAME and GNAME to be used in the tar file
137   //! default is used instead
138   void ClearUNAMEAndGNAME()
139   {
140     this->Uname = "";
141     this->Gname = "";
142   }
143
144 private:
145   bool Okay() const { return this->Error.empty(); }
146   bool AddPath(const char* path, size_t skip, const char* prefix,
147                bool recursive = true);
148   bool AddFile(const char* file, size_t skip, const char* prefix);
149   bool AddData(const char* file, size_t size);
150
151   struct Callback;
152   friend struct Callback;
153
154   class Entry;
155
156   std::ostream& Stream;
157   struct archive* Archive;
158   struct archive* Disk;
159   bool Verbose = false;
160   std::string Format;
161   std::string Error;
162   std::string MTime;
163
164   //! UID of the user in the tar file
165   cmArchiveWriteOptional<int> Uid;
166
167   //! GUID of the user in the tar file
168   cmArchiveWriteOptional<int> Gid;
169
170   //! UNAME/GNAME of the user (does not override UID/GID)
171   //!@{
172   std::string Uname;
173   std::string Gname;
174   //!@}
175
176   //! Permissions on files/folders
177   cmArchiveWriteOptional<int> Permissions;
178   cmArchiveWriteOptional<int> PermissionsMask;
179 };