169030100STrond Norbye/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
269030100STrond Norbye/*
346f2da31STrond Norbye *     Copyright 2016 Couchbase, Inc
469030100STrond Norbye *
569030100STrond Norbye *   Licensed under the Apache License, Version 2.0 (the "License");
669030100STrond Norbye *   you may not use this file except in compliance with the License.
769030100STrond Norbye *   You may obtain a copy of the License at
869030100STrond Norbye *
969030100STrond Norbye *       http://www.apache.org/licenses/LICENSE-2.0
1069030100STrond Norbye *
1169030100STrond Norbye *   Unless required by applicable law or agreed to in writing, software
1269030100STrond Norbye *   distributed under the License is distributed on an "AS IS" BASIS,
1369030100STrond Norbye *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1469030100STrond Norbye *   See the License for the specific language governing permissions and
1569030100STrond Norbye *   limitations under the License.
1669030100STrond Norbye */
17e47c8823STrond Norbye#pragma once
1869030100STrond Norbye
19c941f953STrond Norbye#include <algorithm>
20d3828d9fSTrond Norbye#include <cstdint>
21128fc01bSTrond Norbye#include <cstdio>
222478c239STrond Norbye#include <memory>
2369030100STrond Norbye#include <string>
2469030100STrond Norbye#include <vector>
2569030100STrond Norbye
26b93566a1STrond Norbye#include <platform/dirutils-visibility.h>
27be339d1eSDave Rigby
28e47c8823STrond Norbyenamespace cb {
29e47c8823STrond Norbyenamespace io {
301fd46704STrond Norbye
311fd46704STrond Norbye#ifdef WIN32
321fd46704STrond Norbyeconst char DirectorySeparator{'\\'};
331fd46704STrond Norbye#else
341fd46704STrond Norbyeconst char DirectorySeparator{'/'};
351fd46704STrond Norbye#endif
361fd46704STrond Norbye
37e47c8823STrond Norbye/**
38e47c8823STrond Norbye * Return the directory part of an absolute path
39e47c8823STrond Norbye */
40e47c8823STrond NorbyeDIRUTILS_PUBLIC_API
41e47c8823STrond Norbyestd::string dirname(const std::string& dir);
4269030100STrond Norbye
43e47c8823STrond Norbye/**
44e47c8823STrond Norbye * Return the filename part of an absolute path
45e47c8823STrond Norbye */
46e47c8823STrond NorbyeDIRUTILS_PUBLIC_API
47e47c8823STrond Norbyestd::string basename(const std::string& name);
4869030100STrond Norbye
49e47c8823STrond Norbye/**
50e47c8823STrond Norbye * Return a vector containing all of the files starting with a given
51e47c8823STrond Norbye * name stored in a given directory
52e47c8823STrond Norbye */
53e47c8823STrond NorbyeDIRUTILS_PUBLIC_API
54e47c8823STrond Norbyestd::vector<std::string> findFilesWithPrefix(const std::string& dir,
55e47c8823STrond Norbye                                             const std::string& name);
5669030100STrond Norbye
57e47c8823STrond Norbye/**
58e47c8823STrond Norbye * Return a vector containing all of the files starting with a given
59e47c8823STrond Norbye * name specified with this absolute path
60e47c8823STrond Norbye */
61e47c8823STrond NorbyeDIRUTILS_PUBLIC_API
62e47c8823STrond Norbyestd::vector<std::string> findFilesWithPrefix(const std::string& name);
63877ba0c5STrond Norbye
64e47c8823STrond Norbye/**
65e47c8823STrond Norbye * Return a vector containing all of the files containing a given
66e47c8823STrond Norbye * substring located in a given directory
67e47c8823STrond Norbye */
68e47c8823STrond NorbyeDIRUTILS_PUBLIC_API
69e47c8823STrond Norbyestd::vector<std::string> findFilesContaining(const std::string& dir,
70e47c8823STrond Norbye                                             const std::string& name);
71877ba0c5STrond Norbye
72e47c8823STrond Norbye/**
73e47c8823STrond Norbye * Delete a file or directory (including subdirectories)
74e688f59fSSriram Ganesan * @param path path of the file or directory that is being removed
75e688f59fSSriram Ganesan * @throws system_error in case of any errors during deletion
76e47c8823STrond Norbye */
77e47c8823STrond NorbyeDIRUTILS_PUBLIC_API
78e688f59fSSriram Ganesanvoid rmrf(const std::string& path);
79f46a036aSTrond Norbye
80e47c8823STrond Norbye/**
81e47c8823STrond Norbye * Check if a directory exists or not
82e47c8823STrond Norbye */
83e47c8823STrond NorbyeDIRUTILS_PUBLIC_API
84e47c8823STrond Norbyebool isDirectory(const std::string& directory);
85c681fee5STrond Norbye
86e47c8823STrond Norbye/**
87e47c8823STrond Norbye * Check if a path exists and is a file
88e47c8823STrond Norbye */
89e47c8823STrond NorbyeDIRUTILS_PUBLIC_API
90e47c8823STrond Norbyebool isFile(const std::string& file);
91f46a036aSTrond Norbye
92e47c8823STrond Norbye/**
93e47c8823STrond Norbye * Try to create directory including all of the parent directories
94e47c8823STrond Norbye *
95e47c8823STrond Norbye * @param directory the directory to create
96e6a1e8c9STrond Norbye * @throws std::runtime_error if an error occurs
97e47c8823STrond Norbye */
98e47c8823STrond NorbyeDIRUTILS_PUBLIC_API
99e6a1e8c9STrond Norbyevoid mkdirp(const std::string& directory);
10046f2da31STrond Norbye
101e47c8823STrond Norbye/**
1028b673476SBen Huddleston * Create a unique temporary file with the given prefix.
103e47c8823STrond Norbye *
104e47c8823STrond Norbye * This method is implemented by using cb_mktemp, but the caller
105e47c8823STrond Norbye * does not need to add the XXXXXX in the filename.
106e47c8823STrond Norbye *
107e47c8823STrond Norbye * @param prefix The prefix to use in the filename.
108e47c8823STrond Norbye * @return The unique filename
109e47c8823STrond Norbye */
110e47c8823STrond NorbyeDIRUTILS_PUBLIC_API
111e47c8823STrond Norbyestd::string mktemp(const std::string& prefix);
11246f2da31STrond Norbye
1138b673476SBen Huddleston/**
1148b673476SBen Huddleston * Create a unique temporary directory with the given prefix.
1158b673476SBen Huddleston *
116d7e403a4STrond Norbye * It works similar to mktemp
1178b673476SBen Huddleston *
1188b673476SBen Huddleston * @param prefix The prefix to use in the directory name.
1198b673476SBen Huddleston * @return The unique directory name
1208b673476SBen Huddleston */
1218b673476SBen HuddlestonDIRUTILS_PUBLIC_API
122d7e403a4STrond Norbyestd::string mkdtemp(const std::string& prefix);
1238b673476SBen Huddleston
124e47c8823STrond Norbye/**
125e47c8823STrond Norbye * Get the name of the current working directory
126e47c8823STrond Norbye *
127e47c8823STrond Norbye * @return the name of the current working directory
128e47c8823STrond Norbye * @throws std::system_error if we fail to determine the current working
129e47c8823STrond Norbye *         directory
130e47c8823STrond Norbye */
131e47c8823STrond NorbyeDIRUTILS_PUBLIC_API
132e47c8823STrond Norbyestd::string getcwd(void);
133d3828d9fSTrond Norbye
134d3828d9fSTrond Norbye/**
135d3828d9fSTrond Norbye * Try to set the maximum number of file descriptors to the requested
136d3828d9fSTrond Norbye * limit, and return the number we could get.
137d3828d9fSTrond Norbye *
138d3828d9fSTrond Norbye * On a Unix system this limit affects files and sockets
139d3828d9fSTrond Norbye *
140d3828d9fSTrond Norbye * @param limit the requested maximum number of file descriptors
141d3828d9fSTrond Norbye * @return the maximum number of file descriptors
142d3828d9fSTrond Norbye * @throws std::system_error if we fail to determine the maximum number
143d3828d9fSTrond Norbye *         of file descriptor
144d3828d9fSTrond Norbye */
145d3828d9fSTrond NorbyeDIRUTILS_PUBLIC_API
146d3828d9fSTrond Norbyeuint64_t maximizeFileDescriptors(uint64_t limit);
147c941f953STrond Norbye
148c941f953STrond Norbye/**
149c941f953STrond Norbye * Windows use '\' as the directory separator character (but internally it
150c941f953STrond Norbye * allows '/', but I've seen problems where I try to mix '\' and '/' in the
151c941f953STrond Norbye * same path. This method replace all occurrences of '/' with '\' on windows.
152c941f953STrond Norbye *
153c941f953STrond Norbye * @param path the path to sanitize
154c941f953STrond Norbye */
155c941f953STrond Norbyeinline void sanitizePath(std::string& path) {
156c941f953STrond Norbye#ifdef WIN32
157c941f953STrond Norbye    std::replace(path.begin(), path.end(), '/', '\\');
158c941f953STrond Norbye#endif
159c941f953STrond Norbye}
160255b68abSTrond Norbye
161255b68abSTrond Norbye/**
162255b68abSTrond Norbye * Load the named file
163255b68abSTrond Norbye *
164255b68abSTrond Norbye * @param name the name of the file to load
165255b68abSTrond Norbye * @return The content of the file
166255b68abSTrond Norbye * @throws std::system_exception if an error occurs opening / reading the file
167255b68abSTrond Norbye *         std::bad_alloc for memory allocation errors
168255b68abSTrond Norbye */
169255b68abSTrond NorbyeDIRUTILS_PUBLIC_API
170255b68abSTrond Norbyestd::string loadFile(const std::string& name);
1712478c239STrond Norbye
172128fc01bSTrond Norbye/**
173128fc01bSTrond Norbye * Set the file mode to BINARY
174128fc01bSTrond Norbye *
175128fc01bSTrond Norbye * @param fp the file stream to update
176128fc01bSTrond Norbye * @throws std::system_error if an error occurs
177128fc01bSTrond Norbye */
178128fc01bSTrond NorbyeDIRUTILS_PUBLIC_API
179128fc01bSTrond Norbyevoid setBinaryMode(FILE* fp);
180128fc01bSTrond Norbye
1812478c239STrond Norbye/**
1822478c239STrond Norbye * A representation for a dynamic loaded library
1832478c239STrond Norbye */
1842478c239STrond Norbyeclass LibraryHandle {
1852478c239STrond Norbyepublic:
1862478c239STrond Norbye    /// Can't be copied
1872478c239STrond Norbye    LibraryHandle(LibraryHandle&) = delete;
1882478c239STrond Norbye    virtual ~LibraryHandle();
1892478c239STrond Norbye
1902478c239STrond Norbye    /**
1912478c239STrond Norbye     * Try to find the named symbol in the library
1922478c239STrond Norbye     *
1932478c239STrond Norbye     * @param symbol the symbol to search for
1942478c239STrond Norbye     * @return pointer to the symbol
1952478c239STrond Norbye     * @throws std::exception if an error occurrs or the symbol isn't found
1962478c239STrond Norbye     */
1972478c239STrond Norbye    template <typename T>
1982478c239STrond Norbye    T find(const std::string& symbol_name) const {
1992478c239STrond Norbye        return reinterpret_cast<T>(findSymbol(symbol_name));
2002478c239STrond Norbye    }
2012478c239STrond Norbye
2022478c239STrond Norbye    /// get the name of the loaded library
2032478c239STrond Norbye    virtual std::string getName() const = 0;
2042478c239STrond Norbye
2052478c239STrond Norbyeprotected:
2062478c239STrond Norbye    virtual void* findSymbol(const std::string& symbol) const = 0;
2072478c239STrond Norbye    LibraryHandle() = default;
2082478c239STrond Norbye};
2092478c239STrond Norbye
2102478c239STrond Norbye/**
2112478c239STrond Norbye * Load a dynamic library
2122478c239STrond Norbye *
2132478c239STrond Norbye * @param filename The name of the library to load
2142478c239STrond Norbye * @return a handle to the loaded library. Closing the library invalidates
2152478c239STrond Norbye *         all symbols
2162478c239STrond Norbye * @throws std::exception if an error occurs (file not found or missing
2172478c239STrond Norbye *                        dependencies / symbols)
2182478c239STrond Norbye */
2192478c239STrond NorbyeDIRUTILS_PUBLIC_API
2202478c239STrond Norbyestd::unique_ptr<LibraryHandle> loadLibrary(const std::string& filename);
2212478c239STrond Norbye} // namespace io
2222478c239STrond Norbye} // namespace cb