blob: 70a22adb480602a9ad32aa0fa8b14d250fa77202 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#pragma once
#include <limits.h>
#include <stddef.h>
#include <fbl/macros.h>
#include <fbl/ref_counted.h>
#include <fbl/ref_ptr.h>
#include <fbl/string.h>
#include <fbl/string_buffer.h>
#include <fbl/unique_ptr.h>
#include <fuzz-utils/string-list.h>
#include <zircon/types.h>
namespace fuzzing {
// |fuzzing::Path| is a utility class for interacting with files on the filesystem. In the methods
// below, |relpath| must not be null and is a relative path under the current path.
class Path final {
public:
Path();
~Path();
// Returns the current path as a C-style string.
const char* c_str() const { return path_->buffer_.c_str(); }
size_t length() const { return path_->buffer_.length(); }
// Returns an absolute path to the file described by |relpath|.
fbl::String Join(const char* relpath) const;
fbl::String Join(const fbl::String& relpath) const { return Join(relpath.c_str()); }
// Returns whether the given |relpath| is present and is a regular file.
bool IsFile(const char *relpath) const { return GetSize(relpath, nullptr) == ZX_OK; }
bool IsFile(const fbl::String &relpath) const { return IsFile(relpath.c_str()); }
// Returns the size of the file in |out|, if it exists. |out| is unchanged on error.
zx_status_t GetSize(const char* relpath, size_t* out) const;
zx_status_t GetSize(const fbl::String& relpath, size_t* out) const {
return GetSize(relpath.c_str(), out);
}
// Returns a list of files in the directory given by the current path.
fbl::unique_ptr<StringList> List() const;
// Checks if a directory exists at |relpath| and creates on if it does not.
zx_status_t Ensure(const char* relpath);
zx_status_t Ensure(const fbl::String& relpath) { return Ensure(relpath.c_str()); }
// Changes the current path to the directory described by |relpath|.
zx_status_t Push(const char* relpath);
zx_status_t Push(const fbl::String& relpath) { return Push(relpath.c_str()); }
// Changes to current path to value before the corresponding |Push|. Does nothing if already at
// the filesystem root.
void Pop();
// Deletes the file described by |relpath|, if it exists.
zx_status_t Remove(const char* relpath);
zx_status_t Remove(const fbl::String& relpath) { return Remove(relpath.c_str()); }
// Moves and/or renames the file described by |old_relpath| to |new_relpath|.
zx_status_t Rename(const char* old_relpath, const char* new_relpath);
zx_status_t Rename(const fbl::String& old_relpath, const fbl::String& new_relpath) {
return Rename(old_relpath.c_str(), new_relpath.c_str());
}
// Resets the current path to point at the filesystem root.
void Reset();
private:
// |fuzzing::Path::PathBuffer| defines a reference-counted string buffer that can be shared
// between multiple |fuzzing::Path| objects chained together by |Push|.
struct PathBuffer final : public fbl::RefCounted<PathBuffer> {
fbl::StringBuffer<PATH_MAX> buffer_;
};
explicit Path(fbl::RefPtr<PathBuffer> path);
explicit Path(const Path& other);
Path(Path&&) = delete;
Path& operator=(const Path&) = delete;
Path& operator=(Path&&) = delete;
// The preceding |Path| object as set by |Push|.
fbl::unique_ptr<Path> parent_;
// The reference-counted string buffer shared by |push|-chained |Path| objects.
fbl::RefPtr<PathBuffer> path_;
// The amount of |buffer_| belonging to this |Path| object. The buffer will be reset to this
// length by |Pop|.
size_t length_;
};
} // namespace fuzzing