|  | // Copyright 2018 The Bazel Authors. All rights reserved. | 
|  | // | 
|  | // Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | // you may not use this file except in compliance with the License. | 
|  | // You may obtain a copy of the License at | 
|  | // | 
|  | //    http://www.apache.org/licenses/LICENSE-2.0 | 
|  | // | 
|  | // Unless required by applicable law or agreed to in writing, software | 
|  | // distributed under the License is distributed on an "AS IS" BASIS, | 
|  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | // See the License for the specific language governing permissions and | 
|  | // limitations under the License. | 
|  |  | 
|  | #ifndef BAZEL_TOOLS_TEST_WINDOWS_TW_H_ | 
|  | #define BAZEL_TOOLS_TEST_WINDOWS_TW_H_ | 
|  |  | 
|  | #define WIN32_LEAN_AND_MEAN | 
|  | #include <windows.h> | 
|  |  | 
|  | #include <memory> | 
|  | #include <ostream> | 
|  | #include <string> | 
|  | #include <vector> | 
|  |  | 
|  | namespace bazel { | 
|  |  | 
|  | namespace windows { | 
|  | class AutoHandle; | 
|  | }  // namespace windows | 
|  |  | 
|  | namespace tools { | 
|  | namespace test_wrapper { | 
|  |  | 
|  | // Info about a file/directory in the results of TestOnly_GetFileListRelativeTo. | 
|  | class FileInfo { | 
|  | public: | 
|  | // C'tor for a directory. | 
|  | FileInfo(const std::wstring& rel_path) | 
|  | : rel_path_(rel_path), size_(0), is_dir_(true) {} | 
|  |  | 
|  | // C'tor for a file. | 
|  | // Marked "explicit" because `size` is just a `int`. | 
|  | explicit FileInfo(const std::wstring& rel_path, int size) | 
|  | : rel_path_(rel_path), size_(size), is_dir_(false) {} | 
|  |  | 
|  | inline const std::wstring& RelativePath() const { return rel_path_; } | 
|  |  | 
|  | inline int Size() const { return size_; } | 
|  |  | 
|  | inline bool IsDirectory() const { return is_dir_; } | 
|  |  | 
|  | private: | 
|  | // The file's path, relative to the traversal root. | 
|  | std::wstring rel_path_; | 
|  |  | 
|  | // The file's size, in bytes. | 
|  | // | 
|  | // Unfortunately this field has to be `int`, so it can only describe files up | 
|  | // to 2 GiB in size. The reason is, devtools_ijar::Stat::total_size is | 
|  | // declared as `int`, which is what we ultimately store the file size in, | 
|  | // therefore this field is also `int`. | 
|  | int size_; | 
|  |  | 
|  | // Whether this is a directory (true) or a regular file (false). | 
|  | bool is_dir_; | 
|  | }; | 
|  |  | 
|  | // Zip entry paths for devtools_ijar::ZipBuilder. | 
|  | // The function signatures mirror the signatures of ZipBuilder's functions. | 
|  | class ZipEntryPaths { | 
|  | public: | 
|  | // Initialize the strings in this object. | 
|  | // `root` must be an absolute mixed-style path (Windows path with "/" | 
|  | // separators). | 
|  | // `files` must be relative, Unix-style paths. | 
|  | void Create(const std::string& root, const std::vector<std::string>& files); | 
|  |  | 
|  | // Returns the number of paths in `AbsPathPtrs` and `EntryPathPtrs`. | 
|  | size_t Size() const { return size_; } | 
|  |  | 
|  | // Returns a mutable array of const pointers to const char data. | 
|  | // Each pointer points to an absolute path: the file to archive. | 
|  | // The pointers are owned by this object and become invalid when the object is | 
|  | // destroyed. | 
|  | // Each entry corresponds to the entry at the same index in `EntryPathPtrs`. | 
|  | char const* const* AbsPathPtrs() const { return abs_path_ptrs_.get(); } | 
|  |  | 
|  | // Returns a mutable array of const pointers to const char data. | 
|  | // Each pointer points to a relative path: an entry in the zip file. | 
|  | // The pointers are owned by this object and become invalid when the object is | 
|  | // destroyed. | 
|  | // Each entry corresponds to the entry at the same index in `AbsPathPtrs`. | 
|  | char const* const* EntryPathPtrs() const { return entry_path_ptrs_.get(); } | 
|  |  | 
|  | private: | 
|  | size_t size_; | 
|  | std::unique_ptr<char[]> abs_paths_; | 
|  | std::unique_ptr<char*[]> abs_path_ptrs_; | 
|  | std::unique_ptr<char*[]> entry_path_ptrs_; | 
|  | }; | 
|  |  | 
|  | // Streams data from an input to two outputs. | 
|  | // Inspired by tee(1) in the GNU coreutils. | 
|  | class Tee { | 
|  | public: | 
|  | virtual ~Tee() {} | 
|  |  | 
|  | protected: | 
|  | Tee() {} | 
|  | Tee(const Tee&) = delete; | 
|  | Tee& operator=(const Tee&) = delete; | 
|  | }; | 
|  |  | 
|  | // Buffered input stream (based on a HANDLE) with peek-ahead support. | 
|  | class IFStream { | 
|  | public: | 
|  | enum { | 
|  | kIFStreamErrorEOF = 256, | 
|  | kIFStreamErrorIO = 257, | 
|  | }; | 
|  |  | 
|  | virtual ~IFStream() {} | 
|  |  | 
|  | // Reads one byte from the stream, and moves the cursor ahead. | 
|  | // Returns: | 
|  | //   0..255: success, the value of the read byte | 
|  | //   256 (kIFStreamErrorEOF): failure, EOF was reached | 
|  | //   257 (kIFStreamErrorIO): failure, I/O error | 
|  | virtual int Get() = 0; | 
|  |  | 
|  | // Peeks at 'n' bytes starting at the current cursor position. | 
|  | // Writes into 'out' the 0..'n' successfully peeked bytes. | 
|  | // Returns: | 
|  | //   0..n: the number of successfully peeked bytes | 
|  | virtual DWORD Peek(DWORD n, uint8_t* out) const = 0; | 
|  |  | 
|  | protected: | 
|  | IFStream() {} | 
|  |  | 
|  | private: | 
|  | IFStream(const IFStream&) = delete; | 
|  | IFStream& operator=(const IFStream&) = delete; | 
|  | }; | 
|  |  | 
|  | // The main function of the test wrapper. | 
|  | int TestWrapperMain(int argc, wchar_t** argv); | 
|  |  | 
|  | // The main function of the test XML writer. | 
|  | int XmlWriterMain(int argc, wchar_t** argv); | 
|  |  | 
|  | // The "testing" namespace contains functions that should only be used by tests. | 
|  | namespace testing { | 
|  |  | 
|  | // Retrieves an environment variable. | 
|  | bool TestOnly_GetEnv(const wchar_t* name, std::wstring* result); | 
|  |  | 
|  | // Lists all files under `abs_root`, with paths relative to `abs_root`. | 
|  | // Limits the directory depth to `depth_limit` many directories below | 
|  | // `abs_root`. | 
|  | // A negative depth means unlimited depth. 0 depth means searching only | 
|  | // `abs_root`, while a positive depth limit allows matches in up to that many | 
|  | // subdirectories. | 
|  | bool TestOnly_GetFileListRelativeTo(const std::wstring& abs_root, | 
|  | std::vector<FileInfo>* result, | 
|  | int depth_limit = -1); | 
|  |  | 
|  | // Converts a list of files to ZIP file entry paths.a | 
|  | bool TestOnly_ToZipEntryPaths( | 
|  | const std::wstring& abs_root, | 
|  | const std::vector<bazel::tools::test_wrapper::FileInfo>& files, | 
|  | ZipEntryPaths* result); | 
|  |  | 
|  | // Archives `files` into a zip file at `abs_zip` (absolute path to the zip). | 
|  | bool TestOnly_CreateZip(const std::wstring& abs_root, | 
|  | const std::vector<FileInfo>& files, | 
|  | const std::wstring& abs_zip); | 
|  |  | 
|  | // Returns the MIME type of a file. The file does not need to exist. | 
|  | std::string TestOnly_GetMimeType(const std::string& filename); | 
|  |  | 
|  | // Returns the contents of the Undeclared Outputs manifest. | 
|  | bool TestOnly_CreateUndeclaredOutputsManifest( | 
|  | const std::vector<FileInfo>& files, std::string* result); | 
|  |  | 
|  | bool TestOnly_CreateUndeclaredOutputsAnnotations( | 
|  | const std::wstring& abs_root, const std::wstring& abs_output); | 
|  |  | 
|  | bool TestOnly_AsMixedPath(const std::wstring& path, std::string* result); | 
|  |  | 
|  | // Creates a Tee object. See the Tee class declaration for more info. | 
|  | bool TestOnly_CreateTee(bazel::windows::AutoHandle* input, | 
|  | bazel::windows::AutoHandle* output1, | 
|  | bazel::windows::AutoHandle* output2, | 
|  | std::unique_ptr<Tee>* result); | 
|  |  | 
|  | bool TestOnly_CdataEncode(IFStream* in_stm, std::basic_ostream<char>* out_stm); | 
|  |  | 
|  | IFStream* TestOnly_CreateIFStream(HANDLE handle, DWORD page_size); | 
|  |  | 
|  | }  // namespace testing | 
|  |  | 
|  | }  // namespace test_wrapper | 
|  | }  // namespace tools | 
|  | }  // namespace bazel | 
|  |  | 
|  | #endif  // BAZEL_TOOLS_TEST_WINDOWS_TW_H_ |