OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license | |
5 * that can be found in the LICENSE file in the root of the source | |
6 * tree. An additional intellectual property rights grant can be found | |
7 * in the file PATENTS. All contributing project authors may | |
8 * be found in the AUTHORS file in the root of the source tree. | |
9 */ | |
10 | |
11 #include "webrtc/base/file.h" | |
12 | |
13 #include <limits> | |
14 | |
15 #if defined(WEBRTC_WIN) | |
16 #include <io.h> | |
17 #else | |
18 #include <unistd.h> | |
19 #include <errno.h> | |
20 #endif | |
21 | |
22 namespace rtc { | |
23 | |
24 File::File(rtc::PlatformFile file) : file_(file) {} | |
25 | |
26 File::~File() { | |
27 Close(); | |
28 } | |
29 | |
30 size_t File::Write(const char* data, size_t length) { | |
31 size_t total_written = 0; | |
32 do { | |
33 size_t written = | |
34 WriteNoBestEffort(data + total_written, length - total_written); | |
35 if (written == 0) | |
36 break; | |
37 total_written += written; | |
38 } while (total_written < length); | |
39 return total_written; | |
40 } | |
sprang_webrtc
2016/08/05 14:45:14
nit: empty line between methods
here and elsewhere
palmkvist
2016/08/08 11:15:35
Done.
| |
41 size_t File::Read(char* buffer, size_t length) { | |
42 size_t total_read = 0; | |
43 do { | |
44 size_t read = ReadNoBestEffort(buffer + total_read, length - total_read); | |
45 if (read == 0) | |
46 break; | |
47 total_read += read; | |
48 } while (total_read < length); | |
49 return total_read; | |
50 } | |
51 | |
52 size_t File::WriteAt(const char* data, size_t length, size_t offset) { | |
53 size_t total_written = 0; | |
54 do { | |
55 size_t written = WriteAtNoBestEffort( | |
56 data + total_written, length - total_written, offset + total_written); | |
57 if (written == 0) | |
58 break; | |
59 total_written += written; | |
60 } while (total_written < length); | |
61 return total_written; | |
62 } | |
63 size_t File::ReadAt(char* buffer, size_t length, size_t offset) { | |
64 size_t total_read = 0; | |
65 do { | |
66 size_t read = ReadAtNoBestEffort(buffer + total_read, length - total_read, | |
67 offset + total_read); | |
68 if (read == 0) | |
69 break; | |
70 total_read += read; | |
71 } while (total_read < length); | |
72 return total_read; | |
73 } | |
74 | |
75 #if defined(WEBRTC_WIN) | |
sprang_webrtc
2016/08/05 14:45:14
If there's a large amount of code different betwee
palmkvist
2016/08/08 11:15:35
Done.
| |
76 | |
77 size_t File::WriteNoBestEffort(const char* data, size_t length) { | |
78 RTC_CHECK(length < std::numeric_limits<DWORD>::max()); | |
sprang_webrtc
2016/08/05 14:45:14
RTC_CHECK_LT
palmkvist
2016/08/08 11:15:35
Done.
| |
79 DWORD bytes_written; | |
80 if (::WriteFile(file_, data, static_cast<DWORD>(length), &bytes_written, | |
81 NULL)) | |
sprang_webrtc
2016/08/05 14:45:14
nullptr
palmkvist
2016/08/08 11:15:35
Done.
| |
82 return size_t{bytes_written}; | |
sprang_webrtc
2016/08/05 14:45:14
wrap in {} if if-statement is multi-line
Don't th
| |
83 return 0; | |
84 } | |
85 size_t File::ReadNoBestEffort(char* buffer, size_t length) { | |
86 RTC_CHECK(length < std::numeric_limits<DWORD>::max()); | |
87 DWORD bytes_read; | |
88 if (::ReadFile(file_, buffer, static_cast<DWORD>(length), &bytes_read, NULL)) | |
89 return size_t{bytes_read}; | |
90 return 0; | |
91 } | |
92 | |
93 size_t File::WriteAtNoBestEffort(const char* data, | |
94 size_t length, | |
95 size_t offset) { | |
96 RTC_CHECK(length < std::numeric_limits<DWORD>::max()); | |
97 LARGE_INTEGER offset_li; | |
98 offset_li.QuadPart = offset; | |
99 | |
100 OVERLAPPED overlapped = {0}; | |
101 overlapped.Offset = offset_li.LowPart; | |
102 overlapped.OffsetHigh = offset_li.HighPart; | |
103 | |
104 DWORD bytes_written; | |
105 if (::WriteFile(file_, data, static_cast<DWORD>(length), &bytes_written, | |
106 &overlapped)) | |
107 return size_t{bytes_written}; | |
108 return 0; | |
109 } | |
110 size_t File::ReadAtNoBestEffort(char* data, size_t length, size_t offset) { | |
111 LARGE_INTEGER offest_li; | |
112 offset_li.QuadPart = offset; | |
113 | |
114 OVERLAPPED overlapped = {0}; | |
115 overlapped.Offset = offset_li.LowPart; | |
116 overlapped.OffsetHigh = offset_li.HighPart; | |
117 | |
118 DWORD bytes_read; | |
119 if (::ReadFile(file_, data, length, &bytes_read, &overlapped)) | |
120 return size_t{bytes_read}; | |
121 return 0; | |
122 } | |
123 | |
124 bool File::Seek(size_t offset) { | |
125 LARGE_INTEGER distance; | |
126 distance.QuadPart = offset; | |
127 return SetFilePointerEx(file_, distance, NULL, FILE_BEGIN) != 1; | |
128 } | |
129 | |
130 bool File::Close() { | |
131 if (file_ == rtc::kInvalidPlatformFileValue) | |
132 return false; | |
133 bool ret = CloseHandle(file_) != 0; | |
134 file_ = rtc::kInvalidPlatformFileValue; | |
135 return ret; | |
136 } | |
137 | |
138 #else | |
139 | |
140 #define HANDLE_EINTR(x) \ | |
141 ({ \ | |
142 decltype(x) eintr_wrapper_result; \ | |
143 do { \ | |
144 eintr_wrapper_result = (x); \ | |
145 } while (eintr_wrapper_result == -1 && errno == EINTR); \ | |
146 eintr_wrapper_result; \ | |
147 }) | |
sprang_webrtc
2016/08/05 14:45:14
Avoid macros if possible
palmkvist
2016/08/08 11:15:35
It is possible, with some repetition (four times,
| |
148 | |
149 size_t File::WriteNoBestEffort(const char* data, size_t length) { | |
150 ssize_t rv = HANDLE_EINTR(write(file_, data, length)); | |
151 return rv < 0 ? 0 : size_t{rv}; | |
152 } | |
153 size_t File::ReadNoBestEffort(char* buffer, size_t length) { | |
154 ssize_t rv = HANDLE_EINTR(read(file_, buffer, length)); | |
155 return rv < 0 ? 0 : size_t{rv}; | |
156 } | |
157 | |
158 size_t File::WriteAtNoBestEffort(const char* data, | |
159 size_t length, | |
160 size_t offset) { | |
161 ssize_t rv = HANDLE_EINTR(pwrite(file_, data, length, offset)); | |
162 return rv < 0 ? 0 : size_t{rv}; | |
163 } | |
164 size_t File::ReadAtNoBestEffort(char* data, size_t length, size_t offset) { | |
165 ssize_t rv = HANDLE_EINTR(pread(file_, data, length, offset)); | |
166 return rv < 0 ? 0 : size_t{rv}; | |
167 } | |
168 | |
169 bool File::Seek(size_t offset) { | |
170 static_assert(sizeof(size_t) <= sizeof(off_t), "size_t must fit in off_t"); | |
171 return lseek(file_, off_t{offset}, SEEK_SET) != ((off_t)-1); | |
172 } | |
173 | |
174 bool File::Close() { | |
175 if (file_ == rtc::kInvalidPlatformFileValue) | |
176 return false; | |
177 bool ret = close(file_) == 0; | |
178 file_ = rtc::kInvalidPlatformFileValue; | |
179 return ret; | |
180 } | |
181 | |
182 #endif | |
183 | |
184 } // namespace rtc | |
OLD | NEW |