xref: /aosp_15_r20/external/webrtc/rtc_base/system/file_wrapper.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker #ifndef RTC_BASE_SYSTEM_FILE_WRAPPER_H_
12*d9f75844SAndroid Build Coastguard Worker #define RTC_BASE_SYSTEM_FILE_WRAPPER_H_
13*d9f75844SAndroid Build Coastguard Worker 
14*d9f75844SAndroid Build Coastguard Worker #include <stddef.h>
15*d9f75844SAndroid Build Coastguard Worker #include <stdio.h>
16*d9f75844SAndroid Build Coastguard Worker 
17*d9f75844SAndroid Build Coastguard Worker #include <string>
18*d9f75844SAndroid Build Coastguard Worker 
19*d9f75844SAndroid Build Coastguard Worker #include "absl/strings/string_view.h"
20*d9f75844SAndroid Build Coastguard Worker 
21*d9f75844SAndroid Build Coastguard Worker // Implementation that can read (exclusive) or write from/to a file.
22*d9f75844SAndroid Build Coastguard Worker 
23*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
24*d9f75844SAndroid Build Coastguard Worker 
25*d9f75844SAndroid Build Coastguard Worker // This class is a thin wrapper around FILE*. It's main features are that it
26*d9f75844SAndroid Build Coastguard Worker // owns the FILE*, calling fclose on destruction, and that on windows, file
27*d9f75844SAndroid Build Coastguard Worker // names passed to the open methods are always treated as utf-8, regardless of
28*d9f75844SAndroid Build Coastguard Worker // system code page.
29*d9f75844SAndroid Build Coastguard Worker 
30*d9f75844SAndroid Build Coastguard Worker // Most of the methods return only a success/fail indication. When needed, an
31*d9f75844SAndroid Build Coastguard Worker // optional argument |int* error| should be added to all methods, in the same
32*d9f75844SAndroid Build Coastguard Worker // way as for the OpenWriteOnly methods.
33*d9f75844SAndroid Build Coastguard Worker class FileWrapper final {
34*d9f75844SAndroid Build Coastguard Worker  public:
35*d9f75844SAndroid Build Coastguard Worker   // Opens a file, in read or write mode. Use the is_open() method on the
36*d9f75844SAndroid Build Coastguard Worker   // returned object to check if the open operation was successful. On failure,
37*d9f75844SAndroid Build Coastguard Worker   // and if `error` is non-null, the system errno value is stored at |*error|.
38*d9f75844SAndroid Build Coastguard Worker   // The file is closed by the destructor.
39*d9f75844SAndroid Build Coastguard Worker   static FileWrapper OpenReadOnly(absl::string_view file_name_utf8);
40*d9f75844SAndroid Build Coastguard Worker   static FileWrapper OpenWriteOnly(absl::string_view file_name_utf8,
41*d9f75844SAndroid Build Coastguard Worker                                    int* error = nullptr);
42*d9f75844SAndroid Build Coastguard Worker 
43*d9f75844SAndroid Build Coastguard Worker   FileWrapper() = default;
44*d9f75844SAndroid Build Coastguard Worker 
45*d9f75844SAndroid Build Coastguard Worker   // Takes over ownership of `file`, closing it on destruction. Calling with
46*d9f75844SAndroid Build Coastguard Worker   // null `file` is allowed, and results in a FileWrapper with is_open() false.
FileWrapper(FILE * file)47*d9f75844SAndroid Build Coastguard Worker   explicit FileWrapper(FILE* file) : file_(file) {}
~FileWrapper()48*d9f75844SAndroid Build Coastguard Worker   ~FileWrapper() { Close(); }
49*d9f75844SAndroid Build Coastguard Worker 
50*d9f75844SAndroid Build Coastguard Worker   // Copying is not supported.
51*d9f75844SAndroid Build Coastguard Worker   FileWrapper(const FileWrapper&) = delete;
52*d9f75844SAndroid Build Coastguard Worker   FileWrapper& operator=(const FileWrapper&) = delete;
53*d9f75844SAndroid Build Coastguard Worker 
54*d9f75844SAndroid Build Coastguard Worker   // Support for move semantics.
55*d9f75844SAndroid Build Coastguard Worker   FileWrapper(FileWrapper&&);
56*d9f75844SAndroid Build Coastguard Worker   FileWrapper& operator=(FileWrapper&&);
57*d9f75844SAndroid Build Coastguard Worker 
58*d9f75844SAndroid Build Coastguard Worker   // Returns true if a file has been opened. If the file is not open, no methods
59*d9f75844SAndroid Build Coastguard Worker   // but is_open and Close may be called.
is_open()60*d9f75844SAndroid Build Coastguard Worker   bool is_open() const { return file_ != nullptr; }
61*d9f75844SAndroid Build Coastguard Worker 
62*d9f75844SAndroid Build Coastguard Worker   // Closes the file, and implies Flush. Returns true on success, false if
63*d9f75844SAndroid Build Coastguard Worker   // writing buffered data fails. On failure, the file is nevertheless closed.
64*d9f75844SAndroid Build Coastguard Worker   // Calling Close on an already closed file does nothing and returns success.
65*d9f75844SAndroid Build Coastguard Worker   bool Close();
66*d9f75844SAndroid Build Coastguard Worker 
67*d9f75844SAndroid Build Coastguard Worker   // Releases and returns the wrapped file without closing it. This call passes
68*d9f75844SAndroid Build Coastguard Worker   // the ownership of the file to the caller, and the wrapper is no longer
69*d9f75844SAndroid Build Coastguard Worker   // responsible for closing it. Similarly the previously wrapped file is no
70*d9f75844SAndroid Build Coastguard Worker   // longer available for the wrapper to use in any aspect.
71*d9f75844SAndroid Build Coastguard Worker   FILE* Release();
72*d9f75844SAndroid Build Coastguard Worker 
73*d9f75844SAndroid Build Coastguard Worker   // Write any buffered data to the underlying file. Returns true on success,
74*d9f75844SAndroid Build Coastguard Worker   // false on write error. Note: Flushing when closing, is not required.
75*d9f75844SAndroid Build Coastguard Worker   bool Flush();
76*d9f75844SAndroid Build Coastguard Worker 
77*d9f75844SAndroid Build Coastguard Worker   // Seeks to the beginning of file. Returns true on success, false on failure,
78*d9f75844SAndroid Build Coastguard Worker   // e.g., if the underlying file isn't seekable.
Rewind()79*d9f75844SAndroid Build Coastguard Worker   bool Rewind() { return SeekTo(0); }
80*d9f75844SAndroid Build Coastguard Worker   // TODO(nisse): The seek functions are used only by the WavReader. If that
81*d9f75844SAndroid Build Coastguard Worker   // code is demoted to test code, seek functions can be deleted from this
82*d9f75844SAndroid Build Coastguard Worker   // utility.
83*d9f75844SAndroid Build Coastguard Worker   // Seek relative to current file position.
84*d9f75844SAndroid Build Coastguard Worker   bool SeekRelative(int64_t offset);
85*d9f75844SAndroid Build Coastguard Worker   // Seek to given position.
86*d9f75844SAndroid Build Coastguard Worker   bool SeekTo(int64_t position);
87*d9f75844SAndroid Build Coastguard Worker 
88*d9f75844SAndroid Build Coastguard Worker   // Returns the file size or -1 if a size could not be determined.
89*d9f75844SAndroid Build Coastguard Worker   // (A file size might not exists for non-seekable files or file-like
90*d9f75844SAndroid Build Coastguard Worker   // objects, for example /dev/tty on unix.)
91*d9f75844SAndroid Build Coastguard Worker   long FileSize();
92*d9f75844SAndroid Build Coastguard Worker 
93*d9f75844SAndroid Build Coastguard Worker   // Returns number of bytes read. Short count indicates EOF or error.
94*d9f75844SAndroid Build Coastguard Worker   size_t Read(void* buf, size_t length);
95*d9f75844SAndroid Build Coastguard Worker 
96*d9f75844SAndroid Build Coastguard Worker   // If the most recent Read() returned a short count, this methods returns true
97*d9f75844SAndroid Build Coastguard Worker   // if the short count was due to EOF, and false it it was due to some i/o
98*d9f75844SAndroid Build Coastguard Worker   // error.
99*d9f75844SAndroid Build Coastguard Worker   bool ReadEof() const;
100*d9f75844SAndroid Build Coastguard Worker 
101*d9f75844SAndroid Build Coastguard Worker   // Returns true if all data was successfully written (or buffered), or false
102*d9f75844SAndroid Build Coastguard Worker   // if there was an error. Writing buffered data can fail later, and is
103*d9f75844SAndroid Build Coastguard Worker   // reported with return value from Flush or Close.
104*d9f75844SAndroid Build Coastguard Worker   bool Write(const void* buf, size_t length);
105*d9f75844SAndroid Build Coastguard Worker 
106*d9f75844SAndroid Build Coastguard Worker  private:
107*d9f75844SAndroid Build Coastguard Worker   FILE* file_ = nullptr;
108*d9f75844SAndroid Build Coastguard Worker };
109*d9f75844SAndroid Build Coastguard Worker 
110*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
111*d9f75844SAndroid Build Coastguard Worker 
112*d9f75844SAndroid Build Coastguard Worker #endif  // RTC_BASE_SYSTEM_FILE_WRAPPER_H_
113