blob: c9bd8258f48f087ef7eb55c94be364517540ec5f [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
henrike@webrtc.org143abd92012-02-08 19:39:38 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
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
phoglund@webrtc.org740be442012-12-12 12:52:15 +000011#include "webrtc/system_wrappers/source/file_impl.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000012
andrew@webrtc.org114c7902011-12-10 02:33:33 +000013#include <assert.h>
niklase@google.com470e71d2011-07-07 08:21:25 +000014
15#ifdef _WIN32
andrew@webrtc.org114c7902011-12-10 02:33:33 +000016#include <Windows.h>
niklase@google.com470e71d2011-07-07 08:21:25 +000017#else
andrew@webrtc.org114c7902011-12-10 02:33:33 +000018#include <stdarg.h>
19#include <string.h>
niklase@google.com470e71d2011-07-07 08:21:25 +000020#endif
21
phoglund@webrtc.org740be442012-12-12 12:52:15 +000022#include "webrtc/system_wrappers/interface/rw_lock_wrapper.h"
henrike@webrtc.org9a6dac42012-09-27 22:20:34 +000023
niklase@google.com470e71d2011-07-07 08:21:25 +000024namespace webrtc {
andrew@webrtc.org5ae19de2011-12-13 22:59:33 +000025
phoglund@webrtc.org740be442012-12-12 12:52:15 +000026FileWrapper* FileWrapper::Create() {
27 return new FileWrapperImpl();
niklase@google.com470e71d2011-07-07 08:21:25 +000028}
29
30FileWrapperImpl::FileWrapperImpl()
phoglund@webrtc.org740be442012-12-12 12:52:15 +000031 : rw_lock_(RWLockWrapper::CreateRWLock()),
32 id_(NULL),
33 open_(false),
34 looping_(false),
35 read_only_(false),
36 max_size_in_bytes_(0),
37 size_in_bytes_(0) {
38 memset(file_name_utf8_, 0, kMaxFileNameSize);
niklase@google.com470e71d2011-07-07 08:21:25 +000039}
40
phoglund@webrtc.org740be442012-12-12 12:52:15 +000041FileWrapperImpl::~FileWrapperImpl() {
42 if (id_ != NULL) {
43 fclose(id_);
44 }
45}
46
47int FileWrapperImpl::CloseFile() {
48 WriteLockScoped write(*rw_lock_);
49 return CloseFileImpl();
50}
51
52int FileWrapperImpl::Rewind() {
53 WriteLockScoped write(*rw_lock_);
54 if (looping_ || !read_only_) {
55 if (id_ != NULL) {
56 size_in_bytes_ = 0;
57 return fseek(id_, 0, SEEK_SET);
niklase@google.com470e71d2011-07-07 08:21:25 +000058 }
phoglund@webrtc.org740be442012-12-12 12:52:15 +000059 }
60 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +000061}
62
phoglund@webrtc.org740be442012-12-12 12:52:15 +000063int FileWrapperImpl::SetMaxFileSize(size_t bytes) {
64 WriteLockScoped write(*rw_lock_);
65 max_size_in_bytes_ = bytes;
66 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +000067}
68
phoglund@webrtc.org740be442012-12-12 12:52:15 +000069int FileWrapperImpl::Flush() {
70 WriteLockScoped write(*rw_lock_);
71 return FlushImpl();
72}
73
74int FileWrapperImpl::FileName(char* file_name_utf8,
75 size_t size) const {
76 ReadLockScoped read(*rw_lock_);
77 size_t length = strlen(file_name_utf8_);
78 if (length > kMaxFileNameSize) {
79 assert(false);
niklase@google.com470e71d2011-07-07 08:21:25 +000080 return -1;
phoglund@webrtc.org740be442012-12-12 12:52:15 +000081 }
82 if (length < 1) {
83 return -1;
84 }
85
86 // Make sure to NULL terminate
87 if (size < length) {
88 length = size - 1;
89 }
90 memcpy(file_name_utf8, file_name_utf8_, length);
91 file_name_utf8[length] = 0;
92 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +000093}
94
phoglund@webrtc.org740be442012-12-12 12:52:15 +000095bool FileWrapperImpl::Open() const {
96 ReadLockScoped read(*rw_lock_);
97 return open_;
niklase@google.com470e71d2011-07-07 08:21:25 +000098}
99
phoglund@webrtc.org740be442012-12-12 12:52:15 +0000100int FileWrapperImpl::OpenFile(const char* file_name_utf8, bool read_only,
101 bool loop, bool text) {
102 WriteLockScoped write(*rw_lock_);
103 size_t length = strlen(file_name_utf8);
104 if (length > kMaxFileNameSize - 1) {
105 return -1;
106 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000107
phoglund@webrtc.org740be442012-12-12 12:52:15 +0000108 read_only_ = read_only;
andrew@webrtc.org986fab12011-12-15 19:11:41 +0000109
phoglund@webrtc.org740be442012-12-12 12:52:15 +0000110 FILE* tmp_id = NULL;
niklase@google.com470e71d2011-07-07 08:21:25 +0000111#if defined _WIN32
phoglund@webrtc.org740be442012-12-12 12:52:15 +0000112 wchar_t wide_file_name[kMaxFileNameSize];
113 wide_file_name[0] = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000114
phoglund@webrtc.org740be442012-12-12 12:52:15 +0000115 MultiByteToWideChar(CP_UTF8,
116 0, // UTF8 flag
117 file_name_utf8,
118 -1, // Null terminated string
119 wide_file_name,
120 kMaxFileNameSize);
121 if (text) {
122 if (read_only) {
123 tmp_id = _wfopen(wide_file_name, L"rt");
niklase@google.com470e71d2011-07-07 08:21:25 +0000124 } else {
phoglund@webrtc.org740be442012-12-12 12:52:15 +0000125 tmp_id = _wfopen(wide_file_name, L"wt");
niklase@google.com470e71d2011-07-07 08:21:25 +0000126 }
phoglund@webrtc.org740be442012-12-12 12:52:15 +0000127 } else {
128 if (read_only) {
129 tmp_id = _wfopen(wide_file_name, L"rb");
130 } else {
131 tmp_id = _wfopen(wide_file_name, L"wb");
132 }
133 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000134#else
phoglund@webrtc.org740be442012-12-12 12:52:15 +0000135 if (text) {
136 if (read_only) {
137 tmp_id = fopen(file_name_utf8, "rt");
niklase@google.com470e71d2011-07-07 08:21:25 +0000138 } else {
phoglund@webrtc.org740be442012-12-12 12:52:15 +0000139 tmp_id = fopen(file_name_utf8, "wt");
niklase@google.com470e71d2011-07-07 08:21:25 +0000140 }
phoglund@webrtc.org740be442012-12-12 12:52:15 +0000141 } else {
142 if (read_only) {
143 tmp_id = fopen(file_name_utf8, "rb");
144 } else {
145 tmp_id = fopen(file_name_utf8, "wb");
146 }
147 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000148#endif
149
phoglund@webrtc.org740be442012-12-12 12:52:15 +0000150 if (tmp_id != NULL) {
151 // +1 comes from copying the NULL termination character.
152 memcpy(file_name_utf8_, file_name_utf8, length + 1);
153 if (id_ != NULL) {
154 fclose(id_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000155 }
phoglund@webrtc.org740be442012-12-12 12:52:15 +0000156 id_ = tmp_id;
157 looping_ = loop;
158 open_ = true;
159 return 0;
160 }
161 return -1;
162}
163
164int FileWrapperImpl::Read(void* buf, int length) {
165 WriteLockScoped write(*rw_lock_);
166 if (length < 0)
niklase@google.com470e71d2011-07-07 08:21:25 +0000167 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000168
phoglund@webrtc.org740be442012-12-12 12:52:15 +0000169 if (id_ == NULL)
170 return -1;
andrew@webrtc.org114c7902011-12-10 02:33:33 +0000171
phoglund@webrtc.org740be442012-12-12 12:52:15 +0000172 int bytes_read = static_cast<int>(fread(buf, 1, length, id_));
173 if (bytes_read != length && !looping_) {
henrike@webrtc.org9a6dac42012-09-27 22:20:34 +0000174 CloseFileImpl();
phoglund@webrtc.org740be442012-12-12 12:52:15 +0000175 }
176 return bytes_read;
177}
178
179int FileWrapperImpl::WriteText(const char* format, ...) {
180 WriteLockScoped write(*rw_lock_);
181 if (format == NULL)
182 return -1;
183
184 if (read_only_)
185 return -1;
186
187 if (id_ == NULL)
188 return -1;
189
190 va_list args;
191 va_start(args, format);
192 int num_chars = vfprintf(id_, format, args);
193 va_end(args);
194
195 if (num_chars >= 0) {
196 return num_chars;
197 } else {
198 CloseFileImpl();
199 return -1;
200 }
201}
202
203bool FileWrapperImpl::Write(const void* buf, int length) {
204 WriteLockScoped write(*rw_lock_);
205 if (buf == NULL)
niklase@google.com470e71d2011-07-07 08:21:25 +0000206 return false;
phoglund@webrtc.org740be442012-12-12 12:52:15 +0000207
208 if (length < 0)
209 return false;
210
211 if (read_only_)
212 return false;
213
214 if (id_ == NULL)
215 return false;
216
217 // Check if it's time to stop writing.
218 if (max_size_in_bytes_ > 0 &&
219 (size_in_bytes_ + length) > max_size_in_bytes_) {
220 FlushImpl();
221 return false;
222 }
223
224 size_t num_bytes = fwrite(buf, 1, length, id_);
225 if (num_bytes > 0) {
226 size_in_bytes_ += num_bytes;
227 return true;
228 }
229
230 CloseFileImpl();
231 return false;
niklase@google.com470e71d2011-07-07 08:21:25 +0000232}
andrew@webrtc.org5ae19de2011-12-13 22:59:33 +0000233
henrike@webrtc.org9a6dac42012-09-27 22:20:34 +0000234int FileWrapperImpl::CloseFileImpl() {
phoglund@webrtc.org740be442012-12-12 12:52:15 +0000235 if (id_ != NULL) {
236 fclose(id_);
237 id_ = NULL;
238 }
239 memset(file_name_utf8_, 0, kMaxFileNameSize);
240 open_ = false;
241 return 0;
henrike@webrtc.org9a6dac42012-09-27 22:20:34 +0000242}
243
244int FileWrapperImpl::FlushImpl() {
phoglund@webrtc.org740be442012-12-12 12:52:15 +0000245 if (id_ != NULL) {
246 return fflush(id_);
247 }
248 return -1;
henrike@webrtc.org9a6dac42012-09-27 22:20:34 +0000249}
250
niklase@google.com470e71d2011-07-07 08:21:25 +0000251} // namespace webrtc