192 lines
5.7 KiB
C++
192 lines
5.7 KiB
C++
/* Copyright 2024 The TensorFlow 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 TENSORFLOW_LITE_DELEGATES_XNNPACK_FILE_UTIL_H_
|
|
#define TENSORFLOW_LITE_DELEGATES_XNNPACK_FILE_UTIL_H_
|
|
|
|
#if !defined(_WIN32)
|
|
#include <sys/types.h>
|
|
#endif
|
|
|
|
#include <cstddef>
|
|
#include <utility>
|
|
|
|
namespace tflite {
|
|
namespace xnnpack {
|
|
|
|
#if defined(_WIN32)
|
|
using mode_t = int;
|
|
#endif
|
|
|
|
class FileDescriptorView {
|
|
public:
|
|
#if defined(_WIN32)
|
|
using Offset = __int64;
|
|
#else
|
|
using Offset = off_t;
|
|
#endif
|
|
|
|
explicit FileDescriptorView(int fd) : fd_(fd) {}
|
|
FileDescriptorView() = default;
|
|
|
|
// Checks that the file descriptor has a valid value.
|
|
//
|
|
// WARNING: this does not check that the descriptor points to an open file.
|
|
bool IsValid() const { return fd_ >= 0; }
|
|
|
|
// Returns the file descriptor value.
|
|
int Value() const { return fd_; }
|
|
|
|
// Returns the cursor position in the current file.
|
|
//
|
|
// Equivalent to MovePos(0).
|
|
//
|
|
// WARNING: the file descriptor must be valid and the file must be opened.
|
|
Offset GetPos() const;
|
|
|
|
// Sets the absolute cursor position in the current file.
|
|
//
|
|
// Returns the cursor position in the file or -1 on error.
|
|
//
|
|
// WARNING: the file descriptor must be valid and the file must be opened.
|
|
Offset SetPos(Offset position) const;
|
|
|
|
// Sets the cursor position relative to the file end.
|
|
//
|
|
// Returns the cursor position in the file or -1 on error.
|
|
//
|
|
// WARNING: the file descriptor must be valid and the file must be opened.
|
|
Offset SetPosFromEnd(Offset offset) const;
|
|
|
|
// Moves the cursor position by the given offset in the current file.
|
|
//
|
|
// Returns the cursor position in the file or -1 on error.
|
|
//
|
|
// WARNING: the file descriptor must be valid and the file must be opened.
|
|
Offset MovePos(Offset offset) const;
|
|
|
|
// Returns the size of the file.
|
|
Offset Size() const {
|
|
Offset pos = GetPos();
|
|
Offset size = SetPosFromEnd(0);
|
|
SetPos(pos);
|
|
return size;
|
|
}
|
|
|
|
// Reads `count` bytes from the file at the current position to `dst`.
|
|
//
|
|
// Returns true if all the data available in the file was read to the buffer
|
|
// (i.e. `count` bytes were read or EOF was reached).
|
|
//
|
|
// This is a convenience function wrapping the standard `read` function. If
|
|
// you need finer grain control use that directly.
|
|
[[nodiscard /*Reading from a file may fail.*/]]
|
|
bool Read(void* dst, size_t count) const;
|
|
|
|
// Writes `count` bytes to the file at the current position from `src`.
|
|
//
|
|
// This is a convenience function wrapping the standard `write` function. If
|
|
// you need finer grain control use that directly.
|
|
[[nodiscard /*Reading from a file may fail.*/]]
|
|
bool Write(const void* src, size_t count) const;
|
|
|
|
// Truncates the file to the given size.
|
|
//
|
|
// Returns true if the file was truncated successfully.
|
|
[[nodiscard /*Reading from a file may fail.*/]]
|
|
bool Truncate(size_t size) const;
|
|
|
|
protected:
|
|
int fd_ = -1;
|
|
};
|
|
|
|
// Wraps a C file descriptor and closes it when destroyed.
|
|
//
|
|
// Note that constness of the wrapped does NOT propagate to the file operations.
|
|
class FileDescriptor : public FileDescriptorView {
|
|
public:
|
|
explicit FileDescriptor(int fd) : FileDescriptorView(fd) {}
|
|
|
|
FileDescriptor() = default;
|
|
|
|
FileDescriptor(const FileDescriptor&) = delete;
|
|
FileDescriptor& operator=(const FileDescriptor&) = delete;
|
|
|
|
FileDescriptor(FileDescriptor&& other) : FileDescriptorView{other.fd_} {
|
|
other.fd_ = -1;
|
|
}
|
|
|
|
FileDescriptor& operator=(FileDescriptor&& other) {
|
|
if (other.fd_ != fd_) {
|
|
Close();
|
|
fd_ = other.fd_;
|
|
other.fd_ = -1;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
~FileDescriptor() { Close(); }
|
|
|
|
// Duplicates an existing raw file descriptor.
|
|
static FileDescriptor Duplicate(int fd);
|
|
|
|
// Closes the current file descriptor if needed and assigns the given value.
|
|
void Reset(int new_fd);
|
|
|
|
// Duplicates the current file descriptor and returns the new file descriptor.
|
|
//
|
|
// If the file descriptor is invalid, returns a new invalid FileDescriptor
|
|
// object.
|
|
FileDescriptor Duplicate() const;
|
|
|
|
// Opens a file.
|
|
//
|
|
// Directly maps to the standard C function `open`.
|
|
static FileDescriptor Open(const char* path, int flags, mode_t mode = 0);
|
|
|
|
// Closes the current file descriptor and sets it to -1.
|
|
void Close();
|
|
|
|
// Returns the current file descriptor value and stops managing it.
|
|
int Release() {
|
|
const int fd = fd_;
|
|
fd_ = -1;
|
|
return fd;
|
|
}
|
|
|
|
friend void swap(FileDescriptor& f1, FileDescriptor& f2) {
|
|
using std::swap;
|
|
swap(f1.fd_, f2.fd_);
|
|
}
|
|
};
|
|
|
|
// Checks if the current build and system support creating an in-memory file
|
|
// descriptor.
|
|
bool InMemoryFileDescriptorAvailable();
|
|
|
|
// Returns true if the file is empty (the file may exist)
|
|
//
|
|
// Note: if `fd` is valid, then `path` is ignored.
|
|
bool IsFileEmpty(const char* path, const FileDescriptor& fd);
|
|
|
|
// Creates a new file descriptor that isn't backed by a file system. The file
|
|
// will be automatically cleaned up when the last file descriptor pointing to it
|
|
// is closed.
|
|
FileDescriptor CreateInMemoryFileDescriptor(const char* path);
|
|
|
|
} // namespace xnnpack
|
|
} // namespace tflite
|
|
|
|
#endif // TENSORFLOW_LITE_DELEGATES_XNNPACK_FILE_UTIL_H_
|